Merge branch 'main' into alexdenisov+redsun82/tuple-mangling

This commit is contained in:
Paolo Tranquilli
2023-05-24 11:16:59 +02:00
committed by GitHub
1640 changed files with 111157 additions and 79250 deletions

View File

@@ -1,6 +1,6 @@
{
"extensions": [
"rust-lang.rust",
"rust-lang.rust-analyzer",
"bungcip.better-toml",
"github.vscode-codeql",
"hbenl.vscode-test-explorer",

View File

@@ -27,9 +27,9 @@ jobs:
run: |
gh api 'repos/${{github.repository}}/pulls/${{github.event.number}}/files' --paginate --jq 'any(.[].filename ; test("/change-notes/.*[.]md$"))' |
grep true -c
- name: Fail if the change note filename doesn't match the expected format. The file name must be of the form 'YYYY-MM-DD.md' or 'YYYY-MM-DD-{title}.md', where '{title}' is arbitrary text.
- name: Fail if the change note filename doesn't match the expected format. The file name must be of the form 'YYYY-MM-DD.md', 'YYYY-MM-DD-{title}.md', where '{title}' is arbitrary text, or released/x.y.z.md for released change-notes
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
gh api 'repos/${{github.repository}}/pulls/${{github.event.number}}/files' --paginate --jq '[.[].filename | select(test("/change-notes/.*[.]md$"))] | all(test("/change-notes/[0-9]{4}-[0-9]{2}-[0-9]{2}.*[.]md$"))' |
grep true -c
gh api 'repos/${{github.repository}}/pulls/${{github.event.number}}/files' --paginate --jq '[.[].filename | select(test("/change-notes/.*[.]md$"))] | all(test("/change-notes/[0-9]{4}-[0-9]{2}-[0-9]{2}.*[.]md$") or test("/change-notes/released/[0-9]*[.][0-9]*[.][0-9]*[.]md$"))' |
grep true -c

View File

@@ -32,7 +32,7 @@ jobs:
path: |
ql/extractor-pack/
ql/target/release/buramu
key: ${{ runner.os }}-${{ steps.os_version.outputs.version }}-extractor-${{ hashFiles('ql/**/Cargo.lock') }}-${{ hashFiles('ql/**/*.rs') }}
key: ${{ runner.os }}-${{ steps.os_version.outputs.version }}-extractor-${{ hashFiles('ql/**/Cargo.lock') }}-${{ hashFiles('shared/tree-sitter-extractor') }}-${{ hashFiles('ql/**/*.rs') }}
- name: Cache cargo
if: steps.cache-extractor.outputs.cache-hit != 'true'
uses: actions/cache@v3

View File

@@ -61,7 +61,7 @@ jobs:
ruby/extractor/target/release/codeql-extractor-ruby
ruby/extractor/target/release/codeql-extractor-ruby.exe
ruby/extractor/ql/lib/codeql/ruby/ast/internal/TreeSitter.qll
key: ${{ runner.os }}-${{ steps.os_version.outputs.version }}-ruby-extractor-${{ hashFiles('ruby/extractor/rust-toolchain.toml', 'ruby/extractor/Cargo.lock') }}--${{ hashFiles('ruby/extractor/**/*.rs') }}
key: ${{ runner.os }}-${{ steps.os_version.outputs.version }}-ruby-extractor-${{ hashFiles('ruby/extractor/rust-toolchain.toml', 'ruby/extractor/Cargo.lock') }}-${{ hashFiles('shared/tree-sitter-extractor') }}-${{ hashFiles('ruby/extractor/**/*.rs') }}
- uses: actions/cache@v3
if: steps.cache-extractor.outputs.cache-hit != 'true'
with:

View File

@@ -17,4 +17,6 @@ jobs:
- uses: actions/checkout@v3
- name: Check synchronized files
run: python config/sync-files.py
- name: Check dbscheme fragments
run: python config/sync-dbscheme-fragments.py

View File

@@ -0,0 +1,46 @@
name: Test tree-sitter-extractor
on:
push:
paths:
- "shared/tree-sitter-extractor/**"
- .github/workflows/tree-sitter-extractor-test.yml
branches:
- main
- "rc/*"
pull_request:
paths:
- "shared/tree-sitter-extractor/**"
- .github/workflows/tree-sitter-extractor-test.yml
branches:
- main
- "rc/*"
env:
CARGO_TERM_COLOR: always
defaults:
run:
working-directory: shared/tree-sitter-extractor
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Check formatting
run: cargo fmt --all -- --check
- name: Run tests
run: cargo test --verbose
fmt:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Check formatting
run: cargo fmt --check
clippy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Run clippy
run: cargo clippy -- --no-deps -D warnings -A clippy::new_without_default -A clippy::too_many_arguments

18
.vscode/tasks.json vendored
View File

@@ -22,6 +22,22 @@
"command": "${config:python.pythonPath}",
},
"problemMatcher": []
},
{
"label": "Accept .expected changes from CI",
"type": "process",
// Non-Windows OS will usually have Python 3 already installed at /usr/bin/python3.
"command": "python3",
"args": [
"misc/scripts/accept-expected-changes-from-ci.py"
],
"group": "build",
"windows": {
// On Windows, use whatever Python interpreter is configured for this workspace. The default is
// just `python`, so if Python is already on the path, this will find it.
"command": "${config:python.pythonPath}",
},
"problemMatcher": []
}
]
}
}

View File

@@ -40,3 +40,6 @@ WORKSPACE.bazel @github/codeql-ci-reviewers
/.github/workflows/ql-for-ql-* @github/codeql-ql-for-ql-reviewers
/.github/workflows/ruby-* @github/codeql-ruby
/.github/workflows/swift.yml @github/codeql-swift
# Misc
/misc/scripts/accept-expected-changes-from-ci.py @RasmusWL

View File

@@ -0,0 +1,33 @@
{
"files": [
"javascript/ql/lib/semmlecode.javascript.dbscheme",
"python/ql/lib/semmlecode.python.dbscheme",
"ruby/ql/lib/ruby.dbscheme",
"ql/ql/src/ql.dbscheme"
],
"fragments": [
"/*- External data -*/",
"/*- Files and folders -*/",
"/*- Diagnostic messages -*/",
"/*- Diagnostic messages: severity -*/",
"/*- Source location prefix -*/",
"/*- Lines of code -*/",
"/*- Configuration files with key value pairs -*/",
"/*- YAML -*/",
"/*- XML Files -*/",
"/*- XML: sourceline -*/",
"/*- DEPRECATED: External defects and metrics -*/",
"/*- DEPRECATED: Snapshot date -*/",
"/*- DEPRECATED: Duplicate code -*/",
"/*- DEPRECATED: Version control data -*/",
"/*- JavaScript-specific part -*/",
"/*- Ruby dbscheme -*/",
"/*- Erb dbscheme -*/",
"/*- QL dbscheme -*/",
"/*- Dbscheme dbscheme -*/",
"/*- Yaml dbscheme -*/",
"/*- Blame dbscheme -*/",
"/*- JSON dbscheme -*/",
"/*- Python dbscheme -*/"
]
}

View File

@@ -47,7 +47,6 @@
"python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl2.qll",
"python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl3.qll",
"python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl4.qll",
"python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImplForRegExp.qll",
"ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImpl1.qll",
"ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImpl2.qll",
"ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImplForHttpClientLibraries.qll",

View File

@@ -0,0 +1,86 @@
#!/usr/bin/env python3
import argparse
import json
import os
import pathlib
import re
def make_groups(blocks):
groups = {}
for block in blocks:
groups.setdefault("".join(block["lines"]), []).append(block)
return list(groups.values())
def validate_fragments(fragments):
ok = True
for header, blocks in fragments.items():
groups = make_groups(blocks)
if len(groups) > 1:
ok = False
print("Warning: dbscheme fragments with header '{}' are different for {}".format(header, ["{}:{}:{}".format(
group[0]["file"], group[0]["start"], group[0]["end"]) for group in groups]))
return ok
def main():
script_path = os.path.realpath(__file__)
script_dir = os.path.dirname(script_path)
parser = argparse.ArgumentParser(
prog=os.path.basename(script_path),
description='Sync dbscheme fragments across files.'
)
parser.add_argument('files', metavar='dbscheme_file', type=pathlib.Path, nargs='*', default=[],
help='dbscheme files to check')
args = parser.parse_args()
with open(os.path.join(script_dir, "dbscheme-fragments.json"), "r") as f:
config = json.load(f)
fragment_headers = set(config["fragments"])
fragments = {}
ok = True
for file in args.files + config["files"]:
with open(os.path.join(os.path.dirname(script_dir), file), "r") as dbscheme:
header = None
line_number = 1
block = {"file": file, "start": line_number,
"end": None, "lines": []}
def end_block():
block["end"] = line_number - 1
if len(block["lines"]) > 0:
if header is None:
if re.match(r'(?m)\A(\s|//.*$|/\*(\**[^\*])*\*+/)*\Z', "".join(block["lines"])):
# Ignore comments at the beginning of the file
pass
else:
ok = False
print("Warning: dbscheme fragment without header: {}:{}:{}".format(
block["file"], block["start"], block["end"]))
else:
fragments.setdefault(header, []).append(block)
for line in dbscheme:
m = re.match(r"^\/\*-.*-\*\/$", line)
if m:
end_block()
header = line.strip()
if header not in fragment_headers:
ok = False
print("Warning: unknown header for dbscheme fragment: '{}': {}:{}".format(
header, file, line_number))
block = {"file": file, "start": line_number,
"end": None, "lines": []}
block["lines"].append(line)
line_number += 1
block["lines"].append('\n')
line_number += 1
end_block()
if not ok or not validate_fragments(fragments):
exit(1)
if __name__ == "__main__":
main()

View File

@@ -1,3 +1,7 @@
## 0.7.1
No user-facing changes.
## 0.7.0
### Breaking Changes

View File

@@ -0,0 +1,4 @@
---
category: feature
---
* A new predicate `BarrierGuard::getAnIndirectBarrierNode` has been added to the new dataflow library (`semmle.code.cpp.dataflow.new.DataFlow`) to mark indirect expressions as barrier nodes using the `BarrierGuard` API.

View File

@@ -0,0 +1,4 @@
---
category: minorAnalysis
---
* The new dataflow (`semmle.code.cpp.dataflow.new.DataFlow`) and taint-tracking libraries (`semmle.code.cpp.dataflow.new.TaintTracking`) now support tracking flow through static local variables.

View File

@@ -0,0 +1,4 @@
---
category: majorAnalysis
---
* In the intermediate representation, handling of control flow after non-returning calls has been improved. This should remove false positives in queries that use the intermedite representation or libraries based on it, including the new data flow library.

View File

@@ -0,0 +1,4 @@
---
category: feature
---
* Added an AST-based interface (`semmle.code.cpp.rangeanalysis.new.RangeAnalysis`) for the relative range analysis library.

View File

@@ -0,0 +1,4 @@
---
category: minorAnalysis
---
* The `StdNamespace` class now also includes all inline namespaces that are children of `std` namespace.

View File

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

View File

@@ -1,2 +1,2 @@
---
lastReleaseVersion: 0.7.0
lastReleaseVersion: 0.7.1

View File

@@ -238,7 +238,7 @@ class NoReason extends Reason, TNoReason {
class CondReason extends Reason, TCondReason {
IRGuardCondition getCond() { this = TCondReason(result) }
override string toString() { result = getCond().toString() }
override string toString() { result = this.getCond().toString() }
}
/**
@@ -260,14 +260,14 @@ private predicate typeBound(IRIntegerType typ, int lowerbound, int upperbound) {
private class NarrowingCastInstruction extends ConvertInstruction {
NarrowingCastInstruction() {
not this instanceof SafeCastInstruction and
typeBound(getResultIRType(), _, _)
typeBound(this.getResultIRType(), _, _)
}
/** Gets the lower bound of the resulting type. */
int getLowerBound() { typeBound(getResultIRType(), result, _) }
int getLowerBound() { typeBound(this.getResultIRType(), result, _) }
/** Gets the upper bound of the resulting type. */
int getUpperBound() { typeBound(getResultIRType(), _, result) }
int getUpperBound() { typeBound(this.getResultIRType(), _, result) }
}
/**

View File

@@ -109,8 +109,8 @@ private predicate safeCast(IRIntegerType fromtyp, IRIntegerType totyp) {
*/
class PtrToPtrCastInstruction extends ConvertInstruction {
PtrToPtrCastInstruction() {
getResultIRType() instanceof IRAddressType and
getUnary().getResultIRType() instanceof IRAddressType
this.getResultIRType() instanceof IRAddressType and
this.getUnary().getResultIRType() instanceof IRAddressType
}
}
@@ -119,7 +119,7 @@ class PtrToPtrCastInstruction extends ConvertInstruction {
* that cannot overflow or underflow.
*/
class SafeIntCastInstruction extends ConvertInstruction {
SafeIntCastInstruction() { safeCast(getUnary().getResultIRType(), getResultIRType()) }
SafeIntCastInstruction() { safeCast(this.getUnary().getResultIRType(), this.getResultIRType()) }
}
/**

View File

@@ -50,8 +50,8 @@ private class ConstantBitwiseAndExprRange extends SimpleRangeAnalysisExpr {
// If an operand can have negative values, the lower bound is unconstrained.
// Otherwise, the lower bound is zero.
exists(float lLower, float rLower |
lLower = getFullyConvertedLowerBounds(getLeftOperand()) and
rLower = getFullyConvertedLowerBounds(getRightOperand()) and
lLower = getFullyConvertedLowerBounds(this.getLeftOperand()) and
rLower = getFullyConvertedLowerBounds(this.getRightOperand()) and
(
(lLower < 0 or rLower < 0) and
result = exprMinVal(this)
@@ -68,10 +68,10 @@ private class ConstantBitwiseAndExprRange extends SimpleRangeAnalysisExpr {
// If an operand can have negative values, the upper bound is unconstrained.
// Otherwise, the upper bound is the minimum of the upper bounds of the operands
exists(float lLower, float lUpper, float rLower, float rUpper |
lLower = getFullyConvertedLowerBounds(getLeftOperand()) and
lUpper = getFullyConvertedUpperBounds(getLeftOperand()) and
rLower = getFullyConvertedLowerBounds(getRightOperand()) and
rUpper = getFullyConvertedUpperBounds(getRightOperand()) and
lLower = getFullyConvertedLowerBounds(this.getLeftOperand()) and
lUpper = getFullyConvertedUpperBounds(this.getLeftOperand()) and
rLower = getFullyConvertedLowerBounds(this.getRightOperand()) and
rUpper = getFullyConvertedUpperBounds(this.getRightOperand()) and
(
(lLower < 0 or rLower < 0) and
result = exprMaxVal(this)
@@ -85,6 +85,6 @@ private class ConstantBitwiseAndExprRange extends SimpleRangeAnalysisExpr {
}
override predicate dependsOnChild(Expr child) {
child = getLeftOperand() or child = getRightOperand()
child = this.getLeftOperand() or child = this.getRightOperand()
}
}

View File

@@ -50,7 +50,7 @@ class ConstantRShiftExprRange extends SimpleRangeAnalysisExpr {
* We don't handle the case where `a` and `b` are both non-constant values.
*/
ConstantRShiftExprRange() {
getUnspecifiedType() instanceof IntegralType and
this.getUnspecifiedType() instanceof IntegralType and
exists(Expr l, Expr r |
l = this.(RShiftExpr).getLeftOperand() and
r = this.(RShiftExpr).getRightOperand()
@@ -84,10 +84,10 @@ class ConstantRShiftExprRange extends SimpleRangeAnalysisExpr {
override float getLowerBounds() {
exists(int lLower, int lUpper, int rLower, int rUpper |
lLower = getFullyConvertedLowerBounds(getLeftOperand()) and
lUpper = getFullyConvertedUpperBounds(getLeftOperand()) and
rLower = getFullyConvertedLowerBounds(getRightOperand()) and
rUpper = getFullyConvertedUpperBounds(getRightOperand()) and
lLower = getFullyConvertedLowerBounds(this.getLeftOperand()) and
lUpper = getFullyConvertedUpperBounds(this.getLeftOperand()) and
rLower = getFullyConvertedLowerBounds(this.getRightOperand()) and
rUpper = getFullyConvertedUpperBounds(this.getRightOperand()) and
lLower <= lUpper and
rLower <= rUpper
|
@@ -95,8 +95,8 @@ class ConstantRShiftExprRange extends SimpleRangeAnalysisExpr {
lLower < 0
or
not (
isValidShiftExprShift(rLower, getLeftOperand()) and
isValidShiftExprShift(rUpper, getLeftOperand())
isValidShiftExprShift(rLower, this.getLeftOperand()) and
isValidShiftExprShift(rUpper, this.getLeftOperand())
)
then
// We don't want to deal with shifting negative numbers at the moment,
@@ -111,10 +111,10 @@ class ConstantRShiftExprRange extends SimpleRangeAnalysisExpr {
override float getUpperBounds() {
exists(int lLower, int lUpper, int rLower, int rUpper |
lLower = getFullyConvertedLowerBounds(getLeftOperand()) and
lUpper = getFullyConvertedUpperBounds(getLeftOperand()) and
rLower = getFullyConvertedLowerBounds(getRightOperand()) and
rUpper = getFullyConvertedUpperBounds(getRightOperand()) and
lLower = getFullyConvertedLowerBounds(this.getLeftOperand()) and
lUpper = getFullyConvertedUpperBounds(this.getLeftOperand()) and
rLower = getFullyConvertedLowerBounds(this.getRightOperand()) and
rUpper = getFullyConvertedUpperBounds(this.getRightOperand()) and
lLower <= lUpper and
rLower <= rUpper
|
@@ -122,8 +122,8 @@ class ConstantRShiftExprRange extends SimpleRangeAnalysisExpr {
lLower < 0
or
not (
isValidShiftExprShift(rLower, getLeftOperand()) and
isValidShiftExprShift(rUpper, getLeftOperand())
isValidShiftExprShift(rLower, this.getLeftOperand()) and
isValidShiftExprShift(rUpper, this.getLeftOperand())
)
then
// We don't want to deal with shifting negative numbers at the moment,
@@ -137,7 +137,7 @@ class ConstantRShiftExprRange extends SimpleRangeAnalysisExpr {
}
override predicate dependsOnChild(Expr child) {
child = getLeftOperand() or child = getRightOperand()
child = this.getLeftOperand() or child = this.getRightOperand()
}
}
@@ -163,7 +163,7 @@ class ConstantLShiftExprRange extends SimpleRangeAnalysisExpr {
* We don't handle the case where `a` and `b` are both non-constant values.
*/
ConstantLShiftExprRange() {
getUnspecifiedType() instanceof IntegralType and
this.getUnspecifiedType() instanceof IntegralType and
exists(Expr l, Expr r |
l = this.(LShiftExpr).getLeftOperand() and
r = this.(LShiftExpr).getRightOperand()
@@ -197,10 +197,10 @@ class ConstantLShiftExprRange extends SimpleRangeAnalysisExpr {
override float getLowerBounds() {
exists(int lLower, int lUpper, int rLower, int rUpper |
lLower = getFullyConvertedLowerBounds(getLeftOperand()) and
lUpper = getFullyConvertedUpperBounds(getLeftOperand()) and
rLower = getFullyConvertedLowerBounds(getRightOperand()) and
rUpper = getFullyConvertedUpperBounds(getRightOperand()) and
lLower = getFullyConvertedLowerBounds(this.getLeftOperand()) and
lUpper = getFullyConvertedUpperBounds(this.getLeftOperand()) and
rLower = getFullyConvertedLowerBounds(this.getRightOperand()) and
rUpper = getFullyConvertedUpperBounds(this.getRightOperand()) and
lLower <= lUpper and
rLower <= rUpper
|
@@ -208,8 +208,8 @@ class ConstantLShiftExprRange extends SimpleRangeAnalysisExpr {
lLower < 0
or
not (
isValidShiftExprShift(rLower, getLeftOperand()) and
isValidShiftExprShift(rUpper, getLeftOperand())
isValidShiftExprShift(rLower, this.getLeftOperand()) and
isValidShiftExprShift(rUpper, this.getLeftOperand())
)
then
// We don't want to deal with shifting negative numbers at the moment,
@@ -228,10 +228,10 @@ class ConstantLShiftExprRange extends SimpleRangeAnalysisExpr {
override float getUpperBounds() {
exists(int lLower, int lUpper, int rLower, int rUpper |
lLower = getFullyConvertedLowerBounds(getLeftOperand()) and
lUpper = getFullyConvertedUpperBounds(getLeftOperand()) and
rLower = getFullyConvertedLowerBounds(getRightOperand()) and
rUpper = getFullyConvertedUpperBounds(getRightOperand()) and
lLower = getFullyConvertedLowerBounds(this.getLeftOperand()) and
lUpper = getFullyConvertedUpperBounds(this.getLeftOperand()) and
rLower = getFullyConvertedLowerBounds(this.getRightOperand()) and
rUpper = getFullyConvertedUpperBounds(this.getRightOperand()) and
lLower <= lUpper and
rLower <= rUpper
|
@@ -239,8 +239,8 @@ class ConstantLShiftExprRange extends SimpleRangeAnalysisExpr {
lLower < 0
or
not (
isValidShiftExprShift(rLower, getLeftOperand()) and
isValidShiftExprShift(rUpper, getLeftOperand())
isValidShiftExprShift(rLower, this.getLeftOperand()) and
isValidShiftExprShift(rUpper, this.getLeftOperand())
)
then
// We don't want to deal with shifting negative numbers at the moment,
@@ -258,6 +258,6 @@ class ConstantLShiftExprRange extends SimpleRangeAnalysisExpr {
}
override predicate dependsOnChild(Expr child) {
child = getLeftOperand() or child = getRightOperand()
child = this.getLeftOperand() or child = this.getRightOperand()
}
}

View File

@@ -83,20 +83,23 @@ private class ExprRangeNode extends DataFlow::ExprNode {
private string getCallBounds(Call e) {
result =
getExprBoundAsString(e) + "(" +
concat(Expr arg, int i | arg = e.getArgument(i) | getIntegralBounds(arg) order by i, ",") +
")"
concat(Expr arg, int i |
arg = e.getArgument(i)
|
this.getIntegralBounds(arg), "," order by i
) + ")"
}
override string toString() {
exists(Expr e | e = getExpr() |
exists(Expr e | e = this.getExpr() |
if hasIntegralOrReferenceIntegralType(e)
then
result = super.toString() + ": " + getOperationBounds(e)
result = super.toString() + ": " + this.getOperationBounds(e)
or
result = super.toString() + ": " + getCallBounds(e)
result = super.toString() + ": " + this.getCallBounds(e)
or
not exists(getOperationBounds(e)) and
not exists(getCallBounds(e)) and
not exists(this.getOperationBounds(e)) and
not exists(this.getCallBounds(e)) and
result = super.toString() + ": " + getExprBoundAsString(e)
else result = super.toString()
)
@@ -108,8 +111,8 @@ private class ExprRangeNode extends DataFlow::ExprNode {
*/
private class ReferenceArgumentRangeNode extends DataFlow::DefinitionByReferenceNode {
override string toString() {
if hasIntegralOrReferenceIntegralType(asDefiningArgument())
then result = super.toString() + ": " + getExprBoundAsString(getArgument())
if hasIntegralOrReferenceIntegralType(this.asDefiningArgument())
then result = super.toString() + ": " + getExprBoundAsString(this.getArgument())
else result = super.toString()
}
}

View File

@@ -7,12 +7,12 @@ private import experimental.semmle.code.cpp.models.interfaces.SimpleRangeAnalysi
*/
class StrlenLiteralRangeExpr extends SimpleRangeAnalysisExpr, FunctionCall {
StrlenLiteralRangeExpr() {
getTarget().hasGlobalOrStdName("strlen") and getArgument(0).isConstant()
this.getTarget().hasGlobalOrStdName("strlen") and this.getArgument(0).isConstant()
}
override int getLowerBounds() { result = getArgument(0).getValue().length() }
override int getLowerBounds() { result = this.getArgument(0).getValue().length() }
override int getUpperBounds() { result = getArgument(0).getValue().length() }
override int getUpperBounds() { result = this.getArgument(0).getValue().length() }
override predicate dependsOnChild(Expr e) { none() }
}

View File

@@ -3,8 +3,8 @@ import experimental.semmle.code.cpp.models.interfaces.SimpleRangeAnalysisExpr
private class SelfSub extends SimpleRangeAnalysisExpr, SubExpr {
SelfSub() {
// Match `x - x` but not `myInt - (unsigned char)myInt`.
getLeftOperand().getExplicitlyConverted().(VariableAccess).getTarget() =
getRightOperand().getExplicitlyConverted().(VariableAccess).getTarget()
this.getLeftOperand().getExplicitlyConverted().(VariableAccess).getTarget() =
this.getRightOperand().getExplicitlyConverted().(VariableAccess).getTarget()
}
override float getLowerBounds() { result = 0 }

View File

@@ -1,5 +1,5 @@
name: codeql/cpp-all
version: 0.7.1-dev
version: 0.7.2-dev
groups: cpp
dbscheme: semmlecode.cpp.dbscheme
extractor: cpp
@@ -9,3 +9,4 @@ dependencies:
codeql/ssa: ${workspace}
codeql/tutorial: ${workspace}
codeql/util: ${workspace}
warnOnImplicitThis: true

View File

@@ -42,7 +42,7 @@ class Compilation extends @compilation {
}
/** Gets a file compiled during this invocation. */
File getAFileCompiled() { result = getFileCompiled(_) }
File getAFileCompiled() { result = this.getFileCompiled(_) }
/** Gets the `i`th file compiled during this invocation */
File getFileCompiled(int i) { compilation_compiling_files(this, i, unresolveElement(result)) }
@@ -74,7 +74,7 @@ class Compilation extends @compilation {
/**
* Gets an argument passed to the extractor on this invocation.
*/
string getAnArgument() { result = getArgument(_) }
string getAnArgument() { result = this.getArgument(_) }
/**
* Gets the `i`th argument passed to the extractor on this invocation.

View File

@@ -39,7 +39,8 @@ class Field extends MemberVariable {
* complete most-derived object.
*/
int getAByteOffsetIn(Class mostDerivedClass) {
result = mostDerivedClass.getABaseClassByteOffset(getDeclaringType()) + getByteOffset()
result =
mostDerivedClass.getABaseClassByteOffset(this.getDeclaringType()) + this.getByteOffset()
}
/**
@@ -116,10 +117,10 @@ class BitField extends Field {
int getBitOffset() { fieldoffsets(underlyingElement(this), _, result) }
/** Holds if this bitfield is anonymous. */
predicate isAnonymous() { hasName("(unnamed bitfield)") }
predicate isAnonymous() { this.hasName("(unnamed bitfield)") }
override predicate isInitializable() {
// Anonymous bitfields are not initializable.
not isAnonymous()
not this.isAnonymous()
}
}

View File

@@ -24,10 +24,10 @@ class LinkTarget extends @link_target {
* captured as part of the snapshot, then everything is grouped together
* into a single dummy link target.
*/
predicate isDummy() { getBinary().getAbsolutePath() = "" }
predicate isDummy() { this.getBinary().getAbsolutePath() = "" }
/** Gets a textual representation of this element. */
string toString() { result = getBinary().getAbsolutePath() }
string toString() { result = this.getBinary().getAbsolutePath() }
/**
* Gets a function which was compiled into this link target, or had its

View File

@@ -24,7 +24,7 @@ class NameQualifier extends NameQualifiableElement, @namequalifier {
* Gets the expression ultimately qualified by the chain of name
* qualifiers. For example, `f()` in `N1::N2::f()`.
*/
Expr getExpr() { result = getQualifiedElement+() }
Expr getExpr() { result = this.getQualifiedElement+() }
/** Gets a location for this name qualifier. */
override Location getLocation() { namequalifiers(underlyingElement(this), _, _, result) }
@@ -56,12 +56,12 @@ class NameQualifier extends NameQualifiableElement, @namequalifier {
if nqe instanceof SpecialNameQualifyingElement
then
exists(Access a |
a = getQualifiedElement() and
a = this.getQualifiedElement() and
result = a.getTarget().getDeclaringType()
)
or
exists(FunctionCall c |
c = getQualifiedElement() and
c = this.getQualifiedElement() and
result = c.getTarget().getDeclaringType()
)
else result = nqe
@@ -109,7 +109,7 @@ class NameQualifiableElement extends Element, @namequalifiableelement {
* namespace.
*/
predicate hasGlobalQualifiedName() {
getNameQualifier*().getQualifyingElement() instanceof GlobalNamespace
this.getNameQualifier*().getQualifyingElement() instanceof GlobalNamespace
}
/**
@@ -119,7 +119,7 @@ class NameQualifiableElement extends Element, @namequalifiableelement {
*/
predicate hasSuperQualifiedName() {
exists(NameQualifier nq, SpecialNameQualifyingElement snqe |
nq = getNameQualifier*() and
nq = this.getNameQualifier*() and
namequalifiers(unresolveElement(nq), _, unresolveElement(snqe), _) and
snqe.getName() = "__super"
)
@@ -164,5 +164,5 @@ library class SpecialNameQualifyingElement extends NameQualifyingElement,
/** Gets the name of this special qualifying element. */
override string getName() { specialnamequalifyingelements(underlyingElement(this), result) }
override string toString() { result = getName() }
override string toString() { result = this.getName() }
}

View File

@@ -230,8 +230,12 @@ class GlobalNamespace extends Namespace {
}
/**
* The C++ `std::` namespace.
* The C++ `std::` namespace and its inline namespaces.
*/
class StdNamespace extends Namespace {
StdNamespace() { this.hasName("std") and this.getParentNamespace() instanceof GlobalNamespace }
StdNamespace() {
this.hasName("std") and this.getParentNamespace() instanceof GlobalNamespace
or
this.isInline() and this.getParentNamespace() instanceof StdNamespace
}
}

View File

@@ -37,7 +37,7 @@ class NestedFieldAccess extends FieldAccess {
NestedFieldAccess() {
ultimateQualifier = getUltimateQualifier(this) and
getTarget() = getANestedField(ultimateQualifier.getType().stripType())
this.getTarget() = getANestedField(ultimateQualifier.getType().stripType())
}
/**

View File

@@ -130,7 +130,7 @@ class PrintAstNode extends TPrintAstNode {
// The exact value of `childIndex` doesn't matter, as long as we preserve the correct order.
result =
rank[childIndex](PrintAstNode child, int nonConvertedIndex, boolean isConverted |
childAndAccessorPredicate(child, _, nonConvertedIndex, isConverted)
this.childAndAccessorPredicate(child, _, nonConvertedIndex, isConverted)
|
// Unconverted children come first, then sort by original child index within each group.
child order by isConverted, nonConvertedIndex
@@ -143,7 +143,7 @@ class PrintAstNode extends TPrintAstNode {
*/
private PrintAstNode getConvertedChild(int childIndex) {
exists(Expr expr |
expr = getChildInternal(childIndex).(AstNode).getAst() and
expr = this.getChildInternal(childIndex).(AstNode).getAst() and
expr.getFullyConverted() instanceof Conversion and
result.(AstNode).getAst() = expr.getFullyConverted() and
not expr instanceof Conversion
@@ -155,8 +155,8 @@ class PrintAstNode extends TPrintAstNode {
* at index `childIndex`, if that node has any conversions.
*/
private string getConvertedChildAccessorPredicate(int childIndex) {
exists(getConvertedChild(childIndex)) and
result = getChildAccessorPredicateInternal(childIndex) + ".getFullyConverted()"
exists(this.getConvertedChild(childIndex)) and
result = this.getChildAccessorPredicateInternal(childIndex) + ".getFullyConverted()"
}
/**
@@ -164,12 +164,12 @@ class PrintAstNode extends TPrintAstNode {
* within a function are printed, but the query can override
* `PrintASTConfiguration.shouldPrintFunction` to filter the output.
*/
final predicate shouldPrint() { shouldPrintFunction(getEnclosingFunction()) }
final predicate shouldPrint() { shouldPrintFunction(this.getEnclosingFunction()) }
/**
* Gets the children of this node.
*/
final PrintAstNode getAChild() { result = getChild(_) }
final PrintAstNode getAChild() { result = this.getChild(_) }
/**
* Gets the parent of this node, if any.
@@ -187,7 +187,7 @@ class PrintAstNode extends TPrintAstNode {
*/
string getProperty(string key) {
key = "semmle.label" and
result = toString()
result = this.toString()
}
/**
@@ -201,12 +201,12 @@ class PrintAstNode extends TPrintAstNode {
private predicate childAndAccessorPredicate(
PrintAstNode child, string childPredicate, int nonConvertedIndex, boolean isConverted
) {
child = getChildInternal(nonConvertedIndex) and
childPredicate = getChildAccessorPredicateInternal(nonConvertedIndex) and
child = this.getChildInternal(nonConvertedIndex) and
childPredicate = this.getChildAccessorPredicateInternal(nonConvertedIndex) and
isConverted = false
or
child = getConvertedChild(nonConvertedIndex) and
childPredicate = getConvertedChildAccessorPredicate(nonConvertedIndex) and
child = this.getConvertedChild(nonConvertedIndex) and
childPredicate = this.getConvertedChildAccessorPredicate(nonConvertedIndex) and
isConverted = true
}
@@ -218,7 +218,7 @@ class PrintAstNode extends TPrintAstNode {
// The exact value of `childIndex` doesn't matter, as long as we preserve the correct order.
result =
rank[childIndex](string childPredicate, int nonConvertedIndex, boolean isConverted |
childAndAccessorPredicate(_, childPredicate, nonConvertedIndex, isConverted)
this.childAndAccessorPredicate(_, childPredicate, nonConvertedIndex, isConverted)
|
// Unconverted children come first, then sort by original child index within each group.
childPredicate order by isConverted, nonConvertedIndex
@@ -234,7 +234,9 @@ class PrintAstNode extends TPrintAstNode {
/**
* Gets the `Function` that contains this node.
*/
private Function getEnclosingFunction() { result = getParent*().(FunctionNode).getFunction() }
private Function getEnclosingFunction() {
result = this.getParent*().(FunctionNode).getFunction()
}
}
/** DEPRECATED: Alias for PrintAstNode */
@@ -253,7 +255,7 @@ private class PrintableElement extends Element {
}
pragma[noinline]
string getAPrimaryQlClass0() { result = getAPrimaryQlClass() }
string getAPrimaryQlClass0() { result = this.getAPrimaryQlClass() }
}
/**
@@ -281,7 +283,7 @@ abstract class BaseAstNode extends PrintAstNode {
final Locatable getAst() { result = ast }
/** DEPRECATED: Alias for getAst */
deprecated Locatable getAST() { result = getAst() }
deprecated Locatable getAST() { result = this.getAst() }
}
/** DEPRECATED: Alias for BaseAstNode */
@@ -311,7 +313,7 @@ class ExprNode extends AstNode {
result = super.getProperty(key)
or
key = "Value" and
result = qlClass(expr) + getValue()
result = qlClass(expr) + this.getValue()
or
key = "Type" and
result = qlClass(expr.getType()) + expr.getType().toString()
@@ -321,7 +323,7 @@ class ExprNode extends AstNode {
}
override string getChildAccessorPredicateInternal(int childIndex) {
result = getChildAccessorWithoutConversions(ast, getChildInternal(childIndex).getAst())
result = getChildAccessorWithoutConversions(ast, this.getChildInternal(childIndex).getAst())
}
/**
@@ -441,7 +443,7 @@ class StmtNode extends AstNode {
}
override string getChildAccessorPredicateInternal(int childIndex) {
result = getChildAccessorWithoutConversions(ast, getChildInternal(childIndex).getAst())
result = getChildAccessorWithoutConversions(ast, this.getChildInternal(childIndex).getAst())
}
}
@@ -517,7 +519,7 @@ class ParametersNode extends PrintAstNode, TParametersNode {
}
override string getChildAccessorPredicateInternal(int childIndex) {
exists(getChildInternal(childIndex)) and
exists(this.getChildInternal(childIndex)) and
result = "getParameter(" + childIndex.toString() + ")"
}
@@ -544,7 +546,7 @@ class ConstructorInitializersNode extends PrintAstNode, TConstructorInitializers
}
final override string getChildAccessorPredicateInternal(int childIndex) {
exists(getChildInternal(childIndex)) and
exists(this.getChildInternal(childIndex)) and
result = "getInitializer(" + childIndex.toString() + ")"
}
@@ -571,7 +573,7 @@ class DestructorDestructionsNode extends PrintAstNode, TDestructorDestructionsNo
}
final override string getChildAccessorPredicateInternal(int childIndex) {
exists(getChildInternal(childIndex)) and
exists(this.getChildInternal(childIndex)) and
result = "getDestruction(" + childIndex.toString() + ")"
}
@@ -628,7 +630,7 @@ class FunctionNode extends AstNode {
override string getProperty(string key) {
result = super.getProperty(key)
or
key = "semmle.order" and result = getOrder().toString()
key = "semmle.order" and result = this.getOrder().toString()
}
/**

View File

@@ -1699,7 +1699,28 @@ class AutoType extends TemplateParameter {
private predicate suppressUnusedThis(Type t) { any() }
/** A source code location referring to a type */
/**
* A source code location referring to a user-defined type.
*
* Note that only _user-defined_ types have `TypeMention`s. In particular,
* built-in types, and derived types with built-in types as their base don't
* have any `TypeMention`s. For example, given
* ```cpp
* struct S { ... };
* void f(S s1, int i1) {
* S s2;
* S* s3;
* S& s4 = s2;
* decltype(s2) s5;
*
* int i2;
* int* i3;
* int i4[10];
* }
* ```
* there will be a `TypeMention` for the mention of `S` at `S s1`, `S s2`, and `S& s4 = s2`,
* but not at `decltype(s2) s5`. Additionally, there will be no `TypeMention`s for `int`.
*/
class TypeMention extends Locatable, @type_mention {
override string toString() { result = "type mention" }

View File

@@ -8,7 +8,7 @@ import cpp
*/
deprecated class StrcatFunction extends Function {
StrcatFunction() {
getName() =
this.getName() =
[
"strcat", // strcat(dst, src)
"strncat", // strncat(dst, src, max_amount)

View File

@@ -98,7 +98,7 @@ library class DefOrUse extends ControlFlowNodeBase {
pragma[noinline]
private predicate reaches_helper(boolean isDef, SemanticStackVariable v, BasicBlock bb, int i) {
getVariable(isDef) = v and
this.getVariable(isDef) = v and
bb.getNode(i) = this
}
@@ -118,21 +118,21 @@ library class DefOrUse extends ControlFlowNodeBase {
* predicates are duplicated for now.
*/
exists(BasicBlock bb, int i | reaches_helper(isDef, v, bb, i) |
exists(BasicBlock bb, int i | this.reaches_helper(isDef, v, bb, i) |
exists(int j |
j > i and
(bbDefAt(bb, j, v, defOrUse) or bbUseAt(bb, j, v, defOrUse)) and
not exists(int k | firstBarrierAfterThis(isDef, k, v) and k < j)
not exists(int k | this.firstBarrierAfterThis(isDef, k, v) and k < j)
)
or
not firstBarrierAfterThis(isDef, _, v) and
not this.firstBarrierAfterThis(isDef, _, v) and
bbSuccessorEntryReachesDefOrUse(bb, v, defOrUse, _)
)
}
private predicate firstBarrierAfterThis(boolean isDef, int j, SemanticStackVariable v) {
exists(BasicBlock bb, int i |
getVariable(isDef) = v and
this.getVariable(isDef) = v and
bb.getNode(i) = this and
j = min(int k | bbBarrierAt(bb, k, v, _) and k > i)
)

View File

@@ -130,7 +130,7 @@ library class SsaHelper extends int {
* Remove any custom phi nodes that are invalid.
*/
private predicate sanitized_custom_phi_node(StackVariable v, BasicBlock b) {
custom_phi_node(v, b) and
this.custom_phi_node(v, b) and
not addressTakenVariable(v) and
not isReferenceVar(v) and
b.isReachable()
@@ -142,7 +142,7 @@ library class SsaHelper extends int {
*/
cached
predicate phi_node(StackVariable v, BasicBlock b) {
frontier_phi_node(v, b) or sanitized_custom_phi_node(v, b)
this.frontier_phi_node(v, b) or this.sanitized_custom_phi_node(v, b)
}
/**
@@ -154,14 +154,15 @@ library class SsaHelper extends int {
*/
private predicate frontier_phi_node(StackVariable v, BasicBlock b) {
exists(BasicBlock x |
dominanceFrontier(x, b) and ssa_defn_rec(pragma[only_bind_into](v), pragma[only_bind_into](x))
dominanceFrontier(x, b) and
this.ssa_defn_rec(pragma[only_bind_into](v), pragma[only_bind_into](x))
) and
/* We can also eliminate those nodes where the variable is not live on any incoming edge */
live_at_start_of_bb(pragma[only_bind_into](v), b)
}
private predicate ssa_defn_rec(StackVariable v, BasicBlock b) {
phi_node(v, b)
this.phi_node(v, b)
or
variableUpdate(v, _, b, _)
}
@@ -172,7 +173,7 @@ library class SsaHelper extends int {
*/
cached
predicate ssa_defn(StackVariable v, ControlFlowNode node, BasicBlock b, int index) {
phi_node(v, b) and b.getStart() = node and index = -1
this.phi_node(v, b) and b.getStart() = node and index = -1
or
variableUpdate(v, node, b, index)
}
@@ -196,7 +197,7 @@ library class SsaHelper extends int {
* basic blocks.
*/
private predicate defUseRank(StackVariable v, BasicBlock b, int rankix, int i) {
i = rank[rankix](int j | ssa_defn(v, _, b, j) or ssa_use(v, _, b, j))
i = rank[rankix](int j | this.ssa_defn(v, _, b, j) or ssa_use(v, _, b, j))
}
/**
@@ -206,7 +207,7 @@ library class SsaHelper extends int {
* the block.
*/
private int lastRank(StackVariable v, BasicBlock b) {
result = max(int rankix | defUseRank(v, b, rankix, _)) + 1
result = max(int rankix | this.defUseRank(v, b, rankix, _)) + 1
}
/**
@@ -215,8 +216,8 @@ library class SsaHelper extends int {
*/
private predicate ssaDefRank(StackVariable v, ControlFlowNode def, BasicBlock b, int rankix) {
exists(int i |
ssa_defn(v, def, b, i) and
defUseRank(v, b, rankix, i)
this.ssa_defn(v, def, b, i) and
this.defUseRank(v, b, rankix, i)
)
}
@@ -232,21 +233,21 @@ library class SsaHelper extends int {
// use is understood to happen _before_ the definition. Phi nodes are
// at rankidx -1 and will therefore always reach the first node in the
// basic block.
ssaDefRank(v, def, b, rankix - 1)
this.ssaDefRank(v, def, b, rankix - 1)
or
ssaDefReachesRank(v, def, b, rankix - 1) and
rankix <= lastRank(v, b) and // Without this, the predicate would be infinite.
not ssaDefRank(v, _, b, rankix - 1) // Range is inclusive of but not past next def.
this.ssaDefReachesRank(v, def, b, rankix - 1) and
rankix <= this.lastRank(v, b) and // Without this, the predicate would be infinite.
not this.ssaDefRank(v, _, b, rankix - 1) // Range is inclusive of but not past next def.
}
/** Holds if SSA variable `(v, def)` reaches the end of block `b`. */
cached
predicate ssaDefinitionReachesEndOfBB(StackVariable v, ControlFlowNode def, BasicBlock b) {
live_at_exit_of_bb(v, b) and ssaDefReachesRank(v, def, b, lastRank(v, b))
live_at_exit_of_bb(v, b) and this.ssaDefReachesRank(v, def, b, this.lastRank(v, b))
or
exists(BasicBlock idom |
ssaDefinitionReachesEndOfBB(v, def, idom) and
noDefinitionsSinceIDominator(v, idom, b)
this.ssaDefinitionReachesEndOfBB(v, def, idom) and
this.noDefinitionsSinceIDominator(v, idom, b)
)
}
@@ -260,7 +261,7 @@ library class SsaHelper extends int {
private predicate noDefinitionsSinceIDominator(StackVariable v, BasicBlock idom, BasicBlock b) {
bbIDominates(idom, b) and // It is sufficient to traverse the dominator graph, cf. discussion above.
live_at_exit_of_bb(v, b) and
not ssa_defn(v, _, b, _)
not this.ssa_defn(v, _, b, _)
}
/**
@@ -269,8 +270,8 @@ library class SsaHelper extends int {
*/
private predicate ssaDefinitionReachesUseWithinBB(StackVariable v, ControlFlowNode def, Expr use) {
exists(BasicBlock b, int rankix, int i |
ssaDefReachesRank(v, def, b, rankix) and
defUseRank(v, b, rankix, i) and
this.ssaDefReachesRank(v, def, b, rankix) and
this.defUseRank(v, b, rankix, i) and
ssa_use(v, use, b, i)
)
}
@@ -279,12 +280,12 @@ library class SsaHelper extends int {
* Holds if SSA variable `(v, def)` reaches the control-flow node `use`.
*/
private predicate ssaDefinitionReaches(StackVariable v, ControlFlowNode def, Expr use) {
ssaDefinitionReachesUseWithinBB(v, def, use)
this.ssaDefinitionReachesUseWithinBB(v, def, use)
or
exists(BasicBlock b |
ssa_use(v, use, b, _) and
ssaDefinitionReachesEndOfBB(v, def, b.getAPredecessor()) and
not ssaDefinitionReachesUseWithinBB(v, _, use)
this.ssaDefinitionReachesEndOfBB(v, def, b.getAPredecessor()) and
not this.ssaDefinitionReachesUseWithinBB(v, _, use)
)
}
@@ -294,10 +295,10 @@ library class SsaHelper extends int {
*/
cached
string toString(ControlFlowNode node, StackVariable v) {
if phi_node(v, node)
if this.phi_node(v, node)
then result = "SSA phi(" + v.getName() + ")"
else (
ssa_defn(v, node, _, _) and result = "SSA def(" + v.getName() + ")"
this.ssa_defn(v, node, _, _) and result = "SSA def(" + v.getName() + ")"
)
}
@@ -307,7 +308,7 @@ library class SsaHelper extends int {
*/
cached
VariableAccess getAUse(ControlFlowNode def, StackVariable v) {
ssaDefinitionReaches(v, def, result) and
this.ssaDefinitionReaches(v, def, result) and
ssa_use(v, result, _, _)
}
}

View File

@@ -25,7 +25,7 @@ import cpp
*/
abstract class StackVariableReachability extends string {
bindingset[this]
StackVariableReachability() { length() >= 0 }
StackVariableReachability() { this.length() >= 0 }
/** Holds if `node` is a source for the reachability analysis using variable `v`. */
abstract predicate isSource(ControlFlowNode node, StackVariable v);
@@ -227,7 +227,7 @@ predicate bbSuccessorEntryReachesLoopInvariant(
*/
abstract class StackVariableReachabilityWithReassignment extends StackVariableReachability {
bindingset[this]
StackVariableReachabilityWithReassignment() { length() >= 0 }
StackVariableReachabilityWithReassignment() { this.length() >= 0 }
/** Override this predicate rather than `isSource` (`isSource` is used internally). */
abstract predicate isSourceActual(ControlFlowNode node, StackVariable v);
@@ -330,7 +330,7 @@ abstract class StackVariableReachabilityWithReassignment extends StackVariableRe
*/
abstract class StackVariableReachabilityExt extends string {
bindingset[this]
StackVariableReachabilityExt() { length() >= 0 }
StackVariableReachabilityExt() { this.length() >= 0 }
/** `node` is a source for the reachability analysis using variable `v`. */
abstract predicate isSource(ControlFlowNode node, StackVariable v);

View File

@@ -961,8 +961,16 @@ predicate recordDataFlowCallSite(DataFlowCall call, DataFlowCallable callable) {
/**
* A `Node` at which a cast can occur such that the type should be checked.
*/
class CastingNode extends Node {
class CastingNode instanceof Node {
CastingNode() { castingNode(this) }
string toString() { result = super.toString() }
predicate hasLocationInfo(
string filepath, int startline, int startcolumn, int endline, int endcolumn
) {
super.hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn)
}
}
private predicate readStepWithTypes(
@@ -1110,9 +1118,17 @@ LocalCallContext getLocalCallContext(CallContext ctx, DataFlowCallable callable)
* The value of a parameter at function entry, viewed as a node in a data
* flow graph.
*/
class ParamNode extends Node {
class ParamNode instanceof Node {
ParamNode() { parameterNode(this, _, _) }
string toString() { result = super.toString() }
predicate hasLocationInfo(
string filepath, int startline, int startcolumn, int endline, int endcolumn
) {
super.hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn)
}
/**
* Holds if this node is the parameter of callable `c` at the specified
* position.
@@ -1121,9 +1137,17 @@ class ParamNode extends Node {
}
/** A data-flow node that represents a call argument. */
class ArgNode extends Node {
class ArgNode instanceof Node {
ArgNode() { argumentNode(this, _, _) }
string toString() { result = super.toString() }
predicate hasLocationInfo(
string filepath, int startline, int startcolumn, int endline, int endcolumn
) {
super.hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn)
}
/** Holds if this argument occurs at the given position in the given call. */
final predicate argumentOf(DataFlowCall call, ArgumentPosition pos) {
argumentNode(this, call, pos)
@@ -1134,9 +1158,17 @@ class ArgNode extends Node {
* A node from which flow can return to the caller. This is either a regular
* `ReturnNode` or a `PostUpdateNode` corresponding to the value of a parameter.
*/
class ReturnNodeExt extends Node {
class ReturnNodeExt instanceof Node {
ReturnNodeExt() { returnNodeExt(this, _) }
string toString() { result = super.toString() }
predicate hasLocationInfo(
string filepath, int startline, int startcolumn, int endline, int endcolumn
) {
super.hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn)
}
/** Gets the kind of this returned value. */
ReturnKindExt getKind() { returnNodeExt(this, result) }
}
@@ -1145,8 +1177,16 @@ class ReturnNodeExt extends Node {
* A node to which data can flow from a call. Either an ordinary out node
* or a post-update node associated with a call argument.
*/
class OutNodeExt extends Node {
class OutNodeExt instanceof Node {
OutNodeExt() { outNodeExt(this) }
string toString() { result = super.toString() }
predicate hasLocationInfo(
string filepath, int startline, int startcolumn, int endline, int endcolumn
) {
super.hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn)
}
}
/**

View File

@@ -58,6 +58,9 @@ module Consistency {
predicate uniqueParameterNodePositionExclude(DataFlowCallable c, ParameterPosition pos, Node p) {
none()
}
/** Holds if `n` should be excluded from the consistency test `identityLocalStep`. */
predicate identityLocalStepExclude(Node n) { none() }
}
private class RelevantNode extends Node {
@@ -287,4 +290,10 @@ module Consistency {
not exists(unique(ContentApprox approx | approx = getContentApprox(c))) and
msg = "Non-unique content approximation."
}
query predicate identityLocalStep(Node n, string msg) {
simpleLocalFlowStep(n, n) and
not any(ConsistencyConfiguration c).identityLocalStepExclude(n) and
msg = "Node steps to itself"
}
}

View File

@@ -76,9 +76,9 @@ class GTExpr extends RelationalOperation, @gtexpr {
override string getOperator() { result = ">" }
override Expr getGreaterOperand() { result = getLeftOperand() }
override Expr getGreaterOperand() { result = this.getLeftOperand() }
override Expr getLesserOperand() { result = getRightOperand() }
override Expr getLesserOperand() { result = this.getRightOperand() }
}
/**
@@ -92,9 +92,9 @@ class LTExpr extends RelationalOperation, @ltexpr {
override string getOperator() { result = "<" }
override Expr getGreaterOperand() { result = getRightOperand() }
override Expr getGreaterOperand() { result = this.getRightOperand() }
override Expr getLesserOperand() { result = getLeftOperand() }
override Expr getLesserOperand() { result = this.getLeftOperand() }
}
/**
@@ -108,9 +108,9 @@ class GEExpr extends RelationalOperation, @geexpr {
override string getOperator() { result = ">=" }
override Expr getGreaterOperand() { result = getLeftOperand() }
override Expr getGreaterOperand() { result = this.getLeftOperand() }
override Expr getLesserOperand() { result = getRightOperand() }
override Expr getLesserOperand() { result = this.getRightOperand() }
}
/**
@@ -124,7 +124,7 @@ class LEExpr extends RelationalOperation, @leexpr {
override string getOperator() { result = "<=" }
override Expr getGreaterOperand() { result = getRightOperand() }
override Expr getGreaterOperand() { result = this.getRightOperand() }
override Expr getLesserOperand() { result = getLeftOperand() }
override Expr getLesserOperand() { result = this.getLeftOperand() }
}

View File

@@ -961,8 +961,16 @@ predicate recordDataFlowCallSite(DataFlowCall call, DataFlowCallable callable) {
/**
* A `Node` at which a cast can occur such that the type should be checked.
*/
class CastingNode extends Node {
class CastingNode instanceof Node {
CastingNode() { castingNode(this) }
string toString() { result = super.toString() }
predicate hasLocationInfo(
string filepath, int startline, int startcolumn, int endline, int endcolumn
) {
super.hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn)
}
}
private predicate readStepWithTypes(
@@ -1110,9 +1118,17 @@ LocalCallContext getLocalCallContext(CallContext ctx, DataFlowCallable callable)
* The value of a parameter at function entry, viewed as a node in a data
* flow graph.
*/
class ParamNode extends Node {
class ParamNode instanceof Node {
ParamNode() { parameterNode(this, _, _) }
string toString() { result = super.toString() }
predicate hasLocationInfo(
string filepath, int startline, int startcolumn, int endline, int endcolumn
) {
super.hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn)
}
/**
* Holds if this node is the parameter of callable `c` at the specified
* position.
@@ -1121,9 +1137,17 @@ class ParamNode extends Node {
}
/** A data-flow node that represents a call argument. */
class ArgNode extends Node {
class ArgNode instanceof Node {
ArgNode() { argumentNode(this, _, _) }
string toString() { result = super.toString() }
predicate hasLocationInfo(
string filepath, int startline, int startcolumn, int endline, int endcolumn
) {
super.hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn)
}
/** Holds if this argument occurs at the given position in the given call. */
final predicate argumentOf(DataFlowCall call, ArgumentPosition pos) {
argumentNode(this, call, pos)
@@ -1134,9 +1158,17 @@ class ArgNode extends Node {
* A node from which flow can return to the caller. This is either a regular
* `ReturnNode` or a `PostUpdateNode` corresponding to the value of a parameter.
*/
class ReturnNodeExt extends Node {
class ReturnNodeExt instanceof Node {
ReturnNodeExt() { returnNodeExt(this, _) }
string toString() { result = super.toString() }
predicate hasLocationInfo(
string filepath, int startline, int startcolumn, int endline, int endcolumn
) {
super.hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn)
}
/** Gets the kind of this returned value. */
ReturnKindExt getKind() { returnNodeExt(this, result) }
}
@@ -1145,8 +1177,16 @@ class ReturnNodeExt extends Node {
* A node to which data can flow from a call. Either an ordinary out node
* or a post-update node associated with a call argument.
*/
class OutNodeExt extends Node {
class OutNodeExt instanceof Node {
OutNodeExt() { outNodeExt(this) }
string toString() { result = super.toString() }
predicate hasLocationInfo(
string filepath, int startline, int startcolumn, int endline, int endcolumn
) {
super.hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn)
}
}
/**

View File

@@ -58,6 +58,9 @@ module Consistency {
predicate uniqueParameterNodePositionExclude(DataFlowCallable c, ParameterPosition pos, Node p) {
none()
}
/** Holds if `n` should be excluded from the consistency test `identityLocalStep`. */
predicate identityLocalStepExclude(Node n) { none() }
}
private class RelevantNode extends Node {
@@ -287,4 +290,10 @@ module Consistency {
not exists(unique(ContentApprox approx | approx = getContentApprox(c))) and
msg = "Non-unique content approximation."
}
query predicate identityLocalStep(Node n, string msg) {
simpleLocalFlowStep(n, n) and
not any(ConsistencyConfiguration c).identityLocalStepExclude(n) and
msg = "Node steps to itself"
}
}

View File

@@ -210,8 +210,8 @@ class IndirectOperand extends Node {
this.(RawIndirectOperand).getOperand() = operand and
this.(RawIndirectOperand).getIndirectionIndex() = indirectionIndex
or
this.(OperandNode).getOperand() =
Ssa::getIRRepresentationOfIndirectOperand(operand, indirectionIndex)
nodeHasOperand(this, Ssa::getIRRepresentationOfIndirectOperand(operand, indirectionIndex),
indirectionIndex - 1)
}
/** Gets the underlying operand. */
@@ -250,8 +250,8 @@ class IndirectInstruction extends Node {
this.(RawIndirectInstruction).getInstruction() = instr and
this.(RawIndirectInstruction).getIndirectionIndex() = indirectionIndex
or
this.(InstructionNode).getInstruction() =
Ssa::getIRRepresentationOfIndirectInstruction(instr, indirectionIndex)
nodeHasInstruction(this, Ssa::getIRRepresentationOfIndirectInstruction(instr, indirectionIndex),
indirectionIndex - 1)
}
/** Gets the underlying instruction. */
@@ -607,13 +607,21 @@ OutNode getAnOutNode(DataFlowCall call, ReturnKind kind) {
result.getReturnKind() = kind
}
/** A variable that behaves like a global variable. */
class GlobalLikeVariable extends Variable {
GlobalLikeVariable() {
this instanceof Cpp::GlobalOrNamespaceVariable or
this instanceof Cpp::StaticLocalVariable
}
}
/**
* Holds if data can flow from `node1` to `node2` in a way that loses the
* calling context. For example, this would happen with flow through a
* global or static variable.
*/
predicate jumpStep(Node n1, Node n2) {
exists(Cpp::GlobalOrNamespaceVariable v |
exists(GlobalLikeVariable v |
exists(Ssa::GlobalUse globalUse |
v = globalUse.getVariable() and
n1.(FinalGlobalValue).getGlobalUse() = globalUse

View File

@@ -562,6 +562,14 @@ class SsaPhiNode extends Node, TSsaPhiNode {
/** Gets the source variable underlying this phi node. */
Ssa::SourceVariable getSourceVariable() { result = phi.getSourceVariable() }
/**
* Holds if this phi node is a phi-read node.
*
* Phi-read nodes are like normal phi nodes, but they are inserted based
* on reads instead of writes.
*/
predicate isPhiRead() { phi.isPhiRead() }
}
/**
@@ -1540,7 +1548,7 @@ private module Cached {
cached
predicate simpleLocalFlowStep(Node nodeFrom, Node nodeTo) {
// Post update node -> Node flow
Ssa::ssaFlow(nodeFrom.(PostUpdateNode).getPreUpdateNode(), nodeTo)
Ssa::postUpdateFlow(nodeFrom, nodeTo)
or
// Def-use/Use-use flow
Ssa::ssaFlow(nodeFrom, nodeTo)
@@ -1903,7 +1911,38 @@ signature predicate guardChecksSig(IRGuardCondition g, Expr e, boolean branch);
* in data flow and taint tracking.
*/
module BarrierGuard<guardChecksSig/3 guardChecks> {
/** Gets a node that is safely guarded by the given guard check. */
/**
* Gets an expression node that is safely guarded by the given guard check.
*
* For example, given the following code:
* ```cpp
* int x = source();
* // ...
* if(is_safe_int(x)) {
* sink(x);
* }
* ```
* and the following barrier guard predicate:
* ```ql
* predicate myGuardChecks(IRGuardCondition g, Expr e, boolean branch) {
* exists(Call call |
* g.getUnconvertedResultExpression() = call and
* call.getTarget().hasName("is_safe_int") and
* e = call.getAnArgument() and
* branch = true
* )
* }
* ```
* implementing `isBarrier` as:
* ```ql
* predicate isBarrier(DataFlow::Node barrier) {
* barrier = DataFlow::BarrierGuard<myGuardChecks/3>::getABarrierNode()
* }
* ```
* will block flow from `x = source()` to `sink(x)`.
*
* NOTE: If an indirect expression is tracked, use `getAnIndirectBarrierNode` instead.
*/
ExprNode getABarrierNode() {
exists(IRGuardCondition g, Expr e, ValueNumber value, boolean edge |
e = value.getAnInstruction().getConvertedResultExpression() and
@@ -1912,6 +1951,84 @@ module BarrierGuard<guardChecksSig/3 guardChecks> {
g.controls(result.getBasicBlock(), edge)
)
}
/**
* Gets an indirect expression node that is safely guarded by the given guard check.
*
* For example, given the following code:
* ```cpp
* int* p;
* // ...
* *p = source();
* if(is_safe_pointer(p)) {
* sink(*p);
* }
* ```
* and the following barrier guard check:
* ```ql
* predicate myGuardChecks(IRGuardCondition g, Expr e, boolean branch) {
* exists(Call call |
* g.getUnconvertedResultExpression() = call and
* call.getTarget().hasName("is_safe_pointer") and
* e = call.getAnArgument() and
* branch = true
* )
* }
* ```
* implementing `isBarrier` as:
* ```ql
* predicate isBarrier(DataFlow::Node barrier) {
* barrier = DataFlow::BarrierGuard<myGuardChecks/3>::getAnIndirectBarrierNode()
* }
* ```
* will block flow from `x = source()` to `sink(x)`.
*
* NOTE: If a non-indirect expression is tracked, use `getABarrierNode` instead.
*/
IndirectExprNode getAnIndirectBarrierNode() { result = getAnIndirectBarrierNode(_) }
/**
* Gets an indirect expression node with indirection index `indirectionIndex` that is
* safely guarded by the given guard check.
*
* For example, given the following code:
* ```cpp
* int* p;
* // ...
* *p = source();
* if(is_safe_pointer(p)) {
* sink(*p);
* }
* ```
* and the following barrier guard check:
* ```ql
* predicate myGuardChecks(IRGuardCondition g, Expr e, boolean branch) {
* exists(Call call |
* g.getUnconvertedResultExpression() = call and
* call.getTarget().hasName("is_safe_pointer") and
* e = call.getAnArgument() and
* branch = true
* )
* }
* ```
* implementing `isBarrier` as:
* ```ql
* predicate isBarrier(DataFlow::Node barrier) {
* barrier = DataFlow::BarrierGuard<myGuardChecks/3>::getAnIndirectBarrierNode(1)
* }
* ```
* will block flow from `x = source()` to `sink(x)`.
*
* NOTE: If a non-indirect expression is tracked, use `getABarrierNode` instead.
*/
IndirectExprNode getAnIndirectBarrierNode(int indirectionIndex) {
exists(IRGuardCondition g, Expr e, ValueNumber value, boolean edge |
e = value.getAnInstruction().getConvertedResultExpression() and
result.getConvertedExpr(indirectionIndex) = e and
guardChecks(g, value.getAnInstruction().getConvertedResultExpression(), edge) and
g.controls(result.getBasicBlock(), edge)
)
}
}
/**

View File

@@ -0,0 +1,38 @@
/**
* Print the dataflow local store steps in IR dumps.
*/
private import cpp
private import semmle.code.cpp.ir.IR
private import semmle.code.cpp.ir.dataflow.internal.DataFlowUtil
private import semmle.code.cpp.ir.dataflow.internal.DataFlowPrivate
private import PrintIRUtilities
/** A property provider for local IR dataflow store steps. */
class FieldFlowPropertyProvider extends IRPropertyProvider {
override string getOperandProperty(Operand operand, string key) {
exists(PostFieldUpdateNode pfun, Content content |
key = "store " + content.toString() and
operand = pfun.getPreUpdateNode().(IndirectOperand).getOperand() and
result =
strictconcat(string element, Node node |
storeStep(node, content, pfun) and
element = nodeId(node, _, _)
|
element, ", "
)
)
or
exists(Node node2, Content content |
key = "read " + content.toString() and
operand = node2.(IndirectOperand).getOperand() and
result =
strictconcat(string element, Node node1 |
readStep(node1, content, node2) and
element = nodeId(node1, _, _)
|
element, ", "
)
)
}
}

View File

@@ -1,119 +1,44 @@
private import cpp
// The `ValueNumbering` library has to be imported right after `cpp` to ensure
// that the cached IR gets the same checksum here as it does in queries that use
// `ValueNumbering` without `DataFlow`.
private import semmle.code.cpp.ir.ValueNumbering
private import semmle.code.cpp.ir.IR
private import semmle.code.cpp.ir.dataflow.DataFlow
private import semmle.code.cpp.ir.dataflow.internal.DataFlowUtil
private import SsaInternals as Ssa
private import PrintIRUtilities
/**
* Gets the local dataflow from other nodes in the same function to this node.
*/
private string getFromFlow(DataFlow::Node useNode, int order1, int order2) {
exists(DataFlow::Node defNode, string prefix |
(
simpleLocalFlowStep(defNode, useNode) and prefix = ""
or
any(DataFlow::Configuration cfg).isAdditionalFlowStep(defNode, useNode) and
defNode.getEnclosingCallable() = useNode.getEnclosingCallable() and
prefix = "+"
) and
if defNode.asInstruction() = useNode.asOperand().getAnyDef()
then
// Shorthand for flow from the def of this operand.
result = prefix + "def" and
order1 = -1 and
order2 = 0
else
if defNode.asOperand().getUse() = useNode.asInstruction()
then
// Shorthand for flow from an operand of this instruction
result = prefix + defNode.asOperand().getDumpId() and
order1 = -1 and
order2 = defNode.asOperand().getDumpSortOrder()
else result = prefix + nodeId(defNode, order1, order2)
private string getFromFlow(Node node2, int order1, int order2) {
exists(Node node1 |
simpleLocalFlowStep(node1, node2) and
result = nodeId(node1, order1, order2)
)
}
/**
* Gets the local dataflow from this node to other nodes in the same function.
*/
private string getToFlow(DataFlow::Node defNode, int order1, int order2) {
exists(DataFlow::Node useNode, string prefix |
(
simpleLocalFlowStep(defNode, useNode) and prefix = ""
or
any(DataFlow::Configuration cfg).isAdditionalFlowStep(defNode, useNode) and
defNode.getEnclosingCallable() = useNode.getEnclosingCallable() and
prefix = "+"
) and
if useNode.asInstruction() = defNode.asOperand().getUse()
then
// Shorthand for flow to this operand's instruction.
result = prefix + "result" and
order1 = -1 and
order2 = 0
else result = prefix + nodeId(useNode, order1, order2)
private string getToFlow(Node node1, int order1, int order2) {
exists(Node node2 |
simpleLocalFlowStep(node1, node2) and
result = nodeId(node2, order1, order2)
)
}
/**
* Gets the properties of the dataflow node `node`.
*/
private string getNodeProperty(DataFlow::Node node, string key) {
private string getNodeProperty(Node node, string key) {
// List dataflow into and out of this node. Flow into this node is printed as `src->@`, and flow
// out of this node is printed as `@->dest`.
key = "flow" and
result =
strictconcat(string flow, boolean to, int order1, int order2 |
flow = getFromFlow(node, order1, order2) + "->@" and to = false
flow = getFromFlow(node, order1, order2) + "->" + starsForNode(node) + "@" and to = false
or
flow = "@->" + getToFlow(node, order1, order2) and to = true
flow = starsForNode(node) + "@->" + getToFlow(node, order1, order2) and to = true
|
flow, ", " order by to, order1, order2, flow
)
or
// Is this node a dataflow sink?
key = "sink" and
any(DataFlow::Configuration cfg).isSink(node) and
result = "true"
or
// Is this node a dataflow source?
key = "source" and
any(DataFlow::Configuration cfg).isSource(node) and
result = "true"
or
// Is this node a dataflow barrier, and if so, what kind?
key = "barrier" and
result =
strictconcat(string kind |
any(DataFlow::Configuration cfg).isBarrier(node) and kind = "full"
or
any(DataFlow::Configuration cfg).isBarrierIn(node) and kind = "in"
or
any(DataFlow::Configuration cfg).isBarrierOut(node) and kind = "out"
|
kind, ", "
)
// or
// // Is there partial flow from a source to this node?
// // This property will only be emitted if partial flow is enabled by overriding
// // `DataFlow::Configuration::explorationLimit()`.
// key = "pflow" and
// result =
// strictconcat(DataFlow::PartialPathNode sourceNode, DataFlow::PartialPathNode destNode, int dist,
// int order1, int order2 |
// any(DataFlow::Configuration cfg).hasPartialFlow(sourceNode, destNode, dist) and
// destNode.getNode() = node and
// // Only print flow from a source in the same function.
// sourceNode.getNode().getEnclosingCallable() = node.getEnclosingCallable()
// |
// nodeId(sourceNode.getNode(), order1, order2) + "+" + dist.toString(), ", "
// order by
// order1, order2, dist desc
// )
}
/**
@@ -121,16 +46,21 @@ private string getNodeProperty(DataFlow::Node node, string key) {
*/
class LocalFlowPropertyProvider extends IRPropertyProvider {
override string getOperandProperty(Operand operand, string key) {
exists(DataFlow::Node node |
operand = node.asOperand() and
exists(Node node |
operand = [node.asOperand(), node.(RawIndirectOperand).getOperand()] and
result = getNodeProperty(node, key)
)
}
override string getInstructionProperty(Instruction instruction, string key) {
exists(DataFlow::Node node |
instruction = node.asInstruction() and
exists(Node node |
instruction = [node.asInstruction(), node.(RawIndirectInstruction).getInstruction()]
|
result = getNodeProperty(node, key)
)
}
override predicate shouldPrintOperand(Operand operand) { not Ssa::ignoreOperand(operand) }
override predicate shouldPrintInstruction(Instruction instr) { not Ssa::ignoreInstruction(instr) }
}

View File

@@ -1,33 +0,0 @@
/**
* Print the dataflow local store steps in IR dumps.
*/
private import cpp
// The `ValueNumbering` library has to be imported right after `cpp` to ensure
// that the cached IR gets the same checksum here as it does in queries that use
// `ValueNumbering` without `DataFlow`.
private import semmle.code.cpp.ir.ValueNumbering
private import semmle.code.cpp.ir.IR
private import semmle.code.cpp.ir.dataflow.DataFlow
private import semmle.code.cpp.ir.dataflow.internal.DataFlowUtil
private import semmle.code.cpp.ir.dataflow.internal.DataFlowPrivate
private import PrintIRUtilities
/**
* Property provider for local IR dataflow store steps.
*/
class LocalFlowPropertyProvider extends IRPropertyProvider {
override string getInstructionProperty(Instruction instruction, string key) {
exists(DataFlow::Node objectNode, Content content |
key = "content[" + content.toString() + "]" and
instruction = objectNode.asInstruction() and
result =
strictconcat(string element, DataFlow::Node fieldNode |
storeStep(fieldNode, content, objectNode) and
element = nodeId(fieldNode, _, _)
|
element, ", "
)
)
}
}

View File

@@ -3,37 +3,59 @@
*/
private import cpp
// The `ValueNumbering` library has to be imported right after `cpp` to ensure
// that the cached IR gets the same checksum here as it does in queries that use
// `ValueNumbering` without `DataFlow`.
private import semmle.code.cpp.ir.ValueNumbering
private import semmle.code.cpp.ir.IR
private import semmle.code.cpp.ir.dataflow.DataFlow
private import semmle.code.cpp.ir.dataflow.internal.DataFlowUtil
private import semmle.code.cpp.ir.dataflow.internal.DataFlowPrivate
private string stars(int k) {
k =
[0 .. max([
any(RawIndirectInstruction n).getIndirectionIndex(),
any(RawIndirectOperand n).getIndirectionIndex()
]
)] and
(if k = 0 then result = "" else result = "*" + stars(k - 1))
}
string starsForNode(Node node) {
result = stars(node.(IndirectInstruction).getIndirectionIndex())
or
result = stars(node.(IndirectOperand).getIndirectionIndex())
or
not node instanceof IndirectInstruction and
not node instanceof IndirectOperand and
result = ""
}
private Instruction getInstruction(Node n, string stars) {
result = [n.asInstruction(), n.(RawIndirectInstruction).getInstruction()] and
stars = starsForNode(n)
}
private Operand getOperand(Node n, string stars) {
result = [n.asOperand(), n.(RawIndirectOperand).getOperand()] and
stars = starsForNode(n)
}
/**
* Gets a short ID for an IR dataflow node.
* - For `Instruction`s, this is just the result ID of the instruction (e.g. `m128`).
* - For `Operand`s, this is the label of the operand, prefixed with the result ID of the
* instruction and a dot (e.g. `m128.left`).
* - For `Variable`s, this is the qualified name of the variable.
*/
string nodeId(DataFlow::Node node, int order1, int order2) {
exists(Instruction instruction | instruction = node.asInstruction() |
result = instruction.getResultId() and
string nodeId(Node node, int order1, int order2) {
exists(Instruction instruction, string stars | instruction = getInstruction(node, stars) |
result = stars + instruction.getResultId() and
order1 = instruction.getBlock().getDisplayIndex() and
order2 = instruction.getDisplayIndexInBlock()
)
or
exists(Operand operand, Instruction instruction |
operand = node.asOperand() and
exists(Operand operand, Instruction instruction, string stars |
operand = getOperand(node, stars) and
instruction = operand.getUse()
|
result = instruction.getResultId() + "." + operand.getDumpId() and
result = stars + instruction.getResultId() + "." + operand.getDumpId() and
order1 = instruction.getBlock().getDisplayIndex() and
order2 = instruction.getDisplayIndexInBlock()
)
or
result = "var(" + node.asVariable().getQualifiedName() + ")" and
order1 = 1000000 and
order2 = 0
}

View File

@@ -1,7 +1,29 @@
import semmle.code.cpp.ir.dataflow.DataFlow
/**
* Provides a library for global (inter-procedural) data flow analysis of two
* values "simultaneously". This can be used, for example, if you want to track
* a memory allocation as well as the size of the allocation.
*
* Intuitively, you can think of this as regular dataflow, but where each node
* in the dataflow graph has been replaced by a pair of nodes `(node1, node2)`,
* and two node pairs `(n11, n12)`, `(n21, n22)` is then connected by a dataflow
* edge if there's a regular dataflow edge between `n11` and `n21`, and `n12`
* and `n22`.
*
* Note that the above intuition does not reflect the actual implementation.
*/
import semmle.code.cpp.dataflow.new.DataFlow
private import DataFlowPrivate
private import DataFlowUtil
private import DataFlowImplCommon
private import codeql.util.Unit
/**
* Provides classes for performing global (inter-procedural) data flow analyses
* on a product dataflow graph.
*/
module ProductFlow {
/** An input configuration for product data-flow. */
signature module ConfigSig {
/**
* Holds if `(source1, source2)` is a relevant data flow source.
@@ -67,6 +89,9 @@ module ProductFlow {
default predicate isBarrierIn2(DataFlow::Node node) { none() }
}
/**
* The output of a global data flow computation.
*/
module Global<ConfigSig Config> {
private module StateConfig implements StateConfigSig {
class FlowState1 = Unit;
@@ -135,6 +160,7 @@ module ProductFlow {
import GlobalWithState<StateConfig>
}
/** An input configuration for data flow using flow state. */
signature module StateConfigSig {
bindingset[this]
class FlowState1;
@@ -244,6 +270,9 @@ module ProductFlow {
default predicate isBarrierIn2(DataFlow::Node node) { none() }
}
/**
* The output of a global data flow computation.
*/
module GlobalWithState<StateConfigSig Config> {
class PathNode1 = Flow1::PathNode;
@@ -257,6 +286,7 @@ module ProductFlow {
class FlowState2 = Config::FlowState2;
/** Holds if data can flow from `(source1, source2)` to `(sink1, sink2)`. */
predicate flowPath(
Flow1::PathNode source1, Flow2::PathNode source2, Flow1::PathNode sink1, Flow2::PathNode sink2
) {
@@ -287,9 +317,9 @@ module ProductFlow {
predicate isBarrierIn(DataFlow::Node node) { Config::isBarrierIn1(node) }
}
module Flow1 = DataFlow::GlobalWithState<Config1>;
private module Flow1 = DataFlow::GlobalWithState<Config1>;
module Config2 implements DataFlow::StateConfigSig {
private module Config2 implements DataFlow::StateConfigSig {
class FlowState = FlowState2;
predicate isSource(DataFlow::Node source, FlowState state) {
@@ -319,27 +349,90 @@ module ProductFlow {
predicate isBarrierIn(DataFlow::Node node) { Config::isBarrierIn2(node) }
}
module Flow2 = DataFlow::GlobalWithState<Config2>;
private module Flow2 = DataFlow::GlobalWithState<Config2>;
private predicate isSourcePair(Flow1::PathNode node1, Flow2::PathNode node2) {
Config::isSourcePair(node1.getNode(), node1.getState(), node2.getNode(), node2.getState())
}
private predicate isSinkPair(Flow1::PathNode node1, Flow2::PathNode node2) {
Config::isSinkPair(node1.getNode(), node1.getState(), node2.getNode(), node2.getState())
}
pragma[assume_small_delta]
pragma[nomagic]
private predicate fwdReachableInterprocEntry(Flow1::PathNode node1, Flow2::PathNode node2) {
isSourcePair(node1, node2)
or
fwdIsSuccessor(_, _, node1, node2)
}
pragma[nomagic]
private predicate reachableInterprocEntry(
Flow1::PathNode source1, Flow2::PathNode source2, Flow1::PathNode node1, Flow2::PathNode node2
private predicate fwdIsSuccessorExit(
Flow1::PathNode mid1, Flow2::PathNode mid2, Flow1::PathNode succ1, Flow2::PathNode succ2
) {
Config::isSourcePair(node1.getNode(), node1.getState(), node2.getNode(), node2.getState()) and
node1 = source1 and
node2 = source2
isSinkPair(mid1, mid2) and
succ1 = mid1 and
succ2 = mid2
or
exists(
Flow1::PathNode midEntry1, Flow2::PathNode midEntry2, Flow1::PathNode midExit1,
Flow2::PathNode midExit2
|
reachableInterprocEntry(source1, source2, midEntry1, midEntry2) and
interprocEdgePair(midExit1, midExit2, node1, node2) and
localPathStep1*(midEntry1, midExit1) and
localPathStep2*(midEntry2, midExit2)
interprocEdgePair(mid1, mid2, succ1, succ2)
}
private predicate fwdIsSuccessor1(
Flow1::PathNode pred1, Flow2::PathNode pred2, Flow1::PathNode mid1, Flow2::PathNode mid2,
Flow1::PathNode succ1, Flow2::PathNode succ2
) {
fwdReachableInterprocEntry(pred1, pred2) and
localPathStep1*(pred1, mid1) and
fwdIsSuccessorExit(pragma[only_bind_into](mid1), pragma[only_bind_into](mid2), succ1, succ2)
}
private predicate fwdIsSuccessor2(
Flow1::PathNode pred1, Flow2::PathNode pred2, Flow1::PathNode mid1, Flow2::PathNode mid2,
Flow1::PathNode succ1, Flow2::PathNode succ2
) {
fwdReachableInterprocEntry(pred1, pred2) and
localPathStep2*(pred2, mid2) and
fwdIsSuccessorExit(pragma[only_bind_into](mid1), pragma[only_bind_into](mid2), succ1, succ2)
}
pragma[assume_small_delta]
private predicate fwdIsSuccessor(
Flow1::PathNode pred1, Flow2::PathNode pred2, Flow1::PathNode succ1, Flow2::PathNode succ2
) {
exists(Flow1::PathNode mid1, Flow2::PathNode mid2 |
fwdIsSuccessor1(pred1, pred2, mid1, mid2, succ1, succ2) and
fwdIsSuccessor2(pred1, pred2, mid1, mid2, succ1, succ2)
)
}
pragma[assume_small_delta]
pragma[nomagic]
private predicate revReachableInterprocEntry(Flow1::PathNode node1, Flow2::PathNode node2) {
fwdReachableInterprocEntry(node1, node2) and
isSinkPair(node1, node2)
or
exists(Flow1::PathNode succ1, Flow2::PathNode succ2 |
revReachableInterprocEntry(succ1, succ2) and
fwdIsSuccessor(node1, node2, succ1, succ2)
)
}
private newtype TNodePair =
TMkNodePair(Flow1::PathNode node1, Flow2::PathNode node2) {
revReachableInterprocEntry(node1, node2)
}
private predicate pathSucc(TNodePair n1, TNodePair n2) {
exists(Flow1::PathNode n11, Flow2::PathNode n12, Flow1::PathNode n21, Flow2::PathNode n22 |
n1 = TMkNodePair(n11, n12) and
n2 = TMkNodePair(n21, n22) and
fwdIsSuccessor(n11, n12, n21, n22)
)
}
private predicate pathSuccPlus(TNodePair n1, TNodePair n2) = fastTC(pathSucc/2)(n1, n2)
private predicate localPathStep1(Flow1::PathNode pred, Flow1::PathNode succ) {
Flow1::PathGraph::edges(pred, succ) and
pragma[only_bind_out](pred.getNode().getEnclosingCallable()) =
@@ -352,43 +445,133 @@ module ProductFlow {
pragma[only_bind_out](succ.getNode().getEnclosingCallable())
}
private newtype TKind =
TInto(DataFlowCall call) {
intoImpl1(_, _, call) or
intoImpl2(_, _, call)
} or
TOutOf(DataFlowCall call) {
outImpl1(_, _, call) or
outImpl2(_, _, call)
} or
TJump()
private predicate intoImpl1(Flow1::PathNode pred1, Flow1::PathNode succ1, DataFlowCall call) {
Flow1::PathGraph::edges(pred1, succ1) and
pred1.getNode().(ArgumentNode).getCall() = call and
succ1.getNode() instanceof ParameterNode
}
private predicate into1(Flow1::PathNode pred1, Flow1::PathNode succ1, TKind kind) {
exists(DataFlowCall call |
kind = TInto(call) and
intoImpl1(pred1, succ1, call)
)
}
private predicate outImpl1(Flow1::PathNode pred1, Flow1::PathNode succ1, DataFlowCall call) {
Flow1::PathGraph::edges(pred1, succ1) and
exists(ReturnKindExt returnKind |
succ1.getNode() = returnKind.getAnOutNode(call) and
pred1.getNode().(ReturnNodeExt).getKind() = returnKind
)
}
private predicate out1(Flow1::PathNode pred1, Flow1::PathNode succ1, TKind kind) {
exists(DataFlowCall call |
outImpl1(pred1, succ1, call) and
kind = TOutOf(call)
)
}
private predicate intoImpl2(Flow2::PathNode pred2, Flow2::PathNode succ2, DataFlowCall call) {
Flow2::PathGraph::edges(pred2, succ2) and
pred2.getNode().(ArgumentNode).getCall() = call and
succ2.getNode() instanceof ParameterNode
}
private predicate into2(Flow2::PathNode pred2, Flow2::PathNode succ2, TKind kind) {
exists(DataFlowCall call |
kind = TInto(call) and
intoImpl2(pred2, succ2, call)
)
}
private predicate outImpl2(Flow2::PathNode pred2, Flow2::PathNode succ2, DataFlowCall call) {
Flow2::PathGraph::edges(pred2, succ2) and
exists(ReturnKindExt returnKind |
succ2.getNode() = returnKind.getAnOutNode(call) and
pred2.getNode().(ReturnNodeExt).getKind() = returnKind
)
}
private predicate out2(Flow2::PathNode pred2, Flow2::PathNode succ2, TKind kind) {
exists(DataFlowCall call |
kind = TOutOf(call) and
outImpl2(pred2, succ2, call)
)
}
pragma[nomagic]
private predicate interprocEdge1(
Declaration predDecl, Declaration succDecl, Flow1::PathNode pred1, Flow1::PathNode succ1
Declaration predDecl, Declaration succDecl, Flow1::PathNode pred1, Flow1::PathNode succ1,
TKind kind
) {
Flow1::PathGraph::edges(pred1, succ1) and
predDecl != succDecl and
pred1.getNode().getEnclosingCallable() = predDecl and
succ1.getNode().getEnclosingCallable() = succDecl
succ1.getNode().getEnclosingCallable() = succDecl and
(
into1(pred1, succ1, kind)
or
out1(pred1, succ1, kind)
or
kind = TJump() and
not into1(pred1, succ1, _) and
not out1(pred1, succ1, _)
)
}
pragma[nomagic]
private predicate interprocEdge2(
Declaration predDecl, Declaration succDecl, Flow2::PathNode pred2, Flow2::PathNode succ2
Declaration predDecl, Declaration succDecl, Flow2::PathNode pred2, Flow2::PathNode succ2,
TKind kind
) {
Flow2::PathGraph::edges(pred2, succ2) and
predDecl != succDecl and
pred2.getNode().getEnclosingCallable() = predDecl and
succ2.getNode().getEnclosingCallable() = succDecl
succ2.getNode().getEnclosingCallable() = succDecl and
(
into2(pred2, succ2, kind)
or
out2(pred2, succ2, kind)
or
kind = TJump() and
not into2(pred2, succ2, _) and
not out2(pred2, succ2, _)
)
}
private predicate interprocEdgePair(
Flow1::PathNode pred1, Flow2::PathNode pred2, Flow1::PathNode succ1, Flow2::PathNode succ2
) {
exists(Declaration predDecl, Declaration succDecl |
interprocEdge1(predDecl, succDecl, pred1, succ1) and
interprocEdge2(predDecl, succDecl, pred2, succ2)
exists(Declaration predDecl, Declaration succDecl, TKind kind |
interprocEdge1(predDecl, succDecl, pred1, succ1, kind) and
interprocEdge2(predDecl, succDecl, pred2, succ2, kind)
)
}
private predicate reachable(
Flow1::PathNode source1, Flow2::PathNode source2, Flow1::PathNode sink1, Flow2::PathNode sink2
) {
exists(Flow1::PathNode mid1, Flow2::PathNode mid2 |
reachableInterprocEntry(source1, source2, mid1, mid2) and
Config::isSinkPair(sink1.getNode(), sink1.getState(), sink2.getNode(), sink2.getState()) and
localPathStep1*(mid1, sink1) and
localPathStep2*(mid2, sink2)
isSourcePair(source1, source2) and
isSinkPair(sink1, sink2) and
exists(TNodePair n1, TNodePair n2 |
n1 = TMkNodePair(source1, source2) and
n2 = TMkNodePair(sink1, sink2)
|
pathSuccPlus(n1, n2) or
n1 = n2
)
}
}

View File

@@ -145,14 +145,14 @@ private newtype TDefOrUseImpl =
or
// Since the pruning stage doesn't know about global variables we can't use the above check to
// rule out dead assignments to globals.
base.(VariableAddressInstruction).getAstVariable() instanceof Cpp::GlobalOrNamespaceVariable
base.(VariableAddressInstruction).getAstVariable() instanceof GlobalLikeVariable
)
} or
TUseImpl(Operand operand, int indirectionIndex) {
isUse(_, operand, _, _, indirectionIndex) and
not isDef(_, _, operand, _, _, _)
} or
TGlobalUse(Cpp::GlobalOrNamespaceVariable v, IRFunction f, int indirectionIndex) {
TGlobalUse(GlobalLikeVariable v, IRFunction f, int indirectionIndex) {
// Represents a final "use" of a global variable to ensure that
// the assignment to a global variable isn't ruled out as dead.
exists(VariableAddressInstruction vai, int defIndex |
@@ -162,7 +162,7 @@ private newtype TDefOrUseImpl =
indirectionIndex = [0 .. defIndex] + 1
)
} or
TGlobalDefImpl(Cpp::GlobalOrNamespaceVariable v, IRFunction f, int indirectionIndex) {
TGlobalDefImpl(GlobalLikeVariable v, IRFunction f, int indirectionIndex) {
// Represents the initial "definition" of a global variable when entering
// a function body.
exists(VariableAddressInstruction vai |
@@ -458,7 +458,7 @@ class FinalParameterUse extends UseImpl, TFinalParameterUse {
}
class GlobalUse extends UseImpl, TGlobalUse {
Cpp::GlobalOrNamespaceVariable global;
GlobalLikeVariable global;
IRFunction f;
GlobalUse() { this = TGlobalUse(global, f, ind) }
@@ -468,7 +468,7 @@ class GlobalUse extends UseImpl, TGlobalUse {
override int getIndirection() { result = ind + 1 }
/** Gets the global variable associated with this use. */
Cpp::GlobalOrNamespaceVariable getVariable() { result = global }
GlobalLikeVariable getVariable() { result = global }
/** Gets the `IRFunction` whose body is exited from after this use. */
IRFunction getIRFunction() { result = f }
@@ -496,14 +496,14 @@ class GlobalUse extends UseImpl, TGlobalUse {
}
class GlobalDefImpl extends DefOrUseImpl, TGlobalDefImpl {
Cpp::GlobalOrNamespaceVariable global;
GlobalLikeVariable global;
IRFunction f;
int indirectionIndex;
GlobalDefImpl() { this = TGlobalDefImpl(global, f, indirectionIndex) }
/** Gets the global variable associated with this definition. */
Cpp::GlobalOrNamespaceVariable getVariable() { result = global }
GlobalLikeVariable getVariable() { result = global }
/** Gets the `IRFunction` whose body is evaluated after this definition. */
IRFunction getIRFunction() { result = f }
@@ -657,27 +657,20 @@ private predicate indirectConversionFlowStep(Node nFrom, Node nTo) {
* So this predicate recurses back along conversions and `PointerArithmeticInstruction`s to find the
* first use that has provides use-use flow, and uses that target as the target of the `nodeFrom`.
*/
private predicate adjustForPointerArith(
DefOrUse defOrUse, Node nodeFrom, UseOrPhi use, boolean uncertain
) {
nodeFrom = any(PostUpdateNode pun).getPreUpdateNode() and
exists(Node adjusted |
indirectConversionFlowStep*(adjusted, nodeFrom) and
nodeToDefOrUse(adjusted, defOrUse, uncertain) and
private predicate adjustForPointerArith(PostUpdateNode pun, UseOrPhi use) {
exists(DefOrUse defOrUse, Node adjusted |
indirectConversionFlowStep*(adjusted, pun.getPreUpdateNode()) and
nodeToDefOrUse(adjusted, defOrUse, _) and
adjacentDefRead(defOrUse, use)
)
}
private predicate ssaFlowImpl(SsaDefOrUse defOrUse, Node nodeFrom, Node nodeTo, boolean uncertain) {
// `nodeFrom = any(PostUpdateNode pun).getPreUpdateNode()` is implied by adjustedForPointerArith.
exists(UseOrPhi use |
adjustForPointerArith(defOrUse, nodeFrom, use, uncertain) and
useToNode(use, nodeTo)
or
not nodeFrom = any(PostUpdateNode pun).getPreUpdateNode() and
nodeToDefOrUse(nodeFrom, defOrUse, uncertain) and
adjacentDefRead(defOrUse, use) and
useToNode(use, nodeTo)
useToNode(use, nodeTo) and
nodeFrom != nodeTo
or
// Initial global variable value to a first use
nodeFrom.(InitialGlobalValue).getGlobalDef() = defOrUse and
@@ -712,11 +705,28 @@ private Node getAPriorDefinition(SsaDefOrUse defOrUse) {
/** Holds if there is def-use or use-use flow from `nodeFrom` to `nodeTo`. */
predicate ssaFlow(Node nodeFrom, Node nodeTo) {
exists(Node nFrom, boolean uncertain, SsaDefOrUse defOrUse |
ssaFlowImpl(defOrUse, nFrom, nodeTo, uncertain) and
ssaFlowImpl(defOrUse, nFrom, nodeTo, uncertain) and nodeFrom != nodeTo
|
if uncertain = true then nodeFrom = [nFrom, getAPriorDefinition(defOrUse)] else nodeFrom = nFrom
)
}
private predicate isArgumentOfCallable(DataFlowCall call, ArgumentNode arg) {
arg.argumentOf(call, _)
}
/** Holds if there is def-use or use-use flow from `pun` to `nodeTo`. */
predicate postUpdateFlow(PostUpdateNode pun, Node nodeTo) {
exists(UseOrPhi use, Node preUpdate |
adjustForPointerArith(pun, use) and
useToNode(use, nodeTo) and
preUpdate = pun.getPreUpdateNode() and
not exists(DataFlowCall call |
isArgumentOfCallable(call, preUpdate) and isArgumentOfCallable(call, nodeTo)
)
)
}
/**
* Holds if `use` is a use of `sv` and is a next adjacent use of `phi` in
* index `i1` in basic block `bb1`.
@@ -742,6 +752,7 @@ predicate fromPhiNode(SsaPhiNode nodeFrom, Node nodeTo) {
fromPhiNodeToUse(phi, sv, bb1, i1, use)
or
exists(PhiNode phiTo |
phi != phiTo and
lastRefRedefExt(phi, _, _, phiTo) and
nodeTo.(SsaPhiNode).getPhiNode() = phiTo
)
@@ -760,13 +771,14 @@ private predicate variableWriteCand(IRBlock bb, int i, SourceVariable v) {
}
private predicate sourceVariableIsGlobal(
SourceVariable sv, Cpp::GlobalOrNamespaceVariable global, IRFunction func, int indirectionIndex
SourceVariable sv, GlobalLikeVariable global, IRFunction func, int indirectionIndex
) {
exists(IRVariable irVar, BaseIRVariable base |
sourceVariableHasBaseAndIndex(sv, base, indirectionIndex) and
irVar = base.getIRVariable() and
irVar.getEnclosingIRFunction() = func and
global = irVar.getAst()
global = irVar.getAst() and
not irVar instanceof IRDynamicInitializationFlag
)
}
@@ -919,7 +931,7 @@ class GlobalDef extends TGlobalDef, SsaDefOrUse {
IRFunction getIRFunction() { result = global.getIRFunction() }
/** Gets the global variable associated with this definition. */
Cpp::GlobalOrNamespaceVariable getVariable() { result = global.getVariable() }
GlobalLikeVariable getVariable() { result = global.getVariable() }
}
class Phi extends TPhi, SsaDefOrUse {
@@ -997,6 +1009,14 @@ class PhiNode extends SsaImpl::DefinitionExt {
this instanceof SsaImpl::PhiNode or
this instanceof SsaImpl::PhiReadNode
}
/**
* Holds if this phi node is a phi-read node.
*
* Phi-read nodes are like normal phi nodes, but they are inserted based
* on reads instead of writes.
*/
predicate isPhiRead() { this instanceof SsaImpl::PhiReadNode }
}
class DefinitionExt = SsaImpl::DefinitionExt;

View File

@@ -39,7 +39,7 @@ class IRType extends TIRType {
* Gets a string that uniquely identifies this `IRType`. This string is often the same as the
* result of `IRType.toString()`, but for some types it may be more verbose to ensure uniqueness.
*/
string getIdentityString() { result = toString() }
string getIdentityString() { result = this.toString() }
/**
* Gets the size of the type, in bytes, if known.
@@ -206,7 +206,7 @@ class IRFloatingPointType extends IRNumericType, TIRFloatingPointType {
IRFloatingPointType() { this = TIRFloatingPointType(_, base, domain) }
final override string toString() {
result = getDomainPrefix() + getBaseString() + byteSize.toString()
result = this.getDomainPrefix() + this.getBaseString() + byteSize.toString()
}
final override Language::LanguageType getCanonicalLanguageType() {

View File

@@ -135,11 +135,11 @@ class Opcode extends TOpcode {
* Holds if the instruction must have an operand with the specified `OperandTag`.
*/
final predicate hasOperand(OperandTag tag) {
hasOperandInternal(tag)
this.hasOperandInternal(tag)
or
hasAddressOperand() and tag instanceof AddressOperandTag
this.hasAddressOperand() and tag instanceof AddressOperandTag
or
hasBufferSizeOperand() and tag instanceof BufferSizeOperandTag
this.hasBufferSizeOperand() and tag instanceof BufferSizeOperandTag
}
/**

View File

@@ -77,4 +77,16 @@ class IRPropertyProvider extends TIRPropertyProvider {
* Gets the value of the property named `key` for the specified operand.
*/
string getOperandProperty(Operand operand, string key) { none() }
/**
* Holds if the instruction `instr` should be included when printing
* the IR instructions.
*/
predicate shouldPrintInstruction(Instruction instr) { any() }
/**
* Holds if the operand `operand` should be included when printing the an
* instruction's operand list.
*/
predicate shouldPrintOperand(Operand operand) { any() }
}

View File

@@ -45,7 +45,9 @@ class IRFunction extends IRFunctionBase {
* Gets the block containing the entry point of this function.
*/
pragma[noinline]
final IRBlock getEntryBlock() { result.getFirstInstruction() = getEnterFunctionInstruction() }
final IRBlock getEntryBlock() {
result.getFirstInstruction() = this.getEnterFunctionInstruction()
}
/**
* Gets all instructions in this function.

View File

@@ -39,12 +39,12 @@ class IRVariable extends TIRVariable {
/**
* Gets the type of the variable.
*/
final Language::Type getType() { getLanguageType().hasType(result, false) }
final Language::Type getType() { this.getLanguageType().hasType(result, false) }
/**
* Gets the language-neutral type of the variable.
*/
final IRType getIRType() { result = getLanguageType().getIRType() }
final IRType getIRType() { result = this.getLanguageType().getIRType() }
/**
* Gets the type of the variable.
@@ -58,7 +58,7 @@ class IRVariable extends TIRVariable {
Language::AST getAst() { none() }
/** DEPRECATED: Alias for getAst */
deprecated Language::AST getAST() { result = getAst() }
deprecated Language::AST getAST() { result = this.getAst() }
/**
* Gets an identifier string for the variable. This identifier is unique
@@ -69,7 +69,7 @@ class IRVariable extends TIRVariable {
/**
* Gets the source location of this variable.
*/
final Language::Location getLocation() { result = getAst().getLocation() }
final Language::Location getLocation() { result = this.getAst().getLocation() }
/**
* Gets the IR for the function that references this variable.
@@ -91,15 +91,15 @@ class IRUserVariable extends IRVariable, TIRUserVariable {
IRUserVariable() { this = TIRUserVariable(var, type, func) }
final override string toString() { result = getVariable().toString() }
final override string toString() { result = this.getVariable().toString() }
final override Language::AST getAst() { result = var }
/** DEPRECATED: Alias for getAst */
deprecated override Language::AST getAST() { result = getAst() }
deprecated override Language::AST getAST() { result = this.getAst() }
final override string getUniqueId() {
result = getVariable().toString() + " " + getVariable().getLocation().toString()
result = this.getVariable().toString() + " " + this.getVariable().getLocation().toString()
}
final override Language::LanguageType getLanguageType() { result = type }
@@ -166,9 +166,9 @@ class IRGeneratedVariable extends IRVariable {
final override Language::AST getAst() { result = ast }
/** DEPRECATED: Alias for getAst */
deprecated override Language::AST getAST() { result = getAst() }
deprecated override Language::AST getAST() { result = this.getAst() }
override string toString() { result = getBaseString() + getLocationString() }
override string toString() { result = this.getBaseString() + this.getLocationString() }
override string getUniqueId() { none() }
@@ -272,7 +272,7 @@ class IRStringLiteral extends IRGeneratedVariable, TIRStringLiteral {
final override predicate isReadOnly() { any() }
final override string getUniqueId() {
result = "String: " + getLocationString() + "=" + Language::getStringLiteralText(literal)
result = "String: " + this.getLocationString() + "=" + Language::getStringLiteralText(literal)
}
final override string getBaseString() { result = "#string" }
@@ -303,7 +303,8 @@ class IRDynamicInitializationFlag extends IRGeneratedVariable, TIRDynamicInitial
final Language::Variable getVariable() { result = var }
final override string getUniqueId() {
result = "Init: " + getVariable().toString() + " " + getVariable().getLocation().toString()
result =
"Init: " + this.getVariable().toString() + " " + this.getVariable().getLocation().toString()
}
final override string getBaseString() { result = "#init:" + var.toString() + ":" }
@@ -332,5 +333,5 @@ class IRParameter extends IRAutomaticVariable {
* An IR variable representing a positional parameter.
*/
class IRPositionalParameter extends IRParameter, IRAutomaticUserVariable {
final override int getIndex() { result = getVariable().(Language::Parameter).getIndex() }
final override int getIndex() { result = this.getVariable().(Language::Parameter).getIndex() }
}

View File

@@ -42,6 +42,14 @@ private predicate shouldPrintFunction(Language::Declaration decl) {
exists(PrintIRConfiguration config | config.shouldPrintFunction(decl))
}
private predicate shouldPrintInstruction(Instruction i) {
exists(IRPropertyProvider provider | provider.shouldPrintInstruction(i))
}
private predicate shouldPrintOperand(Operand operand) {
exists(IRPropertyProvider provider | provider.shouldPrintOperand(operand))
}
private string getAdditionalInstructionProperty(Instruction instr, string key) {
exists(IRPropertyProvider provider | result = provider.getInstructionProperty(instr, key))
}
@@ -84,7 +92,9 @@ private string getOperandPropertyString(Operand operand) {
private newtype TPrintableIRNode =
TPrintableIRFunction(IRFunction irFunc) { shouldPrintFunction(irFunc.getFunction()) } or
TPrintableIRBlock(IRBlock block) { shouldPrintFunction(block.getEnclosingFunction()) } or
TPrintableInstruction(Instruction instr) { shouldPrintFunction(instr.getEnclosingFunction()) }
TPrintableInstruction(Instruction instr) {
shouldPrintInstruction(instr) and shouldPrintFunction(instr.getEnclosingFunction())
}
/**
* A node to be emitted in the IR graph.
@@ -127,13 +137,13 @@ abstract private class PrintableIRNode extends TPrintableIRNode {
* Gets the value of the node property with the specified key.
*/
string getProperty(string key) {
key = "semmle.label" and result = getLabel()
key = "semmle.label" and result = this.getLabel()
or
key = "semmle.order" and result = getOrder().toString()
key = "semmle.order" and result = this.getOrder().toString()
or
key = "semmle.graphKind" and result = getGraphKind()
key = "semmle.graphKind" and result = this.getGraphKind()
or
key = "semmle.forceText" and forceText() and result = "true"
key = "semmle.forceText" and this.forceText() and result = "true"
}
}
@@ -178,7 +188,7 @@ private class PrintableIRBlock extends PrintableIRNode, TPrintableIRBlock {
PrintableIRBlock() { this = TPrintableIRBlock(block) }
override string toString() { result = getLabel() }
override string toString() { result = this.getLabel() }
override Language::Location getLocation() { result = block.getLocation() }
@@ -223,7 +233,7 @@ private class PrintableInstruction extends PrintableIRNode, TPrintableInstructio
|
resultString = instr.getResultString() and
operationString = instr.getOperationString() and
operandsString = getOperandsString() and
operandsString = this.getOperandsString() and
columnWidths(block, resultWidth, operationWidth) and
result =
resultString + getPaddingString(resultWidth - resultString.length()) + " = " +
@@ -252,7 +262,8 @@ private class PrintableInstruction extends PrintableIRNode, TPrintableInstructio
private string getOperandsString() {
result =
concat(Operand operand |
operand = instr.getAnOperand()
operand = instr.getAnOperand() and
shouldPrintOperand(operand)
|
operand.getDumpString() + getOperandPropertyString(operand), ", "
order by

View File

@@ -7,17 +7,19 @@ private import internal.ValueNumberingImports
class ValueNumber extends TValueNumber {
final string toString() { result = "GVN" }
final string getDebugString() { result = strictconcat(getAnInstruction().getResultId(), ", ") }
final string getDebugString() {
result = strictconcat(this.getAnInstruction().getResultId(), ", ")
}
final Language::Location getLocation() {
if
exists(Instruction i |
i = getAnInstruction() and not i.getLocation() instanceof Language::UnknownLocation
i = this.getAnInstruction() and not i.getLocation() instanceof Language::UnknownLocation
)
then
result =
min(Language::Location l |
l = getAnInstruction().getLocation() and not l instanceof Language::UnknownLocation
l = this.getAnInstruction().getLocation() and not l instanceof Language::UnknownLocation
|
l
order by
@@ -40,7 +42,7 @@ class ValueNumber extends TValueNumber {
final Instruction getExampleInstruction() {
result =
min(Instruction instr |
instr = getAnInstruction()
instr = this.getAnInstruction()
|
instr order by instr.getBlock().getDisplayIndex(), instr.getDisplayIndexInBlock()
)

View File

@@ -22,7 +22,7 @@ private newtype TAllocation =
abstract class Allocation extends TAllocation {
abstract string toString();
final string getAllocationString() { result = toString() }
final string getAllocationString() { result = this.toString() }
abstract Instruction getABaseInstruction();

View File

@@ -95,7 +95,9 @@ private newtype TMemoryLocation =
*/
abstract class MemoryLocation extends TMemoryLocation {
final string toString() {
if isMayAccess() then result = "?" + toStringInternal() else result = toStringInternal()
if this.isMayAccess()
then result = "?" + this.toStringInternal()
else result = this.toStringInternal()
}
abstract string toStringInternal();
@@ -110,7 +112,7 @@ abstract class MemoryLocation extends TMemoryLocation {
abstract Location getLocation();
final IRType getIRType() { result = getType().getIRType() }
final IRType getIRType() { result = this.getType().getIRType() }
abstract predicate isMayAccess();
@@ -136,7 +138,7 @@ abstract class MemoryLocation extends TMemoryLocation {
final predicate canReuseSsa() { none() }
/** DEPRECATED: Alias for canReuseSsa */
deprecated predicate canReuseSSA() { canReuseSsa() }
deprecated predicate canReuseSSA() { this.canReuseSsa() }
}
/**
@@ -191,19 +193,19 @@ class VariableMemoryLocation extends TVariableMemoryLocation, AllocationMemoryLo
}
private string getIntervalString() {
if coversEntireVariable()
if this.coversEntireVariable()
then result = ""
else result = Interval::getIntervalString(startBitOffset, endBitOffset)
}
private string getTypeString() {
if coversEntireVariable() and type = var.getIRType()
if this.coversEntireVariable() and type = var.getIRType()
then result = ""
else result = "<" + languageType.toString() + ">"
}
final override string toStringInternal() {
result = var.toString() + getIntervalString() + getTypeString()
result = var.toString() + this.getIntervalString() + this.getTypeString()
}
final override Language::LanguageType getType() {
@@ -236,7 +238,7 @@ class VariableMemoryLocation extends TVariableMemoryLocation, AllocationMemoryLo
/**
* Holds if this memory location covers the entire variable.
*/
final predicate coversEntireVariable() { varIRTypeHasBitRange(startBitOffset, endBitOffset) }
final predicate coversEntireVariable() { this.varIRTypeHasBitRange(startBitOffset, endBitOffset) }
pragma[noinline]
private predicate varIRTypeHasBitRange(int start, int end) {
@@ -262,7 +264,7 @@ class EntireAllocationMemoryLocation extends TEntireAllocationMemoryLocation,
class EntireAllocationVirtualVariable extends EntireAllocationMemoryLocation, VirtualVariable {
EntireAllocationVirtualVariable() {
not allocationEscapes(var) and
not isMayAccess()
not this.isMayAccess()
}
}
@@ -275,8 +277,8 @@ class VariableVirtualVariable extends VariableMemoryLocation, VirtualVariable {
VariableVirtualVariable() {
not allocationEscapes(var) and
type = var.getIRType() and
coversEntireVariable() and
not isMayAccess()
this.coversEntireVariable() and
not this.isMayAccess()
}
}
@@ -337,7 +339,7 @@ class AllNonLocalMemory extends TAllNonLocalMemory, MemoryLocation {
// instruction, which provides the initial definition for all memory outside of the current
// function's stack frame. This memory includes string literals and other read-only globals, so
// we allow such an access to be the definition for a use of a read-only location.
not isMayAccess()
not this.isMayAccess()
}
}
@@ -360,7 +362,7 @@ class AllAliasedMemory extends TAllAliasedMemory, MemoryLocation {
final override Location getLocation() { result = irFunc.getLocation() }
final override string getUniqueId() { result = " " + toString() }
final override string getUniqueId() { result = " " + this.toString() }
final override VirtualVariable getVirtualVariable() { result = TAllAliasedMemory(irFunc, false) }
@@ -369,7 +371,7 @@ class AllAliasedMemory extends TAllAliasedMemory, MemoryLocation {
/** A virtual variable that groups all escaped memory within a function. */
class AliasedVirtualVariable extends AllAliasedMemory, VirtualVariable {
AliasedVirtualVariable() { not isMayAccess() }
AliasedVirtualVariable() { not this.isMayAccess() }
}
/**

View File

@@ -34,9 +34,13 @@ private module Cached {
cached
predicate hasUnreachedInstructionCached(IRFunction irFunc) {
exists(OldInstruction oldInstruction |
exists(OldIR::Instruction oldInstruction |
irFunc = oldInstruction.getEnclosingIRFunction() and
Reachability::isInfeasibleInstructionSuccessor(oldInstruction, _)
(
Reachability::isInfeasibleInstructionSuccessor(oldInstruction, _)
or
oldInstruction.getOpcode() instanceof Opcode::Unreached
)
)
}
@@ -366,21 +370,19 @@ private module Cached {
then
result = getChi(getOldInstruction(instruction)) and
kind instanceof GotoEdge
else (
else
exists(OldInstruction oldInstruction |
oldInstruction = getOldInstruction(instruction) and
(
oldInstruction = getOldInstruction(instruction)
or
instruction = getChi(oldInstruction)
) and
(
if Reachability::isInfeasibleInstructionSuccessor(oldInstruction, kind)
then result = unreachedInstruction(instruction.getEnclosingIRFunction())
else result = getNewInstruction(oldInstruction.getSuccessor(kind))
)
)
or
exists(OldInstruction oldInstruction |
instruction = getChi(oldInstruction) and
result = getNewInstruction(oldInstruction.getSuccessor(kind))
)
)
}
cached

View File

@@ -40,7 +40,9 @@ abstract class OperandTag extends TOperandTag {
/**
* Gets a label that will appear before the operand when the IR is printed.
*/
final string getLabel() { if alwaysPrintLabel() then result = getId() + ":" else result = "" }
final string getLabel() {
if this.alwaysPrintLabel() then result = this.getId() + ":" else result = ""
}
/**
* Gets an identifier that uniquely identifies this operand within its instruction.

View File

@@ -19,6 +19,9 @@ newtype TInstruction =
) {
IRConstruction::Raw::hasInstruction(tag1, tag2)
} or
TRawUnreachedInstruction(IRFunctionBase irFunc) {
IRConstruction::hasUnreachedInstruction(irFunc)
} or
TUnaliasedSsaPhiInstruction(
TRawInstruction blockStartInstr, UnaliasedSsa::Ssa::MemoryLocation memoryLocation
) {

View File

@@ -77,4 +77,16 @@ class IRPropertyProvider extends TIRPropertyProvider {
* Gets the value of the property named `key` for the specified operand.
*/
string getOperandProperty(Operand operand, string key) { none() }
/**
* Holds if the instruction `instr` should be included when printing
* the IR instructions.
*/
predicate shouldPrintInstruction(Instruction instr) { any() }
/**
* Holds if the operand `operand` should be included when printing the an
* instruction's operand list.
*/
predicate shouldPrintOperand(Operand operand) { any() }
}

View File

@@ -45,7 +45,9 @@ class IRFunction extends IRFunctionBase {
* Gets the block containing the entry point of this function.
*/
pragma[noinline]
final IRBlock getEntryBlock() { result.getFirstInstruction() = getEnterFunctionInstruction() }
final IRBlock getEntryBlock() {
result.getFirstInstruction() = this.getEnterFunctionInstruction()
}
/**
* Gets all instructions in this function.

View File

@@ -39,12 +39,12 @@ class IRVariable extends TIRVariable {
/**
* Gets the type of the variable.
*/
final Language::Type getType() { getLanguageType().hasType(result, false) }
final Language::Type getType() { this.getLanguageType().hasType(result, false) }
/**
* Gets the language-neutral type of the variable.
*/
final IRType getIRType() { result = getLanguageType().getIRType() }
final IRType getIRType() { result = this.getLanguageType().getIRType() }
/**
* Gets the type of the variable.
@@ -58,7 +58,7 @@ class IRVariable extends TIRVariable {
Language::AST getAst() { none() }
/** DEPRECATED: Alias for getAst */
deprecated Language::AST getAST() { result = getAst() }
deprecated Language::AST getAST() { result = this.getAst() }
/**
* Gets an identifier string for the variable. This identifier is unique
@@ -69,7 +69,7 @@ class IRVariable extends TIRVariable {
/**
* Gets the source location of this variable.
*/
final Language::Location getLocation() { result = getAst().getLocation() }
final Language::Location getLocation() { result = this.getAst().getLocation() }
/**
* Gets the IR for the function that references this variable.
@@ -91,15 +91,15 @@ class IRUserVariable extends IRVariable, TIRUserVariable {
IRUserVariable() { this = TIRUserVariable(var, type, func) }
final override string toString() { result = getVariable().toString() }
final override string toString() { result = this.getVariable().toString() }
final override Language::AST getAst() { result = var }
/** DEPRECATED: Alias for getAst */
deprecated override Language::AST getAST() { result = getAst() }
deprecated override Language::AST getAST() { result = this.getAst() }
final override string getUniqueId() {
result = getVariable().toString() + " " + getVariable().getLocation().toString()
result = this.getVariable().toString() + " " + this.getVariable().getLocation().toString()
}
final override Language::LanguageType getLanguageType() { result = type }
@@ -166,9 +166,9 @@ class IRGeneratedVariable extends IRVariable {
final override Language::AST getAst() { result = ast }
/** DEPRECATED: Alias for getAst */
deprecated override Language::AST getAST() { result = getAst() }
deprecated override Language::AST getAST() { result = this.getAst() }
override string toString() { result = getBaseString() + getLocationString() }
override string toString() { result = this.getBaseString() + this.getLocationString() }
override string getUniqueId() { none() }
@@ -272,7 +272,7 @@ class IRStringLiteral extends IRGeneratedVariable, TIRStringLiteral {
final override predicate isReadOnly() { any() }
final override string getUniqueId() {
result = "String: " + getLocationString() + "=" + Language::getStringLiteralText(literal)
result = "String: " + this.getLocationString() + "=" + Language::getStringLiteralText(literal)
}
final override string getBaseString() { result = "#string" }
@@ -303,7 +303,8 @@ class IRDynamicInitializationFlag extends IRGeneratedVariable, TIRDynamicInitial
final Language::Variable getVariable() { result = var }
final override string getUniqueId() {
result = "Init: " + getVariable().toString() + " " + getVariable().getLocation().toString()
result =
"Init: " + this.getVariable().toString() + " " + this.getVariable().getLocation().toString()
}
final override string getBaseString() { result = "#init:" + var.toString() + ":" }
@@ -332,5 +333,5 @@ class IRParameter extends IRAutomaticVariable {
* An IR variable representing a positional parameter.
*/
class IRPositionalParameter extends IRParameter, IRAutomaticUserVariable {
final override int getIndex() { result = getVariable().(Language::Parameter).getIndex() }
final override int getIndex() { result = this.getVariable().(Language::Parameter).getIndex() }
}

View File

@@ -42,6 +42,14 @@ private predicate shouldPrintFunction(Language::Declaration decl) {
exists(PrintIRConfiguration config | config.shouldPrintFunction(decl))
}
private predicate shouldPrintInstruction(Instruction i) {
exists(IRPropertyProvider provider | provider.shouldPrintInstruction(i))
}
private predicate shouldPrintOperand(Operand operand) {
exists(IRPropertyProvider provider | provider.shouldPrintOperand(operand))
}
private string getAdditionalInstructionProperty(Instruction instr, string key) {
exists(IRPropertyProvider provider | result = provider.getInstructionProperty(instr, key))
}
@@ -84,7 +92,9 @@ private string getOperandPropertyString(Operand operand) {
private newtype TPrintableIRNode =
TPrintableIRFunction(IRFunction irFunc) { shouldPrintFunction(irFunc.getFunction()) } or
TPrintableIRBlock(IRBlock block) { shouldPrintFunction(block.getEnclosingFunction()) } or
TPrintableInstruction(Instruction instr) { shouldPrintFunction(instr.getEnclosingFunction()) }
TPrintableInstruction(Instruction instr) {
shouldPrintInstruction(instr) and shouldPrintFunction(instr.getEnclosingFunction())
}
/**
* A node to be emitted in the IR graph.
@@ -127,13 +137,13 @@ abstract private class PrintableIRNode extends TPrintableIRNode {
* Gets the value of the node property with the specified key.
*/
string getProperty(string key) {
key = "semmle.label" and result = getLabel()
key = "semmle.label" and result = this.getLabel()
or
key = "semmle.order" and result = getOrder().toString()
key = "semmle.order" and result = this.getOrder().toString()
or
key = "semmle.graphKind" and result = getGraphKind()
key = "semmle.graphKind" and result = this.getGraphKind()
or
key = "semmle.forceText" and forceText() and result = "true"
key = "semmle.forceText" and this.forceText() and result = "true"
}
}
@@ -178,7 +188,7 @@ private class PrintableIRBlock extends PrintableIRNode, TPrintableIRBlock {
PrintableIRBlock() { this = TPrintableIRBlock(block) }
override string toString() { result = getLabel() }
override string toString() { result = this.getLabel() }
override Language::Location getLocation() { result = block.getLocation() }
@@ -223,7 +233,7 @@ private class PrintableInstruction extends PrintableIRNode, TPrintableInstructio
|
resultString = instr.getResultString() and
operationString = instr.getOperationString() and
operandsString = getOperandsString() and
operandsString = this.getOperandsString() and
columnWidths(block, resultWidth, operationWidth) and
result =
resultString + getPaddingString(resultWidth - resultString.length()) + " = " +
@@ -252,7 +262,8 @@ private class PrintableInstruction extends PrintableIRNode, TPrintableInstructio
private string getOperandsString() {
result =
concat(Operand operand |
operand = instr.getAnOperand()
operand = instr.getAnOperand() and
shouldPrintOperand(operand)
|
operand.getDumpString() + getOperandPropertyString(operand), ", "
order by

View File

@@ -7,17 +7,19 @@ private import internal.ValueNumberingImports
class ValueNumber extends TValueNumber {
final string toString() { result = "GVN" }
final string getDebugString() { result = strictconcat(getAnInstruction().getResultId(), ", ") }
final string getDebugString() {
result = strictconcat(this.getAnInstruction().getResultId(), ", ")
}
final Language::Location getLocation() {
if
exists(Instruction i |
i = getAnInstruction() and not i.getLocation() instanceof Language::UnknownLocation
i = this.getAnInstruction() and not i.getLocation() instanceof Language::UnknownLocation
)
then
result =
min(Language::Location l |
l = getAnInstruction().getLocation() and not l instanceof Language::UnknownLocation
l = this.getAnInstruction().getLocation() and not l instanceof Language::UnknownLocation
|
l
order by
@@ -40,7 +42,7 @@ class ValueNumber extends TValueNumber {
final Instruction getExampleInstruction() {
result =
min(Instruction instr |
instr = getAnInstruction()
instr = this.getAnInstruction()
|
instr order by instr.getBlock().getDisplayIndex(), instr.getDisplayIndexInBlock()
)

View File

@@ -178,9 +178,9 @@ module Raw {
}
}
class TStageInstruction = TRawInstruction;
class TStageInstruction = TRawInstruction or TRawUnreachedInstruction;
predicate hasInstruction(TRawInstruction instr) { any() }
predicate hasInstruction(TStageInstruction instr) { any() }
predicate hasModeledMemoryResult(Instruction instruction) { none() }
@@ -368,6 +368,11 @@ private predicate isStrictlyForwardGoto(GotoStmt goto) {
Locatable getInstructionAst(TStageInstruction instr) {
result = getInstructionTranslatedElement(instr).getAst()
or
exists(IRFunction irFunc |
instr = TRawUnreachedInstruction(irFunc) and
result = irFunc.getFunction()
)
}
/** DEPRECATED: Alias for getInstructionAst */
@@ -377,14 +382,22 @@ deprecated Locatable getInstructionAST(TStageInstruction instr) {
CppType getInstructionResultType(TStageInstruction instr) {
getInstructionTranslatedElement(instr).hasInstruction(_, getInstructionTag(instr), result)
or
instr instanceof TRawUnreachedInstruction and
result = getVoidType()
}
predicate getInstructionOpcode(Opcode opcode, TStageInstruction instr) {
getInstructionTranslatedElement(instr).hasInstruction(opcode, getInstructionTag(instr), _)
or
instr instanceof TRawUnreachedInstruction and
opcode instanceof Opcode::Unreached
}
IRFunctionBase getInstructionEnclosingIRFunction(TStageInstruction instr) {
result.getFunction() = getInstructionTranslatedElement(instr).getFunction()
or
instr = TRawUnreachedInstruction(result)
}
Instruction getPrimaryInstructionForSideEffect(SideEffectInstruction instruction) {
@@ -393,6 +406,16 @@ Instruction getPrimaryInstructionForSideEffect(SideEffectInstruction instruction
.getPrimaryInstructionForSideEffect(getInstructionTag(instruction))
}
predicate hasUnreachedInstruction(IRFunction func) {
exists(Call c |
c.getEnclosingFunction() = func.getFunction() and
any(Options opt).exits(c.getTarget())
) and
not exists(TranslatedUnreachableReturnStmt return |
return.getEnclosingFunction().getFunction() = func.getFunction()
)
}
import CachedForDebugging
cached

View File

@@ -34,6 +34,7 @@ newtype TInstructionTag =
CallTargetTag() or
CallTag() or
CallSideEffectTag() or
CallNoReturnTag() or
AllocationSizeTag() or
AllocationElementSizeTag() or
AllocationExtentConvertTag() or

View File

@@ -8,6 +8,7 @@ private import SideEffects
private import TranslatedElement
private import TranslatedExpr
private import TranslatedFunction
private import DefaultOptions as DefaultOptions
/**
* Gets the `CallInstruction` from the `TranslatedCallExpr` for the specified expression.
@@ -30,68 +31,74 @@ abstract class TranslatedCall extends TranslatedExpr {
// The qualifier is evaluated before the call target, because the value of
// the call target may depend on the value of the qualifier for virtual
// calls.
id = -2 and result = getQualifier()
id = -2 and result = this.getQualifier()
or
id = -1 and result = getCallTarget()
id = -1 and result = this.getCallTarget()
or
result = getArgument(id)
result = this.getArgument(id)
or
id = getNumberOfArguments() and result = getSideEffects()
id = this.getNumberOfArguments() and result = this.getSideEffects()
}
final override Instruction getFirstInstruction() {
if exists(getQualifier())
then result = getQualifier().getFirstInstruction()
else result = getFirstCallTargetInstruction()
if exists(this.getQualifier())
then result = this.getQualifier().getFirstInstruction()
else result = this.getFirstCallTargetInstruction()
}
override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) {
tag = CallTag() and
opcode instanceof Opcode::Call and
resultType = getTypeForPRValue(getCallResultType())
resultType = getTypeForPRValue(this.getCallResultType())
}
override Instruction getChildSuccessor(TranslatedElement child) {
child = getQualifier() and
result = getFirstCallTargetInstruction()
child = this.getQualifier() and
result = this.getFirstCallTargetInstruction()
or
child = getCallTarget() and
result = getFirstArgumentOrCallInstruction()
child = this.getCallTarget() and
result = this.getFirstArgumentOrCallInstruction()
or
exists(int argIndex |
child = getArgument(argIndex) and
if exists(getArgument(argIndex + 1))
then result = getArgument(argIndex + 1).getFirstInstruction()
else result = getInstruction(CallTag())
child = this.getArgument(argIndex) and
if exists(this.getArgument(argIndex + 1))
then result = this.getArgument(argIndex + 1).getFirstInstruction()
else result = this.getInstruction(CallTag())
)
or
child = getSideEffects() and
result = getParent().getChildSuccessor(this)
child = this.getSideEffects() and
if this.isNoReturn()
then
result =
any(UnreachedInstruction instr |
this.getEnclosingFunction().getFunction() = instr.getEnclosingFunction()
)
else result = this.getParent().getChildSuccessor(this)
}
override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) {
kind instanceof GotoEdge and
tag = CallTag() and
result = getSideEffects().getFirstInstruction()
result = this.getSideEffects().getFirstInstruction()
}
override Instruction getInstructionRegisterOperand(InstructionTag tag, OperandTag operandTag) {
tag = CallTag() and
(
operandTag instanceof CallTargetOperandTag and
result = getCallTargetResult()
result = this.getCallTargetResult()
or
operandTag instanceof ThisArgumentOperandTag and
result = getQualifierResult()
result = this.getQualifierResult()
or
exists(PositionalArgumentOperandTag argTag |
argTag = operandTag and
result = getArgument(argTag.getArgIndex()).getResult()
result = this.getArgument(argTag.getArgIndex()).getResult()
)
)
}
final override Instruction getResult() { result = getInstruction(CallTag()) }
final override Instruction getResult() { result = this.getInstruction(CallTag()) }
/**
* Gets the result type of the call.
@@ -101,7 +108,7 @@ abstract class TranslatedCall extends TranslatedExpr {
/**
* Holds if the call has a `this` argument.
*/
predicate hasQualifier() { exists(getQualifier()) }
predicate hasQualifier() { exists(this.getQualifier()) }
/**
* Gets the `TranslatedExpr` for the indirect target of the call, if any.
@@ -114,7 +121,9 @@ abstract class TranslatedCall extends TranslatedExpr {
* it can be overridden by a subclass for cases where there is a call target
* that is not computed from an expression (e.g. a direct call).
*/
Instruction getFirstCallTargetInstruction() { result = getCallTarget().getFirstInstruction() }
Instruction getFirstCallTargetInstruction() {
result = this.getCallTarget().getFirstInstruction()
}
/**
* Gets the instruction whose result value is the target of the call. By
@@ -122,7 +131,7 @@ abstract class TranslatedCall extends TranslatedExpr {
* overridden by a subclass for cases where there is a call target that is not
* computed from an expression (e.g. a direct call).
*/
Instruction getCallTargetResult() { result = getCallTarget().getResult() }
Instruction getCallTargetResult() { result = this.getCallTarget().getResult() }
/**
* Gets the `TranslatedExpr` for the qualifier of the call (i.e. the value
@@ -136,7 +145,7 @@ abstract class TranslatedCall extends TranslatedExpr {
* overridden by a subclass for cases where there is a `this` argument that is
* not computed from a child expression (e.g. a constructor call).
*/
Instruction getQualifierResult() { result = getQualifier().getResult() }
Instruction getQualifierResult() { result = this.getQualifier().getResult() }
/**
* Gets the argument with the specified `index`. Does not include the `this`
@@ -151,9 +160,9 @@ abstract class TranslatedCall extends TranslatedExpr {
* argument. Otherwise, returns the call instruction.
*/
final Instruction getFirstArgumentOrCallInstruction() {
if hasArguments()
then result = getArgument(0).getFirstInstruction()
else result = getInstruction(CallTag())
if this.hasArguments()
then result = this.getArgument(0).getFirstInstruction()
else result = this.getInstruction(CallTag())
}
/**
@@ -161,6 +170,8 @@ abstract class TranslatedCall extends TranslatedExpr {
*/
abstract predicate hasArguments();
predicate isNoReturn() { none() }
final TranslatedSideEffects getSideEffects() { result.getExpr() = expr }
}
@@ -175,17 +186,17 @@ abstract class TranslatedSideEffects extends TranslatedElement {
/** Gets the expression whose side effects are being modeled. */
abstract Expr getExpr();
final override Locatable getAst() { result = getExpr() }
final override Locatable getAst() { result = this.getExpr() }
/** DEPRECATED: Alias for getAst */
deprecated override Locatable getAST() { result = getAst() }
deprecated override Locatable getAST() { result = this.getAst() }
final override Declaration getFunction() { result = getEnclosingDeclaration(getExpr()) }
final override Declaration getFunction() { result = getEnclosingDeclaration(this.getExpr()) }
final override TranslatedElement getChild(int i) {
result =
rank[i + 1](TranslatedSideEffect tse, int group, int indexInGroup |
tse.getPrimaryExpr() = getExpr() and
tse.getPrimaryExpr() = this.getExpr() and
tse.sortOrder(group, indexInGroup)
|
tse order by group, indexInGroup
@@ -194,10 +205,10 @@ abstract class TranslatedSideEffects extends TranslatedElement {
final override Instruction getChildSuccessor(TranslatedElement te) {
exists(int i |
getChild(i) = te and
if exists(getChild(i + 1))
then result = getChild(i + 1).getFirstInstruction()
else result = getParent().getChildSuccessor(this)
this.getChild(i) = te and
if exists(this.getChild(i + 1))
then result = this.getChild(i + 1).getFirstInstruction()
else result = this.getParent().getChildSuccessor(this)
)
}
@@ -206,10 +217,10 @@ abstract class TranslatedSideEffects extends TranslatedElement {
}
final override Instruction getFirstInstruction() {
result = getChild(0).getFirstInstruction()
result = this.getChild(0).getFirstInstruction()
or
// Some functions, like `std::move()`, have no side effects whatsoever.
not exists(getChild(0)) and result = getParent().getChildSuccessor(this)
not exists(this.getChild(0)) and result = this.getParent().getChildSuccessor(this)
}
final override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) { none() }
@@ -225,10 +236,10 @@ abstract class TranslatedSideEffects extends TranslatedElement {
*/
abstract class TranslatedDirectCall extends TranslatedCall {
final override Instruction getFirstCallTargetInstruction() {
result = getInstruction(CallTargetTag())
result = this.getInstruction(CallTargetTag())
}
final override Instruction getCallTargetResult() { result = getInstruction(CallTargetTag()) }
final override Instruction getCallTargetResult() { result = this.getInstruction(CallTargetTag()) }
override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) {
TranslatedCall.super.hasInstruction(opcode, tag, resultType)
@@ -243,7 +254,7 @@ abstract class TranslatedDirectCall extends TranslatedCall {
or
tag = CallTargetTag() and
kind instanceof GotoEdge and
result = getFirstArgumentOrCallInstruction()
result = this.getFirstArgumentOrCallInstruction()
}
}
@@ -266,6 +277,8 @@ abstract class TranslatedCallExpr extends TranslatedNonConstantExpr, TranslatedC
}
final override int getNumberOfArguments() { result = expr.getNumberOfArguments() }
final override predicate isNoReturn() { any(Options opt).exits(expr.getTarget()) }
}
/**
@@ -290,12 +303,12 @@ class TranslatedFunctionCall extends TranslatedCallExpr, TranslatedDirectCall {
}
override Instruction getQualifierResult() {
hasQualifier() and
result = getQualifier().getResult()
this.hasQualifier() and
result = this.getQualifier().getResult()
}
override predicate hasQualifier() {
exists(getQualifier()) and
exists(this.getQualifier()) and
not exists(MemberFunction func | expr.getTarget() = func and func.isStatic())
}
}
@@ -311,7 +324,7 @@ class TranslatedStructorCall extends TranslatedFunctionCall {
override Instruction getQualifierResult() {
exists(StructorCallContext context |
context = getParent() and
context = this.getParent() and
result = context.getReceiver()
)
}
@@ -362,24 +375,26 @@ abstract class TranslatedSideEffect extends TranslatedElement {
final override Instruction getChildSuccessor(TranslatedElement child) { none() }
final override Instruction getFirstInstruction() { result = getInstruction(OnlyInstructionTag()) }
final override Instruction getFirstInstruction() {
result = this.getInstruction(OnlyInstructionTag())
}
final override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType type) {
tag = OnlyInstructionTag() and
sideEffectInstruction(opcode, type)
this.sideEffectInstruction(opcode, type)
}
final override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) {
result = getParent().getChildSuccessor(this) and
result = this.getParent().getChildSuccessor(this) and
tag = OnlyInstructionTag() and
kind instanceof GotoEdge
}
final override Declaration getFunction() { result = getParent().getFunction() }
final override Declaration getFunction() { result = this.getParent().getFunction() }
final override Instruction getPrimaryInstructionForSideEffect(InstructionTag tag) {
tag = OnlyInstructionTag() and
result = getParent().(TranslatedSideEffects).getPrimaryInstruction()
result = this.getParent().(TranslatedSideEffects).getPrimaryInstruction()
}
/**
@@ -417,18 +432,18 @@ abstract class TranslatedArgumentSideEffect extends TranslatedSideEffect {
TranslatedArgumentSideEffect() { any() }
override string toString() {
isWrite() and
result = "(write side effect for " + getArgString() + ")"
this.isWrite() and
result = "(write side effect for " + this.getArgString() + ")"
or
not isWrite() and
result = "(read side effect for " + getArgString() + ")"
not this.isWrite() and
result = "(read side effect for " + this.getArgString() + ")"
}
override Call getPrimaryExpr() { result = call }
override predicate sortOrder(int group, int indexInGroup) {
indexInGroup = index and
if isWrite() then group = argumentWriteGroup() else group = argumentReadGroup()
if this.isWrite() then group = argumentWriteGroup() else group = argumentReadGroup()
}
final override int getInstructionIndex(InstructionTag tag) {
@@ -439,20 +454,20 @@ abstract class TranslatedArgumentSideEffect extends TranslatedSideEffect {
final override predicate sideEffectInstruction(Opcode opcode, CppType type) {
opcode = sideEffectOpcode and
(
isWrite() and
this.isWrite() and
(
opcode instanceof BufferAccessOpcode and
type = getUnknownType()
or
not opcode instanceof BufferAccessOpcode and
exists(Type indirectionType | indirectionType = getIndirectionType() |
exists(Type indirectionType | indirectionType = this.getIndirectionType() |
if indirectionType instanceof VoidType
then type = getUnknownType()
else type = getTypeForPRValueOrUnknown(indirectionType)
)
)
or
not isWrite() and
not this.isWrite() and
type = getVoidType()
)
}
@@ -460,7 +475,7 @@ abstract class TranslatedArgumentSideEffect extends TranslatedSideEffect {
final override CppType getInstructionMemoryOperandType(
InstructionTag tag, TypedOperandTag operandTag
) {
not isWrite() and
not this.isWrite() and
if sideEffectOpcode instanceof BufferAccessOpcode
then
result = getUnknownType() and
@@ -469,7 +484,7 @@ abstract class TranslatedArgumentSideEffect extends TranslatedSideEffect {
else
exists(Type operandType |
tag instanceof OnlyInstructionTag and
operandType = getIndirectionType() and
operandType = this.getIndirectionType() and
operandTag instanceof SideEffectOperandTag
|
// If the type we select is an incomplete type (e.g. a forward-declared `struct`), there will
@@ -481,7 +496,7 @@ abstract class TranslatedArgumentSideEffect extends TranslatedSideEffect {
final override Instruction getInstructionRegisterOperand(InstructionTag tag, OperandTag operandTag) {
tag instanceof OnlyInstructionTag and
operandTag instanceof AddressOperandTag and
result = getArgInstruction()
result = this.getArgInstruction()
or
tag instanceof OnlyInstructionTag and
operandTag instanceof BufferSizeOperandTag and
@@ -522,7 +537,7 @@ class TranslatedArgumentExprSideEffect extends TranslatedArgumentSideEffect,
final override Locatable getAst() { result = arg }
/** DEPRECATED: Alias for getAst */
deprecated override Locatable getAST() { result = getAst() }
deprecated override Locatable getAST() { result = this.getAst() }
final override Type getIndirectionType() {
result = arg.getUnspecifiedType().(DerivedType).getBaseType()
@@ -557,7 +572,7 @@ class TranslatedStructorQualifierSideEffect extends TranslatedArgumentSideEffect
final override Locatable getAst() { result = call }
/** DEPRECATED: Alias for getAst */
deprecated override Locatable getAST() { result = getAst() }
deprecated override Locatable getAST() { result = this.getAst() }
final override Type getIndirectionType() { result = call.getTarget().getDeclaringType() }
@@ -581,7 +596,7 @@ class TranslatedCallSideEffect extends TranslatedSideEffect, TTranslatedCallSide
override Locatable getAst() { result = expr }
/** DEPRECATED: Alias for getAst */
deprecated override Locatable getAST() { result = getAst() }
deprecated override Locatable getAST() { result = this.getAst() }
override Expr getPrimaryExpr() { result = expr }
@@ -622,7 +637,7 @@ class TranslatedAllocationSideEffect extends TranslatedSideEffect, TTranslatedAl
override Locatable getAst() { result = expr }
/** DEPRECATED: Alias for getAst */
deprecated override Locatable getAST() { result = getAst() }
deprecated override Locatable getAST() { result = this.getAst() }
override Expr getPrimaryExpr() { result = expr }
@@ -635,7 +650,7 @@ class TranslatedAllocationSideEffect extends TranslatedSideEffect, TTranslatedAl
override Instruction getInstructionRegisterOperand(InstructionTag tag, OperandTag operandTag) {
tag = OnlyInstructionTag() and
operandTag = addressOperand() and
result = getPrimaryInstructionForSideEffect(OnlyInstructionTag())
result = this.getPrimaryInstructionForSideEffect(OnlyInstructionTag())
}
override predicate sideEffectInstruction(Opcode opcode, CppType type) {

View File

@@ -22,9 +22,9 @@ abstract class TranslatedCondition extends TranslatedElement {
final override Locatable getAst() { result = expr }
/** DEPRECATED: Alias for getAst */
deprecated override Locatable getAST() { result = getAst() }
deprecated override Locatable getAST() { result = this.getAst() }
final ConditionContext getConditionContext() { result = getParent() }
final ConditionContext getConditionContext() { result = this.getParent() }
final Expr getExpr() { result = expr }
@@ -42,9 +42,11 @@ abstract class TranslatedFlexibleCondition extends TranslatedCondition, Conditio
{
TranslatedFlexibleCondition() { this = TTranslatedFlexibleCondition(expr) }
final override TranslatedElement getChild(int id) { id = 0 and result = getOperand() }
final override TranslatedElement getChild(int id) { id = 0 and result = this.getOperand() }
final override Instruction getFirstInstruction() { result = getOperand().getFirstInstruction() }
final override Instruction getFirstInstruction() {
result = this.getOperand().getFirstInstruction()
}
final override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) {
none()
@@ -61,13 +63,13 @@ class TranslatedParenthesisCondition extends TranslatedFlexibleCondition {
override ParenthesisExpr expr;
final override Instruction getChildTrueSuccessor(TranslatedCondition child) {
child = getOperand() and
result = getConditionContext().getChildTrueSuccessor(this)
child = this.getOperand() and
result = this.getConditionContext().getChildTrueSuccessor(this)
}
final override Instruction getChildFalseSuccessor(TranslatedCondition child) {
child = getOperand() and
result = getConditionContext().getChildFalseSuccessor(this)
child = this.getOperand() and
result = this.getConditionContext().getChildFalseSuccessor(this)
}
final override TranslatedCondition getOperand() {
@@ -79,13 +81,13 @@ class TranslatedNotCondition extends TranslatedFlexibleCondition {
override NotExpr expr;
override Instruction getChildTrueSuccessor(TranslatedCondition child) {
child = getOperand() and
result = getConditionContext().getChildFalseSuccessor(this)
child = this.getOperand() and
result = this.getConditionContext().getChildFalseSuccessor(this)
}
override Instruction getChildFalseSuccessor(TranslatedCondition child) {
child = getOperand() and
result = getConditionContext().getChildTrueSuccessor(this)
child = this.getOperand() and
result = this.getConditionContext().getChildTrueSuccessor(this)
}
override TranslatedCondition getOperand() {
@@ -103,13 +105,13 @@ abstract class TranslatedBinaryLogicalOperation extends TranslatedNativeConditio
override BinaryLogicalOperation expr;
final override TranslatedElement getChild(int id) {
id = 0 and result = getLeftOperand()
id = 0 and result = this.getLeftOperand()
or
id = 1 and result = getRightOperand()
id = 1 and result = this.getRightOperand()
}
final override Instruction getFirstInstruction() {
result = getLeftOperand().getFirstInstruction()
result = this.getLeftOperand().getFirstInstruction()
}
final override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) {
@@ -131,16 +133,16 @@ class TranslatedLogicalAndExpr extends TranslatedBinaryLogicalOperation {
TranslatedLogicalAndExpr() { expr instanceof LogicalAndExpr }
override Instruction getChildTrueSuccessor(TranslatedCondition child) {
child = getLeftOperand() and
result = getRightOperand().getFirstInstruction()
child = this.getLeftOperand() and
result = this.getRightOperand().getFirstInstruction()
or
child = getRightOperand() and
result = getConditionContext().getChildTrueSuccessor(this)
child = this.getRightOperand() and
result = this.getConditionContext().getChildTrueSuccessor(this)
}
override Instruction getChildFalseSuccessor(TranslatedCondition child) {
(child = getLeftOperand() or child = getRightOperand()) and
result = getConditionContext().getChildFalseSuccessor(this)
(child = this.getLeftOperand() or child = this.getRightOperand()) and
result = this.getConditionContext().getChildFalseSuccessor(this)
}
}
@@ -148,25 +150,25 @@ class TranslatedLogicalOrExpr extends TranslatedBinaryLogicalOperation {
override LogicalOrExpr expr;
override Instruction getChildTrueSuccessor(TranslatedCondition child) {
(child = getLeftOperand() or child = getRightOperand()) and
result = getConditionContext().getChildTrueSuccessor(this)
(child = this.getLeftOperand() or child = this.getRightOperand()) and
result = this.getConditionContext().getChildTrueSuccessor(this)
}
override Instruction getChildFalseSuccessor(TranslatedCondition child) {
child = getLeftOperand() and
result = getRightOperand().getFirstInstruction()
child = this.getLeftOperand() and
result = this.getRightOperand().getFirstInstruction()
or
child = getRightOperand() and
result = getConditionContext().getChildFalseSuccessor(this)
child = this.getRightOperand() and
result = this.getConditionContext().getChildFalseSuccessor(this)
}
}
class TranslatedValueCondition extends TranslatedCondition, TTranslatedValueCondition {
TranslatedValueCondition() { this = TTranslatedValueCondition(expr) }
override TranslatedElement getChild(int id) { id = 0 and result = getValueExpr() }
override TranslatedElement getChild(int id) { id = 0 and result = this.getValueExpr() }
override Instruction getFirstInstruction() { result = getValueExpr().getFirstInstruction() }
override Instruction getFirstInstruction() { result = this.getValueExpr().getFirstInstruction() }
override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) {
tag = ValueConditionConditionalBranchTag() and
@@ -175,25 +177,25 @@ class TranslatedValueCondition extends TranslatedCondition, TTranslatedValueCond
}
override Instruction getChildSuccessor(TranslatedElement child) {
child = getValueExpr() and
result = getInstruction(ValueConditionConditionalBranchTag())
child = this.getValueExpr() and
result = this.getInstruction(ValueConditionConditionalBranchTag())
}
override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) {
tag = ValueConditionConditionalBranchTag() and
(
kind instanceof TrueEdge and
result = getConditionContext().getChildTrueSuccessor(this)
result = this.getConditionContext().getChildTrueSuccessor(this)
or
kind instanceof FalseEdge and
result = getConditionContext().getChildFalseSuccessor(this)
result = this.getConditionContext().getChildFalseSuccessor(this)
)
}
override Instruction getInstructionRegisterOperand(InstructionTag tag, OperandTag operandTag) {
tag = ValueConditionConditionalBranchTag() and
operandTag instanceof ConditionOperandTag and
result = getValueExpr().getResult()
result = this.getValueExpr().getResult()
}
private TranslatedExpr getValueExpr() { result = getTranslatedExpr(expr) }

View File

@@ -47,7 +47,7 @@ abstract class TranslatedDeclarationEntry extends TranslatedElement, TTranslated
final override Locatable getAst() { result = entry.getAst() }
/** DEPRECATED: Alias for getAst */
deprecated override Locatable getAST() { result = getAst() }
deprecated override Locatable getAST() { result = this.getAst() }
}
/**
@@ -60,19 +60,19 @@ abstract class TranslatedLocalVariableDeclaration extends TranslatedVariableInit
*/
abstract LocalVariable getVariable();
final override Type getTargetType() { result = getVariableType(getVariable()) }
final override Type getTargetType() { result = getVariableType(this.getVariable()) }
final override TranslatedInitialization getInitialization() {
result =
getTranslatedInitialization(getVariable().getInitializer().getExpr().getFullyConverted())
getTranslatedInitialization(this.getVariable().getInitializer().getExpr().getFullyConverted())
}
final override Instruction getInitializationSuccessor() {
result = getParent().getChildSuccessor(this)
result = this.getParent().getChildSuccessor(this)
}
final override IRVariable getIRVariable() {
result = getIRUserVariable(getFunction(), getVariable())
result = getIRUserVariable(this.getFunction(), this.getVariable())
}
}
@@ -123,7 +123,7 @@ class TranslatedStaticLocalVariableDeclarationEntry extends TranslatedDeclaratio
TranslatedStaticLocalVariableDeclarationEntry() { var = entry.getDeclaration() }
final override TranslatedElement getChild(int id) { id = 0 and result = getInitialization() }
final override TranslatedElement getChild(int id) { id = 0 and result = this.getInitialization() }
final override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType type) {
tag = DynamicInitializationFlagAddressTag() and
@@ -148,39 +148,39 @@ class TranslatedStaticLocalVariableDeclarationEntry extends TranslatedDeclaratio
}
final override Instruction getFirstInstruction() {
result = getInstruction(DynamicInitializationFlagAddressTag())
result = this.getInstruction(DynamicInitializationFlagAddressTag())
}
final override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) {
tag = DynamicInitializationFlagAddressTag() and
kind instanceof GotoEdge and
result = getInstruction(DynamicInitializationFlagLoadTag())
result = this.getInstruction(DynamicInitializationFlagLoadTag())
or
tag = DynamicInitializationFlagLoadTag() and
kind instanceof GotoEdge and
result = getInstruction(DynamicInitializationConditionalBranchTag())
result = this.getInstruction(DynamicInitializationConditionalBranchTag())
or
tag = DynamicInitializationConditionalBranchTag() and
(
kind instanceof TrueEdge and
result = getParent().getChildSuccessor(this)
result = this.getParent().getChildSuccessor(this)
or
kind instanceof FalseEdge and
result = getInitialization().getFirstInstruction()
result = this.getInitialization().getFirstInstruction()
)
or
tag = DynamicInitializationFlagConstantTag() and
kind instanceof GotoEdge and
result = getInstruction(DynamicInitializationFlagStoreTag())
result = this.getInstruction(DynamicInitializationFlagStoreTag())
or
tag = DynamicInitializationFlagStoreTag() and
kind instanceof GotoEdge and
result = getParent().getChildSuccessor(this)
result = this.getParent().getChildSuccessor(this)
}
final override Instruction getChildSuccessor(TranslatedElement child) {
child = getInitialization() and
result = getInstruction(DynamicInitializationFlagConstantTag())
child = this.getInitialization() and
result = this.getInstruction(DynamicInitializationFlagConstantTag())
}
final override IRDynamicInitializationFlag getInstructionVariable(InstructionTag tag) {
@@ -196,20 +196,20 @@ class TranslatedStaticLocalVariableDeclarationEntry extends TranslatedDeclaratio
tag = DynamicInitializationFlagLoadTag() and
(
operandTag instanceof AddressOperandTag and
result = getInstruction(DynamicInitializationFlagAddressTag())
result = this.getInstruction(DynamicInitializationFlagAddressTag())
)
or
tag = DynamicInitializationConditionalBranchTag() and
operandTag instanceof ConditionOperandTag and
result = getInstruction(DynamicInitializationFlagLoadTag())
result = this.getInstruction(DynamicInitializationFlagLoadTag())
or
tag = DynamicInitializationFlagStoreTag() and
(
operandTag instanceof AddressOperandTag and
result = getInstruction(DynamicInitializationFlagAddressTag())
result = this.getInstruction(DynamicInitializationFlagAddressTag())
or
operandTag instanceof StoreValueOperandTag and
result = getInstruction(DynamicInitializationFlagConstantTag())
result = this.getInstruction(DynamicInitializationFlagConstantTag())
)
}
@@ -238,7 +238,7 @@ class TranslatedStaticLocalVariableInitialization extends TranslatedElement,
final override Locatable getAst() { result = entry.getAst() }
/** DEPRECATED: Alias for getAst */
deprecated override Locatable getAST() { result = getAst() }
deprecated override Locatable getAST() { result = this.getAst() }
final override LocalVariable getVariable() { result = var }
@@ -267,7 +267,7 @@ class TranslatedConditionDecl extends TranslatedLocalVariableDeclaration, TTrans
override Locatable getAst() { result = conditionDeclExpr }
/** DEPRECATED: Alias for getAst */
deprecated override Locatable getAST() { result = getAst() }
deprecated override Locatable getAST() { result = this.getAst() }
override Declaration getFunction() { result = getEnclosingFunction(conditionDeclExpr) }

View File

@@ -821,7 +821,7 @@ abstract class TranslatedElement extends TTranslatedElement {
abstract Locatable getAst();
/** DEPRECATED: Alias for getAst */
deprecated Locatable getAST() { result = getAst() }
deprecated Locatable getAST() { result = this.getAst() }
/**
* Get the first instruction to be executed in the evaluation of this element.
@@ -831,7 +831,7 @@ abstract class TranslatedElement extends TTranslatedElement {
/**
* Get the immediate child elements of this element.
*/
final TranslatedElement getAChild() { result = getChild(_) }
final TranslatedElement getAChild() { result = this.getChild(_) }
/**
* Gets the immediate child element of this element. The `id` is unique
@@ -844,25 +844,29 @@ abstract class TranslatedElement extends TTranslatedElement {
* Gets the an identifier string for the element. This id is unique within
* the scope of the element's function.
*/
final int getId() { result = getUniqueId() }
final int getId() { result = this.getUniqueId() }
private TranslatedElement getChildByRank(int rankIndex) {
result =
rank[rankIndex + 1](TranslatedElement child, int id | child = getChild(id) | child order by id)
rank[rankIndex + 1](TranslatedElement child, int id |
child = this.getChild(id)
|
child order by id
)
}
language[monotonicAggregates]
private int getDescendantCount() {
result =
1 + sum(TranslatedElement child | child = getChildByRank(_) | child.getDescendantCount())
1 + sum(TranslatedElement child | child = this.getChildByRank(_) | child.getDescendantCount())
}
private int getUniqueId() {
if not exists(getParent())
if not exists(this.getParent())
then result = 0
else
exists(TranslatedElement parent |
parent = getParent() and
parent = this.getParent() and
if this = parent.getChildByRank(0)
then result = 1 + parent.getUniqueId()
else
@@ -908,7 +912,7 @@ abstract class TranslatedElement extends TTranslatedElement {
* there is no enclosing `try`.
*/
Instruction getExceptionSuccessorInstruction() {
result = getParent().getExceptionSuccessorInstruction()
result = this.getParent().getExceptionSuccessorInstruction()
}
/**
@@ -1022,14 +1026,14 @@ abstract class TranslatedElement extends TTranslatedElement {
exists(Locatable ast |
result.getAst() = ast and
result.getTag() = tag and
hasTempVariableAndAst(tag, ast)
this.hasTempVariableAndAst(tag, ast)
)
}
pragma[noinline]
private predicate hasTempVariableAndAst(TempVariableTag tag, Locatable ast) {
hasTempVariable(tag, _) and
ast = getAst()
this.hasTempVariable(tag, _) and
ast = this.getAst()
}
/**

View File

@@ -68,7 +68,7 @@ class TranslatedFunction extends TranslatedRootElement, TTranslatedFunction {
final override Locatable getAst() { result = func }
/** DEPRECATED: Alias for getAst */
deprecated override Locatable getAST() { result = getAst() }
deprecated override Locatable getAST() { result = this.getAst() }
/**
* Gets the function being translated.
@@ -76,15 +76,15 @@ class TranslatedFunction extends TranslatedRootElement, TTranslatedFunction {
final override Function getFunction() { result = func }
final override TranslatedElement getChild(int id) {
id = -5 and result = getReadEffects()
id = -5 and result = this.getReadEffects()
or
id = -4 and result = getConstructorInitList()
id = -4 and result = this.getConstructorInitList()
or
id = -3 and result = getBody()
id = -3 and result = this.getBody()
or
id = -2 and result = getDestructorDestructionList()
id = -2 and result = this.getDestructorDestructionList()
or
id >= -1 and result = getParameter(id)
id >= -1 and result = this.getParameter(id)
}
final private TranslatedConstructorInitList getConstructorInitList() {
@@ -109,64 +109,66 @@ class TranslatedFunction extends TranslatedRootElement, TTranslatedFunction {
result = getTranslatedEllipsisParameter(func)
}
final override Instruction getFirstInstruction() { result = getInstruction(EnterFunctionTag()) }
final override Instruction getFirstInstruction() {
result = this.getInstruction(EnterFunctionTag())
}
final override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) {
kind instanceof GotoEdge and
(
tag = EnterFunctionTag() and
result = getInstruction(AliasedDefinitionTag())
result = this.getInstruction(AliasedDefinitionTag())
or
tag = AliasedDefinitionTag() and
result = getInstruction(InitializeNonLocalTag())
result = this.getInstruction(InitializeNonLocalTag())
or
(
tag = InitializeNonLocalTag() and
if exists(getThisType())
then result = getParameter(-1).getFirstInstruction()
if exists(this.getThisType())
then result = this.getParameter(-1).getFirstInstruction()
else
if exists(getParameter(0))
then result = getParameter(0).getFirstInstruction()
else result = getBody().getFirstInstruction()
if exists(this.getParameter(0))
then result = this.getParameter(0).getFirstInstruction()
else result = this.getBody().getFirstInstruction()
)
or
tag = ReturnValueAddressTag() and
result = getInstruction(ReturnTag())
result = this.getInstruction(ReturnTag())
or
tag = ReturnTag() and
result = getInstruction(AliasedUseTag())
result = this.getInstruction(AliasedUseTag())
or
tag = UnwindTag() and
result = getInstruction(AliasedUseTag())
result = this.getInstruction(AliasedUseTag())
or
tag = AliasedUseTag() and
result = getInstruction(ExitFunctionTag())
result = this.getInstruction(ExitFunctionTag())
)
}
final override Instruction getChildSuccessor(TranslatedElement child) {
exists(int paramIndex |
child = getParameter(paramIndex) and
child = this.getParameter(paramIndex) and
if
exists(func.getParameter(paramIndex + 1)) or
getEllipsisParameterIndexForFunction(func) = paramIndex + 1
then result = getParameter(paramIndex + 1).getFirstInstruction()
else result = getConstructorInitList().getFirstInstruction()
then result = this.getParameter(paramIndex + 1).getFirstInstruction()
else result = this.getConstructorInitList().getFirstInstruction()
)
or
child = getConstructorInitList() and
result = getBody().getFirstInstruction()
child = this.getConstructorInitList() and
result = this.getBody().getFirstInstruction()
or
child = getBody() and
result = getReturnSuccessorInstruction()
child = this.getBody() and
result = this.getReturnSuccessorInstruction()
or
child = getDestructorDestructionList() and
result = getReadEffects().getFirstInstruction()
child = this.getDestructorDestructionList() and
result = this.getReadEffects().getFirstInstruction()
or
child = getReadEffects() and
if hasReturnValue()
then result = getInstruction(ReturnValueAddressTag())
else result = getInstruction(ReturnTag())
child = this.getReadEffects() and
if this.hasReturnValue()
then result = this.getInstruction(ReturnValueAddressTag())
else result = this.getInstruction(ReturnTag())
}
final override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) {
@@ -185,13 +187,13 @@ class TranslatedFunction extends TranslatedRootElement, TTranslatedFunction {
or
tag = ReturnValueAddressTag() and
opcode instanceof Opcode::VariableAddress and
resultType = getTypeForGLValue(getReturnType()) and
hasReturnValue()
resultType = getTypeForGLValue(this.getReturnType()) and
this.hasReturnValue()
or
(
tag = ReturnTag() and
resultType = getVoidType() and
if hasReturnValue()
if this.hasReturnValue()
then opcode instanceof Opcode::ReturnValue
else opcode instanceof Opcode::ReturnVoid
)
@@ -217,23 +219,23 @@ class TranslatedFunction extends TranslatedRootElement, TTranslatedFunction {
}
final override Instruction getExceptionSuccessorInstruction() {
result = getInstruction(UnwindTag())
result = this.getInstruction(UnwindTag())
}
final override Instruction getInstructionRegisterOperand(InstructionTag tag, OperandTag operandTag) {
tag = ReturnTag() and
hasReturnValue() and
this.hasReturnValue() and
operandTag instanceof AddressOperandTag and
result = getInstruction(ReturnValueAddressTag())
result = this.getInstruction(ReturnValueAddressTag())
}
final override CppType getInstructionMemoryOperandType(
InstructionTag tag, TypedOperandTag operandTag
) {
tag = ReturnTag() and
hasReturnValue() and
this.hasReturnValue() and
operandTag instanceof LoadOperandTag and
result = getTypeForPRValue(getReturnType())
result = getTypeForPRValue(this.getReturnType())
or
tag = AliasedUseTag() and
operandTag instanceof SideEffectOperandTag and
@@ -242,7 +244,7 @@ class TranslatedFunction extends TranslatedRootElement, TTranslatedFunction {
final override IRVariable getInstructionVariable(InstructionTag tag) {
tag = ReturnValueAddressTag() and
result = getReturnVariable()
result = this.getReturnVariable()
}
final override predicate needsUnknownOpaqueType(int byteSize) {
@@ -251,15 +253,15 @@ class TranslatedFunction extends TranslatedRootElement, TTranslatedFunction {
final override predicate hasTempVariable(TempVariableTag tag, CppType type) {
tag = ReturnValueTempVar() and
hasReturnValue() and
type = getTypeForPRValue(getReturnType())
this.hasReturnValue() and
type = getTypeForPRValue(this.getReturnType())
or
tag = EllipsisTempVar() and
func.isVarargs() and
type = getEllipsisVariablePRValueType()
or
tag = ThisTempVar() and
type = getTypeForGLValue(getThisType())
type = getTypeForGLValue(this.getThisType())
}
/**
@@ -267,7 +269,7 @@ class TranslatedFunction extends TranslatedRootElement, TTranslatedFunction {
* statement.
*/
final Instruction getReturnSuccessorInstruction() {
result = getDestructorDestructionList().getFirstInstruction()
result = this.getDestructorDestructionList().getFirstInstruction()
}
/**
@@ -368,25 +370,25 @@ abstract class TranslatedParameter extends TranslatedElement {
final override TranslatedElement getChild(int id) { none() }
final override Instruction getFirstInstruction() {
result = getInstruction(InitializerVariableAddressTag())
result = this.getInstruction(InitializerVariableAddressTag())
}
final override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) {
kind instanceof GotoEdge and
(
tag = InitializerVariableAddressTag() and
result = getInstruction(InitializerStoreTag())
result = this.getInstruction(InitializerStoreTag())
or
tag = InitializerStoreTag() and
if hasIndirection()
then result = getInstruction(InitializerIndirectAddressTag())
else result = getParent().getChildSuccessor(this)
if this.hasIndirection()
then result = this.getInstruction(InitializerIndirectAddressTag())
else result = this.getParent().getChildSuccessor(this)
or
tag = InitializerIndirectAddressTag() and
result = getInstruction(InitializerIndirectStoreTag())
result = this.getInstruction(InitializerIndirectStoreTag())
or
tag = InitializerIndirectStoreTag() and
result = getParent().getChildSuccessor(this)
result = this.getParent().getChildSuccessor(this)
)
}
@@ -395,21 +397,21 @@ abstract class TranslatedParameter extends TranslatedElement {
final override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) {
tag = InitializerVariableAddressTag() and
opcode instanceof Opcode::VariableAddress and
resultType = getGLValueType()
resultType = this.getGLValueType()
or
tag = InitializerStoreTag() and
opcode instanceof Opcode::InitializeParameter and
resultType = getPRValueType()
resultType = this.getPRValueType()
or
hasIndirection() and
this.hasIndirection() and
tag = InitializerIndirectAddressTag() and
opcode instanceof Opcode::Load and
resultType = getPRValueType()
resultType = this.getPRValueType()
or
hasIndirection() and
this.hasIndirection() and
tag = InitializerIndirectStoreTag() and
opcode instanceof Opcode::InitializeIndirection and
resultType = getInitializationResultType()
resultType = this.getInitializationResultType()
}
final override IRVariable getInstructionVariable(InstructionTag tag) {
@@ -418,26 +420,26 @@ abstract class TranslatedParameter extends TranslatedElement {
tag = InitializerVariableAddressTag() or
tag = InitializerIndirectStoreTag()
) and
result = getIRVariable()
result = this.getIRVariable()
}
final override Instruction getInstructionRegisterOperand(InstructionTag tag, OperandTag operandTag) {
tag = InitializerStoreTag() and
(
operandTag instanceof AddressOperandTag and
result = getInstruction(InitializerVariableAddressTag())
result = this.getInstruction(InitializerVariableAddressTag())
)
or
// this feels a little strange, but I think it's the best we can do
tag = InitializerIndirectAddressTag() and
(
operandTag instanceof AddressOperandTag and
result = getInstruction(InitializerVariableAddressTag())
result = this.getInstruction(InitializerVariableAddressTag())
)
or
tag = InitializerIndirectStoreTag() and
operandTag instanceof AddressOperandTag and
result = getInstruction(InitializerIndirectAddressTag())
result = this.getInstruction(InitializerIndirectAddressTag())
}
abstract predicate hasIndirection();
@@ -465,7 +467,7 @@ class TranslatedThisParameter extends TranslatedParameter, TTranslatedThisParame
final override Locatable getAst() { result = func }
/** DEPRECATED: Alias for getAst */
deprecated override Locatable getAST() { result = getAst() }
deprecated override Locatable getAST() { result = this.getAst() }
final override Function getFunction() { result = func }
@@ -500,7 +502,7 @@ class TranslatedPositionalParameter extends TranslatedParameter, TTranslatedPara
final override Locatable getAst() { result = param }
/** DEPRECATED: Alias for getAst */
deprecated override Locatable getAST() { result = getAst() }
deprecated override Locatable getAST() { result = this.getAst() }
final override Function getFunction() {
result = param.getFunction() or
@@ -522,7 +524,7 @@ class TranslatedPositionalParameter extends TranslatedParameter, TTranslatedPara
final override CppType getInitializationResultType() { result = getUnknownType() }
final override IRAutomaticUserVariable getIRVariable() {
result = getIRUserVariable(getFunction(), param)
result = getIRUserVariable(this.getFunction(), param)
}
}
@@ -540,7 +542,7 @@ class TranslatedEllipsisParameter extends TranslatedParameter, TTranslatedEllips
final override Locatable getAst() { result = func }
/** DEPRECATED: Alias for getAst */
deprecated override Locatable getAST() { result = getAst() }
deprecated override Locatable getAST() { result = this.getAst() }
final override Function getFunction() { result = func }
@@ -579,7 +581,7 @@ class TranslatedConstructorInitList extends TranslatedElement, InitializationCon
override Locatable getAst() { result = func }
/** DEPRECATED: Alias for getAst */
deprecated override Locatable getAST() { result = getAst() }
deprecated override Locatable getAST() { result = this.getAst() }
override TranslatedElement getChild(int id) {
exists(ConstructorFieldInit fieldInit |
@@ -599,9 +601,9 @@ class TranslatedConstructorInitList extends TranslatedElement, InitializationCon
}
override Instruction getFirstInstruction() {
if exists(getChild(0))
then result = getChild(0).getFirstInstruction()
else result = getParent().getChildSuccessor(this)
if exists(this.getChild(0))
then result = this.getChild(0).getFirstInstruction()
else result = this.getParent().getChildSuccessor(this)
}
override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) {
@@ -614,10 +616,10 @@ class TranslatedConstructorInitList extends TranslatedElement, InitializationCon
override Instruction getChildSuccessor(TranslatedElement child) {
exists(int id |
child = getChild(id) and
if exists(getChild(id + 1))
then result = getChild(id + 1).getFirstInstruction()
else result = getParent().getChildSuccessor(this)
child = this.getChild(id) and
if exists(this.getChild(id + 1))
then result = this.getChild(id + 1).getFirstInstruction()
else result = this.getParent().getChildSuccessor(this)
)
}
@@ -651,7 +653,7 @@ class TranslatedDestructorDestructionList extends TranslatedElement,
override Locatable getAst() { result = func }
/** DEPRECATED: Alias for getAst */
deprecated override Locatable getAST() { result = getAst() }
deprecated override Locatable getAST() { result = this.getAst() }
override TranslatedElement getChild(int id) {
exists(DestructorFieldDestruction fieldDestruction |
@@ -666,9 +668,9 @@ class TranslatedDestructorDestructionList extends TranslatedElement,
}
override Instruction getFirstInstruction() {
if exists(getChild(0))
then result = getChild(0).getFirstInstruction()
else result = getParent().getChildSuccessor(this)
if exists(this.getChild(0))
then result = this.getChild(0).getFirstInstruction()
else result = this.getParent().getChildSuccessor(this)
}
override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) {
@@ -681,10 +683,10 @@ class TranslatedDestructorDestructionList extends TranslatedElement,
override Instruction getChildSuccessor(TranslatedElement child) {
exists(int id |
child = getChild(id) and
if exists(getChild(id + 1))
then result = getChild(id + 1).getFirstInstruction()
else result = getParent().getChildSuccessor(this)
child = this.getChild(id) and
if exists(this.getChild(id + 1))
then result = this.getChild(id + 1).getFirstInstruction()
else result = this.getParent().getChildSuccessor(this)
)
}
}
@@ -699,7 +701,7 @@ class TranslatedReadEffects extends TranslatedElement, TTranslatedReadEffects {
override Locatable getAst() { result = func }
/** DEPRECATED: Alias for getAst */
deprecated override Locatable getAST() { result = getAst() }
deprecated override Locatable getAST() { result = this.getAst() }
override Function getFunction() { result = func }
@@ -713,25 +715,25 @@ class TranslatedReadEffects extends TranslatedElement, TTranslatedReadEffects {
}
override Instruction getFirstInstruction() {
if exists(getAChild())
if exists(this.getAChild())
then
result =
min(TranslatedElement child, int id | child = getChild(id) | child order by id)
min(TranslatedElement child, int id | child = this.getChild(id) | child order by id)
.getFirstInstruction()
else result = getParent().getChildSuccessor(this)
else result = this.getParent().getChildSuccessor(this)
}
override Instruction getChildSuccessor(TranslatedElement child) {
exists(int id | child = getChild(id) |
if exists(TranslatedReadEffect child2, int id2 | id2 > id and child2 = getChild(id2))
exists(int id | child = this.getChild(id) |
if exists(TranslatedReadEffect child2, int id2 | id2 > id and child2 = this.getChild(id2))
then
result =
min(TranslatedReadEffect child2, int id2 |
child2 = getChild(id2) and id2 > id
child2 = this.getChild(id2) and id2 > id
|
child2 order by id2
).getFirstInstruction()
else result = getParent().getChildSuccessor(this)
else result = this.getParent().getChildSuccessor(this)
)
}
@@ -758,10 +760,10 @@ abstract class TranslatedReadEffect extends TranslatedElement {
override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) {
tag = OnlyInstructionTag() and
kind = EdgeKind::gotoEdge() and
result = getParent().getChildSuccessor(this)
result = this.getParent().getChildSuccessor(this)
}
override Instruction getFirstInstruction() { result = getInstruction(OnlyInstructionTag()) }
override Instruction getFirstInstruction() { result = this.getInstruction(OnlyInstructionTag()) }
override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) {
opcode instanceof Opcode::ReturnIndirection and
@@ -786,7 +788,7 @@ class TranslatedThisReadEffect extends TranslatedReadEffect, TTranslatedThisRead
override Locatable getAst() { result = func }
/** DEPRECATED: Alias for getAst */
deprecated override Locatable getAST() { result = getAst() }
deprecated override Locatable getAST() { result = this.getAst() }
override Function getFunction() { result = func }
@@ -812,7 +814,7 @@ class TranslatedParameterReadEffect extends TranslatedReadEffect, TTranslatedPar
override Locatable getAst() { result = param }
/** DEPRECATED: Alias for getAst */
deprecated override Locatable getAST() { result = getAst() }
deprecated override Locatable getAST() { result = this.getAst() }
override string toString() { result = "read effect: " + param.toString() }
@@ -826,6 +828,6 @@ class TranslatedParameterReadEffect extends TranslatedReadEffect, TTranslatedPar
final override IRVariable getInstructionVariable(InstructionTag tag) {
tag = OnlyInstructionTag() and
result = getIRUserVariable(getFunction(), param)
result = getIRUserVariable(this.getFunction(), param)
}
}

View File

@@ -35,64 +35,64 @@ abstract class InitializationContext extends TranslatedElement {
* declarations, `return` statements, and `throw` expressions.
*/
abstract class TranslatedVariableInitialization extends TranslatedElement, InitializationContext {
final override TranslatedElement getChild(int id) { id = 0 and result = getInitialization() }
final override TranslatedElement getChild(int id) { id = 0 and result = this.getInitialization() }
final override Instruction getFirstInstruction() {
result = getInstruction(InitializerVariableAddressTag())
result = this.getInstruction(InitializerVariableAddressTag())
}
override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) {
tag = InitializerVariableAddressTag() and
opcode instanceof Opcode::VariableAddress and
resultType = getTypeForGLValue(getTargetType())
resultType = getTypeForGLValue(this.getTargetType())
or
hasUninitializedInstruction() and
this.hasUninitializedInstruction() and
tag = InitializerStoreTag() and
opcode instanceof Opcode::Uninitialized and
resultType = getTypeForPRValue(getTargetType())
resultType = getTypeForPRValue(this.getTargetType())
}
override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) {
(
tag = InitializerVariableAddressTag() and
kind instanceof GotoEdge and
if hasUninitializedInstruction()
then result = getInstruction(InitializerStoreTag())
else result = getInitialization().getFirstInstruction()
if this.hasUninitializedInstruction()
then result = this.getInstruction(InitializerStoreTag())
else result = this.getInitialization().getFirstInstruction()
)
or
hasUninitializedInstruction() and
this.hasUninitializedInstruction() and
kind instanceof GotoEdge and
tag = InitializerStoreTag() and
(
result = getInitialization().getFirstInstruction()
result = this.getInitialization().getFirstInstruction()
or
not exists(getInitialization()) and result = getInitializationSuccessor()
not exists(this.getInitialization()) and result = this.getInitializationSuccessor()
)
}
final override Instruction getChildSuccessor(TranslatedElement child) {
child = getInitialization() and result = getInitializationSuccessor()
child = this.getInitialization() and result = this.getInitializationSuccessor()
}
override Instruction getInstructionRegisterOperand(InstructionTag tag, OperandTag operandTag) {
hasUninitializedInstruction() and
this.hasUninitializedInstruction() and
tag = InitializerStoreTag() and
operandTag instanceof AddressOperandTag and
result = getInstruction(InitializerVariableAddressTag())
result = this.getInstruction(InitializerVariableAddressTag())
}
final override IRVariable getInstructionVariable(InstructionTag tag) {
(
tag = InitializerVariableAddressTag()
or
hasUninitializedInstruction() and tag = InitializerStoreTag()
this.hasUninitializedInstruction() and tag = InitializerStoreTag()
) and
result = getIRVariable()
result = this.getIRVariable()
}
final override Instruction getTargetAddress() {
result = getInstruction(InitializerVariableAddressTag())
result = this.getInstruction(InitializerVariableAddressTag())
}
/**
@@ -116,13 +116,13 @@ abstract class TranslatedVariableInitialization extends TranslatedElement, Initi
*/
final predicate hasUninitializedInstruction() {
(
not exists(getInitialization()) or
getInitialization() instanceof TranslatedListInitialization or
getInitialization() instanceof TranslatedConstructorInitialization or
getInitialization().(TranslatedStringLiteralInitialization).zeroInitRange(_, _)
not exists(this.getInitialization()) or
this.getInitialization() instanceof TranslatedListInitialization or
this.getInitialization() instanceof TranslatedConstructorInitialization or
this.getInitialization().(TranslatedStringLiteralInitialization).zeroInitRange(_, _)
) and
// Variables with static or thread-local storage duration are zero-initialized at program startup.
getIRVariable() instanceof IRAutomaticVariable
this.getIRVariable() instanceof IRAutomaticVariable
}
}
@@ -146,7 +146,7 @@ abstract class TranslatedInitialization extends TranslatedElement, TTranslatedIn
final override Locatable getAst() { result = expr }
/** DEPRECATED: Alias for getAst */
deprecated override Locatable getAST() { result = getAst() }
deprecated override Locatable getAST() { result = this.getAst() }
/**
* Gets the expression that is doing the initialization.
@@ -157,7 +157,7 @@ abstract class TranslatedInitialization extends TranslatedElement, TTranslatedIn
* Gets the initialization context that describes the location being
* initialized.
*/
final InitializationContext getContext() { result = getParent() }
final InitializationContext getContext() { result = this.getParent() }
final TranslatedFunction getEnclosingFunction() {
result = getTranslatedFunction(this.getFunction())
@@ -169,17 +169,17 @@ abstract class TranslatedInitialization extends TranslatedElement, TTranslatedIn
*/
abstract class TranslatedListInitialization extends TranslatedInitialization, InitializationContext {
override Instruction getFirstInstruction() {
result = getChild(0).getFirstInstruction()
result = this.getChild(0).getFirstInstruction()
or
not exists(getChild(0)) and result = getParent().getChildSuccessor(this)
not exists(this.getChild(0)) and result = this.getParent().getChildSuccessor(this)
}
override Instruction getChildSuccessor(TranslatedElement child) {
exists(int index |
child = getChild(index) and
if exists(getChild(index + 1))
then result = getChild(index + 1).getFirstInstruction()
else result = getParent().getChildSuccessor(this)
child = this.getChild(index) and
if exists(this.getChild(index + 1))
then result = this.getChild(index + 1).getFirstInstruction()
else result = this.getParent().getChildSuccessor(this)
)
}
@@ -189,9 +189,9 @@ abstract class TranslatedListInitialization extends TranslatedInitialization, In
final override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) { none() }
override Instruction getTargetAddress() { result = getContext().getTargetAddress() }
override Instruction getTargetAddress() { result = this.getContext().getTargetAddress() }
override Type getTargetType() { result = getContext().getTargetType() }
override Type getTargetType() { result = this.getContext().getTargetType() }
}
/**
@@ -237,9 +237,11 @@ class TranslatedArrayListInitialization extends TranslatedListInitialization {
abstract class TranslatedDirectInitialization extends TranslatedInitialization {
TranslatedDirectInitialization() { not expr instanceof AggregateLiteral }
override TranslatedElement getChild(int id) { id = 0 and result = getInitializer() }
override TranslatedElement getChild(int id) { id = 0 and result = this.getInitializer() }
override Instruction getFirstInstruction() { result = getInitializer().getFirstInstruction() }
override Instruction getFirstInstruction() {
result = this.getInitializer().getFirstInstruction()
}
final TranslatedExpr getInitializer() { result = getTranslatedExpr(expr) }
}
@@ -258,27 +260,27 @@ class TranslatedSimpleDirectInitialization extends TranslatedDirectInitializatio
override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) {
tag = InitializerStoreTag() and
opcode instanceof Opcode::Store and
resultType = getTypeForPRValue(getContext().getTargetType())
resultType = getTypeForPRValue(this.getContext().getTargetType())
}
override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) {
tag = InitializerStoreTag() and
result = getParent().getChildSuccessor(this) and
result = this.getParent().getChildSuccessor(this) and
kind instanceof GotoEdge
}
override Instruction getChildSuccessor(TranslatedElement child) {
child = getInitializer() and result = getInstruction(InitializerStoreTag())
child = this.getInitializer() and result = this.getInstruction(InitializerStoreTag())
}
override Instruction getInstructionRegisterOperand(InstructionTag tag, OperandTag operandTag) {
tag = InitializerStoreTag() and
(
operandTag instanceof AddressOperandTag and
result = getContext().getTargetAddress()
result = this.getContext().getTargetAddress()
or
operandTag instanceof StoreValueOperandTag and
result = getInitializer().getResult()
result = this.getInitializer().getResult()
)
}
}
@@ -305,13 +307,13 @@ class TranslatedStringLiteralInitialization extends TranslatedDirectInitializati
// If the initializer string isn't large enough to fill the target, then
// we have to generate another instruction sequence to store a constant
// zero into the remainder of the array.
zeroInitRange(_, elementCount) and
this.zeroInitRange(_, elementCount) and
(
// Create a constant zero whose size is the size of the remaining
// space in the target array.
tag = ZeroPadStringConstantTag() and
opcode instanceof Opcode::Constant and
resultType = getUnknownOpaqueType(elementCount * getElementType().getSize())
resultType = getUnknownOpaqueType(elementCount * this.getElementType().getSize())
or
// The index of the first element to be zero initialized.
tag = ZeroPadStringElementIndexTag() and
@@ -321,12 +323,12 @@ class TranslatedStringLiteralInitialization extends TranslatedDirectInitializati
// Compute the address of the first element to be zero initialized.
tag = ZeroPadStringElementAddressTag() and
opcode instanceof Opcode::PointerAdd and
resultType = getTypeForGLValue(getElementType())
resultType = getTypeForGLValue(this.getElementType())
or
// Store the constant zero into the remainder of the string.
tag = ZeroPadStringStoreTag() and
opcode instanceof Opcode::Store and
resultType = getUnknownOpaqueType(elementCount * getElementType().getSize())
resultType = getUnknownOpaqueType(elementCount * this.getElementType().getSize())
)
)
}
@@ -335,78 +337,78 @@ class TranslatedStringLiteralInitialization extends TranslatedDirectInitializati
kind instanceof GotoEdge and
(
tag = InitializerLoadStringTag() and
result = getInstruction(InitializerStoreTag())
result = this.getInstruction(InitializerStoreTag())
or
if zeroInitRange(_, _)
if this.zeroInitRange(_, _)
then (
tag = InitializerStoreTag() and
result = getInstruction(ZeroPadStringConstantTag())
result = this.getInstruction(ZeroPadStringConstantTag())
or
tag = ZeroPadStringConstantTag() and
result = getInstruction(ZeroPadStringElementIndexTag())
result = this.getInstruction(ZeroPadStringElementIndexTag())
or
tag = ZeroPadStringElementIndexTag() and
result = getInstruction(ZeroPadStringElementAddressTag())
result = this.getInstruction(ZeroPadStringElementAddressTag())
or
tag = ZeroPadStringElementAddressTag() and
result = getInstruction(ZeroPadStringStoreTag())
result = this.getInstruction(ZeroPadStringStoreTag())
or
tag = ZeroPadStringStoreTag() and
result = getParent().getChildSuccessor(this)
result = this.getParent().getChildSuccessor(this)
) else (
tag = InitializerStoreTag() and
result = getParent().getChildSuccessor(this)
result = this.getParent().getChildSuccessor(this)
)
)
}
override Instruction getChildSuccessor(TranslatedElement child) {
child = getInitializer() and result = getInstruction(InitializerLoadStringTag())
child = this.getInitializer() and result = this.getInstruction(InitializerLoadStringTag())
}
override Instruction getInstructionRegisterOperand(InstructionTag tag, OperandTag operandTag) {
tag = InitializerLoadStringTag() and
(
operandTag instanceof AddressOperandTag and
result = getInitializer().getResult()
result = this.getInitializer().getResult()
)
or
tag = InitializerStoreTag() and
(
operandTag instanceof AddressOperandTag and
result = getContext().getTargetAddress()
result = this.getContext().getTargetAddress()
or
operandTag instanceof StoreValueOperandTag and
result = getInstruction(InitializerLoadStringTag())
result = this.getInstruction(InitializerLoadStringTag())
)
or
tag = ZeroPadStringElementAddressTag() and
(
operandTag instanceof LeftOperandTag and
result = getContext().getTargetAddress()
result = this.getContext().getTargetAddress()
or
operandTag instanceof RightOperandTag and
result = getInstruction(ZeroPadStringElementIndexTag())
result = this.getInstruction(ZeroPadStringElementIndexTag())
)
or
tag = ZeroPadStringStoreTag() and
(
operandTag instanceof AddressOperandTag and
result = getInstruction(ZeroPadStringElementAddressTag())
result = this.getInstruction(ZeroPadStringElementAddressTag())
or
operandTag instanceof StoreValueOperandTag and
result = getInstruction(ZeroPadStringConstantTag())
result = this.getInstruction(ZeroPadStringConstantTag())
)
}
override int getInstructionElementSize(InstructionTag tag) {
tag = ZeroPadStringElementAddressTag() and
result = max(getElementType().getSize())
result = max(this.getElementType().getSize())
}
override string getInstructionConstantValue(InstructionTag tag) {
exists(int startIndex |
zeroInitRange(startIndex, _) and
this.zeroInitRange(startIndex, _) and
(
tag = ZeroPadStringConstantTag() and
result = "0"
@@ -419,13 +421,13 @@ class TranslatedStringLiteralInitialization extends TranslatedDirectInitializati
override predicate needsUnknownOpaqueType(int byteSize) {
exists(int elementCount |
zeroInitRange(_, elementCount) and
byteSize = elementCount * getElementType().getSize()
this.zeroInitRange(_, elementCount) and
byteSize = elementCount * this.getElementType().getSize()
)
}
private Type getElementType() {
result = getContext().getTargetType().getUnspecifiedType().(ArrayType).getBaseType()
result = this.getContext().getTargetType().getUnspecifiedType().(ArrayType).getBaseType()
}
/**
@@ -435,7 +437,8 @@ class TranslatedStringLiteralInitialization extends TranslatedDirectInitializati
predicate zeroInitRange(int startIndex, int elementCount) {
exists(int targetCount |
startIndex = expr.getUnspecifiedType().(ArrayType).getArraySize() and
targetCount = getContext().getTargetType().getUnspecifiedType().(ArrayType).getArraySize() and
targetCount =
this.getContext().getTargetType().getUnspecifiedType().(ArrayType).getArraySize() and
elementCount = targetCount - startIndex and
elementCount > 0
)
@@ -454,14 +457,14 @@ class TranslatedConstructorInitialization extends TranslatedDirectInitialization
override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) { none() }
override Instruction getChildSuccessor(TranslatedElement child) {
child = getInitializer() and result = getParent().getChildSuccessor(this)
child = this.getInitializer() and result = this.getParent().getChildSuccessor(this)
}
override Instruction getInstructionRegisterOperand(InstructionTag tag, OperandTag operandTag) {
none()
}
override Instruction getReceiver() { result = getContext().getTargetAddress() }
override Instruction getReceiver() { result = this.getContext().getTargetAddress() }
}
/**
@@ -491,7 +494,7 @@ abstract class TranslatedFieldInitialization extends TranslatedElement {
final override Locatable getAst() { result = ast }
/** DEPRECATED: Alias for getAst */
deprecated override Locatable getAST() { result = getAst() }
deprecated override Locatable getAST() { result = this.getAst() }
final override Declaration getFunction() {
result = getEnclosingFunction(ast) or
@@ -499,7 +502,9 @@ abstract class TranslatedFieldInitialization extends TranslatedElement {
result = getEnclosingVariable(ast).(StaticInitializedStaticLocalVariable)
}
final override Instruction getFirstInstruction() { result = getInstruction(getFieldAddressTag()) }
final override Instruction getFirstInstruction() {
result = this.getInstruction(this.getFieldAddressTag())
}
/**
* Gets the zero-based index describing the order in which this field is to be
@@ -508,19 +513,19 @@ abstract class TranslatedFieldInitialization extends TranslatedElement {
final int getOrder() { result = field.getInitializationOrder() }
override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) {
tag = getFieldAddressTag() and
tag = this.getFieldAddressTag() and
opcode instanceof Opcode::FieldAddress and
resultType = getTypeForGLValue(field.getType())
}
override Instruction getInstructionRegisterOperand(InstructionTag tag, OperandTag operandTag) {
tag = getFieldAddressTag() and
tag = this.getFieldAddressTag() and
operandTag instanceof UnaryOperandTag and
result = getParent().(InitializationContext).getTargetAddress()
result = this.getParent().(InitializationContext).getTargetAddress()
}
override Field getInstructionField(InstructionTag tag) {
tag = getFieldAddressTag() and result = field
tag = this.getFieldAddressTag() and result = field
}
final InstructionTag getFieldAddressTag() { result = InitializerFieldAddressTag() }
@@ -545,21 +550,23 @@ class TranslatedExplicitFieldInitialization extends TranslatedFieldInitializatio
this = TTranslatedExplicitFieldInitialization(ast, field, expr, position)
}
override Instruction getTargetAddress() { result = getInstruction(getFieldAddressTag()) }
override Instruction getTargetAddress() {
result = this.getInstruction(this.getFieldAddressTag())
}
override Type getTargetType() { result = field.getUnspecifiedType() }
override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) {
tag = getFieldAddressTag() and
result = getInitialization().getFirstInstruction() and
tag = this.getFieldAddressTag() and
result = this.getInitialization().getFirstInstruction() and
kind instanceof GotoEdge
}
override Instruction getChildSuccessor(TranslatedElement child) {
child = getInitialization() and result = getParent().getChildSuccessor(this)
child = this.getInitialization() and result = this.getParent().getChildSuccessor(this)
}
override TranslatedElement getChild(int id) { id = 0 and result = getInitialization() }
override TranslatedElement getChild(int id) { id = 0 and result = this.getInitialization() }
private TranslatedInitialization getInitialization() {
result = getTranslatedInitialization(expr)
@@ -584,11 +591,11 @@ class TranslatedFieldValueInitialization extends TranslatedFieldInitialization,
override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) {
TranslatedFieldInitialization.super.hasInstruction(opcode, tag, resultType)
or
tag = getFieldDefaultValueTag() and
tag = this.getFieldDefaultValueTag() and
opcode instanceof Opcode::Constant and
resultType = getTypeForPRValue(field.getType())
or
tag = getFieldDefaultValueStoreTag() and
tag = this.getFieldDefaultValueStoreTag() and
opcode instanceof Opcode::Store and
resultType = getTypeForPRValue(field.getUnspecifiedType())
}
@@ -596,32 +603,32 @@ class TranslatedFieldValueInitialization extends TranslatedFieldInitialization,
override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) {
kind instanceof GotoEdge and
(
tag = getFieldAddressTag() and
result = getInstruction(getFieldDefaultValueTag())
tag = this.getFieldAddressTag() and
result = this.getInstruction(this.getFieldDefaultValueTag())
or
tag = getFieldDefaultValueTag() and
result = getInstruction(getFieldDefaultValueStoreTag())
tag = this.getFieldDefaultValueTag() and
result = this.getInstruction(this.getFieldDefaultValueStoreTag())
or
tag = getFieldDefaultValueStoreTag() and
result = getParent().getChildSuccessor(this)
tag = this.getFieldDefaultValueStoreTag() and
result = this.getParent().getChildSuccessor(this)
)
}
override string getInstructionConstantValue(InstructionTag tag) {
tag = getFieldDefaultValueTag() and
tag = this.getFieldDefaultValueTag() and
result = getZeroValue(field.getUnspecifiedType())
}
override Instruction getInstructionRegisterOperand(InstructionTag tag, OperandTag operandTag) {
result = TranslatedFieldInitialization.super.getInstructionRegisterOperand(tag, operandTag)
or
tag = getFieldDefaultValueStoreTag() and
tag = this.getFieldDefaultValueStoreTag() and
(
operandTag instanceof AddressOperandTag and
result = getInstruction(getFieldAddressTag())
result = this.getInstruction(this.getFieldAddressTag())
or
operandTag instanceof StoreValueOperandTag and
result = getInstruction(getFieldDefaultValueTag())
result = this.getInstruction(this.getFieldDefaultValueTag())
)
}
@@ -644,13 +651,13 @@ abstract class TranslatedElementInitialization extends TranslatedElement {
ArrayOrVectorAggregateLiteral initList;
final override string toString() {
result = initList.toString() + "[" + getElementIndex().toString() + "]"
result = initList.toString() + "[" + this.getElementIndex().toString() + "]"
}
final override Locatable getAst() { result = initList }
/** DEPRECATED: Alias for getAst */
deprecated override Locatable getAST() { result = getAst() }
deprecated override Locatable getAST() { result = this.getAst() }
final override Declaration getFunction() {
result = getEnclosingFunction(initList)
@@ -660,43 +667,45 @@ abstract class TranslatedElementInitialization extends TranslatedElement {
result = getEnclosingVariable(initList).(StaticInitializedStaticLocalVariable)
}
final override Instruction getFirstInstruction() { result = getInstruction(getElementIndexTag()) }
final override Instruction getFirstInstruction() {
result = this.getInstruction(this.getElementIndexTag())
}
override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) {
tag = getElementIndexTag() and
tag = this.getElementIndexTag() and
opcode instanceof Opcode::Constant and
resultType = getIntType()
or
tag = getElementAddressTag() and
tag = this.getElementAddressTag() and
opcode instanceof Opcode::PointerAdd and
resultType = getTypeForGLValue(getElementType())
resultType = getTypeForGLValue(this.getElementType())
}
override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) {
tag = getElementIndexTag() and
result = getInstruction(getElementAddressTag()) and
tag = this.getElementIndexTag() and
result = this.getInstruction(this.getElementAddressTag()) and
kind instanceof GotoEdge
}
override Instruction getInstructionRegisterOperand(InstructionTag tag, OperandTag operandTag) {
tag = getElementAddressTag() and
tag = this.getElementAddressTag() and
(
operandTag instanceof LeftOperandTag and
result = getParent().(InitializationContext).getTargetAddress()
result = this.getParent().(InitializationContext).getTargetAddress()
or
operandTag instanceof RightOperandTag and
result = getInstruction(getElementIndexTag())
result = this.getInstruction(this.getElementIndexTag())
)
}
override int getInstructionElementSize(InstructionTag tag) {
tag = getElementAddressTag() and
result = max(getElementType().getSize())
tag = this.getElementAddressTag() and
result = max(this.getElementType().getSize())
}
override string getInstructionConstantValue(InstructionTag tag) {
tag = getElementIndexTag() and
result = getElementIndex().toString()
tag = this.getElementIndexTag() and
result = this.getElementIndex().toString()
}
abstract int getElementIndex();
@@ -726,23 +735,25 @@ class TranslatedExplicitElementInitialization extends TranslatedElementInitializ
this = TTranslatedExplicitElementInitialization(initList, elementIndex, position)
}
override Instruction getTargetAddress() { result = getInstruction(getElementAddressTag()) }
override Instruction getTargetAddress() {
result = this.getInstruction(this.getElementAddressTag())
}
override Type getTargetType() { result = getElementType() }
override Type getTargetType() { result = this.getElementType() }
override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) {
result = TranslatedElementInitialization.super.getInstructionSuccessor(tag, kind)
or
tag = getElementAddressTag() and
result = getInitialization().getFirstInstruction() and
tag = this.getElementAddressTag() and
result = this.getInitialization().getFirstInstruction() and
kind instanceof GotoEdge
}
override Instruction getChildSuccessor(TranslatedElement child) {
child = getInitialization() and result = getParent().getChildSuccessor(this)
child = this.getInitialization() and result = this.getParent().getChildSuccessor(this)
}
override TranslatedElement getChild(int id) { id = 0 and result = getInitialization() }
override TranslatedElement getChild(int id) { id = 0 and result = this.getInitialization() }
override int getElementIndex() { result = elementIndex }
@@ -773,13 +784,13 @@ class TranslatedElementValueInitialization extends TranslatedElementInitializati
override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) {
TranslatedElementInitialization.super.hasInstruction(opcode, tag, resultType)
or
tag = getElementDefaultValueTag() and
tag = this.getElementDefaultValueTag() and
opcode instanceof Opcode::Constant and
resultType = getDefaultValueType()
resultType = this.getDefaultValueType()
or
tag = getElementDefaultValueStoreTag() and
tag = this.getElementDefaultValueStoreTag() and
opcode instanceof Opcode::Store and
resultType = getDefaultValueType()
resultType = this.getDefaultValueType()
}
override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) {
@@ -787,34 +798,34 @@ class TranslatedElementValueInitialization extends TranslatedElementInitializati
or
kind instanceof GotoEdge and
(
tag = getElementAddressTag() and
result = getInstruction(getElementDefaultValueTag())
tag = this.getElementAddressTag() and
result = this.getInstruction(this.getElementDefaultValueTag())
or
tag = getElementDefaultValueTag() and
result = getInstruction(getElementDefaultValueStoreTag())
tag = this.getElementDefaultValueTag() and
result = this.getInstruction(this.getElementDefaultValueStoreTag())
or
tag = getElementDefaultValueStoreTag() and
result = getParent().getChildSuccessor(this)
tag = this.getElementDefaultValueStoreTag() and
result = this.getParent().getChildSuccessor(this)
)
}
override string getInstructionConstantValue(InstructionTag tag) {
result = TranslatedElementInitialization.super.getInstructionConstantValue(tag)
or
tag = getElementDefaultValueTag() and
result = getZeroValue(getElementType())
tag = this.getElementDefaultValueTag() and
result = getZeroValue(this.getElementType())
}
override Instruction getInstructionRegisterOperand(InstructionTag tag, OperandTag operandTag) {
result = TranslatedElementInitialization.super.getInstructionRegisterOperand(tag, operandTag)
or
tag = getElementDefaultValueStoreTag() and
tag = this.getElementDefaultValueStoreTag() and
(
operandTag instanceof AddressOperandTag and
result = getInstruction(getElementAddressTag())
result = this.getInstruction(this.getElementAddressTag())
or
operandTag instanceof StoreValueOperandTag and
result = getInstruction(getElementDefaultValueTag())
result = this.getInstruction(this.getElementDefaultValueTag())
)
}
@@ -825,7 +836,7 @@ class TranslatedElementValueInitialization extends TranslatedElementInitializati
override int getElementIndex() { result = elementIndex }
override predicate needsUnknownOpaqueType(int byteSize) {
elementCount != 0 and byteSize = elementCount * getElementType().getSize()
elementCount != 0 and byteSize = elementCount * this.getElementType().getSize()
}
private InstructionTag getElementDefaultValueTag() {
@@ -838,8 +849,8 @@ class TranslatedElementValueInitialization extends TranslatedElementInitializati
private CppType getDefaultValueType() {
if elementCount = 1
then result = getTypeForPRValue(getElementType())
else result = getUnknownOpaqueType(elementCount * getElementType().getSize())
then result = getTypeForPRValue(this.getElementType())
else result = getUnknownOpaqueType(elementCount * this.getElementType().getSize())
}
}
@@ -849,18 +860,18 @@ abstract class TranslatedStructorCallFromStructor extends TranslatedElement, Str
final override Locatable getAst() { result = call }
/** DEPRECATED: Alias for getAst */
deprecated override Locatable getAST() { result = getAst() }
deprecated override Locatable getAST() { result = this.getAst() }
final override TranslatedElement getChild(int id) {
id = 0 and
result = getStructorCall()
result = this.getStructorCall()
}
final override Function getFunction() { result = getEnclosingFunction(call) }
final override Instruction getChildSuccessor(TranslatedElement child) {
child = getStructorCall() and
result = getParent().getChildSuccessor(this)
child = this.getStructorCall() and
result = this.getParent().getChildSuccessor(this)
}
final TranslatedExpr getStructorCall() { result = getTranslatedExpr(call) }
@@ -871,7 +882,9 @@ abstract class TranslatedStructorCallFromStructor extends TranslatedElement, Str
* destructor from within a derived class constructor or destructor.
*/
abstract class TranslatedBaseStructorCall extends TranslatedStructorCallFromStructor {
final override Instruction getFirstInstruction() { result = getInstruction(OnlyInstructionTag()) }
final override Instruction getFirstInstruction() {
result = this.getInstruction(OnlyInstructionTag())
}
final override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) {
tag = OnlyInstructionTag() and
@@ -882,15 +895,15 @@ abstract class TranslatedBaseStructorCall extends TranslatedStructorCallFromStru
final override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) {
tag = OnlyInstructionTag() and
kind instanceof GotoEdge and
result = getStructorCall().getFirstInstruction()
result = this.getStructorCall().getFirstInstruction()
}
final override Instruction getReceiver() { result = getInstruction(OnlyInstructionTag()) }
final override Instruction getReceiver() { result = this.getInstruction(OnlyInstructionTag()) }
final override Instruction getInstructionRegisterOperand(InstructionTag tag, OperandTag operandTag) {
tag = OnlyInstructionTag() and
operandTag instanceof UnaryOperandTag and
result = getTranslatedFunction(getFunction()).getInitializeThisInstruction()
result = getTranslatedFunction(this.getFunction()).getInitializeThisInstruction()
}
final override predicate getInstructionInheritance(
@@ -898,7 +911,7 @@ abstract class TranslatedBaseStructorCall extends TranslatedStructorCallFromStru
) {
tag = OnlyInstructionTag() and
baseClass = call.getTarget().getDeclaringType().getUnspecifiedType() and
derivedClass = getFunction().getDeclaringType().getUnspecifiedType()
derivedClass = this.getFunction().getDeclaringType().getUnspecifiedType()
}
}
@@ -924,7 +937,7 @@ class TranslatedConstructorDelegationInit extends TranslatedConstructorCallFromC
final override string toString() { result = "delegation construct: " + call.toString() }
final override Instruction getFirstInstruction() {
result = getStructorCall().getFirstInstruction()
result = this.getStructorCall().getFirstInstruction()
}
final override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) {
@@ -934,7 +947,7 @@ class TranslatedConstructorDelegationInit extends TranslatedConstructorCallFromC
final override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) { none() }
final override Instruction getReceiver() {
result = getTranslatedFunction(getFunction()).getInitializeThisInstruction()
result = getTranslatedFunction(this.getFunction()).getInitializeThisInstruction()
}
}
@@ -981,11 +994,11 @@ class TranslatedConstructorBareInit extends TranslatedElement, TTranslatedConstr
override Locatable getAst() { result = init }
/** DEPRECATED: Alias for getAst */
deprecated override Locatable getAST() { result = getAst() }
deprecated override Locatable getAST() { result = this.getAst() }
final override string toString() { result = "construct base (no constructor)" }
override Instruction getFirstInstruction() { result = getParent().getChildSuccessor(this) }
override Instruction getFirstInstruction() { result = this.getParent().getChildSuccessor(this) }
override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) {
none()

View File

@@ -240,7 +240,7 @@ abstract class TranslatedStmt extends TranslatedElement, TTranslatedStmt {
final override Locatable getAst() { result = stmt }
/** DEPRECATED: Alias for getAst */
deprecated override Locatable getAST() { result = getAst() }
deprecated override Locatable getAST() { result = this.getAst() }
final override Function getFunction() { result = stmt.getEnclosingFunction() }
}
@@ -254,7 +254,7 @@ class TranslatedEmptyStmt extends TranslatedStmt {
override TranslatedElement getChild(int id) { none() }
override Instruction getFirstInstruction() { result = getInstruction(OnlyInstructionTag()) }
override Instruction getFirstInstruction() { result = this.getInstruction(OnlyInstructionTag()) }
override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) {
tag = OnlyInstructionTag() and
@@ -264,7 +264,7 @@ class TranslatedEmptyStmt extends TranslatedStmt {
override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) {
tag = OnlyInstructionTag() and
result = getParent().getChildSuccessor(this) and
result = this.getParent().getChildSuccessor(this) and
kind instanceof GotoEdge
}
@@ -279,19 +279,19 @@ class TranslatedEmptyStmt extends TranslatedStmt {
class TranslatedDeclStmt extends TranslatedStmt {
override DeclStmt stmt;
override TranslatedElement getChild(int id) { result = getDeclarationEntry(id) }
override TranslatedElement getChild(int id) { result = this.getDeclarationEntry(id) }
override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) {
none()
}
override Instruction getFirstInstruction() {
result = getDeclarationEntry(0).getFirstInstruction()
result = this.getDeclarationEntry(0).getFirstInstruction()
or
not exists(getDeclarationEntry(0)) and result = getParent().getChildSuccessor(this)
not exists(this.getDeclarationEntry(0)) and result = this.getParent().getChildSuccessor(this)
}
private int getChildCount() { result = count(getDeclarationEntry(_)) }
private int getChildCount() { result = count(this.getDeclarationEntry(_)) }
IRDeclarationEntry getIRDeclarationEntry(int index) {
result.hasIndex(index) and
@@ -319,10 +319,10 @@ class TranslatedDeclStmt extends TranslatedStmt {
override Instruction getChildSuccessor(TranslatedElement child) {
exists(int index |
child = getDeclarationEntry(index) and
if index = (getChildCount() - 1)
then result = getParent().getChildSuccessor(this)
else result = getDeclarationEntry(index + 1).getFirstInstruction()
child = this.getDeclarationEntry(index) and
if index = (this.getChildCount() - 1)
then result = this.getParent().getChildSuccessor(this)
else result = this.getDeclarationEntry(index + 1).getFirstInstruction()
)
}
}
@@ -332,19 +332,19 @@ class TranslatedExprStmt extends TranslatedStmt {
TranslatedExpr getExpr() { result = getTranslatedExpr(stmt.getExpr().getFullyConverted()) }
override TranslatedElement getChild(int id) { id = 0 and result = getExpr() }
override TranslatedElement getChild(int id) { id = 0 and result = this.getExpr() }
override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) {
none()
}
override Instruction getFirstInstruction() { result = getExpr().getFirstInstruction() }
override Instruction getFirstInstruction() { result = this.getExpr().getFirstInstruction() }
override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) { none() }
override Instruction getChildSuccessor(TranslatedElement child) {
child = getExpr() and
result = getParent().getChildSuccessor(this)
child = this.getExpr() and
result = this.getParent().getChildSuccessor(this)
}
}
@@ -363,16 +363,18 @@ class TranslatedReturnValueStmt extends TranslatedReturnStmt, TranslatedVariable
TranslatedReturnValueStmt() { stmt.hasExpr() and hasReturnValue(stmt.getEnclosingFunction()) }
final override Instruction getInitializationSuccessor() {
result = getEnclosingFunction().getReturnSuccessorInstruction()
result = this.getEnclosingFunction().getReturnSuccessorInstruction()
}
final override Type getTargetType() { result = getEnclosingFunction().getReturnType() }
final override Type getTargetType() { result = this.getEnclosingFunction().getReturnType() }
final override TranslatedInitialization getInitialization() {
result = getTranslatedInitialization(stmt.getExpr().getFullyConverted())
}
final override IRVariable getIRVariable() { result = getEnclosingFunction().getReturnVariable() }
final override IRVariable getIRVariable() {
result = this.getEnclosingFunction().getReturnVariable()
}
}
/**
@@ -385,10 +387,10 @@ class TranslatedReturnVoidExpressionStmt extends TranslatedReturnStmt {
override TranslatedElement getChild(int id) {
id = 0 and
result = getExpr()
result = this.getExpr()
}
override Instruction getFirstInstruction() { result = getExpr().getFirstInstruction() }
override Instruction getFirstInstruction() { result = this.getExpr().getFirstInstruction() }
override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) {
tag = OnlyInstructionTag() and
@@ -398,13 +400,13 @@ class TranslatedReturnVoidExpressionStmt extends TranslatedReturnStmt {
override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) {
tag = OnlyInstructionTag() and
result = getEnclosingFunction().getReturnSuccessorInstruction() and
result = this.getEnclosingFunction().getReturnSuccessorInstruction() and
kind instanceof GotoEdge
}
override Instruction getChildSuccessor(TranslatedElement child) {
child = getExpr() and
result = getInstruction(OnlyInstructionTag())
child = this.getExpr() and
result = this.getInstruction(OnlyInstructionTag())
}
private TranslatedExpr getExpr() { result = getTranslatedExpr(stmt.getExpr()) }
@@ -421,7 +423,7 @@ class TranslatedReturnVoidStmt extends TranslatedReturnStmt {
override TranslatedElement getChild(int id) { none() }
override Instruction getFirstInstruction() { result = getInstruction(OnlyInstructionTag()) }
override Instruction getFirstInstruction() { result = this.getInstruction(OnlyInstructionTag()) }
override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) {
tag = OnlyInstructionTag() and
@@ -431,7 +433,7 @@ class TranslatedReturnVoidStmt extends TranslatedReturnStmt {
override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) {
tag = OnlyInstructionTag() and
result = getEnclosingFunction().getReturnSuccessorInstruction() and
result = this.getEnclosingFunction().getReturnSuccessorInstruction() and
kind instanceof GotoEdge
}
@@ -452,7 +454,7 @@ class TranslatedUnreachableReturnStmt extends TranslatedReturnStmt {
override TranslatedElement getChild(int id) { none() }
override Instruction getFirstInstruction() { result = getInstruction(OnlyInstructionTag()) }
override Instruction getFirstInstruction() { result = this.getInstruction(OnlyInstructionTag()) }
override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) {
tag = OnlyInstructionTag() and
@@ -511,9 +513,9 @@ class TranslatedTryStmt extends TranslatedStmt {
override TryOrMicrosoftTryStmt stmt;
override TranslatedElement getChild(int id) {
id = 0 and result = getBody()
id = 0 and result = this.getBody()
or
result = getHandler(id - 1)
result = this.getHandler(id - 1)
or
id = stmt.getNumberOfCatchClauses() + 1 and
result = this.getFinally()
@@ -525,7 +527,7 @@ class TranslatedTryStmt extends TranslatedStmt {
override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) { none() }
override Instruction getFirstInstruction() { result = getBody().getFirstInstruction() }
override Instruction getFirstInstruction() { result = this.getBody().getFirstInstruction() }
override Instruction getChildSuccessor(TranslatedElement child) {
// All non-finally children go to the successor of the `try` if
@@ -546,19 +548,19 @@ class TranslatedTryStmt extends TranslatedStmt {
final Instruction getNextHandler(TranslatedHandler handler) {
exists(int index |
handler = getHandler(index) and
result = getHandler(index + 1).getFirstInstruction()
handler = this.getHandler(index) and
result = this.getHandler(index + 1).getFirstInstruction()
)
or
// The last catch clause flows to the exception successor of the parent
// of the `try`, because the exception successor of the `try` itself is
// the first catch clause.
handler = getHandler(stmt.getNumberOfCatchClauses() - 1) and
result = getParent().getExceptionSuccessorInstruction()
handler = this.getHandler(stmt.getNumberOfCatchClauses() - 1) and
result = this.getParent().getExceptionSuccessorInstruction()
}
final override Instruction getExceptionSuccessorInstruction() {
result = getHandler(0).getFirstInstruction()
result = this.getHandler(0).getFirstInstruction()
}
private TranslatedElement getHandler(int index) { result = stmt.getTranslatedHandler(index) }
@@ -571,19 +573,19 @@ class TranslatedTryStmt extends TranslatedStmt {
class TranslatedBlock extends TranslatedStmt {
override BlockStmt stmt;
override TranslatedElement getChild(int id) { result = getStmt(id) }
override TranslatedElement getChild(int id) { result = this.getStmt(id) }
override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) {
isEmpty() and
this.isEmpty() and
opcode instanceof Opcode::NoOp and
tag = OnlyInstructionTag() and
resultType = getVoidType()
}
override Instruction getFirstInstruction() {
if isEmpty()
then result = getInstruction(OnlyInstructionTag())
else result = getStmt(0).getFirstInstruction()
if this.isEmpty()
then result = this.getInstruction(OnlyInstructionTag())
else result = this.getStmt(0).getFirstInstruction()
}
private predicate isEmpty() { not exists(stmt.getStmt(0)) }
@@ -594,16 +596,16 @@ class TranslatedBlock extends TranslatedStmt {
override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) {
tag = OnlyInstructionTag() and
result = getParent().getChildSuccessor(this) and
result = this.getParent().getChildSuccessor(this) and
kind instanceof GotoEdge
}
override Instruction getChildSuccessor(TranslatedElement child) {
exists(int index |
child = getStmt(index) and
if index = (getStmtCount() - 1)
then result = getParent().getChildSuccessor(this)
else result = getStmt(index + 1).getFirstInstruction()
child = this.getStmt(index) and
if index = (this.getStmtCount() - 1)
then result = this.getParent().getChildSuccessor(this)
else result = this.getStmt(index + 1).getFirstInstruction()
)
}
}
@@ -614,18 +616,18 @@ class TranslatedBlock extends TranslatedStmt {
abstract class TranslatedHandler extends TranslatedStmt {
override Handler stmt;
override TranslatedElement getChild(int id) { id = 1 and result = getBlock() }
override TranslatedElement getChild(int id) { id = 1 and result = this.getBlock() }
override Instruction getFirstInstruction() { result = getInstruction(CatchTag()) }
override Instruction getFirstInstruction() { result = this.getInstruction(CatchTag()) }
override Instruction getChildSuccessor(TranslatedElement child) {
child = getBlock() and result = getParent().getChildSuccessor(this)
child = this.getBlock() and result = this.getParent().getChildSuccessor(this)
}
override Instruction getExceptionSuccessorInstruction() {
// A throw from within a `catch` block flows to the handler for the parent of
// the `try`.
result = getParent().getParent().getExceptionSuccessorInstruction()
result = this.getParent().getParent().getExceptionSuccessorInstruction()
}
TranslatedStmt getBlock() { result = getTranslatedStmt(stmt.getBlock()) }
@@ -647,23 +649,23 @@ class TranslatedCatchByTypeHandler extends TranslatedHandler {
override TranslatedElement getChild(int id) {
result = super.getChild(id)
or
id = 0 and result = getParameter()
id = 0 and result = this.getParameter()
}
override Instruction getChildSuccessor(TranslatedElement child) {
result = super.getChildSuccessor(child)
or
child = getParameter() and result = getBlock().getFirstInstruction()
child = this.getParameter() and result = this.getBlock().getFirstInstruction()
}
override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) {
tag = CatchTag() and
(
kind instanceof GotoEdge and
result = getParameter().getFirstInstruction()
result = this.getParameter().getFirstInstruction()
or
kind instanceof ExceptionEdge and
result = getParent().(TranslatedTryStmt).getNextHandler(this)
result = this.getParent().(TranslatedTryStmt).getNextHandler(this)
)
}
@@ -692,7 +694,7 @@ class TranslatedCatchAnyHandler extends TranslatedHandler {
override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) {
tag = CatchTag() and
kind instanceof GotoEdge and
result = getBlock().getFirstInstruction()
result = this.getBlock().getFirstInstruction()
}
}
@@ -700,19 +702,19 @@ class TranslatedIfStmt extends TranslatedStmt, ConditionContext {
override IfStmt stmt;
override Instruction getFirstInstruction() {
if hasInitialization()
then result = getInitialization().getFirstInstruction()
else result = getFirstConditionInstruction()
if this.hasInitialization()
then result = this.getInitialization().getFirstInstruction()
else result = this.getFirstConditionInstruction()
}
override TranslatedElement getChild(int id) {
id = 0 and result = getInitialization()
id = 0 and result = this.getInitialization()
or
id = 1 and result = getCondition()
id = 1 and result = this.getCondition()
or
id = 2 and result = getThen()
id = 2 and result = this.getThen()
or
id = 3 and result = getElse()
id = 3 and result = this.getElse()
}
private predicate hasInitialization() { exists(stmt.getInitialization()) }
@@ -726,7 +728,7 @@ class TranslatedIfStmt extends TranslatedStmt, ConditionContext {
}
private Instruction getFirstConditionInstruction() {
result = getCondition().getFirstInstruction()
result = this.getCondition().getFirstInstruction()
}
private TranslatedStmt getThen() { result = getTranslatedStmt(stmt.getThen()) }
@@ -738,23 +740,23 @@ class TranslatedIfStmt extends TranslatedStmt, ConditionContext {
override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) { none() }
override Instruction getChildTrueSuccessor(TranslatedCondition child) {
child = getCondition() and
result = getThen().getFirstInstruction()
child = this.getCondition() and
result = this.getThen().getFirstInstruction()
}
override Instruction getChildFalseSuccessor(TranslatedCondition child) {
child = getCondition() and
if hasElse()
then result = getElse().getFirstInstruction()
else result = getParent().getChildSuccessor(this)
child = this.getCondition() and
if this.hasElse()
then result = this.getElse().getFirstInstruction()
else result = this.getParent().getChildSuccessor(this)
}
override Instruction getChildSuccessor(TranslatedElement child) {
child = getInitialization() and
result = getFirstConditionInstruction()
child = this.getInitialization() and
result = this.getFirstConditionInstruction()
or
(child = getThen() or child = getElse()) and
result = getParent().getChildSuccessor(this)
(child = this.getThen() or child = this.getElse()) and
result = this.getParent().getChildSuccessor(this)
}
override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) {
@@ -772,17 +774,17 @@ abstract class TranslatedLoop extends TranslatedStmt, ConditionContext {
final TranslatedStmt getBody() { result = getTranslatedStmt(stmt.getStmt()) }
final Instruction getFirstConditionInstruction() {
if hasCondition()
then result = getCondition().getFirstInstruction()
else result = getBody().getFirstInstruction()
if this.hasCondition()
then result = this.getCondition().getFirstInstruction()
else result = this.getBody().getFirstInstruction()
}
final predicate hasCondition() { exists(stmt.getCondition()) }
override TranslatedElement getChild(int id) {
id = 0 and result = getCondition()
id = 0 and result = this.getCondition()
or
id = 1 and result = getBody()
id = 1 and result = this.getBody()
}
override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) {
@@ -792,31 +794,31 @@ abstract class TranslatedLoop extends TranslatedStmt, ConditionContext {
final override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) { none() }
final override Instruction getChildTrueSuccessor(TranslatedCondition child) {
child = getCondition() and result = getBody().getFirstInstruction()
child = this.getCondition() and result = this.getBody().getFirstInstruction()
}
final override Instruction getChildFalseSuccessor(TranslatedCondition child) {
child = getCondition() and result = getParent().getChildSuccessor(this)
child = this.getCondition() and result = this.getParent().getChildSuccessor(this)
}
}
class TranslatedWhileStmt extends TranslatedLoop {
TranslatedWhileStmt() { stmt instanceof WhileStmt }
override Instruction getFirstInstruction() { result = getFirstConditionInstruction() }
override Instruction getFirstInstruction() { result = this.getFirstConditionInstruction() }
override Instruction getChildSuccessor(TranslatedElement child) {
child = getBody() and result = getFirstConditionInstruction()
child = this.getBody() and result = this.getFirstConditionInstruction()
}
}
class TranslatedDoStmt extends TranslatedLoop {
TranslatedDoStmt() { stmt instanceof DoStmt }
override Instruction getFirstInstruction() { result = getBody().getFirstInstruction() }
override Instruction getFirstInstruction() { result = this.getBody().getFirstInstruction() }
override Instruction getChildSuccessor(TranslatedElement child) {
child = getBody() and result = getFirstConditionInstruction()
child = this.getBody() and result = this.getFirstConditionInstruction()
}
}
@@ -824,13 +826,13 @@ class TranslatedForStmt extends TranslatedLoop {
override ForStmt stmt;
override TranslatedElement getChild(int id) {
id = 0 and result = getInitialization()
id = 0 and result = this.getInitialization()
or
id = 1 and result = getCondition()
id = 1 and result = this.getCondition()
or
id = 2 and result = getUpdate()
id = 2 and result = this.getUpdate()
or
id = 3 and result = getBody()
id = 3 and result = this.getBody()
}
private TranslatedStmt getInitialization() {
@@ -844,23 +846,23 @@ class TranslatedForStmt extends TranslatedLoop {
private predicate hasUpdate() { exists(stmt.getUpdate()) }
override Instruction getFirstInstruction() {
if hasInitialization()
then result = getInitialization().getFirstInstruction()
else result = getFirstConditionInstruction()
if this.hasInitialization()
then result = this.getInitialization().getFirstInstruction()
else result = this.getFirstConditionInstruction()
}
override Instruction getChildSuccessor(TranslatedElement child) {
child = getInitialization() and
result = getFirstConditionInstruction()
child = this.getInitialization() and
result = this.getFirstConditionInstruction()
or
(
child = getBody() and
if hasUpdate()
then result = getUpdate().getFirstInstruction()
else result = getFirstConditionInstruction()
child = this.getBody() and
if this.hasUpdate()
then result = this.getUpdate().getFirstInstruction()
else result = this.getFirstConditionInstruction()
)
or
child = getUpdate() and result = getFirstConditionInstruction()
child = this.getUpdate() and result = this.getFirstConditionInstruction()
}
}
@@ -875,39 +877,39 @@ class TranslatedRangeBasedForStmt extends TranslatedStmt, ConditionContext {
override RangeBasedForStmt stmt;
override TranslatedElement getChild(int id) {
id = 0 and result = getRangeVariableDeclStmt()
id = 0 and result = this.getRangeVariableDeclStmt()
or
// Note: `__begin` and `__end` are declared by the same `DeclStmt`
id = 1 and result = getBeginEndVariableDeclStmt()
id = 1 and result = this.getBeginEndVariableDeclStmt()
or
id = 2 and result = getCondition()
id = 2 and result = this.getCondition()
or
id = 3 and result = getUpdate()
id = 3 and result = this.getUpdate()
or
id = 4 and result = getVariableDeclStmt()
id = 4 and result = this.getVariableDeclStmt()
or
id = 5 and result = getBody()
id = 5 and result = this.getBody()
}
override Instruction getFirstInstruction() {
result = getRangeVariableDeclStmt().getFirstInstruction()
result = this.getRangeVariableDeclStmt().getFirstInstruction()
}
override Instruction getChildSuccessor(TranslatedElement child) {
child = getRangeVariableDeclStmt() and
result = getBeginEndVariableDeclStmt().getFirstInstruction()
child = this.getRangeVariableDeclStmt() and
result = this.getBeginEndVariableDeclStmt().getFirstInstruction()
or
child = getBeginEndVariableDeclStmt() and
result = getCondition().getFirstInstruction()
child = this.getBeginEndVariableDeclStmt() and
result = this.getCondition().getFirstInstruction()
or
child = getVariableDeclStmt() and
result = getBody().getFirstInstruction()
child = this.getVariableDeclStmt() and
result = this.getBody().getFirstInstruction()
or
child = getBody() and
result = getUpdate().getFirstInstruction()
child = this.getBody() and
result = this.getUpdate().getFirstInstruction()
or
child = getUpdate() and
result = getCondition().getFirstInstruction()
child = this.getUpdate() and
result = this.getCondition().getFirstInstruction()
}
override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) {
@@ -917,11 +919,11 @@ class TranslatedRangeBasedForStmt extends TranslatedStmt, ConditionContext {
override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) { none() }
override Instruction getChildTrueSuccessor(TranslatedCondition child) {
child = getCondition() and result = getVariableDeclStmt().getFirstInstruction()
child = this.getCondition() and result = this.getVariableDeclStmt().getFirstInstruction()
}
override Instruction getChildFalseSuccessor(TranslatedCondition child) {
child = getCondition() and result = getParent().getChildSuccessor(this)
child = this.getCondition() and result = this.getParent().getChildSuccessor(this)
}
private TranslatedDeclStmt getRangeVariableDeclStmt() {
@@ -961,7 +963,7 @@ class TranslatedRangeBasedForStmt extends TranslatedStmt, ConditionContext {
class TranslatedJumpStmt extends TranslatedStmt {
override JumpStmt stmt;
override Instruction getFirstInstruction() { result = getInstruction(OnlyInstructionTag()) }
override Instruction getFirstInstruction() { result = this.getInstruction(OnlyInstructionTag()) }
override TranslatedElement getChild(int id) { none() }
@@ -996,22 +998,22 @@ class TranslatedSwitchStmt extends TranslatedStmt {
result = getTranslatedExpr(stmt.getExpr().getFullyConverted())
}
private Instruction getFirstExprInstruction() { result = getExpr().getFirstInstruction() }
private Instruction getFirstExprInstruction() { result = this.getExpr().getFirstInstruction() }
private TranslatedStmt getBody() { result = getTranslatedStmt(stmt.getStmt()) }
override Instruction getFirstInstruction() {
if hasInitialization()
then result = getInitialization().getFirstInstruction()
else result = getFirstExprInstruction()
if this.hasInitialization()
then result = this.getInitialization().getFirstInstruction()
else result = this.getFirstExprInstruction()
}
override TranslatedElement getChild(int id) {
id = 0 and result = getInitialization()
id = 0 and result = this.getInitialization()
or
id = 1 and result = getExpr()
id = 1 and result = this.getExpr()
or
id = 2 and result = getBody()
id = 2 and result = this.getBody()
}
private predicate hasInitialization() { exists(stmt.getInitialization()) }
@@ -1029,7 +1031,7 @@ class TranslatedSwitchStmt extends TranslatedStmt {
override Instruction getInstructionRegisterOperand(InstructionTag tag, OperandTag operandTag) {
tag = SwitchBranchTag() and
operandTag instanceof ConditionOperandTag and
result = getExpr().getResult()
result = this.getExpr().getResult()
}
override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) {
@@ -1043,15 +1045,15 @@ class TranslatedSwitchStmt extends TranslatedStmt {
not stmt.hasDefaultCase() and
tag = SwitchBranchTag() and
kind instanceof DefaultEdge and
result = getParent().getChildSuccessor(this)
result = this.getParent().getChildSuccessor(this)
}
override Instruction getChildSuccessor(TranslatedElement child) {
child = getInitialization() and result = getFirstExprInstruction()
child = this.getInitialization() and result = this.getFirstExprInstruction()
or
child = getExpr() and result = getInstruction(SwitchBranchTag())
child = this.getExpr() and result = this.getInstruction(SwitchBranchTag())
or
child = getBody() and result = getParent().getChildSuccessor(this)
child = this.getBody() and result = this.getParent().getChildSuccessor(this)
}
}
@@ -1063,9 +1065,9 @@ class TranslatedAsmStmt extends TranslatedStmt {
}
override Instruction getFirstInstruction() {
if exists(getChild(0))
then result = getChild(0).getFirstInstruction()
else result = getInstruction(AsmTag())
if exists(this.getChild(0))
then result = this.getChild(0).getFirstInstruction()
else result = this.getInstruction(AsmTag())
}
override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) {
@@ -1078,7 +1080,7 @@ class TranslatedAsmStmt extends TranslatedStmt {
exists(int index |
tag = AsmTag() and
operandTag = asmOperand(index) and
result = getChild(index).getResult()
result = this.getChild(index).getResult()
)
}
@@ -1092,16 +1094,16 @@ class TranslatedAsmStmt extends TranslatedStmt {
override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) {
tag = AsmTag() and
result = getParent().getChildSuccessor(this) and
result = this.getParent().getChildSuccessor(this) and
kind instanceof GotoEdge
}
override Instruction getChildSuccessor(TranslatedElement child) {
exists(int index |
child = getChild(index) and
if exists(getChild(index + 1))
then result = getChild(index + 1).getFirstInstruction()
else result = getInstruction(AsmTag())
child = this.getChild(index) and
if exists(this.getChild(index + 1))
then result = this.getChild(index + 1).getFirstInstruction()
else result = this.getInstruction(AsmTag())
)
}
}

View File

@@ -7,6 +7,9 @@ predicate isInfeasibleInstructionSuccessor(Instruction instr, EdgeKind kind) {
conditionValue = getConstantValue(instr.(ConditionalBranchInstruction).getCondition()) and
if conditionValue = 0 then kind instanceof TrueEdge else kind instanceof FalseEdge
)
or
instr.getSuccessor(kind) instanceof UnreachedInstruction and
kind instanceof GotoEdge
}
pragma[noinline]
@@ -41,7 +44,9 @@ class ReachableBlock extends IRBlockBase {
* An instruction that is contained in a reachable block.
*/
class ReachableInstruction extends Instruction {
ReachableInstruction() { this.getBlock() instanceof ReachableBlock }
ReachableInstruction() {
this.getBlock() instanceof ReachableBlock and not this instanceof UnreachedInstruction
}
}
module Graph {

View File

@@ -77,4 +77,16 @@ class IRPropertyProvider extends TIRPropertyProvider {
* Gets the value of the property named `key` for the specified operand.
*/
string getOperandProperty(Operand operand, string key) { none() }
/**
* Holds if the instruction `instr` should be included when printing
* the IR instructions.
*/
predicate shouldPrintInstruction(Instruction instr) { any() }
/**
* Holds if the operand `operand` should be included when printing the an
* instruction's operand list.
*/
predicate shouldPrintOperand(Operand operand) { any() }
}

View File

@@ -45,7 +45,9 @@ class IRFunction extends IRFunctionBase {
* Gets the block containing the entry point of this function.
*/
pragma[noinline]
final IRBlock getEntryBlock() { result.getFirstInstruction() = getEnterFunctionInstruction() }
final IRBlock getEntryBlock() {
result.getFirstInstruction() = this.getEnterFunctionInstruction()
}
/**
* Gets all instructions in this function.

View File

@@ -39,12 +39,12 @@ class IRVariable extends TIRVariable {
/**
* Gets the type of the variable.
*/
final Language::Type getType() { getLanguageType().hasType(result, false) }
final Language::Type getType() { this.getLanguageType().hasType(result, false) }
/**
* Gets the language-neutral type of the variable.
*/
final IRType getIRType() { result = getLanguageType().getIRType() }
final IRType getIRType() { result = this.getLanguageType().getIRType() }
/**
* Gets the type of the variable.
@@ -58,7 +58,7 @@ class IRVariable extends TIRVariable {
Language::AST getAst() { none() }
/** DEPRECATED: Alias for getAst */
deprecated Language::AST getAST() { result = getAst() }
deprecated Language::AST getAST() { result = this.getAst() }
/**
* Gets an identifier string for the variable. This identifier is unique
@@ -69,7 +69,7 @@ class IRVariable extends TIRVariable {
/**
* Gets the source location of this variable.
*/
final Language::Location getLocation() { result = getAst().getLocation() }
final Language::Location getLocation() { result = this.getAst().getLocation() }
/**
* Gets the IR for the function that references this variable.
@@ -91,15 +91,15 @@ class IRUserVariable extends IRVariable, TIRUserVariable {
IRUserVariable() { this = TIRUserVariable(var, type, func) }
final override string toString() { result = getVariable().toString() }
final override string toString() { result = this.getVariable().toString() }
final override Language::AST getAst() { result = var }
/** DEPRECATED: Alias for getAst */
deprecated override Language::AST getAST() { result = getAst() }
deprecated override Language::AST getAST() { result = this.getAst() }
final override string getUniqueId() {
result = getVariable().toString() + " " + getVariable().getLocation().toString()
result = this.getVariable().toString() + " " + this.getVariable().getLocation().toString()
}
final override Language::LanguageType getLanguageType() { result = type }
@@ -166,9 +166,9 @@ class IRGeneratedVariable extends IRVariable {
final override Language::AST getAst() { result = ast }
/** DEPRECATED: Alias for getAst */
deprecated override Language::AST getAST() { result = getAst() }
deprecated override Language::AST getAST() { result = this.getAst() }
override string toString() { result = getBaseString() + getLocationString() }
override string toString() { result = this.getBaseString() + this.getLocationString() }
override string getUniqueId() { none() }
@@ -272,7 +272,7 @@ class IRStringLiteral extends IRGeneratedVariable, TIRStringLiteral {
final override predicate isReadOnly() { any() }
final override string getUniqueId() {
result = "String: " + getLocationString() + "=" + Language::getStringLiteralText(literal)
result = "String: " + this.getLocationString() + "=" + Language::getStringLiteralText(literal)
}
final override string getBaseString() { result = "#string" }
@@ -303,7 +303,8 @@ class IRDynamicInitializationFlag extends IRGeneratedVariable, TIRDynamicInitial
final Language::Variable getVariable() { result = var }
final override string getUniqueId() {
result = "Init: " + getVariable().toString() + " " + getVariable().getLocation().toString()
result =
"Init: " + this.getVariable().toString() + " " + this.getVariable().getLocation().toString()
}
final override string getBaseString() { result = "#init:" + var.toString() + ":" }
@@ -332,5 +333,5 @@ class IRParameter extends IRAutomaticVariable {
* An IR variable representing a positional parameter.
*/
class IRPositionalParameter extends IRParameter, IRAutomaticUserVariable {
final override int getIndex() { result = getVariable().(Language::Parameter).getIndex() }
final override int getIndex() { result = this.getVariable().(Language::Parameter).getIndex() }
}

View File

@@ -42,6 +42,14 @@ private predicate shouldPrintFunction(Language::Declaration decl) {
exists(PrintIRConfiguration config | config.shouldPrintFunction(decl))
}
private predicate shouldPrintInstruction(Instruction i) {
exists(IRPropertyProvider provider | provider.shouldPrintInstruction(i))
}
private predicate shouldPrintOperand(Operand operand) {
exists(IRPropertyProvider provider | provider.shouldPrintOperand(operand))
}
private string getAdditionalInstructionProperty(Instruction instr, string key) {
exists(IRPropertyProvider provider | result = provider.getInstructionProperty(instr, key))
}
@@ -84,7 +92,9 @@ private string getOperandPropertyString(Operand operand) {
private newtype TPrintableIRNode =
TPrintableIRFunction(IRFunction irFunc) { shouldPrintFunction(irFunc.getFunction()) } or
TPrintableIRBlock(IRBlock block) { shouldPrintFunction(block.getEnclosingFunction()) } or
TPrintableInstruction(Instruction instr) { shouldPrintFunction(instr.getEnclosingFunction()) }
TPrintableInstruction(Instruction instr) {
shouldPrintInstruction(instr) and shouldPrintFunction(instr.getEnclosingFunction())
}
/**
* A node to be emitted in the IR graph.
@@ -127,13 +137,13 @@ abstract private class PrintableIRNode extends TPrintableIRNode {
* Gets the value of the node property with the specified key.
*/
string getProperty(string key) {
key = "semmle.label" and result = getLabel()
key = "semmle.label" and result = this.getLabel()
or
key = "semmle.order" and result = getOrder().toString()
key = "semmle.order" and result = this.getOrder().toString()
or
key = "semmle.graphKind" and result = getGraphKind()
key = "semmle.graphKind" and result = this.getGraphKind()
or
key = "semmle.forceText" and forceText() and result = "true"
key = "semmle.forceText" and this.forceText() and result = "true"
}
}
@@ -178,7 +188,7 @@ private class PrintableIRBlock extends PrintableIRNode, TPrintableIRBlock {
PrintableIRBlock() { this = TPrintableIRBlock(block) }
override string toString() { result = getLabel() }
override string toString() { result = this.getLabel() }
override Language::Location getLocation() { result = block.getLocation() }
@@ -223,7 +233,7 @@ private class PrintableInstruction extends PrintableIRNode, TPrintableInstructio
|
resultString = instr.getResultString() and
operationString = instr.getOperationString() and
operandsString = getOperandsString() and
operandsString = this.getOperandsString() and
columnWidths(block, resultWidth, operationWidth) and
result =
resultString + getPaddingString(resultWidth - resultString.length()) + " = " +
@@ -252,7 +262,8 @@ private class PrintableInstruction extends PrintableIRNode, TPrintableInstructio
private string getOperandsString() {
result =
concat(Operand operand |
operand = instr.getAnOperand()
operand = instr.getAnOperand() and
shouldPrintOperand(operand)
|
operand.getDumpString() + getOperandPropertyString(operand), ", "
order by

View File

@@ -7,17 +7,19 @@ private import internal.ValueNumberingImports
class ValueNumber extends TValueNumber {
final string toString() { result = "GVN" }
final string getDebugString() { result = strictconcat(getAnInstruction().getResultId(), ", ") }
final string getDebugString() {
result = strictconcat(this.getAnInstruction().getResultId(), ", ")
}
final Language::Location getLocation() {
if
exists(Instruction i |
i = getAnInstruction() and not i.getLocation() instanceof Language::UnknownLocation
i = this.getAnInstruction() and not i.getLocation() instanceof Language::UnknownLocation
)
then
result =
min(Language::Location l |
l = getAnInstruction().getLocation() and not l instanceof Language::UnknownLocation
l = this.getAnInstruction().getLocation() and not l instanceof Language::UnknownLocation
|
l
order by
@@ -40,7 +42,7 @@ class ValueNumber extends TValueNumber {
final Instruction getExampleInstruction() {
result =
min(Instruction instr |
instr = getAnInstruction()
instr = this.getAnInstruction()
|
instr order by instr.getBlock().getDisplayIndex(), instr.getDisplayIndexInBlock()
)

View File

@@ -7,7 +7,7 @@ private import AliasConfigurationImports
class Allocation extends IRAutomaticVariable {
VariableAddressInstruction getABaseInstruction() { result.getIRVariable() = this }
final string getAllocationString() { result = toString() }
final string getAllocationString() { result = this.toString() }
predicate alwaysEscapes() {
// An automatic variable only escapes if its address is taken and escapes.

View File

@@ -34,9 +34,13 @@ private module Cached {
cached
predicate hasUnreachedInstructionCached(IRFunction irFunc) {
exists(OldInstruction oldInstruction |
exists(OldIR::Instruction oldInstruction |
irFunc = oldInstruction.getEnclosingIRFunction() and
Reachability::isInfeasibleInstructionSuccessor(oldInstruction, _)
(
Reachability::isInfeasibleInstructionSuccessor(oldInstruction, _)
or
oldInstruction.getOpcode() instanceof Opcode::Unreached
)
)
}
@@ -366,21 +370,19 @@ private module Cached {
then
result = getChi(getOldInstruction(instruction)) and
kind instanceof GotoEdge
else (
else
exists(OldInstruction oldInstruction |
oldInstruction = getOldInstruction(instruction) and
(
oldInstruction = getOldInstruction(instruction)
or
instruction = getChi(oldInstruction)
) and
(
if Reachability::isInfeasibleInstructionSuccessor(oldInstruction, kind)
then result = unreachedInstruction(instruction.getEnclosingIRFunction())
else result = getNewInstruction(oldInstruction.getSuccessor(kind))
)
)
or
exists(OldInstruction oldInstruction |
instruction = getChi(oldInstruction) and
result = getNewInstruction(oldInstruction.getSuccessor(kind))
)
)
}
cached

View File

@@ -75,7 +75,7 @@ class MemoryLocation extends TMemoryLocation {
final predicate canReuseSsa() { canReuseSsaForVariable(var) }
/** DEPRECATED: Alias for canReuseSsa */
deprecated predicate canReuseSSA() { canReuseSsa() }
deprecated predicate canReuseSSA() { this.canReuseSsa() }
}
predicate canReuseSsaForOldResult(Instruction instr) { none() }

View File

@@ -7,6 +7,9 @@ predicate isInfeasibleInstructionSuccessor(Instruction instr, EdgeKind kind) {
conditionValue = getConstantValue(instr.(ConditionalBranchInstruction).getCondition()) and
if conditionValue = 0 then kind instanceof TrueEdge else kind instanceof FalseEdge
)
or
instr.getSuccessor(kind) instanceof UnreachedInstruction and
kind instanceof GotoEdge
}
pragma[noinline]
@@ -41,7 +44,9 @@ class ReachableBlock extends IRBlockBase {
* An instruction that is contained in a reachable block.
*/
class ReachableInstruction extends Instruction {
ReachableInstruction() { this.getBlock() instanceof ReachableBlock }
ReachableInstruction() {
this.getBlock() instanceof ReachableBlock and not this instanceof UnreachedInstruction
}
}
module Graph {

View File

@@ -62,14 +62,14 @@ class GVN extends TValueNumber {
final string toString() { result = "GVN" }
final string getDebugString() { result = strictconcat(getAnExpr().toString(), ", ") }
final string getDebugString() { result = strictconcat(this.getAnExpr().toString(), ", ") }
final Location getLocation() {
if exists(Expr e | e = getAnExpr() and not e.getLocation() instanceof UnknownLocation)
if exists(Expr e | e = this.getAnExpr() and not e.getLocation() instanceof UnknownLocation)
then
result =
min(Location l |
l = getAnExpr().getLocation() and not l instanceof UnknownLocation
l = this.getAnExpr().getLocation() and not l instanceof UnknownLocation
|
l
order by
@@ -102,13 +102,13 @@ class GVN extends TValueNumber {
}
/** Gets an expression that has this GVN. */
Expr getAnExpr() { result = getAnUnconvertedExpr() }
Expr getAnExpr() { result = this.getAnUnconvertedExpr() }
/** Gets an expression that has this GVN. */
Expr getAnUnconvertedExpr() { result = getAnInstruction().getUnconvertedResultExpression() }
Expr getAnUnconvertedExpr() { result = this.getAnInstruction().getUnconvertedResultExpression() }
/** Gets an expression that has this GVN. */
Expr getAConvertedExpr() { result = getAnInstruction().getConvertedResultExpression() }
Expr getAConvertedExpr() { result = this.getAnInstruction().getConvertedResultExpression() }
}
/** Gets the global value number of expression `e`. */

View File

@@ -208,10 +208,10 @@ class CppType extends TCppType {
string toString() { none() }
/** Gets a string used in IR dumps */
string getDumpString() { result = toString() }
string getDumpString() { result = this.toString() }
/** Gets the size of the type in bytes, if known. */
final int getByteSize() { result = getIRType().getByteSize() }
final int getByteSize() { result = this.getIRType().getByteSize() }
/**
* Gets the `IRType` that represents this `CppType`. Many different `CppType`s can map to a single
@@ -232,7 +232,7 @@ class CppType extends TCppType {
*/
final predicate hasUnspecifiedType(Type type, boolean isGLValue) {
exists(Type specifiedType |
hasType(specifiedType, isGLValue) and
this.hasType(specifiedType, isGLValue) and
type = specifiedType.getUnspecifiedType()
)
}

View File

@@ -206,7 +206,34 @@ private predicate deconstructSizeExpr(Expr sizeExpr, Expr lengthExpr, int sizeof
}
/** A `Function` that is a call target of an allocation. */
private signature class CallAllocationExprTarget extends Function;
private signature class CallAllocationExprTarget extends Function {
/**
* Gets the index of the input pointer argument to be reallocated, if
* this is a `realloc` function.
*/
int getReallocPtrArg();
/**
* Gets the index of the argument for the allocation size, if any. The actual
* allocation size is the value of this argument multiplied by the result of
* `getSizeMult()`, in bytes.
*/
int getSizeArg();
/**
* Gets the index of an argument that multiplies the allocation size given
* by `getSizeArg`, if any.
*/
int getSizeMult();
/**
* Holds if this allocation requires a
* corresponding deallocation of some sort (most do, but `alloca` for example
* does not). If it is unclear, we default to no (for example a placement `new`
* allocation may or may not require a corresponding `delete`).
*/
predicate requiresDealloc();
}
/**
* This module abstracts over the type of allocation call-targets and provides a
@@ -220,118 +247,68 @@ private signature class CallAllocationExprTarget extends Function;
* function using various heuristics.
*/
private module CallAllocationExprBase<CallAllocationExprTarget Target> {
/** A module that contains the collection of member-predicates required on `Target`. */
signature module Param {
/**
* Gets the index of the input pointer argument to be reallocated, if
* this is a `realloc` function.
*/
int getReallocPtrArg(Target target);
/**
* Gets the index of the argument for the allocation size, if any. The actual
* allocation size is the value of this argument multiplied by the result of
* `getSizeMult()`, in bytes.
*/
int getSizeArg(Target target);
/**
* Gets the index of an argument that multiplies the allocation size given
* by `getSizeArg`, if any.
*/
int getSizeMult(Target target);
/**
* Holds if this allocation requires a
* corresponding deallocation of some sort (most do, but `alloca` for example
* does not). If it is unclear, we default to no (for example a placement `new`
* allocation may or may not require a corresponding `delete`).
*/
predicate requiresDealloc(Target target);
}
/**
* A module that abstracts over a collection of predicates in
* the `Param` module). This should really be member-predicates
* on `CallAllocationExprTarget`, but we cannot yet write this in QL.
* An allocation expression that is a function call, such as call to `malloc`.
*/
module With<Param P> {
private import P
class CallAllocationExprImpl instanceof FunctionCall {
Target target;
/**
* An allocation expression that is a function call, such as call to `malloc`.
*/
class CallAllocationExprImpl instanceof FunctionCall {
Target target;
CallAllocationExprImpl() {
target = this.getTarget() and
// realloc(ptr, 0) only frees the pointer
not (
exists(getReallocPtrArg(target)) and
this.getArgument(getSizeArg(target)).getValue().toInt() = 0
) and
// these are modeled directly (and more accurately), avoid duplication
not exists(NewOrNewArrayExpr new | new.getAllocatorCall() = this)
}
string toString() { result = super.toString() }
Expr getSizeExprImpl() {
exists(Expr sizeExpr | sizeExpr = super.getArgument(getSizeArg(target)) |
if exists(getSizeMult(target))
then result = sizeExpr
else
exists(Expr lengthExpr |
deconstructSizeExpr(sizeExpr, lengthExpr, _) and
result = lengthExpr
)
)
}
int getSizeMultImpl() {
// malloc with multiplier argument that is a constant
result = super.getArgument(getSizeMult(target)).getValue().toInt()
or
// malloc with no multiplier argument
not exists(getSizeMult(target)) and
deconstructSizeExpr(super.getArgument(getSizeArg(target)), _, result)
}
int getSizeBytesImpl() {
result = this.getSizeExprImpl().getValue().toInt() * this.getSizeMultImpl()
}
Expr getReallocPtrImpl() { result = super.getArgument(getReallocPtrArg(target)) }
Type getAllocatedElementTypeImpl() {
result =
super.getFullyConverted().getType().stripTopLevelSpecifiers().(PointerType).getBaseType() and
not result instanceof VoidType
}
predicate requiresDeallocImpl() { requiresDealloc(target) }
CallAllocationExprImpl() {
target = this.getTarget() and
// realloc(ptr, 0) only frees the pointer
not (
exists(target.getReallocPtrArg()) and
this.getArgument(target.getSizeArg()).getValue().toInt() = 0
) and
// these are modeled directly (and more accurately), avoid duplication
not exists(NewOrNewArrayExpr new | new.getAllocatorCall() = this)
}
string toString() { result = super.toString() }
Expr getSizeExprImpl() {
exists(Expr sizeExpr | sizeExpr = super.getArgument(target.getSizeArg()) |
if exists(target.getSizeMult())
then result = sizeExpr
else
exists(Expr lengthExpr |
deconstructSizeExpr(sizeExpr, lengthExpr, _) and
result = lengthExpr
)
)
}
int getSizeMultImpl() {
// malloc with multiplier argument that is a constant
result = super.getArgument(target.getSizeMult()).getValue().toInt()
or
// malloc with no multiplier argument
not exists(target.getSizeMult()) and
deconstructSizeExpr(super.getArgument(target.getSizeArg()), _, result)
}
int getSizeBytesImpl() {
result = this.getSizeExprImpl().getValue().toInt() * this.getSizeMultImpl()
}
Expr getReallocPtrImpl() { result = super.getArgument(target.getReallocPtrArg()) }
Type getAllocatedElementTypeImpl() {
result =
super.getFullyConverted().getType().stripTopLevelSpecifiers().(PointerType).getBaseType() and
not result instanceof VoidType
}
predicate requiresDeallocImpl() { target.requiresDealloc() }
}
}
private module CallAllocationExpr {
private module Param implements CallAllocationExprBase<AllocationFunction>::Param {
int getReallocPtrArg(AllocationFunction f) { result = f.getReallocPtrArg() }
int getSizeArg(AllocationFunction f) { result = f.getSizeArg() }
int getSizeMult(AllocationFunction f) { result = f.getSizeMult() }
predicate requiresDealloc(AllocationFunction f) { f.requiresDealloc() }
}
/**
* A class that provides the implementation of `AllocationExpr` for an allocation
* that calls an `AllocationFunction`.
*/
private class Base =
CallAllocationExprBase<AllocationFunction>::With<Param>::CallAllocationExprImpl;
private class Base = CallAllocationExprBase<AllocationFunction>::CallAllocationExprImpl;
class CallAllocationExpr extends AllocationExpr, Base {
override Expr getSizeExpr() { result = super.getSizeExprImpl() }
@@ -437,7 +414,7 @@ private module HeuristicAllocation {
int sizeArg;
HeuristicAllocationFunctionByName() {
Function.super.getName().matches("%alloc%") and
Function.super.getName().matches(["%alloc%", "%Alloc%"]) and
Function.super.getUnspecifiedType() instanceof PointerType and
sizeArg = unique( | | getAnUnsignedParameter(this))
}
@@ -452,22 +429,11 @@ private module HeuristicAllocation {
override predicate requiresDealloc() { none() }
}
private module Param implements CallAllocationExprBase<HeuristicAllocationFunction>::Param {
int getReallocPtrArg(HeuristicAllocationFunction f) { result = f.getReallocPtrArg() }
int getSizeArg(HeuristicAllocationFunction f) { result = f.getSizeArg() }
int getSizeMult(HeuristicAllocationFunction f) { result = f.getSizeMult() }
predicate requiresDealloc(HeuristicAllocationFunction f) { f.requiresDealloc() }
}
/**
* A class that provides the implementation of `AllocationExpr` for an allocation
* that calls an `HeuristicAllocationFunction`.
*/
private class Base =
CallAllocationExprBase<HeuristicAllocationFunction>::With<Param>::CallAllocationExprImpl;
private class Base = CallAllocationExprBase<HeuristicAllocationFunction>::CallAllocationExprImpl;
private class CallAllocationExpr extends HeuristicAllocationExpr, Base {
override Expr getSizeExpr() { result = super.getSizeExprImpl() }

View File

@@ -13,19 +13,19 @@ private class StandardDeallocationFunction extends DeallocationFunction {
int freedArg;
StandardDeallocationFunction() {
hasGlobalOrStdOrBslName([
this.hasGlobalOrStdOrBslName([
// --- C library allocation
"free", "realloc"
]) and
freedArg = 0
or
hasGlobalName([
this.hasGlobalName([
// --- OpenSSL memory allocation
"CRYPTO_free", "CRYPTO_secure_free"
]) and
freedArg = 0
or
hasGlobalOrStdName([
this.hasGlobalOrStdName([
// --- Windows Memory Management for Windows Drivers
"ExFreePoolWithTag", "ExDeleteTimer", "IoFreeMdl", "IoFreeWorkItem", "IoFreeErrorLogEntry",
"MmFreeContiguousMemory", "MmFreeContiguousMemorySpecifyCache", "MmFreeNonCachedMemory",
@@ -44,7 +44,7 @@ private class StandardDeallocationFunction extends DeallocationFunction {
]) and
freedArg = 0
or
hasGlobalOrStdName([
this.hasGlobalOrStdName([
// --- Windows Memory Management for Windows Drivers
"ExFreeToLookasideListEx", "ExFreeToPagedLookasideList", "ExFreeToNPagedLookasideList",
// --- NetBSD pool manager
@@ -52,7 +52,7 @@ private class StandardDeallocationFunction extends DeallocationFunction {
]) and
freedArg = 1
or
hasGlobalOrStdName(["HeapFree", "HeapReAlloc"]) and
this.hasGlobalOrStdName(["HeapFree", "HeapReAlloc"]) and
freedArg = 2
}
@@ -65,9 +65,9 @@ private class StandardDeallocationFunction extends DeallocationFunction {
private class CallDeallocationExpr extends DeallocationExpr, FunctionCall {
DeallocationFunction target;
CallDeallocationExpr() { target = getTarget() }
CallDeallocationExpr() { target = this.getTarget() }
override Expr getFreedExpr() { result = getArgument(target.getFreedArg()) }
override Expr getFreedExpr() { result = this.getArgument(target.getFreedArg()) }
}
/**
@@ -76,7 +76,7 @@ private class CallDeallocationExpr extends DeallocationExpr, FunctionCall {
private class DeleteDeallocationExpr extends DeallocationExpr, DeleteExpr {
DeleteDeallocationExpr() { this instanceof DeleteExpr }
override Expr getFreedExpr() { result = getExpr() }
override Expr getFreedExpr() { result = this.getExpr() }
}
/**
@@ -85,5 +85,5 @@ private class DeleteDeallocationExpr extends DeallocationExpr, DeleteExpr {
private class DeleteArrayDeallocationExpr extends DeallocationExpr, DeleteArrayExpr {
DeleteArrayDeallocationExpr() { this instanceof DeleteArrayExpr }
override Expr getFreedExpr() { result = getExpr() }
override Expr getFreedExpr() { result = this.getExpr() }
}

View File

@@ -14,8 +14,8 @@ import semmle.code.cpp.models.interfaces.Taint
*/
private class ConversionConstructorModel extends Constructor, TaintFunction {
ConversionConstructorModel() {
strictcount(Parameter p | p = getAParameter() and not p.hasInitializer()) = 1 and
not hasSpecifier("explicit")
strictcount(Parameter p | p = this.getAParameter() and not p.hasInitializer()) = 1 and
not this.hasSpecifier("explicit")
}
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {

View File

@@ -15,10 +15,10 @@ private class Printf extends FormattingFunction, AliasFunction {
Printf() {
this instanceof TopLevelFunction and
(
hasGlobalOrStdOrBslName(["printf", "wprintf"]) or
hasGlobalName(["printf_s", "wprintf_s", "g_printf"])
this.hasGlobalOrStdOrBslName(["printf", "wprintf"]) or
this.hasGlobalName(["printf_s", "wprintf_s", "g_printf"])
) and
not exists(getDefinition().getFile().getRelativePath())
not exists(this.getDefinition().getFile().getRelativePath())
}
override int getFormatParameterIndex() { result = 0 }
@@ -39,10 +39,10 @@ private class Fprintf extends FormattingFunction {
Fprintf() {
this instanceof TopLevelFunction and
(
hasGlobalOrStdOrBslName(["fprintf", "fwprintf"]) or
hasGlobalName("g_fprintf")
this.hasGlobalOrStdOrBslName(["fprintf", "fwprintf"]) or
this.hasGlobalName("g_fprintf")
) and
not exists(getDefinition().getFile().getRelativePath())
not exists(this.getDefinition().getFile().getRelativePath())
}
override int getFormatParameterIndex() { result = 1 }
@@ -57,12 +57,12 @@ private class Sprintf extends FormattingFunction {
Sprintf() {
this instanceof TopLevelFunction and
(
hasGlobalOrStdOrBslName([
this.hasGlobalOrStdOrBslName([
"sprintf", // sprintf(dst, format, args...)
"wsprintf" // wsprintf(dst, format, args...)
])
or
hasGlobalName([
this.hasGlobalName([
"_sprintf_l", // _sprintf_l(dst, format, locale, args...)
"__swprintf_l", // __swprintf_l(dst, format, locale, args...)
"g_strdup_printf", // g_strdup_printf(format, ...)
@@ -70,24 +70,26 @@ private class Sprintf extends FormattingFunction {
"__builtin___sprintf_chk" // __builtin___sprintf_chk(dst, flag, os, format, ...)
])
) and
not exists(getDefinition().getFile().getRelativePath())
not exists(this.getDefinition().getFile().getRelativePath())
}
override int getFormatParameterIndex() {
hasName("g_strdup_printf") and result = 0
this.hasName("g_strdup_printf") and result = 0
or
hasName("__builtin___sprintf_chk") and result = 3
this.hasName("__builtin___sprintf_chk") and result = 3
or
not getName() = ["g_strdup_printf", "__builtin___sprintf_chk"] and
not this.getName() = ["g_strdup_printf", "__builtin___sprintf_chk"] and
result = 1
}
override int getOutputParameterIndex(boolean isStream) {
not hasName("g_strdup_printf") and result = 0 and isStream = false
not this.hasName("g_strdup_printf") and result = 0 and isStream = false
}
override int getFirstFormatArgumentIndex() {
if hasName("__builtin___sprintf_chk") then result = 4 else result = getNumberOfParameters()
if this.hasName("__builtin___sprintf_chk")
then result = 4
else result = this.getNumberOfParameters()
}
}
@@ -98,46 +100,46 @@ private class SnprintfImpl extends Snprintf {
SnprintfImpl() {
this instanceof TopLevelFunction and
(
hasGlobalOrStdOrBslName([
this.hasGlobalOrStdOrBslName([
"snprintf", // C99 defines snprintf
"swprintf" // The s version of wide-char printf is also always the n version
])
or
// Microsoft has _snprintf as well as several other variations
hasGlobalName([
this.hasGlobalName([
"sprintf_s", "snprintf_s", "swprintf_s", "_snprintf", "_snprintf_s", "_snprintf_l",
"_snprintf_s_l", "_snwprintf", "_snwprintf_s", "_snwprintf_l", "_snwprintf_s_l",
"_sprintf_s_l", "_swprintf_l", "_swprintf_s_l", "g_snprintf", "wnsprintf",
"__builtin___snprintf_chk"
])
) and
not exists(getDefinition().getFile().getRelativePath())
not exists(this.getDefinition().getFile().getRelativePath())
}
override int getFormatParameterIndex() {
if getName().matches("%\\_l")
then result = getFirstFormatArgumentIndex() - 2
else result = getFirstFormatArgumentIndex() - 1
if this.getName().matches("%\\_l")
then result = this.getFirstFormatArgumentIndex() - 2
else result = this.getFirstFormatArgumentIndex() - 1
}
override int getOutputParameterIndex(boolean isStream) { result = 0 and isStream = false }
override int getFirstFormatArgumentIndex() {
exists(string name |
name = getQualifiedName() and
name = this.getQualifiedName() and
(
name = "__builtin___snprintf_chk" and
result = 5
or
name != "__builtin___snprintf_chk" and
result = getNumberOfParameters()
result = this.getNumberOfParameters()
)
)
}
override predicate returnsFullFormatLength() {
hasName(["snprintf", "g_snprintf", "__builtin___snprintf_chk", "snprintf_s"]) and
not exists(getDefinition().getFile().getRelativePath())
this.hasName(["snprintf", "g_snprintf", "__builtin___snprintf_chk", "snprintf_s"]) and
not exists(this.getDefinition().getFile().getRelativePath())
}
override int getSizeParameterIndex() { result = 1 }
@@ -149,15 +151,15 @@ private class SnprintfImpl extends Snprintf {
private class StringCchPrintf extends FormattingFunction {
StringCchPrintf() {
this instanceof TopLevelFunction and
hasGlobalName([
this.hasGlobalName([
"StringCchPrintf", "StringCchPrintfEx", "StringCchPrintf_l", "StringCchPrintf_lEx",
"StringCbPrintf", "StringCbPrintfEx", "StringCbPrintf_l", "StringCbPrintf_lEx"
]) and
not exists(getDefinition().getFile().getRelativePath())
not exists(this.getDefinition().getFile().getRelativePath())
}
override int getFormatParameterIndex() {
if getName().matches("%Ex") then result = 5 else result = 2
if this.getName().matches("%Ex") then result = 5 else result = 2
}
override int getOutputParameterIndex(boolean isStream) { result = 0 and isStream = false }
@@ -171,8 +173,8 @@ private class StringCchPrintf extends FormattingFunction {
private class Syslog extends FormattingFunction {
Syslog() {
this instanceof TopLevelFunction and
hasGlobalName("syslog") and
not exists(getDefinition().getFile().getRelativePath())
this.hasGlobalName("syslog") and
not exists(this.getDefinition().getFile().getRelativePath())
}
override int getFormatParameterIndex() { result = 1 }

View File

@@ -13,7 +13,7 @@ import semmle.code.cpp.models.interfaces.Taint
*/
private class StrdupFunction extends AllocationFunction, ArrayFunction, DataFlowFunction {
StrdupFunction() {
hasGlobalName([
this.hasGlobalName([
// --- C library allocation
"strdup", // strdup(str)
"strdupa", // strdupa(str) - returns stack allocated buffer
@@ -33,7 +33,7 @@ private class StrdupFunction extends AllocationFunction, ArrayFunction, DataFlow
output.isReturnValueDeref()
}
override predicate requiresDealloc() { not hasGlobalName("strdupa") }
override predicate requiresDealloc() { not this.hasGlobalName("strdupa") }
}
/**
@@ -41,7 +41,7 @@ private class StrdupFunction extends AllocationFunction, ArrayFunction, DataFlow
*/
private class StrndupFunction extends AllocationFunction, ArrayFunction, DataFlowFunction {
StrndupFunction() {
hasGlobalName([
this.hasGlobalName([
// -- C library allocation
"strndup", // strndup(str, maxlen)
"strndupa" // strndupa(str, maxlen) -- returns stack allocated buffer
@@ -60,5 +60,5 @@ private class StrndupFunction extends AllocationFunction, ArrayFunction, DataFlo
output.isReturnValueDeref()
}
override predicate requiresDealloc() { not hasGlobalName("strndupa") }
override predicate requiresDealloc() { not this.hasGlobalName("strndupa") }
}

View File

@@ -2,7 +2,7 @@ import semmle.code.cpp.models.interfaces.Taint
import semmle.code.cpp.models.interfaces.ArrayFunction
private class Strftime extends TaintFunction, ArrayFunction {
Strftime() { hasGlobalName("strftime") }
Strftime() { this.hasGlobalName("strftime") }
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
(

View File

@@ -16,7 +16,7 @@ private class StrsetFunction extends ArrayFunction, DataFlowFunction, AliasFunct
SideEffectFunction
{
StrsetFunction() {
hasGlobalName([
this.hasGlobalName([
"strset", "_strset", "_strset_l", "_wcsset", "_wcsset_l", "_mbsset", "_mbsset_l",
"_mbsnbset", "_mbsnbset_l", "_strnset", "_strnset_l", "_wcsnset", "_wcsnset_l", "_mbsnset",
"_mbsnset_l"

View File

@@ -10,12 +10,12 @@ private class SystemFunction extends CommandExecutionFunction, ArrayFunction, Al
SideEffectFunction
{
SystemFunction() {
hasGlobalOrStdName("system") or // system(command)
hasGlobalName("popen") or // popen(command, mode)
this.hasGlobalOrStdName("system") or // system(command)
this.hasGlobalName("popen") or // popen(command, mode)
// Windows variants
hasGlobalName("_popen") or // _popen(command, mode)
hasGlobalName("_wpopen") or // _wpopen(command, mode)
hasGlobalName("_wsystem") // _wsystem(command)
this.hasGlobalName("_popen") or // _popen(command, mode)
this.hasGlobalName("_wpopen") or // _wpopen(command, mode)
this.hasGlobalName("_wsystem") // _wsystem(command)
}
override predicate hasCommandArgument(FunctionInput input) { input.isParameterDeref(0) }
@@ -33,8 +33,8 @@ private class SystemFunction extends CommandExecutionFunction, ArrayFunction, Al
override predicate hasOnlySpecificReadSideEffects() { any() }
override predicate hasOnlySpecificWriteSideEffects() {
hasGlobalOrStdName("system") or
hasGlobalName("_wsystem")
this.hasGlobalOrStdName("system") or
this.hasGlobalName("_wsystem")
}
override predicate hasSpecificReadSideEffect(ParameterIndex i, boolean buffer) {

View File

@@ -96,7 +96,7 @@ abstract class AllocationFunction extends Function {
*/
class OperatorNewAllocationFunction extends AllocationFunction {
OperatorNewAllocationFunction() {
hasGlobalName([
this.hasGlobalName([
"operator new", // operator new(bytes, ...)
"operator new[]" // operator new[](bytes, ...)
])
@@ -104,15 +104,15 @@ class OperatorNewAllocationFunction extends AllocationFunction {
override int getSizeArg() { result = 0 }
override predicate requiresDealloc() { not exists(getPlacementArgument()) }
override predicate requiresDealloc() { not exists(this.getPlacementArgument()) }
/**
* Gets the position of the placement pointer if this is a placement
* `operator new` function.
*/
int getPlacementArgument() {
getNumberOfParameters() = 2 and
getParameter(1).getType() instanceof VoidPointerType and
this.getNumberOfParameters() = 2 and
this.getParameter(1).getType() instanceof VoidPointerType and
result = 1
}
}

View File

@@ -41,7 +41,7 @@ abstract class DeallocationFunction extends Function {
*/
class OperatorDeleteDeallocationFunction extends DeallocationFunction {
OperatorDeleteDeallocationFunction() {
hasGlobalName([
this.hasGlobalName([
"operator delete", // operator delete(pointer, ...)
"operator delete[]" // operator delete[](pointer, ...)
])

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