Compare commits

..

6 Commits

Author SHA1 Message Date
Robert Marsh
06be3aec3e C++: fix duplicated UnreachedInstruction in raw IR 2023-05-01 17:39:23 -04:00
Robert Marsh
cb93684287 C++: more UnreachedInstruction fixes 2023-05-01 17:35:37 -04:00
Robert Marsh
fd1ade8e50 C#: Add hasUnreachedInstruction to raw IR 2023-05-01 17:35:36 -04:00
Robert Marsh
536f9f9cca C++/C#: format and sync identical files 2023-05-01 17:35:36 -04:00
Robert Marsh
f4d3cdeca9 C++: use Options::exits() for noreturn functions 2023-05-01 17:35:36 -04:00
Robert Marsh
d0c603f2eb C++: handle calls to noreturn functions 2023-05-01 17:35:28 -04:00
2605 changed files with 99508 additions and 173294 deletions

View File

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

3
.github/labeler.yml vendored
View File

@@ -11,7 +11,7 @@ Go:
- change-notes/**/*go.*
Java:
- any: [ 'java/**/*', '!java/kotlin-extractor/**/*', '!java/ql/test/kotlin/**/*' ]
- any: [ 'java/**/*', '!java/kotlin-extractor/**/*', '!java/kotlin-explorer/**/*', '!java/ql/test/kotlin/**/*' ]
- change-notes/**/*java.*
JS:
@@ -20,6 +20,7 @@ JS:
Kotlin:
- java/kotlin-extractor/**/*
- java/kotlin-explorer/**/*
- java/ql/test/kotlin/**/*
Python:

View File

@@ -11,6 +11,7 @@ on:
- "*/ql/lib/**/*.yml"
- "!**/experimental/**"
- "!ql/**"
- "!swift/**"
- ".github/workflows/check-change-note.yml"
jobs:
@@ -26,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', 'YYYY-MM-DD-{title}.md', where '{title}' is arbitrary text, or released/x.y.z.md for released change-notes
- 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.
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$") or test("/change-notes/released/[0-9]*[.][0-9]*[.][0-9]*[.]md$"))' |
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

View File

@@ -10,7 +10,6 @@ on:
- "*/ql/src/**/*.qll"
- "*/ql/lib/**/*.ql"
- "*/ql/lib/**/*.qll"
- "*/ql/lib/ext/**/*.yml"
- "misc/scripts/library-coverage/*.py"
# input data files
- "*/documentation/library-coverage/cwe-sink.csv"

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('shared/tree-sitter-extractor') }}-${{ hashFiles('ql/**/*.rs') }}
key: ${{ runner.os }}-${{ steps.os_version.outputs.version }}-extractor-${{ hashFiles('ql/**/Cargo.lock') }}-${{ 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('shared/tree-sitter-extractor') }}-${{ 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('ruby/extractor/**/*.rs') }}
- uses: actions/cache@v3
if: steps.cache-extractor.outputs.cache-hit != 'true'
with:

View File

@@ -16,7 +16,6 @@ on:
branches:
- main
- rc/*
- codeql-cli-*
push:
paths:
- "swift/**"
@@ -31,7 +30,6 @@ on:
branches:
- main
- rc/*
- codeql-cli-*
jobs:
# not using a matrix as you cannot depend on a specific job in a matrix, and we want to start linux checks

View File

@@ -17,6 +17,4 @@ 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

@@ -1,46 +0,0 @@
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,22 +22,6 @@
"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

@@ -8,6 +8,7 @@
/swift/ @github/codeql-swift
/misc/codegen/ @github/codeql-swift
/java/kotlin-extractor/ @github/codeql-kotlin
/java/kotlin-explorer/ @github/codeql-kotlin
# ML-powered queries
/javascript/ql/experimental/adaptivethreatmodeling/ @github/codeql-ml-powered-queries-reviewers
@@ -39,6 +40,3 @@ 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

@@ -1,33 +0,0 @@
{
"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

@@ -40,6 +40,7 @@
"csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl3.qll",
"csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl4.qll",
"csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl5.qll",
"csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImplForContentDataFlow.qll",
"go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl1.qll",
"go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl2.qll",
"go/ql/lib/semmle/go/dataflow/internal/DataFlowImplForStringsNewReplacer.qll",
@@ -47,6 +48,7 @@
"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",
@@ -511,8 +513,7 @@
"SensitiveDataHeuristics Python/JS": [
"javascript/ql/lib/semmle/javascript/security/internal/SensitiveDataHeuristics.qll",
"python/ql/lib/semmle/python/security/internal/SensitiveDataHeuristics.qll",
"ruby/ql/lib/codeql/ruby/security/internal/SensitiveDataHeuristics.qll",
"swift/ql/lib/codeql/swift/security/internal/SensitiveDataHeuristics.qll"
"ruby/ql/lib/codeql/ruby/security/internal/SensitiveDataHeuristics.qll"
],
"CFG": [
"csharp/ql/lib/semmle/code/csharp/controlflow/internal/ControlFlowGraphImplShared.qll",
@@ -599,4 +600,4 @@
"python/ql/lib/semmle/python/security/internal/EncryptionKeySizes.qll",
"java/ql/lib/semmle/code/java/security/internal/EncryptionKeySizes.qll"
]
}
}

View File

@@ -1,86 +0,0 @@
#!/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,35 +1,3 @@
## 0.7.4
No user-facing changes.
## 0.7.3
### Minor Analysis Improvements
* Deleted the deprecated `hasCopyConstructor` predicate from the `Class` class in `Class.qll`.
* Deleted many deprecated predicates and classes with uppercase `AST`, `SSA`, `CFG`, `API`, etc. in their names. Use the PascalCased versions instead.
* Deleted the deprecated `CodeDuplication.qll` file.
## 0.7.2
### New Features
* Added an AST-based interface (`semmle.code.cpp.rangeanalysis.new.RangeAnalysis`) for the relative range analysis library.
* 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.
### Major Analysis Improvements
* 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.
### Minor Analysis Improvements
* The `StdNamespace` class now also includes all inline namespaces that are children of `std` namespace.
* 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.
## 0.7.1
No user-facing changes.
## 0.7.0
### Breaking Changes

View File

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

View File

@@ -1,15 +0,0 @@
## 0.7.2
### New Features
* Added an AST-based interface (`semmle.code.cpp.rangeanalysis.new.RangeAnalysis`) for the relative range analysis library.
* 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.
### Major Analysis Improvements
* 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.
### Minor Analysis Improvements
* The `StdNamespace` class now also includes all inline namespaces that are children of `std` namespace.
* 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

@@ -1,7 +0,0 @@
## 0.7.3
### Minor Analysis Improvements
* Deleted the deprecated `hasCopyConstructor` predicate from the `Class` class in `Class.qll`.
* Deleted many deprecated predicates and classes with uppercase `AST`, `SSA`, `CFG`, `API`, etc. in their names. Use the PascalCased versions instead.
* Deleted the deprecated `CodeDuplication.qll` file.

View File

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

View File

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

View File

@@ -1,29 +1,7 @@
/**
* 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
import semmle.code.cpp.ir.dataflow.DataFlow
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.
@@ -89,9 +67,6 @@ 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;
@@ -160,7 +135,6 @@ module ProductFlow {
import GlobalWithState<StateConfig>
}
/** An input configuration for data flow using flow state. */
signature module StateConfigSig {
bindingset[this]
class FlowState1;
@@ -270,9 +244,6 @@ 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;
@@ -286,7 +257,6 @@ 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
) {
@@ -317,9 +287,9 @@ module ProductFlow {
predicate isBarrierIn(DataFlow::Node node) { Config::isBarrierIn1(node) }
}
private module Flow1 = DataFlow::GlobalWithState<Config1>;
module Flow1 = DataFlow::GlobalWithState<Config1>;
private module Config2 implements DataFlow::StateConfigSig {
module Config2 implements DataFlow::StateConfigSig {
class FlowState = FlowState2;
predicate isSource(DataFlow::Node source, FlowState state) {
@@ -349,90 +319,27 @@ module ProductFlow {
predicate isBarrierIn(DataFlow::Node node) { Config::isBarrierIn2(node) }
}
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)
}
module Flow2 = DataFlow::GlobalWithState<Config2>;
pragma[nomagic]
private predicate fwdIsSuccessorExit(
Flow1::PathNode mid1, Flow2::PathNode mid2, Flow1::PathNode succ1, Flow2::PathNode succ2
private predicate reachableInterprocEntry(
Flow1::PathNode source1, Flow2::PathNode source2, Flow1::PathNode node1, Flow2::PathNode node2
) {
isSinkPair(mid1, mid2) and
succ1 = mid1 and
succ2 = mid2
Config::isSourcePair(node1.getNode(), node1.getState(), node2.getNode(), node2.getState()) and
node1 = source1 and
node2 = source2
or
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)
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)
)
}
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()) =
@@ -445,133 +352,43 @@ 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,
TKind kind
Declaration predDecl, Declaration succDecl, Flow1::PathNode pred1, Flow1::PathNode succ1
) {
Flow1::PathGraph::edges(pred1, succ1) and
predDecl != succDecl and
pred1.getNode().getEnclosingCallable() = predDecl and
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, _)
)
succ1.getNode().getEnclosingCallable() = succDecl
}
pragma[nomagic]
private predicate interprocEdge2(
Declaration predDecl, Declaration succDecl, Flow2::PathNode pred2, Flow2::PathNode succ2,
TKind kind
Declaration predDecl, Declaration succDecl, Flow2::PathNode pred2, Flow2::PathNode succ2
) {
Flow2::PathGraph::edges(pred2, succ2) and
predDecl != succDecl and
pred2.getNode().getEnclosingCallable() = predDecl and
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, _)
)
succ2.getNode().getEnclosingCallable() = succDecl
}
private predicate interprocEdgePair(
Flow1::PathNode pred1, Flow2::PathNode pred2, Flow1::PathNode succ1, Flow2::PathNode succ2
) {
exists(Declaration predDecl, Declaration succDecl, TKind kind |
interprocEdge1(predDecl, succDecl, pred1, succ1, kind) and
interprocEdge2(predDecl, succDecl, pred2, succ2, kind)
exists(Declaration predDecl, Declaration succDecl |
interprocEdge1(predDecl, succDecl, pred1, succ1) and
interprocEdge2(predDecl, succDecl, pred2, succ2)
)
}
private predicate reachable(
Flow1::PathNode source1, Flow2::PathNode source2, Flow1::PathNode sink1, Flow2::PathNode 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
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)
)
}
}

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 = this.getCond().toString() }
override string toString() { result = 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(this.getResultIRType(), _, _)
typeBound(getResultIRType(), _, _)
}
/** Gets the lower bound of the resulting type. */
int getLowerBound() { typeBound(this.getResultIRType(), result, _) }
int getLowerBound() { typeBound(getResultIRType(), result, _) }
/** Gets the upper bound of the resulting type. */
int getUpperBound() { typeBound(this.getResultIRType(), _, result) }
int getUpperBound() { typeBound(getResultIRType(), _, result) }
}
/**

View File

@@ -109,8 +109,8 @@ private predicate safeCast(IRIntegerType fromtyp, IRIntegerType totyp) {
*/
class PtrToPtrCastInstruction extends ConvertInstruction {
PtrToPtrCastInstruction() {
this.getResultIRType() instanceof IRAddressType and
this.getUnary().getResultIRType() instanceof IRAddressType
getResultIRType() instanceof IRAddressType and
getUnary().getResultIRType() instanceof IRAddressType
}
}
@@ -119,7 +119,7 @@ class PtrToPtrCastInstruction extends ConvertInstruction {
* that cannot overflow or underflow.
*/
class SafeIntCastInstruction extends ConvertInstruction {
SafeIntCastInstruction() { safeCast(this.getUnary().getResultIRType(), this.getResultIRType()) }
SafeIntCastInstruction() { safeCast(getUnary().getResultIRType(), 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(this.getLeftOperand()) and
rLower = getFullyConvertedLowerBounds(this.getRightOperand()) and
lLower = getFullyConvertedLowerBounds(getLeftOperand()) and
rLower = getFullyConvertedLowerBounds(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(this.getLeftOperand()) and
lUpper = getFullyConvertedUpperBounds(this.getLeftOperand()) and
rLower = getFullyConvertedLowerBounds(this.getRightOperand()) and
rUpper = getFullyConvertedUpperBounds(this.getRightOperand()) and
lLower = getFullyConvertedLowerBounds(getLeftOperand()) and
lUpper = getFullyConvertedUpperBounds(getLeftOperand()) and
rLower = getFullyConvertedLowerBounds(getRightOperand()) and
rUpper = getFullyConvertedUpperBounds(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 = this.getLeftOperand() or child = this.getRightOperand()
child = getLeftOperand() or child = 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() {
this.getUnspecifiedType() instanceof IntegralType and
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(this.getLeftOperand()) and
lUpper = getFullyConvertedUpperBounds(this.getLeftOperand()) and
rLower = getFullyConvertedLowerBounds(this.getRightOperand()) and
rUpper = getFullyConvertedUpperBounds(this.getRightOperand()) and
lLower = getFullyConvertedLowerBounds(getLeftOperand()) and
lUpper = getFullyConvertedUpperBounds(getLeftOperand()) and
rLower = getFullyConvertedLowerBounds(getRightOperand()) and
rUpper = getFullyConvertedUpperBounds(getRightOperand()) and
lLower <= lUpper and
rLower <= rUpper
|
@@ -95,8 +95,8 @@ class ConstantRShiftExprRange extends SimpleRangeAnalysisExpr {
lLower < 0
or
not (
isValidShiftExprShift(rLower, this.getLeftOperand()) and
isValidShiftExprShift(rUpper, this.getLeftOperand())
isValidShiftExprShift(rLower, getLeftOperand()) and
isValidShiftExprShift(rUpper, 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(this.getLeftOperand()) and
lUpper = getFullyConvertedUpperBounds(this.getLeftOperand()) and
rLower = getFullyConvertedLowerBounds(this.getRightOperand()) and
rUpper = getFullyConvertedUpperBounds(this.getRightOperand()) and
lLower = getFullyConvertedLowerBounds(getLeftOperand()) and
lUpper = getFullyConvertedUpperBounds(getLeftOperand()) and
rLower = getFullyConvertedLowerBounds(getRightOperand()) and
rUpper = getFullyConvertedUpperBounds(getRightOperand()) and
lLower <= lUpper and
rLower <= rUpper
|
@@ -122,8 +122,8 @@ class ConstantRShiftExprRange extends SimpleRangeAnalysisExpr {
lLower < 0
or
not (
isValidShiftExprShift(rLower, this.getLeftOperand()) and
isValidShiftExprShift(rUpper, this.getLeftOperand())
isValidShiftExprShift(rLower, getLeftOperand()) and
isValidShiftExprShift(rUpper, 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 = this.getLeftOperand() or child = this.getRightOperand()
child = getLeftOperand() or child = 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() {
this.getUnspecifiedType() instanceof IntegralType and
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(this.getLeftOperand()) and
lUpper = getFullyConvertedUpperBounds(this.getLeftOperand()) and
rLower = getFullyConvertedLowerBounds(this.getRightOperand()) and
rUpper = getFullyConvertedUpperBounds(this.getRightOperand()) and
lLower = getFullyConvertedLowerBounds(getLeftOperand()) and
lUpper = getFullyConvertedUpperBounds(getLeftOperand()) and
rLower = getFullyConvertedLowerBounds(getRightOperand()) and
rUpper = getFullyConvertedUpperBounds(getRightOperand()) and
lLower <= lUpper and
rLower <= rUpper
|
@@ -208,8 +208,8 @@ class ConstantLShiftExprRange extends SimpleRangeAnalysisExpr {
lLower < 0
or
not (
isValidShiftExprShift(rLower, this.getLeftOperand()) and
isValidShiftExprShift(rUpper, this.getLeftOperand())
isValidShiftExprShift(rLower, getLeftOperand()) and
isValidShiftExprShift(rUpper, 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(this.getLeftOperand()) and
lUpper = getFullyConvertedUpperBounds(this.getLeftOperand()) and
rLower = getFullyConvertedLowerBounds(this.getRightOperand()) and
rUpper = getFullyConvertedUpperBounds(this.getRightOperand()) and
lLower = getFullyConvertedLowerBounds(getLeftOperand()) and
lUpper = getFullyConvertedUpperBounds(getLeftOperand()) and
rLower = getFullyConvertedLowerBounds(getRightOperand()) and
rUpper = getFullyConvertedUpperBounds(getRightOperand()) and
lLower <= lUpper and
rLower <= rUpper
|
@@ -239,8 +239,8 @@ class ConstantLShiftExprRange extends SimpleRangeAnalysisExpr {
lLower < 0
or
not (
isValidShiftExprShift(rLower, this.getLeftOperand()) and
isValidShiftExprShift(rUpper, this.getLeftOperand())
isValidShiftExprShift(rLower, getLeftOperand()) and
isValidShiftExprShift(rUpper, 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 = this.getLeftOperand() or child = this.getRightOperand()
child = getLeftOperand() or child = getRightOperand()
}
}

View File

@@ -83,23 +83,20 @@ private class ExprRangeNode extends DataFlow::ExprNode {
private string getCallBounds(Call e) {
result =
getExprBoundAsString(e) + "(" +
concat(Expr arg, int i |
arg = e.getArgument(i)
|
this.getIntegralBounds(arg), "," order by i
) + ")"
concat(Expr arg, int i | arg = e.getArgument(i) | getIntegralBounds(arg) order by i, ",") +
")"
}
override string toString() {
exists(Expr e | e = this.getExpr() |
exists(Expr e | e = getExpr() |
if hasIntegralOrReferenceIntegralType(e)
then
result = super.toString() + ": " + this.getOperationBounds(e)
result = super.toString() + ": " + getOperationBounds(e)
or
result = super.toString() + ": " + this.getCallBounds(e)
result = super.toString() + ": " + getCallBounds(e)
or
not exists(this.getOperationBounds(e)) and
not exists(this.getCallBounds(e)) and
not exists(getOperationBounds(e)) and
not exists(getCallBounds(e)) and
result = super.toString() + ": " + getExprBoundAsString(e)
else result = super.toString()
)
@@ -111,8 +108,8 @@ private class ExprRangeNode extends DataFlow::ExprNode {
*/
private class ReferenceArgumentRangeNode extends DataFlow::DefinitionByReferenceNode {
override string toString() {
if hasIntegralOrReferenceIntegralType(this.asDefiningArgument())
then result = super.toString() + ": " + getExprBoundAsString(this.getArgument())
if hasIntegralOrReferenceIntegralType(asDefiningArgument())
then result = super.toString() + ": " + getExprBoundAsString(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() {
this.getTarget().hasGlobalOrStdName("strlen") and this.getArgument(0).isConstant()
getTarget().hasGlobalOrStdName("strlen") and getArgument(0).isConstant()
}
override int getLowerBounds() { result = this.getArgument(0).getValue().length() }
override int getLowerBounds() { result = getArgument(0).getValue().length() }
override int getUpperBounds() { result = this.getArgument(0).getValue().length() }
override int getUpperBounds() { result = 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`.
this.getLeftOperand().getExplicitlyConverted().(VariableAccess).getTarget() =
this.getRightOperand().getExplicitlyConverted().(VariableAccess).getTarget()
getLeftOperand().getExplicitlyConverted().(VariableAccess).getTarget() =
getRightOperand().getExplicitlyConverted().(VariableAccess).getTarget()
}
override float getLowerBounds() { result = 0 }

View File

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

View File

@@ -176,6 +176,20 @@ class Class extends UserType {
/** Holds if this class, struct or union has a constructor. */
predicate hasConstructor() { exists(this.getAConstructor()) }
/**
* Holds if this class has a copy constructor that is either explicitly
* declared (though possibly `= delete`) or is auto-generated, non-trivial
* and called from somewhere.
*
* DEPRECATED: There is more than one reasonable definition of what it means
* to have a copy constructor, and we do not want to promote one particular
* definition by naming it with this predicate. Having a copy constructor
* could mean that such a member is declared or defined in the source or that
* it is callable by a particular caller. For C++11, there's also a question
* of whether to include members that are defaulted or deleted.
*/
deprecated predicate hasCopyConstructor() { this.getAMemberFunction() instanceof CopyConstructor }
/**
* Like accessOfBaseMember but returns multiple results if there are multiple
* paths to `base` through the inheritance graph.

View File

@@ -42,7 +42,7 @@ class Compilation extends @compilation {
}
/** Gets a file compiled during this invocation. */
File getAFileCompiled() { result = this.getFileCompiled(_) }
File getAFileCompiled() { result = 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 = this.getArgument(_) }
string getAnArgument() { result = getArgument(_) }
/**
* Gets the `i`th argument passed to the extractor on this invocation.

View File

@@ -39,8 +39,7 @@ class Field extends MemberVariable {
* complete most-derived object.
*/
int getAByteOffsetIn(Class mostDerivedClass) {
result =
mostDerivedClass.getABaseClassByteOffset(this.getDeclaringType()) + this.getByteOffset()
result = mostDerivedClass.getABaseClassByteOffset(getDeclaringType()) + getByteOffset()
}
/**
@@ -117,10 +116,10 @@ class BitField extends Field {
int getBitOffset() { fieldoffsets(underlyingElement(this), _, result) }
/** Holds if this bitfield is anonymous. */
predicate isAnonymous() { this.hasName("(unnamed bitfield)") }
predicate isAnonymous() { hasName("(unnamed bitfield)") }
override predicate isInitializable() {
// Anonymous bitfields are not initializable.
not this.isAnonymous()
not 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() { this.getBinary().getAbsolutePath() = "" }
predicate isDummy() { getBinary().getAbsolutePath() = "" }
/** Gets a textual representation of this element. */
string toString() { result = this.getBinary().getAbsolutePath() }
string toString() { result = getBinary().getAbsolutePath() }
/**
* Gets a function which was compiled into this link target, or had its

View File

@@ -34,7 +34,7 @@ class Macro extends PreprocessorDirective, @ppd_define {
* Gets the name of the macro. For example, `MAX` in
* `#define MAX(x,y) (((x)>(y))?(x):(y))`.
*/
string getName() { result = this.getHead().regexpCapture("([^(]*+).*", 1) }
string getName() { result = this.getHead().splitAt("(", 0) }
/** Holds if the macro has name `name`. */
predicate hasName(string name) { this.getName() = name }

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 = this.getQualifiedElement+() }
Expr getExpr() { result = 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 = this.getQualifiedElement() and
a = getQualifiedElement() and
result = a.getTarget().getDeclaringType()
)
or
exists(FunctionCall c |
c = this.getQualifiedElement() and
c = getQualifiedElement() and
result = c.getTarget().getDeclaringType()
)
else result = nqe
@@ -109,7 +109,7 @@ class NameQualifiableElement extends Element, @namequalifiableelement {
* namespace.
*/
predicate hasGlobalQualifiedName() {
this.getNameQualifier*().getQualifyingElement() instanceof GlobalNamespace
getNameQualifier*().getQualifyingElement() instanceof GlobalNamespace
}
/**
@@ -119,7 +119,7 @@ class NameQualifiableElement extends Element, @namequalifiableelement {
*/
predicate hasSuperQualifiedName() {
exists(NameQualifier nq, SpecialNameQualifyingElement snqe |
nq = this.getNameQualifier*() and
nq = 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 = this.getName() }
override string toString() { result = getName() }
}

View File

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

View File

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

View File

@@ -27,6 +27,9 @@ class PrintAstConfiguration extends TPrintAstConfiguration {
predicate shouldPrintFunction(Function func) { any() }
}
/** DEPRECATED: Alias for PrintAstConfiguration */
deprecated class PrintASTConfiguration = PrintAstConfiguration;
private predicate shouldPrintFunction(Function func) {
exists(PrintAstConfiguration config | config.shouldPrintFunction(func))
}
@@ -127,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 |
this.childAndAccessorPredicate(child, _, nonConvertedIndex, isConverted)
childAndAccessorPredicate(child, _, nonConvertedIndex, isConverted)
|
// Unconverted children come first, then sort by original child index within each group.
child order by isConverted, nonConvertedIndex
@@ -140,7 +143,7 @@ class PrintAstNode extends TPrintAstNode {
*/
private PrintAstNode getConvertedChild(int childIndex) {
exists(Expr expr |
expr = this.getChildInternal(childIndex).(AstNode).getAst() and
expr = getChildInternal(childIndex).(AstNode).getAst() and
expr.getFullyConverted() instanceof Conversion and
result.(AstNode).getAst() = expr.getFullyConverted() and
not expr instanceof Conversion
@@ -152,8 +155,8 @@ class PrintAstNode extends TPrintAstNode {
* at index `childIndex`, if that node has any conversions.
*/
private string getConvertedChildAccessorPredicate(int childIndex) {
exists(this.getConvertedChild(childIndex)) and
result = this.getChildAccessorPredicateInternal(childIndex) + ".getFullyConverted()"
exists(getConvertedChild(childIndex)) and
result = getChildAccessorPredicateInternal(childIndex) + ".getFullyConverted()"
}
/**
@@ -161,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(this.getEnclosingFunction()) }
final predicate shouldPrint() { shouldPrintFunction(getEnclosingFunction()) }
/**
* Gets the children of this node.
*/
final PrintAstNode getAChild() { result = this.getChild(_) }
final PrintAstNode getAChild() { result = getChild(_) }
/**
* Gets the parent of this node, if any.
@@ -184,7 +187,7 @@ class PrintAstNode extends TPrintAstNode {
*/
string getProperty(string key) {
key = "semmle.label" and
result = this.toString()
result = toString()
}
/**
@@ -198,12 +201,12 @@ class PrintAstNode extends TPrintAstNode {
private predicate childAndAccessorPredicate(
PrintAstNode child, string childPredicate, int nonConvertedIndex, boolean isConverted
) {
child = this.getChildInternal(nonConvertedIndex) and
childPredicate = this.getChildAccessorPredicateInternal(nonConvertedIndex) and
child = getChildInternal(nonConvertedIndex) and
childPredicate = getChildAccessorPredicateInternal(nonConvertedIndex) and
isConverted = false
or
child = this.getConvertedChild(nonConvertedIndex) and
childPredicate = this.getConvertedChildAccessorPredicate(nonConvertedIndex) and
child = getConvertedChild(nonConvertedIndex) and
childPredicate = getConvertedChildAccessorPredicate(nonConvertedIndex) and
isConverted = true
}
@@ -215,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 |
this.childAndAccessorPredicate(_, childPredicate, nonConvertedIndex, isConverted)
childAndAccessorPredicate(_, childPredicate, nonConvertedIndex, isConverted)
|
// Unconverted children come first, then sort by original child index within each group.
childPredicate order by isConverted, nonConvertedIndex
@@ -231,11 +234,12 @@ class PrintAstNode extends TPrintAstNode {
/**
* Gets the `Function` that contains this node.
*/
private Function getEnclosingFunction() {
result = this.getParent*().(FunctionNode).getFunction()
}
private Function getEnclosingFunction() { result = getParent*().(FunctionNode).getFunction() }
}
/** DEPRECATED: Alias for PrintAstNode */
deprecated class PrintASTNode = PrintAstNode;
/**
* Class that restricts the elements that we compute `qlClass` for.
*/
@@ -249,7 +253,7 @@ private class PrintableElement extends Element {
}
pragma[noinline]
string getAPrimaryQlClass0() { result = this.getAPrimaryQlClass() }
string getAPrimaryQlClass0() { result = getAPrimaryQlClass() }
}
/**
@@ -277,9 +281,12 @@ abstract class BaseAstNode extends PrintAstNode {
final Locatable getAst() { result = ast }
/** DEPRECATED: Alias for getAst */
deprecated Locatable getAST() { result = this.getAst() }
deprecated Locatable getAST() { result = getAst() }
}
/** DEPRECATED: Alias for BaseAstNode */
deprecated class BaseASTNode = BaseAstNode;
/**
* A node representing an AST node other than a `DeclarationEntry`.
*/
@@ -287,6 +294,9 @@ abstract class AstNode extends BaseAstNode, TAstNode {
AstNode() { this = TAstNode(ast) }
}
/** DEPRECATED: Alias for AstNode */
deprecated class ASTNode = AstNode;
/**
* A node representing an `Expr`.
*/
@@ -301,7 +311,7 @@ class ExprNode extends AstNode {
result = super.getProperty(key)
or
key = "Value" and
result = qlClass(expr) + this.getValue()
result = qlClass(expr) + getValue()
or
key = "Type" and
result = qlClass(expr.getType()) + expr.getType().toString()
@@ -311,7 +321,7 @@ class ExprNode extends AstNode {
}
override string getChildAccessorPredicateInternal(int childIndex) {
result = getChildAccessorWithoutConversions(ast, this.getChildInternal(childIndex).getAst())
result = getChildAccessorWithoutConversions(ast, getChildInternal(childIndex).getAst())
}
/**
@@ -431,7 +441,7 @@ class StmtNode extends AstNode {
}
override string getChildAccessorPredicateInternal(int childIndex) {
result = getChildAccessorWithoutConversions(ast, this.getChildInternal(childIndex).getAst())
result = getChildAccessorWithoutConversions(ast, getChildInternal(childIndex).getAst())
}
}
@@ -507,7 +517,7 @@ class ParametersNode extends PrintAstNode, TParametersNode {
}
override string getChildAccessorPredicateInternal(int childIndex) {
exists(this.getChildInternal(childIndex)) and
exists(getChildInternal(childIndex)) and
result = "getParameter(" + childIndex.toString() + ")"
}
@@ -534,7 +544,7 @@ class ConstructorInitializersNode extends PrintAstNode, TConstructorInitializers
}
final override string getChildAccessorPredicateInternal(int childIndex) {
exists(this.getChildInternal(childIndex)) and
exists(getChildInternal(childIndex)) and
result = "getInitializer(" + childIndex.toString() + ")"
}
@@ -561,7 +571,7 @@ class DestructorDestructionsNode extends PrintAstNode, TDestructorDestructionsNo
}
final override string getChildAccessorPredicateInternal(int childIndex) {
exists(this.getChildInternal(childIndex)) and
exists(getChildInternal(childIndex)) and
result = "getDestruction(" + childIndex.toString() + ")"
}
@@ -618,7 +628,7 @@ class FunctionNode extends AstNode {
override string getProperty(string key) {
result = super.getProperty(key)
or
key = "semmle.order" and result = this.getOrder().toString()
key = "semmle.order" and result = getOrder().toString()
}
/**

View File

@@ -1699,28 +1699,7 @@ class AutoType extends TemplateParameter {
private predicate suppressUnusedThis(Type t) { any() }
/**
* 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`.
*/
/** A source code location referring to a type */
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() {
this.getName() =
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) {
this.getVariable(isDef) = v and
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 | this.reaches_helper(isDef, v, bb, i) |
exists(BasicBlock bb, int i | 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 | this.firstBarrierAfterThis(isDef, k, v) and k < j)
not exists(int k | firstBarrierAfterThis(isDef, k, v) and k < j)
)
or
not this.firstBarrierAfterThis(isDef, _, v) and
not firstBarrierAfterThis(isDef, _, v) and
bbSuccessorEntryReachesDefOrUse(bb, v, defOrUse, _)
)
}
private predicate firstBarrierAfterThis(boolean isDef, int j, SemanticStackVariable v) {
exists(BasicBlock bb, int i |
this.getVariable(isDef) = v and
getVariable(isDef) = v and
bb.getNode(i) = this and
j = min(int k | bbBarrierAt(bb, k, v, _) and k > i)
)

View File

@@ -14,6 +14,9 @@ library class StandardSsa extends SsaHelper {
StandardSsa() { this = 0 }
}
/** DEPRECATED: Alias for StandardSsa */
deprecated class StandardSSA = StandardSsa;
/**
* A definition of one or more SSA variables, including phi node definitions.
* An _SSA variable_, as defined in the literature, is effectively the pair of

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) {
this.custom_phi_node(v, b) and
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) {
this.frontier_phi_node(v, b) or this.sanitized_custom_phi_node(v, b)
frontier_phi_node(v, b) or sanitized_custom_phi_node(v, b)
}
/**
@@ -154,15 +154,14 @@ library class SsaHelper extends int {
*/
private predicate frontier_phi_node(StackVariable v, BasicBlock b) {
exists(BasicBlock x |
dominanceFrontier(x, b) and
this.ssa_defn_rec(pragma[only_bind_into](v), pragma[only_bind_into](x))
dominanceFrontier(x, b) and 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) {
this.phi_node(v, b)
phi_node(v, b)
or
variableUpdate(v, _, b, _)
}
@@ -173,7 +172,7 @@ library class SsaHelper extends int {
*/
cached
predicate ssa_defn(StackVariable v, ControlFlowNode node, BasicBlock b, int index) {
this.phi_node(v, b) and b.getStart() = node and index = -1
phi_node(v, b) and b.getStart() = node and index = -1
or
variableUpdate(v, node, b, index)
}
@@ -197,7 +196,7 @@ library class SsaHelper extends int {
* basic blocks.
*/
private predicate defUseRank(StackVariable v, BasicBlock b, int rankix, int i) {
i = rank[rankix](int j | this.ssa_defn(v, _, b, j) or ssa_use(v, _, b, j))
i = rank[rankix](int j | ssa_defn(v, _, b, j) or ssa_use(v, _, b, j))
}
/**
@@ -207,7 +206,7 @@ library class SsaHelper extends int {
* the block.
*/
private int lastRank(StackVariable v, BasicBlock b) {
result = max(int rankix | this.defUseRank(v, b, rankix, _)) + 1
result = max(int rankix | defUseRank(v, b, rankix, _)) + 1
}
/**
@@ -216,8 +215,8 @@ library class SsaHelper extends int {
*/
private predicate ssaDefRank(StackVariable v, ControlFlowNode def, BasicBlock b, int rankix) {
exists(int i |
this.ssa_defn(v, def, b, i) and
this.defUseRank(v, b, rankix, i)
ssa_defn(v, def, b, i) and
defUseRank(v, b, rankix, i)
)
}
@@ -233,21 +232,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.
this.ssaDefRank(v, def, b, rankix - 1)
ssaDefRank(v, def, b, rankix - 1)
or
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.
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.
}
/** 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 this.ssaDefReachesRank(v, def, b, this.lastRank(v, b))
live_at_exit_of_bb(v, b) and ssaDefReachesRank(v, def, b, lastRank(v, b))
or
exists(BasicBlock idom |
this.ssaDefinitionReachesEndOfBB(v, def, idom) and
this.noDefinitionsSinceIDominator(v, idom, b)
ssaDefinitionReachesEndOfBB(v, def, idom) and
noDefinitionsSinceIDominator(v, idom, b)
)
}
@@ -261,7 +260,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 this.ssa_defn(v, _, b, _)
not ssa_defn(v, _, b, _)
}
/**
@@ -270,8 +269,8 @@ library class SsaHelper extends int {
*/
private predicate ssaDefinitionReachesUseWithinBB(StackVariable v, ControlFlowNode def, Expr use) {
exists(BasicBlock b, int rankix, int i |
this.ssaDefReachesRank(v, def, b, rankix) and
this.defUseRank(v, b, rankix, i) and
ssaDefReachesRank(v, def, b, rankix) and
defUseRank(v, b, rankix, i) and
ssa_use(v, use, b, i)
)
}
@@ -280,12 +279,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) {
this.ssaDefinitionReachesUseWithinBB(v, def, use)
ssaDefinitionReachesUseWithinBB(v, def, use)
or
exists(BasicBlock b |
ssa_use(v, use, b, _) and
this.ssaDefinitionReachesEndOfBB(v, def, b.getAPredecessor()) and
not this.ssaDefinitionReachesUseWithinBB(v, _, use)
ssaDefinitionReachesEndOfBB(v, def, b.getAPredecessor()) and
not ssaDefinitionReachesUseWithinBB(v, _, use)
)
}
@@ -295,10 +294,10 @@ library class SsaHelper extends int {
*/
cached
string toString(ControlFlowNode node, StackVariable v) {
if this.phi_node(v, node)
if phi_node(v, node)
then result = "SSA phi(" + v.getName() + ")"
else (
this.ssa_defn(v, node, _, _) and result = "SSA def(" + v.getName() + ")"
ssa_defn(v, node, _, _) and result = "SSA def(" + v.getName() + ")"
)
}
@@ -308,7 +307,10 @@ library class SsaHelper extends int {
*/
cached
VariableAccess getAUse(ControlFlowNode def, StackVariable v) {
this.ssaDefinitionReaches(v, def, result) and
ssaDefinitionReaches(v, def, result) and
ssa_use(v, result, _, _)
}
}
/** DEPRECATED: Alias for SsaHelper */
deprecated class SSAHelper = SsaHelper;

View File

@@ -25,7 +25,7 @@ import cpp
*/
abstract class StackVariableReachability extends string {
bindingset[this]
StackVariableReachability() { this.length() >= 0 }
StackVariableReachability() { 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() { this.length() >= 0 }
StackVariableReachabilityWithReassignment() { 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() { this.length() >= 0 }
StackVariableReachabilityExt() { length() >= 0 }
/** `node` is a source for the reachability analysis using variable `v`. */
abstract predicate isSource(ControlFlowNode node, StackVariable v);

View File

@@ -1385,6 +1385,9 @@ private module Cached {
conditionalSuccessor(n1, _, n2)
}
/** DEPRECATED: Alias for qlCfgSuccessor */
deprecated predicate qlCFGSuccessor = qlCfgSuccessor/2;
/**
* Holds if `n2` is a control-flow node such that the control-flow
* edge `(n1, n2)` may be taken when `n1` is an expression that is true.
@@ -1395,6 +1398,9 @@ private module Cached {
not conditionalSuccessor(n1, false, n2)
}
/** DEPRECATED: Alias for qlCfgTrueSuccessor */
deprecated predicate qlCFGTrueSuccessor = qlCfgTrueSuccessor/2;
/**
* Holds if `n2` is a control-flow node such that the control-flow
* edge `(n1, n2)` may be taken when `n1` is an expression that is false.
@@ -1404,4 +1410,7 @@ private module Cached {
conditionalSuccessor(n1, false, n2) and
not conditionalSuccessor(n1, true, n2)
}
/** DEPRECATED: Alias for qlCfgFalseSuccessor */
deprecated predicate qlCFGFalseSuccessor = qlCfgFalseSuccessor/2;
}

File diff suppressed because it is too large Load Diff

View File

@@ -815,15 +815,7 @@ private module Cached {
)
}
/**
* Holds if data can flow from `node1` to `node2` via a direct assignment to
* `c`.
*
* This includes reverse steps through reads when the result of the read has
* been stored into, in order to handle cases like `x.f1.f2 = y`.
*/
cached
predicate store(
private predicate store(
Node node1, Content c, Node node2, DataFlowType contentType, DataFlowType containerType
) {
exists(ContentSet cs |
@@ -831,6 +823,18 @@ private module Cached {
)
}
/**
* Holds if data can flow from `node1` to `node2` via a direct assignment to
* `f`.
*
* This includes reverse steps through reads when the result of the read has
* been stored into, in order to handle cases like `x.f1.f2 = y`.
*/
cached
predicate store(Node node1, TypedContent tc, Node node2, DataFlowType contentType) {
store(node1, tc.getContent(), node2, contentType, tc.getContainerType())
}
/**
* Holds if data can flow from `fromNode` to `toNode` because they are the post-update
* nodes of some function output and input respectively, where the output and input
@@ -928,15 +932,36 @@ private module Cached {
TReturnCtxNoFlowThrough() or
TReturnCtxMaybeFlowThrough(ReturnPosition pos)
cached
newtype TTypedContentApprox =
MkTypedContentApprox(ContentApprox c, DataFlowType t) {
exists(Content cont |
c = getContentApprox(cont) and
store(_, cont, _, _, t)
)
}
cached
newtype TTypedContent = MkTypedContent(Content c, DataFlowType t) { store(_, c, _, _, t) }
cached
TypedContent getATypedContent(TypedContentApprox c) {
exists(ContentApprox cls, DataFlowType t, Content cont |
c = MkTypedContentApprox(cls, pragma[only_bind_into](t)) and
result = MkTypedContent(cont, pragma[only_bind_into](t)) and
cls = getContentApprox(cont)
)
}
cached
newtype TAccessPathFront =
TFrontNil() or
TFrontHead(Content c)
TFrontNil(DataFlowType t) or
TFrontHead(TypedContent tc)
cached
newtype TApproxAccessPathFront =
TApproxFrontNil() or
TApproxFrontHead(ContentApprox c)
TApproxFrontNil(DataFlowType t) or
TApproxFrontHead(TypedContentApprox tc)
cached
newtype TAccessPathFrontOption =
@@ -961,16 +986,8 @@ predicate recordDataFlowCallSite(DataFlowCall call, DataFlowCallable callable) {
/**
* A `Node` at which a cast can occur such that the type should be checked.
*/
class CastingNode instanceof Node {
class CastingNode extends 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(
@@ -1118,17 +1135,9 @@ 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 instanceof Node {
class ParamNode extends 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.
@@ -1137,17 +1146,9 @@ class ParamNode instanceof Node {
}
/** A data-flow node that represents a call argument. */
class ArgNode instanceof Node {
class ArgNode extends 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)
@@ -1158,17 +1159,9 @@ class ArgNode instanceof 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 instanceof Node {
class ReturnNodeExt extends 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) }
}
@@ -1177,16 +1170,8 @@ class ReturnNodeExt instanceof 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 instanceof Node {
class OutNodeExt extends 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)
}
}
/**
@@ -1402,37 +1387,67 @@ class ReturnCtx extends TReturnCtx {
}
}
/** An approximated `Content` tagged with the type of a containing object. */
class TypedContentApprox extends MkTypedContentApprox {
private ContentApprox c;
private DataFlowType t;
TypedContentApprox() { this = MkTypedContentApprox(c, t) }
/** Gets a typed content approximated by this value. */
TypedContent getATypedContent() { result = getATypedContent(this) }
/** Gets the content. */
ContentApprox getContent() { result = c }
/** Gets the container type. */
DataFlowType getContainerType() { result = t }
/** Gets a textual representation of this approximated content. */
string toString() { result = c.toString() }
}
/**
* The front of an approximated access path. This is either a head or a nil.
*/
abstract class ApproxAccessPathFront extends TApproxAccessPathFront {
abstract string toString();
abstract DataFlowType getType();
abstract boolean toBoolNonEmpty();
ContentApprox getHead() { this = TApproxFrontHead(result) }
TypedContentApprox getHead() { this = TApproxFrontHead(result) }
pragma[nomagic]
Content getAHead() {
exists(ContentApprox cont |
TypedContent getAHead() {
exists(TypedContentApprox cont |
this = TApproxFrontHead(cont) and
cont = getContentApprox(result)
result = cont.getATypedContent()
)
}
}
class ApproxAccessPathFrontNil extends ApproxAccessPathFront, TApproxFrontNil {
override string toString() { result = "nil" }
private DataFlowType t;
ApproxAccessPathFrontNil() { this = TApproxFrontNil(t) }
override string toString() { result = ppReprType(t) }
override DataFlowType getType() { result = t }
override boolean toBoolNonEmpty() { result = false }
}
class ApproxAccessPathFrontHead extends ApproxAccessPathFront, TApproxFrontHead {
private ContentApprox c;
private TypedContentApprox tc;
ApproxAccessPathFrontHead() { this = TApproxFrontHead(c) }
ApproxAccessPathFrontHead() { this = TApproxFrontHead(tc) }
override string toString() { result = c.toString() }
override string toString() { result = tc.toString() }
override DataFlowType getType() { result = tc.getContainerType() }
override boolean toBoolNonEmpty() { result = true }
}
@@ -1446,31 +1461,65 @@ class ApproxAccessPathFrontOption extends TApproxAccessPathFrontOption {
}
}
/** A `Content` tagged with the type of a containing object. */
class TypedContent extends MkTypedContent {
private Content c;
private DataFlowType t;
TypedContent() { this = MkTypedContent(c, t) }
/** Gets the content. */
Content getContent() { result = c }
/** Gets the container type. */
DataFlowType getContainerType() { result = t }
/** Gets a textual representation of this content. */
string toString() { result = c.toString() }
/**
* Holds if access paths with this `TypedContent` at their head always should
* be tracked at high precision. This disables adaptive access path precision
* for such access paths.
*/
predicate forceHighPrecision() { forceHighPrecision(c) }
}
/**
* The front of an access path. This is either a head or a nil.
*/
abstract class AccessPathFront extends TAccessPathFront {
abstract string toString();
abstract DataFlowType getType();
abstract ApproxAccessPathFront toApprox();
Content getHead() { this = TFrontHead(result) }
TypedContent getHead() { this = TFrontHead(result) }
}
class AccessPathFrontNil extends AccessPathFront, TFrontNil {
override string toString() { result = "nil" }
private DataFlowType t;
override ApproxAccessPathFront toApprox() { result = TApproxFrontNil() }
AccessPathFrontNil() { this = TFrontNil(t) }
override string toString() { result = ppReprType(t) }
override DataFlowType getType() { result = t }
override ApproxAccessPathFront toApprox() { result = TApproxFrontNil(t) }
}
class AccessPathFrontHead extends AccessPathFront, TFrontHead {
private Content c;
private TypedContent tc;
AccessPathFrontHead() { this = TFrontHead(c) }
AccessPathFrontHead() { this = TFrontHead(tc) }
override string toString() { result = c.toString() }
override string toString() { result = tc.toString() }
override ApproxAccessPathFront toApprox() { result.getAHead() = c }
override DataFlowType getType() { result = tc.getContainerType() }
override ApproxAccessPathFront toApprox() { result.getAHead() = tc }
}
/** An optional access path front. */

View File

@@ -58,9 +58,6 @@ 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 {
@@ -290,10 +287,4 @@ 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 = this.getLeftOperand() }
override Expr getGreaterOperand() { result = getLeftOperand() }
override Expr getLesserOperand() { result = this.getRightOperand() }
override Expr getLesserOperand() { result = getRightOperand() }
}
/**
@@ -92,9 +92,9 @@ class LTExpr extends RelationalOperation, @ltexpr {
override string getOperator() { result = "<" }
override Expr getGreaterOperand() { result = this.getRightOperand() }
override Expr getGreaterOperand() { result = getRightOperand() }
override Expr getLesserOperand() { result = this.getLeftOperand() }
override Expr getLesserOperand() { result = getLeftOperand() }
}
/**
@@ -108,9 +108,9 @@ class GEExpr extends RelationalOperation, @geexpr {
override string getOperator() { result = ">=" }
override Expr getGreaterOperand() { result = this.getLeftOperand() }
override Expr getGreaterOperand() { result = getLeftOperand() }
override Expr getLesserOperand() { result = this.getRightOperand() }
override Expr getLesserOperand() { result = getRightOperand() }
}
/**
@@ -124,7 +124,7 @@ class LEExpr extends RelationalOperation, @leexpr {
override string getOperator() { result = "<=" }
override Expr getGreaterOperand() { result = this.getRightOperand() }
override Expr getGreaterOperand() { result = getRightOperand() }
override Expr getLesserOperand() { result = this.getLeftOperand() }
override Expr getLesserOperand() { result = getLeftOperand() }
}

View File

@@ -815,15 +815,7 @@ private module Cached {
)
}
/**
* Holds if data can flow from `node1` to `node2` via a direct assignment to
* `c`.
*
* This includes reverse steps through reads when the result of the read has
* been stored into, in order to handle cases like `x.f1.f2 = y`.
*/
cached
predicate store(
private predicate store(
Node node1, Content c, Node node2, DataFlowType contentType, DataFlowType containerType
) {
exists(ContentSet cs |
@@ -831,6 +823,18 @@ private module Cached {
)
}
/**
* Holds if data can flow from `node1` to `node2` via a direct assignment to
* `f`.
*
* This includes reverse steps through reads when the result of the read has
* been stored into, in order to handle cases like `x.f1.f2 = y`.
*/
cached
predicate store(Node node1, TypedContent tc, Node node2, DataFlowType contentType) {
store(node1, tc.getContent(), node2, contentType, tc.getContainerType())
}
/**
* Holds if data can flow from `fromNode` to `toNode` because they are the post-update
* nodes of some function output and input respectively, where the output and input
@@ -928,15 +932,36 @@ private module Cached {
TReturnCtxNoFlowThrough() or
TReturnCtxMaybeFlowThrough(ReturnPosition pos)
cached
newtype TTypedContentApprox =
MkTypedContentApprox(ContentApprox c, DataFlowType t) {
exists(Content cont |
c = getContentApprox(cont) and
store(_, cont, _, _, t)
)
}
cached
newtype TTypedContent = MkTypedContent(Content c, DataFlowType t) { store(_, c, _, _, t) }
cached
TypedContent getATypedContent(TypedContentApprox c) {
exists(ContentApprox cls, DataFlowType t, Content cont |
c = MkTypedContentApprox(cls, pragma[only_bind_into](t)) and
result = MkTypedContent(cont, pragma[only_bind_into](t)) and
cls = getContentApprox(cont)
)
}
cached
newtype TAccessPathFront =
TFrontNil() or
TFrontHead(Content c)
TFrontNil(DataFlowType t) or
TFrontHead(TypedContent tc)
cached
newtype TApproxAccessPathFront =
TApproxFrontNil() or
TApproxFrontHead(ContentApprox c)
TApproxFrontNil(DataFlowType t) or
TApproxFrontHead(TypedContentApprox tc)
cached
newtype TAccessPathFrontOption =
@@ -961,16 +986,8 @@ predicate recordDataFlowCallSite(DataFlowCall call, DataFlowCallable callable) {
/**
* A `Node` at which a cast can occur such that the type should be checked.
*/
class CastingNode instanceof Node {
class CastingNode extends 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(
@@ -1118,17 +1135,9 @@ 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 instanceof Node {
class ParamNode extends 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.
@@ -1137,17 +1146,9 @@ class ParamNode instanceof Node {
}
/** A data-flow node that represents a call argument. */
class ArgNode instanceof Node {
class ArgNode extends 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)
@@ -1158,17 +1159,9 @@ class ArgNode instanceof 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 instanceof Node {
class ReturnNodeExt extends 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) }
}
@@ -1177,16 +1170,8 @@ class ReturnNodeExt instanceof 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 instanceof Node {
class OutNodeExt extends 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)
}
}
/**
@@ -1402,37 +1387,67 @@ class ReturnCtx extends TReturnCtx {
}
}
/** An approximated `Content` tagged with the type of a containing object. */
class TypedContentApprox extends MkTypedContentApprox {
private ContentApprox c;
private DataFlowType t;
TypedContentApprox() { this = MkTypedContentApprox(c, t) }
/** Gets a typed content approximated by this value. */
TypedContent getATypedContent() { result = getATypedContent(this) }
/** Gets the content. */
ContentApprox getContent() { result = c }
/** Gets the container type. */
DataFlowType getContainerType() { result = t }
/** Gets a textual representation of this approximated content. */
string toString() { result = c.toString() }
}
/**
* The front of an approximated access path. This is either a head or a nil.
*/
abstract class ApproxAccessPathFront extends TApproxAccessPathFront {
abstract string toString();
abstract DataFlowType getType();
abstract boolean toBoolNonEmpty();
ContentApprox getHead() { this = TApproxFrontHead(result) }
TypedContentApprox getHead() { this = TApproxFrontHead(result) }
pragma[nomagic]
Content getAHead() {
exists(ContentApprox cont |
TypedContent getAHead() {
exists(TypedContentApprox cont |
this = TApproxFrontHead(cont) and
cont = getContentApprox(result)
result = cont.getATypedContent()
)
}
}
class ApproxAccessPathFrontNil extends ApproxAccessPathFront, TApproxFrontNil {
override string toString() { result = "nil" }
private DataFlowType t;
ApproxAccessPathFrontNil() { this = TApproxFrontNil(t) }
override string toString() { result = ppReprType(t) }
override DataFlowType getType() { result = t }
override boolean toBoolNonEmpty() { result = false }
}
class ApproxAccessPathFrontHead extends ApproxAccessPathFront, TApproxFrontHead {
private ContentApprox c;
private TypedContentApprox tc;
ApproxAccessPathFrontHead() { this = TApproxFrontHead(c) }
ApproxAccessPathFrontHead() { this = TApproxFrontHead(tc) }
override string toString() { result = c.toString() }
override string toString() { result = tc.toString() }
override DataFlowType getType() { result = tc.getContainerType() }
override boolean toBoolNonEmpty() { result = true }
}
@@ -1446,31 +1461,65 @@ class ApproxAccessPathFrontOption extends TApproxAccessPathFrontOption {
}
}
/** A `Content` tagged with the type of a containing object. */
class TypedContent extends MkTypedContent {
private Content c;
private DataFlowType t;
TypedContent() { this = MkTypedContent(c, t) }
/** Gets the content. */
Content getContent() { result = c }
/** Gets the container type. */
DataFlowType getContainerType() { result = t }
/** Gets a textual representation of this content. */
string toString() { result = c.toString() }
/**
* Holds if access paths with this `TypedContent` at their head always should
* be tracked at high precision. This disables adaptive access path precision
* for such access paths.
*/
predicate forceHighPrecision() { forceHighPrecision(c) }
}
/**
* The front of an access path. This is either a head or a nil.
*/
abstract class AccessPathFront extends TAccessPathFront {
abstract string toString();
abstract DataFlowType getType();
abstract ApproxAccessPathFront toApprox();
Content getHead() { this = TFrontHead(result) }
TypedContent getHead() { this = TFrontHead(result) }
}
class AccessPathFrontNil extends AccessPathFront, TFrontNil {
override string toString() { result = "nil" }
private DataFlowType t;
override ApproxAccessPathFront toApprox() { result = TApproxFrontNil() }
AccessPathFrontNil() { this = TFrontNil(t) }
override string toString() { result = ppReprType(t) }
override DataFlowType getType() { result = t }
override ApproxAccessPathFront toApprox() { result = TApproxFrontNil(t) }
}
class AccessPathFrontHead extends AccessPathFront, TFrontHead {
private Content c;
private TypedContent tc;
AccessPathFrontHead() { this = TFrontHead(c) }
AccessPathFrontHead() { this = TFrontHead(tc) }
override string toString() { result = c.toString() }
override string toString() { result = tc.toString() }
override ApproxAccessPathFront toApprox() { result.getAHead() = c }
override DataFlowType getType() { result = tc.getContainerType() }
override ApproxAccessPathFront toApprox() { result.getAHead() = tc }
}
/** An optional access path front. */

View File

@@ -58,9 +58,6 @@ 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 {
@@ -290,10 +287,4 @@ 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
nodeHasOperand(this, Ssa::getIRRepresentationOfIndirectOperand(operand, indirectionIndex),
indirectionIndex - 1)
this.(OperandNode).getOperand() =
Ssa::getIRRepresentationOfIndirectOperand(operand, indirectionIndex)
}
/** Gets the underlying operand. */
@@ -250,8 +250,8 @@ class IndirectInstruction extends Node {
this.(RawIndirectInstruction).getInstruction() = instr and
this.(RawIndirectInstruction).getIndirectionIndex() = indirectionIndex
or
nodeHasInstruction(this, Ssa::getIRRepresentationOfIndirectInstruction(instr, indirectionIndex),
indirectionIndex - 1)
this.(InstructionNode).getInstruction() =
Ssa::getIRRepresentationOfIndirectInstruction(instr, indirectionIndex)
}
/** Gets the underlying instruction. */
@@ -607,21 +607,13 @@ 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(GlobalLikeVariable v |
exists(Cpp::GlobalOrNamespaceVariable v |
exists(Ssa::GlobalUse globalUse |
v = globalUse.getVariable() and
n1.(FinalGlobalValue).getGlobalUse() = globalUse

View File

@@ -562,14 +562,6 @@ 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() }
}
/**
@@ -1548,7 +1540,7 @@ private module Cached {
cached
predicate simpleLocalFlowStep(Node nodeFrom, Node nodeTo) {
// Post update node -> Node flow
Ssa::postUpdateFlow(nodeFrom, nodeTo)
Ssa::ssaFlow(nodeFrom.(PostUpdateNode).getPreUpdateNode(), nodeTo)
or
// Def-use/Use-use flow
Ssa::ssaFlow(nodeFrom, nodeTo)
@@ -1640,15 +1632,8 @@ predicate localInstructionFlow(Instruction e1, Instruction e2) {
localFlow(instructionNode(e1), instructionNode(e2))
}
/**
* INTERNAL: Do not use.
*
* Ideally this module would be private, but the `asExprInternal` predicate is
* needed in `DefaultTaintTrackingImpl`. Once `DefaultTaintTrackingImpl` is gone
* we can make this module private.
*/
cached
module ExprFlowCached {
private module ExprFlowCached {
/**
* Holds if `n` is an indirect operand of a `PointerArithmeticInstruction`, and
* `e` is the result of loading from the `PointerArithmeticInstruction`.
@@ -1699,8 +1684,7 @@ module ExprFlowCached {
* `x[i]` steps to the expression `x[i - 1]` without traversing the
* entire chain.
*/
cached
Expr asExprInternal(Node n) {
private Expr asExpr(Node n) {
isIndirectBaseOfArrayAccess(n, result)
or
not isIndirectBaseOfArrayAccess(n, _) and
@@ -1712,7 +1696,7 @@ module ExprFlowCached {
* dataflow step.
*/
private predicate localStepFromNonExpr(Node n1, Node n2) {
not exists(asExprInternal(n1)) and
not exists(asExpr(n1)) and
localFlowStep(n1, n2)
}
@@ -1723,7 +1707,7 @@ module ExprFlowCached {
pragma[nomagic]
private predicate localStepsToExpr(Node n1, Node n2, Expr e2) {
localStepFromNonExpr*(n1, n2) and
e2 = asExprInternal(n2)
e2 = asExpr(n2)
}
/**
@@ -1734,7 +1718,7 @@ module ExprFlowCached {
exists(Node mid |
localFlowStep(n1, mid) and
localStepsToExpr(mid, n2, e2) and
e1 = asExprInternal(n1)
e1 = asExpr(n1)
)
}
@@ -1919,38 +1903,7 @@ signature predicate guardChecksSig(IRGuardCondition g, Expr e, boolean branch);
* in data flow and taint tracking.
*/
module BarrierGuard<guardChecksSig/3 guardChecks> {
/**
* 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.
*/
/** Gets a node that is safely guarded by the given guard check. */
ExprNode getABarrierNode() {
exists(IRGuardCondition g, Expr e, ValueNumber value, boolean edge |
e = value.getAnInstruction().getConvertedResultExpression() and
@@ -1959,84 +1912,6 @@ 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

@@ -60,7 +60,7 @@ private DataFlow::Node getNodeForSource(Expr source) {
}
private DataFlow::Node getNodeForExpr(Expr node) {
node = DataFlow::ExprFlowCached::asExprInternal(result)
result = DataFlow::exprNode(node)
or
// Some of the sources in `isUserInput` are intended to match the value of
// an expression, while others (those modeled below) are intended to match
@@ -221,7 +221,7 @@ private module Cached {
predicate nodeIsBarrierIn(DataFlow::Node node) {
// don't use dataflow into taint sources, as this leads to duplicate results.
exists(Expr source | isUserInput(source, _) |
source = DataFlow::ExprFlowCached::asExprInternal(node)
node = DataFlow::exprNode(source)
or
// This case goes together with the similar (but not identical) rule in
// `getNodeForSource`.

View File

@@ -1,38 +0,0 @@
/**
* 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,44 +1,119 @@
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(Node node2, int order1, int order2) {
exists(Node node1 |
simpleLocalFlowStep(node1, node2) and
result = nodeId(node1, order1, order2)
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)
)
}
/**
* Gets the local dataflow from this node to other nodes in the same function.
*/
private string getToFlow(Node node1, int order1, int order2) {
exists(Node node2 |
simpleLocalFlowStep(node1, node2) and
result = nodeId(node2, order1, order2)
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)
)
}
/**
* Gets the properties of the dataflow node `node`.
*/
private string getNodeProperty(Node node, string key) {
private string getNodeProperty(DataFlow::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) + "->" + starsForNode(node) + "@" and to = false
flow = getFromFlow(node, order1, order2) + "->@" and to = false
or
flow = starsForNode(node) + "@->" + getToFlow(node, order1, order2) and to = true
flow = "@->" + 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
// )
}
/**
@@ -46,21 +121,16 @@ private string getNodeProperty(Node node, string key) {
*/
class LocalFlowPropertyProvider extends IRPropertyProvider {
override string getOperandProperty(Operand operand, string key) {
exists(Node node |
operand = [node.asOperand(), node.(RawIndirectOperand).getOperand()] and
exists(DataFlow::Node node |
operand = node.asOperand() and
result = getNodeProperty(node, key)
)
}
override string getInstructionProperty(Instruction instruction, string key) {
exists(Node node |
instruction = [node.asInstruction(), node.(RawIndirectInstruction).getInstruction()]
|
exists(DataFlow::Node node |
instruction = node.asInstruction() and
result = getNodeProperty(node, key)
)
}
override predicate shouldPrintOperand(Operand operand) { not Ssa::ignoreOperand(operand) }
override predicate shouldPrintInstruction(Instruction instr) { not Ssa::ignoreInstruction(instr) }
}

View File

@@ -0,0 +1,33 @@
/**
* 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,59 +3,37 @@
*/
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.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)
}
private import semmle.code.cpp.ir.dataflow.DataFlow
/**
* 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(Node node, int order1, int order2) {
exists(Instruction instruction, string stars | instruction = getInstruction(node, stars) |
result = stars + instruction.getResultId() and
string nodeId(DataFlow::Node node, int order1, int order2) {
exists(Instruction instruction | instruction = node.asInstruction() |
result = instruction.getResultId() and
order1 = instruction.getBlock().getDisplayIndex() and
order2 = instruction.getDisplayIndexInBlock()
)
or
exists(Operand operand, Instruction instruction, string stars |
operand = getOperand(node, stars) and
exists(Operand operand, Instruction instruction |
operand = node.asOperand() and
instruction = operand.getUse()
|
result = stars + instruction.getResultId() + "." + operand.getDumpId() and
result = 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

@@ -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 GlobalLikeVariable
base.(VariableAddressInstruction).getAstVariable() instanceof Cpp::GlobalOrNamespaceVariable
)
} or
TUseImpl(Operand operand, int indirectionIndex) {
isUse(_, operand, _, _, indirectionIndex) and
not isDef(_, _, operand, _, _, _)
} or
TGlobalUse(GlobalLikeVariable v, IRFunction f, int indirectionIndex) {
TGlobalUse(Cpp::GlobalOrNamespaceVariable 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(GlobalLikeVariable v, IRFunction f, int indirectionIndex) {
TGlobalDefImpl(Cpp::GlobalOrNamespaceVariable 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 {
GlobalLikeVariable global;
Cpp::GlobalOrNamespaceVariable 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. */
GlobalLikeVariable getVariable() { result = global }
Cpp::GlobalOrNamespaceVariable 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 {
GlobalLikeVariable global;
Cpp::GlobalOrNamespaceVariable global;
IRFunction f;
int indirectionIndex;
GlobalDefImpl() { this = TGlobalDefImpl(global, f, indirectionIndex) }
/** Gets the global variable associated with this definition. */
GlobalLikeVariable getVariable() { result = global }
Cpp::GlobalOrNamespaceVariable getVariable() { result = global }
/** Gets the `IRFunction` whose body is evaluated after this definition. */
IRFunction getIRFunction() { result = f }
@@ -657,20 +657,27 @@ 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(PostUpdateNode pun, UseOrPhi use) {
exists(DefOrUse defOrUse, Node adjusted |
indirectConversionFlowStep*(adjusted, pun.getPreUpdateNode()) and
nodeToDefOrUse(adjusted, defOrUse, _) and
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
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) and
nodeFrom != nodeTo
useToNode(use, nodeTo)
or
// Initial global variable value to a first use
nodeFrom.(InitialGlobalValue).getGlobalDef() = defOrUse and
@@ -705,28 +712,11 @@ 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 nodeFrom != nodeTo
|
ssaFlowImpl(defOrUse, nFrom, nodeTo, uncertain) and
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`.
@@ -752,7 +742,6 @@ 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
)
@@ -771,14 +760,13 @@ private predicate variableWriteCand(IRBlock bb, int i, SourceVariable v) {
}
private predicate sourceVariableIsGlobal(
SourceVariable sv, GlobalLikeVariable global, IRFunction func, int indirectionIndex
SourceVariable sv, Cpp::GlobalOrNamespaceVariable 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() and
not irVar instanceof IRDynamicInitializationFlag
global = irVar.getAst()
)
}
@@ -931,7 +919,7 @@ class GlobalDef extends TGlobalDef, SsaDefOrUse {
IRFunction getIRFunction() { result = global.getIRFunction() }
/** Gets the global variable associated with this definition. */
GlobalLikeVariable getVariable() { result = global.getVariable() }
Cpp::GlobalOrNamespaceVariable getVariable() { result = global.getVariable() }
}
class Phi extends TPhi, SsaDefOrUse {
@@ -1009,14 +997,6 @@ 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

@@ -144,20 +144,6 @@ class AllocationInstruction extends CallInstruction {
AllocationInstruction() { this.getStaticCallTarget() instanceof Cpp::AllocationFunction }
}
private predicate isIndirectionType(Type t) { t instanceof Indirection }
private predicate hasUnspecifiedBaseType(Indirection t, Type base) {
base = t.getBaseType().getUnspecifiedType()
}
/**
* Holds if `t2` is the same type as `t1`, but after stripping away `result` number
* of indirections.
* Furthermore, specifies in `t2` been deeply stripped and typedefs has been resolved.
*/
private int getNumberOfIndirectionsImpl(Type t1, Type t2) =
shortestDistances(isIndirectionType/1, hasUnspecifiedBaseType/2)(t1, t2, result)
/**
* An abstract class for handling indirections.
*
@@ -176,10 +162,7 @@ abstract class Indirection extends Type {
* For example, the number of indirections of a variable `p` of type
* `int**` is `3` (i.e., `p`, `*p` and `**p`).
*/
final int getNumberOfIndirections() {
result =
getNumberOfIndirectionsImpl(this.getType(), any(Type end | not end instanceof Indirection))
}
abstract int getNumberOfIndirections();
/**
* Holds if `deref` is an instruction that behaves as a `LoadInstruction`
@@ -217,11 +200,19 @@ private class PointerOrArrayOrReferenceTypeIndirection extends Indirection insta
PointerOrArrayOrReferenceTypeIndirection() {
baseType = PointerOrArrayOrReferenceType.super.getBaseType()
}
override int getNumberOfIndirections() {
result = 1 + countIndirections(this.getBaseType().getUnspecifiedType())
}
}
private class PointerWrapperTypeIndirection extends Indirection instanceof PointerWrapper {
PointerWrapperTypeIndirection() { baseType = PointerWrapper.super.getBaseType() }
override int getNumberOfIndirections() {
result = 1 + countIndirections(this.getBaseType().getUnspecifiedType())
}
override predicate isAdditionalDereference(Instruction deref, Operand address) {
exists(CallInstruction call |
operandForFullyConvertedCall(getAUse(deref), call) and
@@ -242,6 +233,10 @@ private module IteratorIndirections {
baseType = super.getValueType()
}
override int getNumberOfIndirections() {
result = 1 + countIndirections(this.getBaseType().getUnspecifiedType())
}
override predicate isAdditionalDereference(Instruction deref, Operand address) {
exists(CallInstruction call |
operandForFullyConvertedCall(getAUse(deref), call) and

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 = this.toString() }
string getIdentityString() { result = 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 = this.getDomainPrefix() + this.getBaseString() + byteSize.toString()
result = getDomainPrefix() + 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) {
this.hasOperandInternal(tag)
hasOperandInternal(tag)
or
this.hasAddressOperand() and tag instanceof AddressOperandTag
hasAddressOperand() and tag instanceof AddressOperandTag
or
this.hasBufferSizeOperand() and tag instanceof BufferSizeOperandTag
hasBufferSizeOperand() and tag instanceof BufferSizeOperandTag
}
/**

View File

@@ -77,16 +77,4 @@ 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,9 +45,7 @@ class IRFunction extends IRFunctionBase {
* Gets the block containing the entry point of this function.
*/
pragma[noinline]
final IRBlock getEntryBlock() {
result.getFirstInstruction() = this.getEnterFunctionInstruction()
}
final IRBlock getEntryBlock() { result.getFirstInstruction() = 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() { this.getLanguageType().hasType(result, false) }
final Language::Type getType() { getLanguageType().hasType(result, false) }
/**
* Gets the language-neutral type of the variable.
*/
final IRType getIRType() { result = this.getLanguageType().getIRType() }
final IRType getIRType() { result = 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 = this.getAst() }
deprecated Language::AST getAST() { result = 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 = this.getAst().getLocation() }
final Language::Location getLocation() { result = 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 = this.getVariable().toString() }
final override string toString() { result = getVariable().toString() }
final override Language::AST getAst() { result = var }
/** DEPRECATED: Alias for getAst */
deprecated override Language::AST getAST() { result = this.getAst() }
deprecated override Language::AST getAST() { result = getAst() }
final override string getUniqueId() {
result = this.getVariable().toString() + " " + this.getVariable().getLocation().toString()
result = getVariable().toString() + " " + 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 = this.getAst() }
deprecated override Language::AST getAST() { result = getAst() }
override string toString() { result = this.getBaseString() + this.getLocationString() }
override string toString() { result = getBaseString() + 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: " + this.getLocationString() + "=" + Language::getStringLiteralText(literal)
result = "String: " + getLocationString() + "=" + Language::getStringLiteralText(literal)
}
final override string getBaseString() { result = "#string" }
@@ -303,8 +303,7 @@ class IRDynamicInitializationFlag extends IRGeneratedVariable, TIRDynamicInitial
final Language::Variable getVariable() { result = var }
final override string getUniqueId() {
result =
"Init: " + this.getVariable().toString() + " " + this.getVariable().getLocation().toString()
result = "Init: " + getVariable().toString() + " " + getVariable().getLocation().toString()
}
final override string getBaseString() { result = "#init:" + var.toString() + ":" }
@@ -333,5 +332,5 @@ class IRParameter extends IRAutomaticVariable {
* An IR variable representing a positional parameter.
*/
class IRPositionalParameter extends IRParameter, IRAutomaticUserVariable {
final override int getIndex() { result = this.getVariable().(Language::Parameter).getIndex() }
final override int getIndex() { result = getVariable().(Language::Parameter).getIndex() }
}

View File

@@ -210,6 +210,9 @@ class Instruction extends Construction::TStageInstruction {
*/
final Language::AST getAst() { result = Construction::getInstructionAst(this) }
/** DEPRECATED: Alias for getAst */
deprecated Language::AST getAST() { result = this.getAst() }
/**
* Gets the location of the source code for this instruction.
*/
@@ -460,6 +463,9 @@ class VariableInstruction extends Instruction {
* Gets the AST variable that this instruction's IR variable refers to, if one exists.
*/
final Language::Variable getAstVariable() { result = var.(IRUserVariable).getVariable() }
/** DEPRECATED: Alias for getAstVariable */
deprecated Language::Variable getASTVariable() { result = this.getAstVariable() }
}
/**

View File

@@ -42,14 +42,6 @@ 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))
}
@@ -92,9 +84,7 @@ 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) {
shouldPrintInstruction(instr) and shouldPrintFunction(instr.getEnclosingFunction())
}
TPrintableInstruction(Instruction instr) { shouldPrintFunction(instr.getEnclosingFunction()) }
/**
* A node to be emitted in the IR graph.
@@ -137,13 +127,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 = this.getLabel()
key = "semmle.label" and result = getLabel()
or
key = "semmle.order" and result = this.getOrder().toString()
key = "semmle.order" and result = getOrder().toString()
or
key = "semmle.graphKind" and result = this.getGraphKind()
key = "semmle.graphKind" and result = getGraphKind()
or
key = "semmle.forceText" and this.forceText() and result = "true"
key = "semmle.forceText" and forceText() and result = "true"
}
}
@@ -188,7 +178,7 @@ private class PrintableIRBlock extends PrintableIRNode, TPrintableIRBlock {
PrintableIRBlock() { this = TPrintableIRBlock(block) }
override string toString() { result = this.getLabel() }
override string toString() { result = getLabel() }
override Language::Location getLocation() { result = block.getLocation() }
@@ -233,7 +223,7 @@ private class PrintableInstruction extends PrintableIRNode, TPrintableInstructio
|
resultString = instr.getResultString() and
operationString = instr.getOperationString() and
operandsString = this.getOperandsString() and
operandsString = getOperandsString() and
columnWidths(block, resultWidth, operationWidth) and
result =
resultString + getPaddingString(resultWidth - resultString.length()) + " = " +
@@ -262,8 +252,7 @@ private class PrintableInstruction extends PrintableIRNode, TPrintableInstructio
private string getOperandsString() {
result =
concat(Operand operand |
operand = instr.getAnOperand() and
shouldPrintOperand(operand)
operand = instr.getAnOperand()
|
operand.getDumpString() + getOperandPropertyString(operand), ", "
order by

View File

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

View File

@@ -95,9 +95,7 @@ private newtype TMemoryLocation =
*/
abstract class MemoryLocation extends TMemoryLocation {
final string toString() {
if this.isMayAccess()
then result = "?" + this.toStringInternal()
else result = this.toStringInternal()
if isMayAccess() then result = "?" + toStringInternal() else result = toStringInternal()
}
abstract string toStringInternal();
@@ -112,7 +110,7 @@ abstract class MemoryLocation extends TMemoryLocation {
abstract Location getLocation();
final IRType getIRType() { result = this.getType().getIRType() }
final IRType getIRType() { result = getType().getIRType() }
abstract predicate isMayAccess();
@@ -138,7 +136,7 @@ abstract class MemoryLocation extends TMemoryLocation {
final predicate canReuseSsa() { none() }
/** DEPRECATED: Alias for canReuseSsa */
deprecated predicate canReuseSSA() { this.canReuseSsa() }
deprecated predicate canReuseSSA() { canReuseSsa() }
}
/**
@@ -193,19 +191,19 @@ class VariableMemoryLocation extends TVariableMemoryLocation, AllocationMemoryLo
}
private string getIntervalString() {
if this.coversEntireVariable()
if coversEntireVariable()
then result = ""
else result = Interval::getIntervalString(startBitOffset, endBitOffset)
}
private string getTypeString() {
if this.coversEntireVariable() and type = var.getIRType()
if coversEntireVariable() and type = var.getIRType()
then result = ""
else result = "<" + languageType.toString() + ">"
}
final override string toStringInternal() {
result = var.toString() + this.getIntervalString() + this.getTypeString()
result = var.toString() + getIntervalString() + getTypeString()
}
final override Language::LanguageType getType() {
@@ -238,7 +236,7 @@ class VariableMemoryLocation extends TVariableMemoryLocation, AllocationMemoryLo
/**
* Holds if this memory location covers the entire variable.
*/
final predicate coversEntireVariable() { this.varIRTypeHasBitRange(startBitOffset, endBitOffset) }
final predicate coversEntireVariable() { varIRTypeHasBitRange(startBitOffset, endBitOffset) }
pragma[noinline]
private predicate varIRTypeHasBitRange(int start, int end) {
@@ -264,7 +262,7 @@ class EntireAllocationMemoryLocation extends TEntireAllocationMemoryLocation,
class EntireAllocationVirtualVariable extends EntireAllocationMemoryLocation, VirtualVariable {
EntireAllocationVirtualVariable() {
not allocationEscapes(var) and
not this.isMayAccess()
not isMayAccess()
}
}
@@ -277,8 +275,8 @@ class VariableVirtualVariable extends VariableMemoryLocation, VirtualVariable {
VariableVirtualVariable() {
not allocationEscapes(var) and
type = var.getIRType() and
this.coversEntireVariable() and
not this.isMayAccess()
coversEntireVariable() and
not isMayAccess()
}
}
@@ -339,7 +337,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 this.isMayAccess()
not isMayAccess()
}
}
@@ -362,7 +360,7 @@ class AllAliasedMemory extends TAllAliasedMemory, MemoryLocation {
final override Location getLocation() { result = irFunc.getLocation() }
final override string getUniqueId() { result = " " + this.toString() }
final override string getUniqueId() { result = " " + toString() }
final override VirtualVariable getVirtualVariable() { result = TAllAliasedMemory(irFunc, false) }
@@ -371,7 +369,7 @@ class AllAliasedMemory extends TAllAliasedMemory, MemoryLocation {
/** A virtual variable that groups all escaped memory within a function. */
class AliasedVirtualVariable extends AllAliasedMemory, VirtualVariable {
AliasedVirtualVariable() { not this.isMayAccess() }
AliasedVirtualVariable() { not isMayAccess() }
}
/**
@@ -577,6 +575,9 @@ private Overlap getVariableMemoryLocationOverlap(
*/
predicate canReuseSsaForOldResult(Instruction instr) { OldSsa::canReuseSsaForMemoryResult(instr) }
/** DEPRECATED: Alias for canReuseSsaForOldResult */
deprecated predicate canReuseSSAForOldResult = canReuseSsaForOldResult/1;
bindingset[result, b]
private boolean unbindBool(boolean b) { result != b.booleanNot() }

View File

@@ -422,6 +422,12 @@ private module Cached {
)
}
/** DEPRECATED: Alias for getInstructionAst */
cached
deprecated Language::AST getInstructionAST(Instruction instr) {
result = getInstructionAst(instr)
}
cached
Language::LanguageType getInstructionResultType(Instruction instr) {
result = instr.(RawIR::Instruction).getResultLanguageType()
@@ -987,6 +993,9 @@ predicate canReuseSsaForMemoryResult(Instruction instruction) {
// We don't support reusing SSA for any location that could create a `Chi` instruction.
}
/** DEPRECATED: Alias for canReuseSsaForMemoryResult */
deprecated predicate canReuseSSAForMemoryResult = canReuseSsaForMemoryResult/1;
/**
* Expose some of the internal predicates to PrintSSA.qll. We do this by publicly importing those modules in the
* `DebugSsa` module, which is then imported by PrintSSA.
@@ -996,6 +1005,9 @@ module DebugSsa {
import DefUse
}
/** DEPRECATED: Alias for DebugSsa */
deprecated module DebugSSA = DebugSsa;
import CachedForDebugging
cached

View File

@@ -6,7 +6,7 @@ private import IRFunctionBaseInternal
private newtype TIRFunction =
TFunctionIRFunction(Language::Function func) { IRConstruction::Raw::functionHasIR(func) } or
TVarInitIRFunction(Language::Variable var) { IRConstruction::Raw::varHasIRFunc(var) }
TVarInitIRFunction(Language::GlobalVariable var) { IRConstruction::Raw::varHasIRFunc(var) }
/**
* The IR for a function. This base class contains only the predicates that are the same between all

View File

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

View File

@@ -73,6 +73,9 @@ module UnaliasedSsaInstructions {
}
}
/** DEPRECATED: Alias for UnaliasedSsaInstructions */
deprecated module UnaliasedSSAInstructions = UnaliasedSsaInstructions;
/**
* Provides wrappers for the constructors of each branch of `TInstruction` that is used by the
* aliased SSA stage.
@@ -104,3 +107,6 @@ module AliasedSsaInstructions {
result = TAliasedSsaUnreachedInstruction(irFunc)
}
}
/** DEPRECATED: Alias for AliasedSsaInstructions */
deprecated module AliasedSSAInstructions = AliasedSsaInstructions;

View File

@@ -74,12 +74,20 @@ private module Shared {
class TNonSsaMemoryOperand = Internal::TNonSsaMemoryOperand;
/** DEPRECATED: Alias for TNonSsaMemoryOperand */
deprecated class TNonSSAMemoryOperand = TNonSsaMemoryOperand;
/**
* Returns the non-Phi memory operand with the specified parameters.
*/
TNonSsaMemoryOperand nonSsaMemoryOperand(TRawInstruction useInstr, MemoryOperandTag tag) {
result = Internal::TNonSsaMemoryOperand(useInstr, tag)
}
/** DEPRECATED: Alias for nonSsaMemoryOperand */
deprecated TNonSSAMemoryOperand nonSSAMemoryOperand(TRawInstruction useInstr, MemoryOperandTag tag) {
result = nonSsaMemoryOperand(useInstr, tag)
}
}
/**
@@ -159,6 +167,9 @@ module UnaliasedSsaOperands {
TChiOperand chiOperand(Unaliased::Instruction useInstr, ChiOperandTag tag) { none() }
}
/** DEPRECATED: Alias for UnaliasedSsaOperands */
deprecated module UnaliasedSSAOperands = UnaliasedSsaOperands;
/**
* Provides wrappers for the constructors of each branch of `TOperand` that is used by the
* aliased SSA stage.
@@ -206,3 +217,6 @@ module AliasedSsaOperands {
result = Internal::TAliasedChiOperand(useInstr, tag)
}
}
/** DEPRECATED: Alias for AliasedSsaOperands */
deprecated module AliasedSSAOperands = AliasedSsaOperands;

View File

@@ -77,16 +77,4 @@ 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,9 +45,7 @@ class IRFunction extends IRFunctionBase {
* Gets the block containing the entry point of this function.
*/
pragma[noinline]
final IRBlock getEntryBlock() {
result.getFirstInstruction() = this.getEnterFunctionInstruction()
}
final IRBlock getEntryBlock() { result.getFirstInstruction() = 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() { this.getLanguageType().hasType(result, false) }
final Language::Type getType() { getLanguageType().hasType(result, false) }
/**
* Gets the language-neutral type of the variable.
*/
final IRType getIRType() { result = this.getLanguageType().getIRType() }
final IRType getIRType() { result = 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 = this.getAst() }
deprecated Language::AST getAST() { result = 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 = this.getAst().getLocation() }
final Language::Location getLocation() { result = 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 = this.getVariable().toString() }
final override string toString() { result = getVariable().toString() }
final override Language::AST getAst() { result = var }
/** DEPRECATED: Alias for getAst */
deprecated override Language::AST getAST() { result = this.getAst() }
deprecated override Language::AST getAST() { result = getAst() }
final override string getUniqueId() {
result = this.getVariable().toString() + " " + this.getVariable().getLocation().toString()
result = getVariable().toString() + " " + 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 = this.getAst() }
deprecated override Language::AST getAST() { result = getAst() }
override string toString() { result = this.getBaseString() + this.getLocationString() }
override string toString() { result = getBaseString() + 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: " + this.getLocationString() + "=" + Language::getStringLiteralText(literal)
result = "String: " + getLocationString() + "=" + Language::getStringLiteralText(literal)
}
final override string getBaseString() { result = "#string" }
@@ -303,8 +303,7 @@ class IRDynamicInitializationFlag extends IRGeneratedVariable, TIRDynamicInitial
final Language::Variable getVariable() { result = var }
final override string getUniqueId() {
result =
"Init: " + this.getVariable().toString() + " " + this.getVariable().getLocation().toString()
result = "Init: " + getVariable().toString() + " " + getVariable().getLocation().toString()
}
final override string getBaseString() { result = "#init:" + var.toString() + ":" }
@@ -333,5 +332,5 @@ class IRParameter extends IRAutomaticVariable {
* An IR variable representing a positional parameter.
*/
class IRPositionalParameter extends IRParameter, IRAutomaticUserVariable {
final override int getIndex() { result = this.getVariable().(Language::Parameter).getIndex() }
final override int getIndex() { result = getVariable().(Language::Parameter).getIndex() }
}

View File

@@ -210,6 +210,9 @@ class Instruction extends Construction::TStageInstruction {
*/
final Language::AST getAst() { result = Construction::getInstructionAst(this) }
/** DEPRECATED: Alias for getAst */
deprecated Language::AST getAST() { result = this.getAst() }
/**
* Gets the location of the source code for this instruction.
*/
@@ -460,6 +463,9 @@ class VariableInstruction extends Instruction {
* Gets the AST variable that this instruction's IR variable refers to, if one exists.
*/
final Language::Variable getAstVariable() { result = var.(IRUserVariable).getVariable() }
/** DEPRECATED: Alias for getAstVariable */
deprecated Language::Variable getASTVariable() { result = this.getAstVariable() }
}
/**

View File

@@ -42,14 +42,6 @@ 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))
}
@@ -92,9 +84,7 @@ 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) {
shouldPrintInstruction(instr) and shouldPrintFunction(instr.getEnclosingFunction())
}
TPrintableInstruction(Instruction instr) { shouldPrintFunction(instr.getEnclosingFunction()) }
/**
* A node to be emitted in the IR graph.
@@ -137,13 +127,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 = this.getLabel()
key = "semmle.label" and result = getLabel()
or
key = "semmle.order" and result = this.getOrder().toString()
key = "semmle.order" and result = getOrder().toString()
or
key = "semmle.graphKind" and result = this.getGraphKind()
key = "semmle.graphKind" and result = getGraphKind()
or
key = "semmle.forceText" and this.forceText() and result = "true"
key = "semmle.forceText" and forceText() and result = "true"
}
}
@@ -188,7 +178,7 @@ private class PrintableIRBlock extends PrintableIRNode, TPrintableIRBlock {
PrintableIRBlock() { this = TPrintableIRBlock(block) }
override string toString() { result = this.getLabel() }
override string toString() { result = getLabel() }
override Language::Location getLocation() { result = block.getLocation() }
@@ -233,7 +223,7 @@ private class PrintableInstruction extends PrintableIRNode, TPrintableInstructio
|
resultString = instr.getResultString() and
operationString = instr.getOperationString() and
operandsString = this.getOperandsString() and
operandsString = getOperandsString() and
columnWidths(block, resultWidth, operationWidth) and
result =
resultString + getPaddingString(resultWidth - resultString.length()) + " = " +
@@ -262,8 +252,7 @@ private class PrintableInstruction extends PrintableIRNode, TPrintableInstructio
private string getOperandsString() {
result =
concat(Operand operand |
operand = instr.getAnOperand() and
shouldPrintOperand(operand)
operand = instr.getAnOperand()
|
operand.getDumpString() + getOperandPropertyString(operand), ", "
order by

View File

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

View File

@@ -37,13 +37,7 @@ module Raw {
predicate functionHasIR(Function func) { exists(getTranslatedFunction(func)) }
cached
predicate varHasIRFunc(Variable var) {
(
var instanceof GlobalOrNamespaceVariable
or
not var.isFromUninstantiatedTemplate(_) and
var instanceof StaticInitializedStaticLocalVariable
) and
predicate varHasIRFunc(GlobalOrNamespaceVariable var) {
var.hasInitializer() and
(
not var.getType().isDeeplyConst()
@@ -81,10 +75,9 @@ module Raw {
}
cached
predicate hasDynamicInitializationFlag(
Function func, RuntimeInitializedStaticLocalVariable var, CppType type
) {
predicate hasDynamicInitializationFlag(Function func, StaticLocalVariable var, CppType type) {
var.getFunction() = func and
var.hasDynamicInitialization() and
type = getBoolType()
}
@@ -375,6 +368,11 @@ Locatable getInstructionAst(TStageInstruction instr) {
)
}
/** DEPRECATED: Alias for getInstructionAst */
deprecated Locatable getInstructionAST(TStageInstruction instr) {
result = getInstructionAst(instr)
}
CppType getInstructionResultType(TStageInstruction instr) {
getInstructionTranslatedElement(instr).hasInstruction(_, getInstructionTag(instr), result)
or

View File

@@ -31,42 +31,42 @@ 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 = this.getQualifier()
id = -2 and result = getQualifier()
or
id = -1 and result = this.getCallTarget()
id = -1 and result = getCallTarget()
or
result = this.getArgument(id)
result = getArgument(id)
or
id = this.getNumberOfArguments() and result = this.getSideEffects()
id = getNumberOfArguments() and result = getSideEffects()
}
final override Instruction getFirstInstruction() {
if exists(this.getQualifier())
then result = this.getQualifier().getFirstInstruction()
else result = this.getFirstCallTargetInstruction()
if exists(getQualifier())
then result = getQualifier().getFirstInstruction()
else result = getFirstCallTargetInstruction()
}
override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) {
tag = CallTag() and
opcode instanceof Opcode::Call and
resultType = getTypeForPRValue(this.getCallResultType())
resultType = getTypeForPRValue(getCallResultType())
}
override Instruction getChildSuccessor(TranslatedElement child) {
child = this.getQualifier() and
result = this.getFirstCallTargetInstruction()
child = getQualifier() and
result = getFirstCallTargetInstruction()
or
child = this.getCallTarget() and
result = this.getFirstArgumentOrCallInstruction()
child = getCallTarget() and
result = getFirstArgumentOrCallInstruction()
or
exists(int argIndex |
child = this.getArgument(argIndex) and
if exists(this.getArgument(argIndex + 1))
then result = this.getArgument(argIndex + 1).getFirstInstruction()
else result = this.getInstruction(CallTag())
child = getArgument(argIndex) and
if exists(getArgument(argIndex + 1))
then result = getArgument(argIndex + 1).getFirstInstruction()
else result = getInstruction(CallTag())
)
or
child = this.getSideEffects() and
child = getSideEffects() and
if this.isNoReturn()
then
result =
@@ -79,26 +79,26 @@ abstract class TranslatedCall extends TranslatedExpr {
override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) {
kind instanceof GotoEdge and
tag = CallTag() and
result = this.getSideEffects().getFirstInstruction()
result = getSideEffects().getFirstInstruction()
}
override Instruction getInstructionRegisterOperand(InstructionTag tag, OperandTag operandTag) {
tag = CallTag() and
(
operandTag instanceof CallTargetOperandTag and
result = this.getCallTargetResult()
result = getCallTargetResult()
or
operandTag instanceof ThisArgumentOperandTag and
result = this.getQualifierResult()
result = getQualifierResult()
or
exists(PositionalArgumentOperandTag argTag |
argTag = operandTag and
result = this.getArgument(argTag.getArgIndex()).getResult()
result = getArgument(argTag.getArgIndex()).getResult()
)
)
}
final override Instruction getResult() { result = this.getInstruction(CallTag()) }
final override Instruction getResult() { result = getInstruction(CallTag()) }
/**
* Gets the result type of the call.
@@ -108,7 +108,7 @@ abstract class TranslatedCall extends TranslatedExpr {
/**
* Holds if the call has a `this` argument.
*/
predicate hasQualifier() { exists(this.getQualifier()) }
predicate hasQualifier() { exists(getQualifier()) }
/**
* Gets the `TranslatedExpr` for the indirect target of the call, if any.
@@ -121,9 +121,7 @@ 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 = this.getCallTarget().getFirstInstruction()
}
Instruction getFirstCallTargetInstruction() { result = getCallTarget().getFirstInstruction() }
/**
* Gets the instruction whose result value is the target of the call. By
@@ -131,7 +129,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 = this.getCallTarget().getResult() }
Instruction getCallTargetResult() { result = getCallTarget().getResult() }
/**
* Gets the `TranslatedExpr` for the qualifier of the call (i.e. the value
@@ -145,7 +143,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 = this.getQualifier().getResult() }
Instruction getQualifierResult() { result = getQualifier().getResult() }
/**
* Gets the argument with the specified `index`. Does not include the `this`
@@ -160,9 +158,9 @@ abstract class TranslatedCall extends TranslatedExpr {
* argument. Otherwise, returns the call instruction.
*/
final Instruction getFirstArgumentOrCallInstruction() {
if this.hasArguments()
then result = this.getArgument(0).getFirstInstruction()
else result = this.getInstruction(CallTag())
if hasArguments()
then result = getArgument(0).getFirstInstruction()
else result = getInstruction(CallTag())
}
/**
@@ -186,17 +184,17 @@ abstract class TranslatedSideEffects extends TranslatedElement {
/** Gets the expression whose side effects are being modeled. */
abstract Expr getExpr();
final override Locatable getAst() { result = this.getExpr() }
final override Locatable getAst() { result = getExpr() }
/** DEPRECATED: Alias for getAst */
deprecated override Locatable getAST() { result = this.getAst() }
deprecated override Locatable getAST() { result = getAst() }
final override Declaration getFunction() { result = getEnclosingDeclaration(this.getExpr()) }
final override Declaration getFunction() { result = getExpr().getEnclosingDeclaration() }
final override TranslatedElement getChild(int i) {
result =
rank[i + 1](TranslatedSideEffect tse, int group, int indexInGroup |
tse.getPrimaryExpr() = this.getExpr() and
tse.getPrimaryExpr() = getExpr() and
tse.sortOrder(group, indexInGroup)
|
tse order by group, indexInGroup
@@ -205,10 +203,10 @@ abstract class TranslatedSideEffects extends TranslatedElement {
final override Instruction getChildSuccessor(TranslatedElement te) {
exists(int i |
this.getChild(i) = te and
if exists(this.getChild(i + 1))
then result = this.getChild(i + 1).getFirstInstruction()
else result = this.getParent().getChildSuccessor(this)
getChild(i) = te and
if exists(getChild(i + 1))
then result = getChild(i + 1).getFirstInstruction()
else result = getParent().getChildSuccessor(this)
)
}
@@ -217,10 +215,10 @@ abstract class TranslatedSideEffects extends TranslatedElement {
}
final override Instruction getFirstInstruction() {
result = this.getChild(0).getFirstInstruction()
result = getChild(0).getFirstInstruction()
or
// Some functions, like `std::move()`, have no side effects whatsoever.
not exists(this.getChild(0)) and result = this.getParent().getChildSuccessor(this)
not exists(getChild(0)) and result = getParent().getChildSuccessor(this)
}
final override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) { none() }
@@ -236,10 +234,10 @@ abstract class TranslatedSideEffects extends TranslatedElement {
*/
abstract class TranslatedDirectCall extends TranslatedCall {
final override Instruction getFirstCallTargetInstruction() {
result = this.getInstruction(CallTargetTag())
result = getInstruction(CallTargetTag())
}
final override Instruction getCallTargetResult() { result = this.getInstruction(CallTargetTag()) }
final override Instruction getCallTargetResult() { result = getInstruction(CallTargetTag()) }
override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) {
TranslatedCall.super.hasInstruction(opcode, tag, resultType)
@@ -254,7 +252,7 @@ abstract class TranslatedDirectCall extends TranslatedCall {
or
tag = CallTargetTag() and
kind instanceof GotoEdge and
result = this.getFirstArgumentOrCallInstruction()
result = getFirstArgumentOrCallInstruction()
}
}
@@ -303,12 +301,12 @@ class TranslatedFunctionCall extends TranslatedCallExpr, TranslatedDirectCall {
}
override Instruction getQualifierResult() {
this.hasQualifier() and
result = this.getQualifier().getResult()
hasQualifier() and
result = getQualifier().getResult()
}
override predicate hasQualifier() {
exists(this.getQualifier()) and
exists(getQualifier()) and
not exists(MemberFunction func | expr.getTarget() = func and func.isStatic())
}
}
@@ -324,7 +322,7 @@ class TranslatedStructorCall extends TranslatedFunctionCall {
override Instruction getQualifierResult() {
exists(StructorCallContext context |
context = this.getParent() and
context = getParent() and
result = context.getReceiver()
)
}
@@ -375,26 +373,24 @@ abstract class TranslatedSideEffect extends TranslatedElement {
final override Instruction getChildSuccessor(TranslatedElement child) { none() }
final override Instruction getFirstInstruction() {
result = this.getInstruction(OnlyInstructionTag())
}
final override Instruction getFirstInstruction() { result = getInstruction(OnlyInstructionTag()) }
final override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType type) {
tag = OnlyInstructionTag() and
this.sideEffectInstruction(opcode, type)
sideEffectInstruction(opcode, type)
}
final override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) {
result = this.getParent().getChildSuccessor(this) and
result = getParent().getChildSuccessor(this) and
tag = OnlyInstructionTag() and
kind instanceof GotoEdge
}
final override Declaration getFunction() { result = this.getParent().getFunction() }
final override Declaration getFunction() { result = getParent().getFunction() }
final override Instruction getPrimaryInstructionForSideEffect(InstructionTag tag) {
tag = OnlyInstructionTag() and
result = this.getParent().(TranslatedSideEffects).getPrimaryInstruction()
result = getParent().(TranslatedSideEffects).getPrimaryInstruction()
}
/**
@@ -432,18 +428,18 @@ abstract class TranslatedArgumentSideEffect extends TranslatedSideEffect {
TranslatedArgumentSideEffect() { any() }
override string toString() {
this.isWrite() and
result = "(write side effect for " + this.getArgString() + ")"
isWrite() and
result = "(write side effect for " + getArgString() + ")"
or
not this.isWrite() and
result = "(read side effect for " + this.getArgString() + ")"
not isWrite() and
result = "(read side effect for " + getArgString() + ")"
}
override Call getPrimaryExpr() { result = call }
override predicate sortOrder(int group, int indexInGroup) {
indexInGroup = index and
if this.isWrite() then group = argumentWriteGroup() else group = argumentReadGroup()
if isWrite() then group = argumentWriteGroup() else group = argumentReadGroup()
}
final override int getInstructionIndex(InstructionTag tag) {
@@ -454,20 +450,20 @@ abstract class TranslatedArgumentSideEffect extends TranslatedSideEffect {
final override predicate sideEffectInstruction(Opcode opcode, CppType type) {
opcode = sideEffectOpcode and
(
this.isWrite() and
isWrite() and
(
opcode instanceof BufferAccessOpcode and
type = getUnknownType()
or
not opcode instanceof BufferAccessOpcode and
exists(Type indirectionType | indirectionType = this.getIndirectionType() |
exists(Type indirectionType | indirectionType = getIndirectionType() |
if indirectionType instanceof VoidType
then type = getUnknownType()
else type = getTypeForPRValueOrUnknown(indirectionType)
)
)
or
not this.isWrite() and
not isWrite() and
type = getVoidType()
)
}
@@ -475,7 +471,7 @@ abstract class TranslatedArgumentSideEffect extends TranslatedSideEffect {
final override CppType getInstructionMemoryOperandType(
InstructionTag tag, TypedOperandTag operandTag
) {
not this.isWrite() and
not isWrite() and
if sideEffectOpcode instanceof BufferAccessOpcode
then
result = getUnknownType() and
@@ -484,7 +480,7 @@ abstract class TranslatedArgumentSideEffect extends TranslatedSideEffect {
else
exists(Type operandType |
tag instanceof OnlyInstructionTag and
operandType = this.getIndirectionType() and
operandType = getIndirectionType() and
operandTag instanceof SideEffectOperandTag
|
// If the type we select is an incomplete type (e.g. a forward-declared `struct`), there will
@@ -496,7 +492,7 @@ abstract class TranslatedArgumentSideEffect extends TranslatedSideEffect {
final override Instruction getInstructionRegisterOperand(InstructionTag tag, OperandTag operandTag) {
tag instanceof OnlyInstructionTag and
operandTag instanceof AddressOperandTag and
result = this.getArgInstruction()
result = getArgInstruction()
or
tag instanceof OnlyInstructionTag and
operandTag instanceof BufferSizeOperandTag and
@@ -537,7 +533,7 @@ class TranslatedArgumentExprSideEffect extends TranslatedArgumentSideEffect,
final override Locatable getAst() { result = arg }
/** DEPRECATED: Alias for getAst */
deprecated override Locatable getAST() { result = this.getAst() }
deprecated override Locatable getAST() { result = getAst() }
final override Type getIndirectionType() {
result = arg.getUnspecifiedType().(DerivedType).getBaseType()
@@ -572,7 +568,7 @@ class TranslatedStructorQualifierSideEffect extends TranslatedArgumentSideEffect
final override Locatable getAst() { result = call }
/** DEPRECATED: Alias for getAst */
deprecated override Locatable getAST() { result = this.getAst() }
deprecated override Locatable getAST() { result = getAst() }
final override Type getIndirectionType() { result = call.getTarget().getDeclaringType() }
@@ -596,7 +592,7 @@ class TranslatedCallSideEffect extends TranslatedSideEffect, TTranslatedCallSide
override Locatable getAst() { result = expr }
/** DEPRECATED: Alias for getAst */
deprecated override Locatable getAST() { result = this.getAst() }
deprecated override Locatable getAST() { result = getAst() }
override Expr getPrimaryExpr() { result = expr }
@@ -637,7 +633,7 @@ class TranslatedAllocationSideEffect extends TranslatedSideEffect, TTranslatedAl
override Locatable getAst() { result = expr }
/** DEPRECATED: Alias for getAst */
deprecated override Locatable getAST() { result = this.getAst() }
deprecated override Locatable getAST() { result = getAst() }
override Expr getPrimaryExpr() { result = expr }
@@ -650,7 +646,7 @@ class TranslatedAllocationSideEffect extends TranslatedSideEffect, TTranslatedAl
override Instruction getInstructionRegisterOperand(InstructionTag tag, OperandTag operandTag) {
tag = OnlyInstructionTag() and
operandTag = addressOperand() and
result = this.getPrimaryInstructionForSideEffect(OnlyInstructionTag())
result = getPrimaryInstructionForSideEffect(OnlyInstructionTag())
}
override predicate sideEffectInstruction(Opcode opcode, CppType type) {

View File

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

View File

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

View File

@@ -62,6 +62,15 @@ private predicate ignoreExprAndDescendants(Expr expr) {
// constant value.
isIRConstant(getRealParent(expr))
or
// Only translate the initializer of a static local if it uses run-time data.
// Otherwise the initializer does not run in function scope.
exists(Initializer init, StaticStorageDurationVariable var |
init = var.getInitializer() and
not var.hasDynamicInitialization() and
expr = init.getExpr().getFullyConverted() and
not var instanceof GlobalOrNamespaceVariable
)
or
// Ignore descendants of `__assume` expressions, since we translated these to `NoOp`.
getRealParent(expr) instanceof AssumeExpr
or
@@ -109,8 +118,8 @@ private predicate ignoreExprOnly(Expr expr) {
// should not be translated.
exists(NewOrNewArrayExpr new | expr = new.getAllocatorCall().getArgument(0))
or
not translateFunction(getEnclosingFunction(expr)) and
not Raw::varHasIRFunc(getEnclosingVariable(expr))
not translateFunction(expr.getEnclosingFunction()) and
not Raw::varHasIRFunc(expr.getEnclosingVariable())
or
// We do not yet translate destructors properly, so for now we ignore the
// destructor call. We do, however, translate the expression being
@@ -429,17 +438,6 @@ predicate hasTranslatedSyntheticTemporaryObject(Expr expr) {
not expr.hasLValueToRValueConversion()
}
class StaticInitializedStaticLocalVariable extends StaticLocalVariable {
StaticInitializedStaticLocalVariable() {
this.hasInitializer() and
not this.hasDynamicInitialization()
}
}
class RuntimeInitializedStaticLocalVariable extends StaticLocalVariable {
RuntimeInitializedStaticLocalVariable() { this.hasDynamicInitialization() }
}
/**
* Holds if the specified `DeclarationEntry` needs an IR translation. An IR translation is only
* necessary for automatic local variables, or for static local variables with dynamic
@@ -455,7 +453,7 @@ private predicate translateDeclarationEntry(IRDeclarationEntry entry) {
not var.isStatic()
or
// Ignore static variables unless they have a dynamic initializer.
var instanceof RuntimeInitializedStaticLocalVariable
var.(StaticLocalVariable).hasDynamicInitialization()
)
)
}
@@ -757,7 +755,7 @@ newtype TTranslatedElement =
} or
// The side effect that initializes newly-allocated memory.
TTranslatedAllocationSideEffect(AllocationExpr expr) { not ignoreSideEffects(expr) } or
TTranslatedStaticStorageDurationVarInit(Variable var) { Raw::varHasIRFunc(var) }
TTranslatedGlobalOrNamespaceVarInit(GlobalOrNamespaceVariable var) { Raw::varHasIRFunc(var) }
/**
* Gets the index of the first explicitly initialized element in `initList`
@@ -821,7 +819,7 @@ abstract class TranslatedElement extends TTranslatedElement {
abstract Locatable getAst();
/** DEPRECATED: Alias for getAst */
deprecated Locatable getAST() { result = this.getAst() }
deprecated Locatable getAST() { result = getAst() }
/**
* Get the first instruction to be executed in the evaluation of this element.
@@ -831,7 +829,7 @@ abstract class TranslatedElement extends TTranslatedElement {
/**
* Get the immediate child elements of this element.
*/
final TranslatedElement getAChild() { result = this.getChild(_) }
final TranslatedElement getAChild() { result = getChild(_) }
/**
* Gets the immediate child element of this element. The `id` is unique
@@ -844,29 +842,25 @@ 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 = this.getUniqueId() }
final int getId() { result = getUniqueId() }
private TranslatedElement getChildByRank(int rankIndex) {
result =
rank[rankIndex + 1](TranslatedElement child, int id |
child = this.getChild(id)
|
child order by id
)
rank[rankIndex + 1](TranslatedElement child, int id | child = getChild(id) | child order by id)
}
language[monotonicAggregates]
private int getDescendantCount() {
result =
1 + sum(TranslatedElement child | child = this.getChildByRank(_) | child.getDescendantCount())
1 + sum(TranslatedElement child | child = getChildByRank(_) | child.getDescendantCount())
}
private int getUniqueId() {
if not exists(this.getParent())
if not exists(getParent())
then result = 0
else
exists(TranslatedElement parent |
parent = this.getParent() and
parent = getParent() and
if this = parent.getChildByRank(0)
then result = 1 + parent.getUniqueId()
else
@@ -912,7 +906,7 @@ abstract class TranslatedElement extends TTranslatedElement {
* there is no enclosing `try`.
*/
Instruction getExceptionSuccessorInstruction() {
result = this.getParent().getExceptionSuccessorInstruction()
result = getParent().getExceptionSuccessorInstruction()
}
/**
@@ -1026,14 +1020,14 @@ abstract class TranslatedElement extends TTranslatedElement {
exists(Locatable ast |
result.getAst() = ast and
result.getTag() = tag and
this.hasTempVariableAndAst(tag, ast)
hasTempVariableAndAst(tag, ast)
)
}
pragma[noinline]
private predicate hasTempVariableAndAst(TempVariableTag tag, Locatable ast) {
this.hasTempVariable(tag, _) and
ast = this.getAst()
hasTempVariable(tag, _) and
ast = getAst()
}
/**
@@ -1049,6 +1043,6 @@ abstract class TranslatedRootElement extends TranslatedElement {
TranslatedRootElement() {
this instanceof TTranslatedFunction
or
this instanceof TTranslatedStaticStorageDurationVarInit
this instanceof TTranslatedGlobalOrNamespaceVarInit
}
}

View File

@@ -76,7 +76,10 @@ abstract class TranslatedExpr extends TranslatedElement {
final override Locatable getAst() { result = expr }
final override Declaration getFunction() { result = getEnclosingDeclaration(expr) }
/** DEPRECATED: Alias for getAst */
deprecated override Locatable getAST() { result = this.getAst() }
final override Declaration getFunction() { result = expr.getEnclosingDeclaration() }
/**
* Gets the expression from which this `TranslatedExpr` is generated.
@@ -87,57 +90,12 @@ abstract class TranslatedExpr extends TranslatedElement {
* Gets the `TranslatedFunction` containing this expression.
*/
final TranslatedRootElement getEnclosingFunction() {
result = getTranslatedFunction(getEnclosingFunction(expr))
result = getTranslatedFunction(expr.getEnclosingFunction())
or
result = getTranslatedVarInit(getEnclosingVariable(expr))
result = getTranslatedVarInit(expr.getEnclosingVariable())
}
}
Function getEnclosingFunction(Expr e) {
not exists(getEnclosingVariable(e)) and
result = e.getEnclosingFunction()
}
Declaration getEnclosingDeclaration0(Expr e) {
result = getEnclosingDeclaration0(e.getParentWithConversions())
or
exists(Initializer i, Variable v |
i.getExpr().getFullyConverted() = e and
v = i.getDeclaration()
|
if v instanceof StaticInitializedStaticLocalVariable or v instanceof GlobalOrNamespaceVariable
then result = v
else result = e.getEnclosingDeclaration()
)
}
Declaration getEnclosingDeclaration(Expr e) {
result = getEnclosingDeclaration0(e)
or
not exists(getEnclosingDeclaration0(e)) and
result = e.getEnclosingDeclaration()
}
Variable getEnclosingVariable0(Expr e) {
result = getEnclosingVariable0(e.getParentWithConversions())
or
exists(Initializer i, Variable v |
i.getExpr().getFullyConverted() = e and
v = i.getDeclaration()
|
if v instanceof StaticInitializedStaticLocalVariable or v instanceof GlobalOrNamespaceVariable
then result = v
else result = e.getEnclosingVariable()
)
}
Variable getEnclosingVariable(Expr e) {
result = getEnclosingVariable0(e)
or
not exists(getEnclosingVariable0(e)) and
result = e.getEnclosingVariable()
}
/**
* The IR translation of the "core" part of an expression. This is the part of
* the expression that produces the result value of the expression, before any
@@ -885,21 +843,10 @@ class TranslatedNonFieldVariableAccess extends TranslatedVariableAccess {
override IRVariable getInstructionVariable(InstructionTag tag) {
tag = OnlyInstructionTag() and
exists(Declaration d, Variable v |
accessHasEnclosingDeclarationAndVariable(d, v, expr) and
result = getIRUserVariable(d, v)
)
result = getIRUserVariable(expr.getEnclosingDeclaration(), expr.getTarget())
}
}
pragma[nomagic]
private predicate accessHasEnclosingDeclarationAndVariable(
Declaration d, Variable v, VariableAccess va
) {
d = getEnclosingDeclaration(va) and
v = va.getTarget()
}
class TranslatedFieldAccess extends TranslatedVariableAccess {
override FieldAccess expr;
@@ -2053,7 +2000,7 @@ class TranslatedDestructorFieldDestruction extends TranslatedNonConstantExpr, St
final override Instruction getInstructionRegisterOperand(InstructionTag tag, OperandTag operandTag) {
tag = OnlyInstructionTag() and
operandTag instanceof UnaryOperandTag and
result = getTranslatedFunction(getEnclosingFunction(expr)).getInitializeThisInstruction()
result = getTranslatedFunction(expr.getEnclosingFunction()).getInitializeThisInstruction()
}
final override Field getInstructionField(InstructionTag tag) {

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 = this.getAst() }
deprecated override Locatable getAST() { result = 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 = this.getReadEffects()
id = -5 and result = getReadEffects()
or
id = -4 and result = this.getConstructorInitList()
id = -4 and result = getConstructorInitList()
or
id = -3 and result = this.getBody()
id = -3 and result = getBody()
or
id = -2 and result = this.getDestructorDestructionList()
id = -2 and result = getDestructorDestructionList()
or
id >= -1 and result = this.getParameter(id)
id >= -1 and result = getParameter(id)
}
final private TranslatedConstructorInitList getConstructorInitList() {
@@ -109,66 +109,64 @@ class TranslatedFunction extends TranslatedRootElement, TTranslatedFunction {
result = getTranslatedEllipsisParameter(func)
}
final override Instruction getFirstInstruction() {
result = this.getInstruction(EnterFunctionTag())
}
final override Instruction getFirstInstruction() { result = getInstruction(EnterFunctionTag()) }
final override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) {
kind instanceof GotoEdge and
(
tag = EnterFunctionTag() and
result = this.getInstruction(AliasedDefinitionTag())
result = getInstruction(AliasedDefinitionTag())
or
tag = AliasedDefinitionTag() and
result = this.getInstruction(InitializeNonLocalTag())
result = getInstruction(InitializeNonLocalTag())
or
(
tag = InitializeNonLocalTag() and
if exists(this.getThisType())
then result = this.getParameter(-1).getFirstInstruction()
if exists(getThisType())
then result = getParameter(-1).getFirstInstruction()
else
if exists(this.getParameter(0))
then result = this.getParameter(0).getFirstInstruction()
else result = this.getBody().getFirstInstruction()
if exists(getParameter(0))
then result = getParameter(0).getFirstInstruction()
else result = getBody().getFirstInstruction()
)
or
tag = ReturnValueAddressTag() and
result = this.getInstruction(ReturnTag())
result = getInstruction(ReturnTag())
or
tag = ReturnTag() and
result = this.getInstruction(AliasedUseTag())
result = getInstruction(AliasedUseTag())
or
tag = UnwindTag() and
result = this.getInstruction(AliasedUseTag())
result = getInstruction(AliasedUseTag())
or
tag = AliasedUseTag() and
result = this.getInstruction(ExitFunctionTag())
result = getInstruction(ExitFunctionTag())
)
}
final override Instruction getChildSuccessor(TranslatedElement child) {
exists(int paramIndex |
child = this.getParameter(paramIndex) and
child = getParameter(paramIndex) and
if
exists(func.getParameter(paramIndex + 1)) or
getEllipsisParameterIndexForFunction(func) = paramIndex + 1
then result = this.getParameter(paramIndex + 1).getFirstInstruction()
else result = this.getConstructorInitList().getFirstInstruction()
then result = getParameter(paramIndex + 1).getFirstInstruction()
else result = getConstructorInitList().getFirstInstruction()
)
or
child = this.getConstructorInitList() and
result = this.getBody().getFirstInstruction()
child = getConstructorInitList() and
result = getBody().getFirstInstruction()
or
child = this.getBody() and
result = this.getReturnSuccessorInstruction()
child = getBody() and
result = getReturnSuccessorInstruction()
or
child = this.getDestructorDestructionList() and
result = this.getReadEffects().getFirstInstruction()
child = getDestructorDestructionList() and
result = getReadEffects().getFirstInstruction()
or
child = this.getReadEffects() and
if this.hasReturnValue()
then result = this.getInstruction(ReturnValueAddressTag())
else result = this.getInstruction(ReturnTag())
child = getReadEffects() and
if hasReturnValue()
then result = getInstruction(ReturnValueAddressTag())
else result = getInstruction(ReturnTag())
}
final override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) {
@@ -187,13 +185,13 @@ class TranslatedFunction extends TranslatedRootElement, TTranslatedFunction {
or
tag = ReturnValueAddressTag() and
opcode instanceof Opcode::VariableAddress and
resultType = getTypeForGLValue(this.getReturnType()) and
this.hasReturnValue()
resultType = getTypeForGLValue(getReturnType()) and
hasReturnValue()
or
(
tag = ReturnTag() and
resultType = getVoidType() and
if this.hasReturnValue()
if hasReturnValue()
then opcode instanceof Opcode::ReturnValue
else opcode instanceof Opcode::ReturnVoid
)
@@ -219,23 +217,23 @@ class TranslatedFunction extends TranslatedRootElement, TTranslatedFunction {
}
final override Instruction getExceptionSuccessorInstruction() {
result = this.getInstruction(UnwindTag())
result = getInstruction(UnwindTag())
}
final override Instruction getInstructionRegisterOperand(InstructionTag tag, OperandTag operandTag) {
tag = ReturnTag() and
this.hasReturnValue() and
hasReturnValue() and
operandTag instanceof AddressOperandTag and
result = this.getInstruction(ReturnValueAddressTag())
result = getInstruction(ReturnValueAddressTag())
}
final override CppType getInstructionMemoryOperandType(
InstructionTag tag, TypedOperandTag operandTag
) {
tag = ReturnTag() and
this.hasReturnValue() and
hasReturnValue() and
operandTag instanceof LoadOperandTag and
result = getTypeForPRValue(this.getReturnType())
result = getTypeForPRValue(getReturnType())
or
tag = AliasedUseTag() and
operandTag instanceof SideEffectOperandTag and
@@ -244,7 +242,7 @@ class TranslatedFunction extends TranslatedRootElement, TTranslatedFunction {
final override IRVariable getInstructionVariable(InstructionTag tag) {
tag = ReturnValueAddressTag() and
result = this.getReturnVariable()
result = getReturnVariable()
}
final override predicate needsUnknownOpaqueType(int byteSize) {
@@ -253,15 +251,15 @@ class TranslatedFunction extends TranslatedRootElement, TTranslatedFunction {
final override predicate hasTempVariable(TempVariableTag tag, CppType type) {
tag = ReturnValueTempVar() and
this.hasReturnValue() and
type = getTypeForPRValue(this.getReturnType())
hasReturnValue() and
type = getTypeForPRValue(getReturnType())
or
tag = EllipsisTempVar() and
func.isVarargs() and
type = getEllipsisVariablePRValueType()
or
tag = ThisTempVar() and
type = getTypeForGLValue(this.getThisType())
type = getTypeForGLValue(getThisType())
}
/**
@@ -269,7 +267,7 @@ class TranslatedFunction extends TranslatedRootElement, TTranslatedFunction {
* statement.
*/
final Instruction getReturnSuccessorInstruction() {
result = this.getDestructorDestructionList().getFirstInstruction()
result = getDestructorDestructionList().getFirstInstruction()
}
/**
@@ -324,13 +322,11 @@ class TranslatedFunction extends TranslatedRootElement, TTranslatedFunction {
(
var instanceof GlobalOrNamespaceVariable
or
var instanceof StaticLocalVariable
or
var instanceof MemberVariable and not var instanceof Field
) and
exists(VariableAccess access |
access.getTarget() = var and
getEnclosingFunction(access) = func
access.getEnclosingFunction() = func
)
or
var.(LocalScopeVariable).getFunction() = func
@@ -370,25 +366,25 @@ abstract class TranslatedParameter extends TranslatedElement {
final override TranslatedElement getChild(int id) { none() }
final override Instruction getFirstInstruction() {
result = this.getInstruction(InitializerVariableAddressTag())
result = getInstruction(InitializerVariableAddressTag())
}
final override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) {
kind instanceof GotoEdge and
(
tag = InitializerVariableAddressTag() and
result = this.getInstruction(InitializerStoreTag())
result = getInstruction(InitializerStoreTag())
or
tag = InitializerStoreTag() and
if this.hasIndirection()
then result = this.getInstruction(InitializerIndirectAddressTag())
else result = this.getParent().getChildSuccessor(this)
if hasIndirection()
then result = getInstruction(InitializerIndirectAddressTag())
else result = getParent().getChildSuccessor(this)
or
tag = InitializerIndirectAddressTag() and
result = this.getInstruction(InitializerIndirectStoreTag())
result = getInstruction(InitializerIndirectStoreTag())
or
tag = InitializerIndirectStoreTag() and
result = this.getParent().getChildSuccessor(this)
result = getParent().getChildSuccessor(this)
)
}
@@ -397,21 +393,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 = this.getGLValueType()
resultType = getGLValueType()
or
tag = InitializerStoreTag() and
opcode instanceof Opcode::InitializeParameter and
resultType = this.getPRValueType()
resultType = getPRValueType()
or
this.hasIndirection() and
hasIndirection() and
tag = InitializerIndirectAddressTag() and
opcode instanceof Opcode::Load and
resultType = this.getPRValueType()
resultType = getPRValueType()
or
this.hasIndirection() and
hasIndirection() and
tag = InitializerIndirectStoreTag() and
opcode instanceof Opcode::InitializeIndirection and
resultType = this.getInitializationResultType()
resultType = getInitializationResultType()
}
final override IRVariable getInstructionVariable(InstructionTag tag) {
@@ -420,26 +416,26 @@ abstract class TranslatedParameter extends TranslatedElement {
tag = InitializerVariableAddressTag() or
tag = InitializerIndirectStoreTag()
) and
result = this.getIRVariable()
result = getIRVariable()
}
final override Instruction getInstructionRegisterOperand(InstructionTag tag, OperandTag operandTag) {
tag = InitializerStoreTag() and
(
operandTag instanceof AddressOperandTag and
result = this.getInstruction(InitializerVariableAddressTag())
result = 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 = this.getInstruction(InitializerVariableAddressTag())
result = getInstruction(InitializerVariableAddressTag())
)
or
tag = InitializerIndirectStoreTag() and
operandTag instanceof AddressOperandTag and
result = this.getInstruction(InitializerIndirectAddressTag())
result = getInstruction(InitializerIndirectAddressTag())
}
abstract predicate hasIndirection();
@@ -467,7 +463,7 @@ class TranslatedThisParameter extends TranslatedParameter, TTranslatedThisParame
final override Locatable getAst() { result = func }
/** DEPRECATED: Alias for getAst */
deprecated override Locatable getAST() { result = this.getAst() }
deprecated override Locatable getAST() { result = getAst() }
final override Function getFunction() { result = func }
@@ -502,7 +498,7 @@ class TranslatedPositionalParameter extends TranslatedParameter, TTranslatedPara
final override Locatable getAst() { result = param }
/** DEPRECATED: Alias for getAst */
deprecated override Locatable getAST() { result = this.getAst() }
deprecated override Locatable getAST() { result = getAst() }
final override Function getFunction() {
result = param.getFunction() or
@@ -524,7 +520,7 @@ class TranslatedPositionalParameter extends TranslatedParameter, TTranslatedPara
final override CppType getInitializationResultType() { result = getUnknownType() }
final override IRAutomaticUserVariable getIRVariable() {
result = getIRUserVariable(this.getFunction(), param)
result = getIRUserVariable(getFunction(), param)
}
}
@@ -542,7 +538,7 @@ class TranslatedEllipsisParameter extends TranslatedParameter, TTranslatedEllips
final override Locatable getAst() { result = func }
/** DEPRECATED: Alias for getAst */
deprecated override Locatable getAST() { result = this.getAst() }
deprecated override Locatable getAST() { result = getAst() }
final override Function getFunction() { result = func }
@@ -581,7 +577,7 @@ class TranslatedConstructorInitList extends TranslatedElement, InitializationCon
override Locatable getAst() { result = func }
/** DEPRECATED: Alias for getAst */
deprecated override Locatable getAST() { result = this.getAst() }
deprecated override Locatable getAST() { result = getAst() }
override TranslatedElement getChild(int id) {
exists(ConstructorFieldInit fieldInit |
@@ -601,9 +597,9 @@ class TranslatedConstructorInitList extends TranslatedElement, InitializationCon
}
override Instruction getFirstInstruction() {
if exists(this.getChild(0))
then result = this.getChild(0).getFirstInstruction()
else result = this.getParent().getChildSuccessor(this)
if exists(getChild(0))
then result = getChild(0).getFirstInstruction()
else result = getParent().getChildSuccessor(this)
}
override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) {
@@ -616,10 +612,10 @@ class TranslatedConstructorInitList extends TranslatedElement, InitializationCon
override Instruction getChildSuccessor(TranslatedElement child) {
exists(int id |
child = this.getChild(id) and
if exists(this.getChild(id + 1))
then result = this.getChild(id + 1).getFirstInstruction()
else result = this.getParent().getChildSuccessor(this)
child = getChild(id) and
if exists(getChild(id + 1))
then result = getChild(id + 1).getFirstInstruction()
else result = getParent().getChildSuccessor(this)
)
}
@@ -653,7 +649,7 @@ class TranslatedDestructorDestructionList extends TranslatedElement,
override Locatable getAst() { result = func }
/** DEPRECATED: Alias for getAst */
deprecated override Locatable getAST() { result = this.getAst() }
deprecated override Locatable getAST() { result = getAst() }
override TranslatedElement getChild(int id) {
exists(DestructorFieldDestruction fieldDestruction |
@@ -668,9 +664,9 @@ class TranslatedDestructorDestructionList extends TranslatedElement,
}
override Instruction getFirstInstruction() {
if exists(this.getChild(0))
then result = this.getChild(0).getFirstInstruction()
else result = this.getParent().getChildSuccessor(this)
if exists(getChild(0))
then result = getChild(0).getFirstInstruction()
else result = getParent().getChildSuccessor(this)
}
override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) {
@@ -683,10 +679,10 @@ class TranslatedDestructorDestructionList extends TranslatedElement,
override Instruction getChildSuccessor(TranslatedElement child) {
exists(int id |
child = this.getChild(id) and
if exists(this.getChild(id + 1))
then result = this.getChild(id + 1).getFirstInstruction()
else result = this.getParent().getChildSuccessor(this)
child = getChild(id) and
if exists(getChild(id + 1))
then result = getChild(id + 1).getFirstInstruction()
else result = getParent().getChildSuccessor(this)
)
}
}
@@ -701,7 +697,7 @@ class TranslatedReadEffects extends TranslatedElement, TTranslatedReadEffects {
override Locatable getAst() { result = func }
/** DEPRECATED: Alias for getAst */
deprecated override Locatable getAST() { result = this.getAst() }
deprecated override Locatable getAST() { result = getAst() }
override Function getFunction() { result = func }
@@ -715,25 +711,25 @@ class TranslatedReadEffects extends TranslatedElement, TTranslatedReadEffects {
}
override Instruction getFirstInstruction() {
if exists(this.getAChild())
if exists(getAChild())
then
result =
min(TranslatedElement child, int id | child = this.getChild(id) | child order by id)
min(TranslatedElement child, int id | child = getChild(id) | child order by id)
.getFirstInstruction()
else result = this.getParent().getChildSuccessor(this)
else result = getParent().getChildSuccessor(this)
}
override Instruction getChildSuccessor(TranslatedElement child) {
exists(int id | child = this.getChild(id) |
if exists(TranslatedReadEffect child2, int id2 | id2 > id and child2 = this.getChild(id2))
exists(int id | child = getChild(id) |
if exists(TranslatedReadEffect child2, int id2 | id2 > id and child2 = getChild(id2))
then
result =
min(TranslatedReadEffect child2, int id2 |
child2 = this.getChild(id2) and id2 > id
child2 = getChild(id2) and id2 > id
|
child2 order by id2
).getFirstInstruction()
else result = this.getParent().getChildSuccessor(this)
else result = getParent().getChildSuccessor(this)
)
}
@@ -760,10 +756,10 @@ abstract class TranslatedReadEffect extends TranslatedElement {
override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) {
tag = OnlyInstructionTag() and
kind = EdgeKind::gotoEdge() and
result = this.getParent().getChildSuccessor(this)
result = getParent().getChildSuccessor(this)
}
override Instruction getFirstInstruction() { result = this.getInstruction(OnlyInstructionTag()) }
override Instruction getFirstInstruction() { result = getInstruction(OnlyInstructionTag()) }
override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) {
opcode instanceof Opcode::ReturnIndirection and
@@ -788,7 +784,7 @@ class TranslatedThisReadEffect extends TranslatedReadEffect, TTranslatedThisRead
override Locatable getAst() { result = func }
/** DEPRECATED: Alias for getAst */
deprecated override Locatable getAST() { result = this.getAst() }
deprecated override Locatable getAST() { result = getAst() }
override Function getFunction() { result = func }
@@ -814,7 +810,7 @@ class TranslatedParameterReadEffect extends TranslatedReadEffect, TTranslatedPar
override Locatable getAst() { result = param }
/** DEPRECATED: Alias for getAst */
deprecated override Locatable getAST() { result = this.getAst() }
deprecated override Locatable getAST() { result = getAst() }
override string toString() { result = "read effect: " + param.toString() }
@@ -828,6 +824,6 @@ class TranslatedParameterReadEffect extends TranslatedReadEffect, TTranslatedPar
final override IRVariable getInstructionVariable(InstructionTag tag) {
tag = OnlyInstructionTag() and
result = getIRUserVariable(this.getFunction(), param)
result = getIRUserVariable(getFunction(), param)
}
}

View File

@@ -1,5 +1,4 @@
import semmle.code.cpp.ir.implementation.raw.internal.TranslatedElement
private import TranslatedExpr
private import cpp
private import semmle.code.cpp.ir.implementation.IRType
private import semmle.code.cpp.ir.implementation.Opcode
@@ -9,16 +8,16 @@ private import TranslatedInitialization
private import InstructionTag
private import semmle.code.cpp.ir.internal.IRUtilities
class TranslatedStaticStorageDurationVarInit extends TranslatedRootElement,
TTranslatedStaticStorageDurationVarInit, InitializationContext
class TranslatedGlobalOrNamespaceVarInit extends TranslatedRootElement,
TTranslatedGlobalOrNamespaceVarInit, InitializationContext
{
Variable var;
GlobalOrNamespaceVariable var;
TranslatedStaticStorageDurationVarInit() { this = TTranslatedStaticStorageDurationVarInit(var) }
TranslatedGlobalOrNamespaceVarInit() { this = TTranslatedGlobalOrNamespaceVarInit(var) }
override string toString() { result = var.toString() }
final override Variable getAst() { result = var }
final override GlobalOrNamespaceVariable getAst() { result = var }
final override Declaration getFunction() { result = var }
@@ -112,13 +111,11 @@ class TranslatedStaticStorageDurationVarInit extends TranslatedRootElement,
(
varUsed instanceof GlobalOrNamespaceVariable
or
varUsed instanceof StaticLocalVariable
or
varUsed instanceof MemberVariable and not varUsed instanceof Field
) and
exists(VariableAccess access |
access.getTarget() = varUsed and
getEnclosingVariable(access) = var
access.getEnclosingVariable() = var
)
or
var = varUsed
@@ -131,4 +128,6 @@ class TranslatedStaticStorageDurationVarInit extends TranslatedRootElement,
}
}
TranslatedStaticStorageDurationVarInit getTranslatedVarInit(Variable var) { result.getAst() = var }
TranslatedGlobalOrNamespaceVarInit getTranslatedVarInit(GlobalOrNamespaceVariable var) {
result.getAst() = var
}

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 = this.getInitialization() }
final override TranslatedElement getChild(int id) { id = 0 and result = getInitialization() }
final override Instruction getFirstInstruction() {
result = this.getInstruction(InitializerVariableAddressTag())
result = getInstruction(InitializerVariableAddressTag())
}
override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) {
tag = InitializerVariableAddressTag() and
opcode instanceof Opcode::VariableAddress and
resultType = getTypeForGLValue(this.getTargetType())
resultType = getTypeForGLValue(getTargetType())
or
this.hasUninitializedInstruction() and
hasUninitializedInstruction() and
tag = InitializerStoreTag() and
opcode instanceof Opcode::Uninitialized and
resultType = getTypeForPRValue(this.getTargetType())
resultType = getTypeForPRValue(getTargetType())
}
override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) {
(
tag = InitializerVariableAddressTag() and
kind instanceof GotoEdge and
if this.hasUninitializedInstruction()
then result = this.getInstruction(InitializerStoreTag())
else result = this.getInitialization().getFirstInstruction()
if hasUninitializedInstruction()
then result = getInstruction(InitializerStoreTag())
else result = getInitialization().getFirstInstruction()
)
or
this.hasUninitializedInstruction() and
hasUninitializedInstruction() and
kind instanceof GotoEdge and
tag = InitializerStoreTag() and
(
result = this.getInitialization().getFirstInstruction()
result = getInitialization().getFirstInstruction()
or
not exists(this.getInitialization()) and result = this.getInitializationSuccessor()
not exists(getInitialization()) and result = getInitializationSuccessor()
)
}
final override Instruction getChildSuccessor(TranslatedElement child) {
child = this.getInitialization() and result = this.getInitializationSuccessor()
child = getInitialization() and result = getInitializationSuccessor()
}
override Instruction getInstructionRegisterOperand(InstructionTag tag, OperandTag operandTag) {
this.hasUninitializedInstruction() and
hasUninitializedInstruction() and
tag = InitializerStoreTag() and
operandTag instanceof AddressOperandTag and
result = this.getInstruction(InitializerVariableAddressTag())
result = getInstruction(InitializerVariableAddressTag())
}
final override IRVariable getInstructionVariable(InstructionTag tag) {
(
tag = InitializerVariableAddressTag()
or
this.hasUninitializedInstruction() and tag = InitializerStoreTag()
hasUninitializedInstruction() and tag = InitializerStoreTag()
) and
result = this.getIRVariable()
result = getIRVariable()
}
final override Instruction getTargetAddress() {
result = this.getInstruction(InitializerVariableAddressTag())
result = getInstruction(InitializerVariableAddressTag())
}
/**
@@ -116,13 +116,13 @@ abstract class TranslatedVariableInitialization extends TranslatedElement, Initi
*/
final predicate hasUninitializedInstruction() {
(
not exists(this.getInitialization()) or
this.getInitialization() instanceof TranslatedListInitialization or
this.getInitialization() instanceof TranslatedConstructorInitialization or
this.getInitialization().(TranslatedStringLiteralInitialization).zeroInitRange(_, _)
not exists(getInitialization()) or
getInitialization() instanceof TranslatedListInitialization or
getInitialization() instanceof TranslatedConstructorInitialization or
getInitialization().(TranslatedStringLiteralInitialization).zeroInitRange(_, _)
) and
// Variables with static or thread-local storage duration are zero-initialized at program startup.
this.getIRVariable() instanceof IRAutomaticVariable
getIRVariable() instanceof IRAutomaticVariable
}
}
@@ -138,15 +138,14 @@ abstract class TranslatedInitialization extends TranslatedElement, TTranslatedIn
final override string toString() { result = "init: " + expr.toString() }
final override Declaration getFunction() {
result = getEnclosingFunction(expr) or
result = getEnclosingVariable(expr).(GlobalOrNamespaceVariable) or
result = getEnclosingVariable(expr).(StaticInitializedStaticLocalVariable)
result = expr.getEnclosingFunction() or
result = expr.getEnclosingVariable().(GlobalOrNamespaceVariable)
}
final override Locatable getAst() { result = expr }
/** DEPRECATED: Alias for getAst */
deprecated override Locatable getAST() { result = this.getAst() }
deprecated override Locatable getAST() { result = getAst() }
/**
* Gets the expression that is doing the initialization.
@@ -157,10 +156,10 @@ abstract class TranslatedInitialization extends TranslatedElement, TTranslatedIn
* Gets the initialization context that describes the location being
* initialized.
*/
final InitializationContext getContext() { result = this.getParent() }
final InitializationContext getContext() { result = getParent() }
final TranslatedFunction getEnclosingFunction() {
result = getTranslatedFunction(this.getFunction())
result = getTranslatedFunction(expr.getEnclosingFunction())
}
}
@@ -169,17 +168,17 @@ abstract class TranslatedInitialization extends TranslatedElement, TTranslatedIn
*/
abstract class TranslatedListInitialization extends TranslatedInitialization, InitializationContext {
override Instruction getFirstInstruction() {
result = this.getChild(0).getFirstInstruction()
result = getChild(0).getFirstInstruction()
or
not exists(this.getChild(0)) and result = this.getParent().getChildSuccessor(this)
not exists(getChild(0)) and result = getParent().getChildSuccessor(this)
}
override Instruction getChildSuccessor(TranslatedElement child) {
exists(int index |
child = this.getChild(index) and
if exists(this.getChild(index + 1))
then result = this.getChild(index + 1).getFirstInstruction()
else result = this.getParent().getChildSuccessor(this)
child = getChild(index) and
if exists(getChild(index + 1))
then result = getChild(index + 1).getFirstInstruction()
else result = getParent().getChildSuccessor(this)
)
}
@@ -189,9 +188,9 @@ abstract class TranslatedListInitialization extends TranslatedInitialization, In
final override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) { none() }
override Instruction getTargetAddress() { result = this.getContext().getTargetAddress() }
override Instruction getTargetAddress() { result = getContext().getTargetAddress() }
override Type getTargetType() { result = this.getContext().getTargetType() }
override Type getTargetType() { result = getContext().getTargetType() }
}
/**
@@ -237,11 +236,9 @@ class TranslatedArrayListInitialization extends TranslatedListInitialization {
abstract class TranslatedDirectInitialization extends TranslatedInitialization {
TranslatedDirectInitialization() { not expr instanceof AggregateLiteral }
override TranslatedElement getChild(int id) { id = 0 and result = this.getInitializer() }
override TranslatedElement getChild(int id) { id = 0 and result = getInitializer() }
override Instruction getFirstInstruction() {
result = this.getInitializer().getFirstInstruction()
}
override Instruction getFirstInstruction() { result = getInitializer().getFirstInstruction() }
final TranslatedExpr getInitializer() { result = getTranslatedExpr(expr) }
}
@@ -260,27 +257,27 @@ class TranslatedSimpleDirectInitialization extends TranslatedDirectInitializatio
override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) {
tag = InitializerStoreTag() and
opcode instanceof Opcode::Store and
resultType = getTypeForPRValue(this.getContext().getTargetType())
resultType = getTypeForPRValue(getContext().getTargetType())
}
override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) {
tag = InitializerStoreTag() and
result = this.getParent().getChildSuccessor(this) and
result = getParent().getChildSuccessor(this) and
kind instanceof GotoEdge
}
override Instruction getChildSuccessor(TranslatedElement child) {
child = this.getInitializer() and result = this.getInstruction(InitializerStoreTag())
child = getInitializer() and result = getInstruction(InitializerStoreTag())
}
override Instruction getInstructionRegisterOperand(InstructionTag tag, OperandTag operandTag) {
tag = InitializerStoreTag() and
(
operandTag instanceof AddressOperandTag and
result = this.getContext().getTargetAddress()
result = getContext().getTargetAddress()
or
operandTag instanceof StoreValueOperandTag and
result = this.getInitializer().getResult()
result = getInitializer().getResult()
)
}
}
@@ -307,13 +304,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.
this.zeroInitRange(_, elementCount) and
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 * this.getElementType().getSize())
resultType = getUnknownOpaqueType(elementCount * getElementType().getSize())
or
// The index of the first element to be zero initialized.
tag = ZeroPadStringElementIndexTag() and
@@ -323,12 +320,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(this.getElementType())
resultType = getTypeForGLValue(getElementType())
or
// Store the constant zero into the remainder of the string.
tag = ZeroPadStringStoreTag() and
opcode instanceof Opcode::Store and
resultType = getUnknownOpaqueType(elementCount * this.getElementType().getSize())
resultType = getUnknownOpaqueType(elementCount * getElementType().getSize())
)
)
}
@@ -337,78 +334,78 @@ class TranslatedStringLiteralInitialization extends TranslatedDirectInitializati
kind instanceof GotoEdge and
(
tag = InitializerLoadStringTag() and
result = this.getInstruction(InitializerStoreTag())
result = getInstruction(InitializerStoreTag())
or
if this.zeroInitRange(_, _)
if zeroInitRange(_, _)
then (
tag = InitializerStoreTag() and
result = this.getInstruction(ZeroPadStringConstantTag())
result = getInstruction(ZeroPadStringConstantTag())
or
tag = ZeroPadStringConstantTag() and
result = this.getInstruction(ZeroPadStringElementIndexTag())
result = getInstruction(ZeroPadStringElementIndexTag())
or
tag = ZeroPadStringElementIndexTag() and
result = this.getInstruction(ZeroPadStringElementAddressTag())
result = getInstruction(ZeroPadStringElementAddressTag())
or
tag = ZeroPadStringElementAddressTag() and
result = this.getInstruction(ZeroPadStringStoreTag())
result = getInstruction(ZeroPadStringStoreTag())
or
tag = ZeroPadStringStoreTag() and
result = this.getParent().getChildSuccessor(this)
result = getParent().getChildSuccessor(this)
) else (
tag = InitializerStoreTag() and
result = this.getParent().getChildSuccessor(this)
result = getParent().getChildSuccessor(this)
)
)
}
override Instruction getChildSuccessor(TranslatedElement child) {
child = this.getInitializer() and result = this.getInstruction(InitializerLoadStringTag())
child = getInitializer() and result = getInstruction(InitializerLoadStringTag())
}
override Instruction getInstructionRegisterOperand(InstructionTag tag, OperandTag operandTag) {
tag = InitializerLoadStringTag() and
(
operandTag instanceof AddressOperandTag and
result = this.getInitializer().getResult()
result = getInitializer().getResult()
)
or
tag = InitializerStoreTag() and
(
operandTag instanceof AddressOperandTag and
result = this.getContext().getTargetAddress()
result = getContext().getTargetAddress()
or
operandTag instanceof StoreValueOperandTag and
result = this.getInstruction(InitializerLoadStringTag())
result = getInstruction(InitializerLoadStringTag())
)
or
tag = ZeroPadStringElementAddressTag() and
(
operandTag instanceof LeftOperandTag and
result = this.getContext().getTargetAddress()
result = getContext().getTargetAddress()
or
operandTag instanceof RightOperandTag and
result = this.getInstruction(ZeroPadStringElementIndexTag())
result = getInstruction(ZeroPadStringElementIndexTag())
)
or
tag = ZeroPadStringStoreTag() and
(
operandTag instanceof AddressOperandTag and
result = this.getInstruction(ZeroPadStringElementAddressTag())
result = getInstruction(ZeroPadStringElementAddressTag())
or
operandTag instanceof StoreValueOperandTag and
result = this.getInstruction(ZeroPadStringConstantTag())
result = getInstruction(ZeroPadStringConstantTag())
)
}
override int getInstructionElementSize(InstructionTag tag) {
tag = ZeroPadStringElementAddressTag() and
result = max(this.getElementType().getSize())
result = max(getElementType().getSize())
}
override string getInstructionConstantValue(InstructionTag tag) {
exists(int startIndex |
this.zeroInitRange(startIndex, _) and
zeroInitRange(startIndex, _) and
(
tag = ZeroPadStringConstantTag() and
result = "0"
@@ -421,13 +418,13 @@ class TranslatedStringLiteralInitialization extends TranslatedDirectInitializati
override predicate needsUnknownOpaqueType(int byteSize) {
exists(int elementCount |
this.zeroInitRange(_, elementCount) and
byteSize = elementCount * this.getElementType().getSize()
zeroInitRange(_, elementCount) and
byteSize = elementCount * getElementType().getSize()
)
}
private Type getElementType() {
result = this.getContext().getTargetType().getUnspecifiedType().(ArrayType).getBaseType()
result = getContext().getTargetType().getUnspecifiedType().(ArrayType).getBaseType()
}
/**
@@ -437,8 +434,7 @@ class TranslatedStringLiteralInitialization extends TranslatedDirectInitializati
predicate zeroInitRange(int startIndex, int elementCount) {
exists(int targetCount |
startIndex = expr.getUnspecifiedType().(ArrayType).getArraySize() and
targetCount =
this.getContext().getTargetType().getUnspecifiedType().(ArrayType).getArraySize() and
targetCount = getContext().getTargetType().getUnspecifiedType().(ArrayType).getArraySize() and
elementCount = targetCount - startIndex and
elementCount > 0
)
@@ -457,14 +453,14 @@ class TranslatedConstructorInitialization extends TranslatedDirectInitialization
override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) { none() }
override Instruction getChildSuccessor(TranslatedElement child) {
child = this.getInitializer() and result = this.getParent().getChildSuccessor(this)
child = getInitializer() and result = getParent().getChildSuccessor(this)
}
override Instruction getInstructionRegisterOperand(InstructionTag tag, OperandTag operandTag) {
none()
}
override Instruction getReceiver() { result = this.getContext().getTargetAddress() }
override Instruction getReceiver() { result = getContext().getTargetAddress() }
}
/**
@@ -494,17 +490,14 @@ abstract class TranslatedFieldInitialization extends TranslatedElement {
final override Locatable getAst() { result = ast }
/** DEPRECATED: Alias for getAst */
deprecated override Locatable getAST() { result = this.getAst() }
deprecated override Locatable getAST() { result = getAst() }
final override Declaration getFunction() {
result = getEnclosingFunction(ast) or
result = getEnclosingVariable(ast).(GlobalOrNamespaceVariable) or
result = getEnclosingVariable(ast).(StaticInitializedStaticLocalVariable)
result = ast.getEnclosingFunction() or
result = ast.getEnclosingVariable().(GlobalOrNamespaceVariable)
}
final override Instruction getFirstInstruction() {
result = this.getInstruction(this.getFieldAddressTag())
}
final override Instruction getFirstInstruction() { result = getInstruction(getFieldAddressTag()) }
/**
* Gets the zero-based index describing the order in which this field is to be
@@ -513,19 +506,19 @@ abstract class TranslatedFieldInitialization extends TranslatedElement {
final int getOrder() { result = field.getInitializationOrder() }
override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) {
tag = this.getFieldAddressTag() and
tag = getFieldAddressTag() and
opcode instanceof Opcode::FieldAddress and
resultType = getTypeForGLValue(field.getType())
}
override Instruction getInstructionRegisterOperand(InstructionTag tag, OperandTag operandTag) {
tag = this.getFieldAddressTag() and
tag = getFieldAddressTag() and
operandTag instanceof UnaryOperandTag and
result = this.getParent().(InitializationContext).getTargetAddress()
result = getParent().(InitializationContext).getTargetAddress()
}
override Field getInstructionField(InstructionTag tag) {
tag = this.getFieldAddressTag() and result = field
tag = getFieldAddressTag() and result = field
}
final InstructionTag getFieldAddressTag() { result = InitializerFieldAddressTag() }
@@ -550,23 +543,21 @@ class TranslatedExplicitFieldInitialization extends TranslatedFieldInitializatio
this = TTranslatedExplicitFieldInitialization(ast, field, expr, position)
}
override Instruction getTargetAddress() {
result = this.getInstruction(this.getFieldAddressTag())
}
override Instruction getTargetAddress() { result = getInstruction(getFieldAddressTag()) }
override Type getTargetType() { result = field.getUnspecifiedType() }
override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) {
tag = this.getFieldAddressTag() and
result = this.getInitialization().getFirstInstruction() and
tag = getFieldAddressTag() and
result = getInitialization().getFirstInstruction() and
kind instanceof GotoEdge
}
override Instruction getChildSuccessor(TranslatedElement child) {
child = this.getInitialization() and result = this.getParent().getChildSuccessor(this)
child = getInitialization() and result = getParent().getChildSuccessor(this)
}
override TranslatedElement getChild(int id) { id = 0 and result = this.getInitialization() }
override TranslatedElement getChild(int id) { id = 0 and result = getInitialization() }
private TranslatedInitialization getInitialization() {
result = getTranslatedInitialization(expr)
@@ -591,11 +582,11 @@ class TranslatedFieldValueInitialization extends TranslatedFieldInitialization,
override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) {
TranslatedFieldInitialization.super.hasInstruction(opcode, tag, resultType)
or
tag = this.getFieldDefaultValueTag() and
tag = getFieldDefaultValueTag() and
opcode instanceof Opcode::Constant and
resultType = getTypeForPRValue(field.getType())
or
tag = this.getFieldDefaultValueStoreTag() and
tag = getFieldDefaultValueStoreTag() and
opcode instanceof Opcode::Store and
resultType = getTypeForPRValue(field.getUnspecifiedType())
}
@@ -603,32 +594,32 @@ class TranslatedFieldValueInitialization extends TranslatedFieldInitialization,
override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) {
kind instanceof GotoEdge and
(
tag = this.getFieldAddressTag() and
result = this.getInstruction(this.getFieldDefaultValueTag())
tag = getFieldAddressTag() and
result = getInstruction(getFieldDefaultValueTag())
or
tag = this.getFieldDefaultValueTag() and
result = this.getInstruction(this.getFieldDefaultValueStoreTag())
tag = getFieldDefaultValueTag() and
result = getInstruction(getFieldDefaultValueStoreTag())
or
tag = this.getFieldDefaultValueStoreTag() and
result = this.getParent().getChildSuccessor(this)
tag = getFieldDefaultValueStoreTag() and
result = getParent().getChildSuccessor(this)
)
}
override string getInstructionConstantValue(InstructionTag tag) {
tag = this.getFieldDefaultValueTag() and
tag = getFieldDefaultValueTag() and
result = getZeroValue(field.getUnspecifiedType())
}
override Instruction getInstructionRegisterOperand(InstructionTag tag, OperandTag operandTag) {
result = TranslatedFieldInitialization.super.getInstructionRegisterOperand(tag, operandTag)
or
tag = this.getFieldDefaultValueStoreTag() and
tag = getFieldDefaultValueStoreTag() and
(
operandTag instanceof AddressOperandTag and
result = this.getInstruction(this.getFieldAddressTag())
result = getInstruction(getFieldAddressTag())
or
operandTag instanceof StoreValueOperandTag and
result = this.getInstruction(this.getFieldDefaultValueTag())
result = getInstruction(getFieldDefaultValueTag())
)
}
@@ -651,61 +642,57 @@ abstract class TranslatedElementInitialization extends TranslatedElement {
ArrayOrVectorAggregateLiteral initList;
final override string toString() {
result = initList.toString() + "[" + this.getElementIndex().toString() + "]"
result = initList.toString() + "[" + getElementIndex().toString() + "]"
}
final override Locatable getAst() { result = initList }
/** DEPRECATED: Alias for getAst */
deprecated override Locatable getAST() { result = this.getAst() }
deprecated override Locatable getAST() { result = getAst() }
final override Declaration getFunction() {
result = getEnclosingFunction(initList)
result = initList.getEnclosingFunction()
or
result = getEnclosingVariable(initList).(GlobalOrNamespaceVariable)
or
result = getEnclosingVariable(initList).(StaticInitializedStaticLocalVariable)
result = initList.getEnclosingVariable().(GlobalOrNamespaceVariable)
}
final override Instruction getFirstInstruction() {
result = this.getInstruction(this.getElementIndexTag())
}
final override Instruction getFirstInstruction() { result = getInstruction(getElementIndexTag()) }
override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) {
tag = this.getElementIndexTag() and
tag = getElementIndexTag() and
opcode instanceof Opcode::Constant and
resultType = getIntType()
or
tag = this.getElementAddressTag() and
tag = getElementAddressTag() and
opcode instanceof Opcode::PointerAdd and
resultType = getTypeForGLValue(this.getElementType())
resultType = getTypeForGLValue(getElementType())
}
override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) {
tag = this.getElementIndexTag() and
result = this.getInstruction(this.getElementAddressTag()) and
tag = getElementIndexTag() and
result = getInstruction(getElementAddressTag()) and
kind instanceof GotoEdge
}
override Instruction getInstructionRegisterOperand(InstructionTag tag, OperandTag operandTag) {
tag = this.getElementAddressTag() and
tag = getElementAddressTag() and
(
operandTag instanceof LeftOperandTag and
result = this.getParent().(InitializationContext).getTargetAddress()
result = getParent().(InitializationContext).getTargetAddress()
or
operandTag instanceof RightOperandTag and
result = this.getInstruction(this.getElementIndexTag())
result = getInstruction(getElementIndexTag())
)
}
override int getInstructionElementSize(InstructionTag tag) {
tag = this.getElementAddressTag() and
result = max(this.getElementType().getSize())
tag = getElementAddressTag() and
result = max(getElementType().getSize())
}
override string getInstructionConstantValue(InstructionTag tag) {
tag = this.getElementIndexTag() and
result = this.getElementIndex().toString()
tag = getElementIndexTag() and
result = getElementIndex().toString()
}
abstract int getElementIndex();
@@ -735,25 +722,23 @@ class TranslatedExplicitElementInitialization extends TranslatedElementInitializ
this = TTranslatedExplicitElementInitialization(initList, elementIndex, position)
}
override Instruction getTargetAddress() {
result = this.getInstruction(this.getElementAddressTag())
}
override Instruction getTargetAddress() { result = getInstruction(getElementAddressTag()) }
override Type getTargetType() { result = this.getElementType() }
override Type getTargetType() { result = getElementType() }
override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) {
result = TranslatedElementInitialization.super.getInstructionSuccessor(tag, kind)
or
tag = this.getElementAddressTag() and
result = this.getInitialization().getFirstInstruction() and
tag = getElementAddressTag() and
result = getInitialization().getFirstInstruction() and
kind instanceof GotoEdge
}
override Instruction getChildSuccessor(TranslatedElement child) {
child = this.getInitialization() and result = this.getParent().getChildSuccessor(this)
child = getInitialization() and result = getParent().getChildSuccessor(this)
}
override TranslatedElement getChild(int id) { id = 0 and result = this.getInitialization() }
override TranslatedElement getChild(int id) { id = 0 and result = getInitialization() }
override int getElementIndex() { result = elementIndex }
@@ -784,13 +769,13 @@ class TranslatedElementValueInitialization extends TranslatedElementInitializati
override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) {
TranslatedElementInitialization.super.hasInstruction(opcode, tag, resultType)
or
tag = this.getElementDefaultValueTag() and
tag = getElementDefaultValueTag() and
opcode instanceof Opcode::Constant and
resultType = this.getDefaultValueType()
resultType = getDefaultValueType()
or
tag = this.getElementDefaultValueStoreTag() and
tag = getElementDefaultValueStoreTag() and
opcode instanceof Opcode::Store and
resultType = this.getDefaultValueType()
resultType = getDefaultValueType()
}
override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) {
@@ -798,34 +783,34 @@ class TranslatedElementValueInitialization extends TranslatedElementInitializati
or
kind instanceof GotoEdge and
(
tag = this.getElementAddressTag() and
result = this.getInstruction(this.getElementDefaultValueTag())
tag = getElementAddressTag() and
result = getInstruction(getElementDefaultValueTag())
or
tag = this.getElementDefaultValueTag() and
result = this.getInstruction(this.getElementDefaultValueStoreTag())
tag = getElementDefaultValueTag() and
result = getInstruction(getElementDefaultValueStoreTag())
or
tag = this.getElementDefaultValueStoreTag() and
result = this.getParent().getChildSuccessor(this)
tag = getElementDefaultValueStoreTag() and
result = getParent().getChildSuccessor(this)
)
}
override string getInstructionConstantValue(InstructionTag tag) {
result = TranslatedElementInitialization.super.getInstructionConstantValue(tag)
or
tag = this.getElementDefaultValueTag() and
result = getZeroValue(this.getElementType())
tag = getElementDefaultValueTag() and
result = getZeroValue(getElementType())
}
override Instruction getInstructionRegisterOperand(InstructionTag tag, OperandTag operandTag) {
result = TranslatedElementInitialization.super.getInstructionRegisterOperand(tag, operandTag)
or
tag = this.getElementDefaultValueStoreTag() and
tag = getElementDefaultValueStoreTag() and
(
operandTag instanceof AddressOperandTag and
result = this.getInstruction(this.getElementAddressTag())
result = getInstruction(getElementAddressTag())
or
operandTag instanceof StoreValueOperandTag and
result = this.getInstruction(this.getElementDefaultValueTag())
result = getInstruction(getElementDefaultValueTag())
)
}
@@ -836,7 +821,7 @@ class TranslatedElementValueInitialization extends TranslatedElementInitializati
override int getElementIndex() { result = elementIndex }
override predicate needsUnknownOpaqueType(int byteSize) {
elementCount != 0 and byteSize = elementCount * this.getElementType().getSize()
elementCount != 0 and byteSize = elementCount * getElementType().getSize()
}
private InstructionTag getElementDefaultValueTag() {
@@ -849,8 +834,8 @@ class TranslatedElementValueInitialization extends TranslatedElementInitializati
private CppType getDefaultValueType() {
if elementCount = 1
then result = getTypeForPRValue(this.getElementType())
else result = getUnknownOpaqueType(elementCount * this.getElementType().getSize())
then result = getTypeForPRValue(getElementType())
else result = getUnknownOpaqueType(elementCount * getElementType().getSize())
}
}
@@ -860,18 +845,18 @@ abstract class TranslatedStructorCallFromStructor extends TranslatedElement, Str
final override Locatable getAst() { result = call }
/** DEPRECATED: Alias for getAst */
deprecated override Locatable getAST() { result = this.getAst() }
deprecated override Locatable getAST() { result = getAst() }
final override TranslatedElement getChild(int id) {
id = 0 and
result = this.getStructorCall()
result = getStructorCall()
}
final override Function getFunction() { result = getEnclosingFunction(call) }
final override Function getFunction() { result = call.getEnclosingFunction() }
final override Instruction getChildSuccessor(TranslatedElement child) {
child = this.getStructorCall() and
result = this.getParent().getChildSuccessor(this)
child = getStructorCall() and
result = getParent().getChildSuccessor(this)
}
final TranslatedExpr getStructorCall() { result = getTranslatedExpr(call) }
@@ -882,9 +867,7 @@ 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 = this.getInstruction(OnlyInstructionTag())
}
final override Instruction getFirstInstruction() { result = getInstruction(OnlyInstructionTag()) }
final override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) {
tag = OnlyInstructionTag() and
@@ -895,15 +878,15 @@ abstract class TranslatedBaseStructorCall extends TranslatedStructorCallFromStru
final override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) {
tag = OnlyInstructionTag() and
kind instanceof GotoEdge and
result = this.getStructorCall().getFirstInstruction()
result = getStructorCall().getFirstInstruction()
}
final override Instruction getReceiver() { result = this.getInstruction(OnlyInstructionTag()) }
final override Instruction getReceiver() { result = getInstruction(OnlyInstructionTag()) }
final override Instruction getInstructionRegisterOperand(InstructionTag tag, OperandTag operandTag) {
tag = OnlyInstructionTag() and
operandTag instanceof UnaryOperandTag and
result = getTranslatedFunction(this.getFunction()).getInitializeThisInstruction()
result = getTranslatedFunction(getFunction()).getInitializeThisInstruction()
}
final override predicate getInstructionInheritance(
@@ -911,7 +894,7 @@ abstract class TranslatedBaseStructorCall extends TranslatedStructorCallFromStru
) {
tag = OnlyInstructionTag() and
baseClass = call.getTarget().getDeclaringType().getUnspecifiedType() and
derivedClass = this.getFunction().getDeclaringType().getUnspecifiedType()
derivedClass = getFunction().getDeclaringType().getUnspecifiedType()
}
}
@@ -937,7 +920,7 @@ class TranslatedConstructorDelegationInit extends TranslatedConstructorCallFromC
final override string toString() { result = "delegation construct: " + call.toString() }
final override Instruction getFirstInstruction() {
result = this.getStructorCall().getFirstInstruction()
result = getStructorCall().getFirstInstruction()
}
final override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) {
@@ -947,7 +930,7 @@ class TranslatedConstructorDelegationInit extends TranslatedConstructorCallFromC
final override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) { none() }
final override Instruction getReceiver() {
result = getTranslatedFunction(this.getFunction()).getInitializeThisInstruction()
result = getTranslatedFunction(getFunction()).getInitializeThisInstruction()
}
}
@@ -994,11 +977,11 @@ class TranslatedConstructorBareInit extends TranslatedElement, TTranslatedConstr
override Locatable getAst() { result = init }
/** DEPRECATED: Alias for getAst */
deprecated override Locatable getAST() { result = this.getAst() }
deprecated override Locatable getAST() { result = getAst() }
final override string toString() { result = "construct base (no constructor)" }
override Instruction getFirstInstruction() { result = this.getParent().getChildSuccessor(this) }
override Instruction getFirstInstruction() { result = getParent().getChildSuccessor(this) }
override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) {
none()
@@ -1006,7 +989,7 @@ class TranslatedConstructorBareInit extends TranslatedElement, TTranslatedConstr
override TranslatedElement getChild(int id) { none() }
override Declaration getFunction() { result = this.getParent().getFunction() }
override Function getFunction() { result = getParent().getFunction() }
override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) { 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 = this.getAst() }
deprecated override Locatable getAST() { result = 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 = this.getInstruction(OnlyInstructionTag()) }
override Instruction getFirstInstruction() { result = 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 = this.getParent().getChildSuccessor(this) and
result = 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 = this.getDeclarationEntry(id) }
override TranslatedElement getChild(int id) { result = getDeclarationEntry(id) }
override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) {
none()
}
override Instruction getFirstInstruction() {
result = this.getDeclarationEntry(0).getFirstInstruction()
result = getDeclarationEntry(0).getFirstInstruction()
or
not exists(this.getDeclarationEntry(0)) and result = this.getParent().getChildSuccessor(this)
not exists(getDeclarationEntry(0)) and result = getParent().getChildSuccessor(this)
}
private int getChildCount() { result = count(this.getDeclarationEntry(_)) }
private int getChildCount() { result = count(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 = this.getDeclarationEntry(index) and
if index = (this.getChildCount() - 1)
then result = this.getParent().getChildSuccessor(this)
else result = this.getDeclarationEntry(index + 1).getFirstInstruction()
child = getDeclarationEntry(index) and
if index = (getChildCount() - 1)
then result = getParent().getChildSuccessor(this)
else result = 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 = this.getExpr() }
override TranslatedElement getChild(int id) { id = 0 and result = getExpr() }
override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) {
none()
}
override Instruction getFirstInstruction() { result = this.getExpr().getFirstInstruction() }
override Instruction getFirstInstruction() { result = getExpr().getFirstInstruction() }
override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) { none() }
override Instruction getChildSuccessor(TranslatedElement child) {
child = this.getExpr() and
result = this.getParent().getChildSuccessor(this)
child = getExpr() and
result = getParent().getChildSuccessor(this)
}
}
@@ -363,18 +363,16 @@ class TranslatedReturnValueStmt extends TranslatedReturnStmt, TranslatedVariable
TranslatedReturnValueStmt() { stmt.hasExpr() and hasReturnValue(stmt.getEnclosingFunction()) }
final override Instruction getInitializationSuccessor() {
result = this.getEnclosingFunction().getReturnSuccessorInstruction()
result = getEnclosingFunction().getReturnSuccessorInstruction()
}
final override Type getTargetType() { result = this.getEnclosingFunction().getReturnType() }
final override Type getTargetType() { result = getEnclosingFunction().getReturnType() }
final override TranslatedInitialization getInitialization() {
result = getTranslatedInitialization(stmt.getExpr().getFullyConverted())
}
final override IRVariable getIRVariable() {
result = this.getEnclosingFunction().getReturnVariable()
}
final override IRVariable getIRVariable() { result = getEnclosingFunction().getReturnVariable() }
}
/**
@@ -387,10 +385,10 @@ class TranslatedReturnVoidExpressionStmt extends TranslatedReturnStmt {
override TranslatedElement getChild(int id) {
id = 0 and
result = this.getExpr()
result = getExpr()
}
override Instruction getFirstInstruction() { result = this.getExpr().getFirstInstruction() }
override Instruction getFirstInstruction() { result = getExpr().getFirstInstruction() }
override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) {
tag = OnlyInstructionTag() and
@@ -400,13 +398,13 @@ class TranslatedReturnVoidExpressionStmt extends TranslatedReturnStmt {
override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) {
tag = OnlyInstructionTag() and
result = this.getEnclosingFunction().getReturnSuccessorInstruction() and
result = getEnclosingFunction().getReturnSuccessorInstruction() and
kind instanceof GotoEdge
}
override Instruction getChildSuccessor(TranslatedElement child) {
child = this.getExpr() and
result = this.getInstruction(OnlyInstructionTag())
child = getExpr() and
result = getInstruction(OnlyInstructionTag())
}
private TranslatedExpr getExpr() { result = getTranslatedExpr(stmt.getExpr()) }
@@ -423,7 +421,7 @@ class TranslatedReturnVoidStmt extends TranslatedReturnStmt {
override TranslatedElement getChild(int id) { none() }
override Instruction getFirstInstruction() { result = this.getInstruction(OnlyInstructionTag()) }
override Instruction getFirstInstruction() { result = getInstruction(OnlyInstructionTag()) }
override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) {
tag = OnlyInstructionTag() and
@@ -433,7 +431,7 @@ class TranslatedReturnVoidStmt extends TranslatedReturnStmt {
override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) {
tag = OnlyInstructionTag() and
result = this.getEnclosingFunction().getReturnSuccessorInstruction() and
result = getEnclosingFunction().getReturnSuccessorInstruction() and
kind instanceof GotoEdge
}
@@ -454,7 +452,7 @@ class TranslatedUnreachableReturnStmt extends TranslatedReturnStmt {
override TranslatedElement getChild(int id) { none() }
override Instruction getFirstInstruction() { result = this.getInstruction(OnlyInstructionTag()) }
override Instruction getFirstInstruction() { result = getInstruction(OnlyInstructionTag()) }
override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) {
tag = OnlyInstructionTag() and
@@ -513,9 +511,9 @@ class TranslatedTryStmt extends TranslatedStmt {
override TryOrMicrosoftTryStmt stmt;
override TranslatedElement getChild(int id) {
id = 0 and result = this.getBody()
id = 0 and result = getBody()
or
result = this.getHandler(id - 1)
result = getHandler(id - 1)
or
id = stmt.getNumberOfCatchClauses() + 1 and
result = this.getFinally()
@@ -527,7 +525,7 @@ class TranslatedTryStmt extends TranslatedStmt {
override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) { none() }
override Instruction getFirstInstruction() { result = this.getBody().getFirstInstruction() }
override Instruction getFirstInstruction() { result = getBody().getFirstInstruction() }
override Instruction getChildSuccessor(TranslatedElement child) {
// All non-finally children go to the successor of the `try` if
@@ -548,19 +546,19 @@ class TranslatedTryStmt extends TranslatedStmt {
final Instruction getNextHandler(TranslatedHandler handler) {
exists(int index |
handler = this.getHandler(index) and
result = this.getHandler(index + 1).getFirstInstruction()
handler = getHandler(index) and
result = 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 = this.getHandler(stmt.getNumberOfCatchClauses() - 1) and
result = this.getParent().getExceptionSuccessorInstruction()
handler = getHandler(stmt.getNumberOfCatchClauses() - 1) and
result = getParent().getExceptionSuccessorInstruction()
}
final override Instruction getExceptionSuccessorInstruction() {
result = this.getHandler(0).getFirstInstruction()
result = getHandler(0).getFirstInstruction()
}
private TranslatedElement getHandler(int index) { result = stmt.getTranslatedHandler(index) }
@@ -573,19 +571,19 @@ class TranslatedTryStmt extends TranslatedStmt {
class TranslatedBlock extends TranslatedStmt {
override BlockStmt stmt;
override TranslatedElement getChild(int id) { result = this.getStmt(id) }
override TranslatedElement getChild(int id) { result = getStmt(id) }
override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) {
this.isEmpty() and
isEmpty() and
opcode instanceof Opcode::NoOp and
tag = OnlyInstructionTag() and
resultType = getVoidType()
}
override Instruction getFirstInstruction() {
if this.isEmpty()
then result = this.getInstruction(OnlyInstructionTag())
else result = this.getStmt(0).getFirstInstruction()
if isEmpty()
then result = getInstruction(OnlyInstructionTag())
else result = getStmt(0).getFirstInstruction()
}
private predicate isEmpty() { not exists(stmt.getStmt(0)) }
@@ -596,16 +594,16 @@ class TranslatedBlock extends TranslatedStmt {
override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) {
tag = OnlyInstructionTag() and
result = this.getParent().getChildSuccessor(this) and
result = getParent().getChildSuccessor(this) and
kind instanceof GotoEdge
}
override Instruction getChildSuccessor(TranslatedElement child) {
exists(int index |
child = this.getStmt(index) and
if index = (this.getStmtCount() - 1)
then result = this.getParent().getChildSuccessor(this)
else result = this.getStmt(index + 1).getFirstInstruction()
child = getStmt(index) and
if index = (getStmtCount() - 1)
then result = getParent().getChildSuccessor(this)
else result = getStmt(index + 1).getFirstInstruction()
)
}
}
@@ -616,18 +614,18 @@ class TranslatedBlock extends TranslatedStmt {
abstract class TranslatedHandler extends TranslatedStmt {
override Handler stmt;
override TranslatedElement getChild(int id) { id = 1 and result = this.getBlock() }
override TranslatedElement getChild(int id) { id = 1 and result = getBlock() }
override Instruction getFirstInstruction() { result = this.getInstruction(CatchTag()) }
override Instruction getFirstInstruction() { result = getInstruction(CatchTag()) }
override Instruction getChildSuccessor(TranslatedElement child) {
child = this.getBlock() and result = this.getParent().getChildSuccessor(this)
child = getBlock() and result = getParent().getChildSuccessor(this)
}
override Instruction getExceptionSuccessorInstruction() {
// A throw from within a `catch` block flows to the handler for the parent of
// the `try`.
result = this.getParent().getParent().getExceptionSuccessorInstruction()
result = getParent().getParent().getExceptionSuccessorInstruction()
}
TranslatedStmt getBlock() { result = getTranslatedStmt(stmt.getBlock()) }
@@ -649,23 +647,23 @@ class TranslatedCatchByTypeHandler extends TranslatedHandler {
override TranslatedElement getChild(int id) {
result = super.getChild(id)
or
id = 0 and result = this.getParameter()
id = 0 and result = getParameter()
}
override Instruction getChildSuccessor(TranslatedElement child) {
result = super.getChildSuccessor(child)
or
child = this.getParameter() and result = this.getBlock().getFirstInstruction()
child = getParameter() and result = getBlock().getFirstInstruction()
}
override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) {
tag = CatchTag() and
(
kind instanceof GotoEdge and
result = this.getParameter().getFirstInstruction()
result = getParameter().getFirstInstruction()
or
kind instanceof ExceptionEdge and
result = this.getParent().(TranslatedTryStmt).getNextHandler(this)
result = getParent().(TranslatedTryStmt).getNextHandler(this)
)
}
@@ -694,7 +692,7 @@ class TranslatedCatchAnyHandler extends TranslatedHandler {
override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) {
tag = CatchTag() and
kind instanceof GotoEdge and
result = this.getBlock().getFirstInstruction()
result = getBlock().getFirstInstruction()
}
}
@@ -702,19 +700,19 @@ class TranslatedIfStmt extends TranslatedStmt, ConditionContext {
override IfStmt stmt;
override Instruction getFirstInstruction() {
if this.hasInitialization()
then result = this.getInitialization().getFirstInstruction()
else result = this.getFirstConditionInstruction()
if hasInitialization()
then result = getInitialization().getFirstInstruction()
else result = getFirstConditionInstruction()
}
override TranslatedElement getChild(int id) {
id = 0 and result = this.getInitialization()
id = 0 and result = getInitialization()
or
id = 1 and result = this.getCondition()
id = 1 and result = getCondition()
or
id = 2 and result = this.getThen()
id = 2 and result = getThen()
or
id = 3 and result = this.getElse()
id = 3 and result = getElse()
}
private predicate hasInitialization() { exists(stmt.getInitialization()) }
@@ -728,7 +726,7 @@ class TranslatedIfStmt extends TranslatedStmt, ConditionContext {
}
private Instruction getFirstConditionInstruction() {
result = this.getCondition().getFirstInstruction()
result = getCondition().getFirstInstruction()
}
private TranslatedStmt getThen() { result = getTranslatedStmt(stmt.getThen()) }
@@ -740,23 +738,23 @@ class TranslatedIfStmt extends TranslatedStmt, ConditionContext {
override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) { none() }
override Instruction getChildTrueSuccessor(TranslatedCondition child) {
child = this.getCondition() and
result = this.getThen().getFirstInstruction()
child = getCondition() and
result = getThen().getFirstInstruction()
}
override Instruction getChildFalseSuccessor(TranslatedCondition child) {
child = this.getCondition() and
if this.hasElse()
then result = this.getElse().getFirstInstruction()
else result = this.getParent().getChildSuccessor(this)
child = getCondition() and
if hasElse()
then result = getElse().getFirstInstruction()
else result = getParent().getChildSuccessor(this)
}
override Instruction getChildSuccessor(TranslatedElement child) {
child = this.getInitialization() and
result = this.getFirstConditionInstruction()
child = getInitialization() and
result = getFirstConditionInstruction()
or
(child = this.getThen() or child = this.getElse()) and
result = this.getParent().getChildSuccessor(this)
(child = getThen() or child = getElse()) and
result = getParent().getChildSuccessor(this)
}
override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) {
@@ -774,17 +772,17 @@ abstract class TranslatedLoop extends TranslatedStmt, ConditionContext {
final TranslatedStmt getBody() { result = getTranslatedStmt(stmt.getStmt()) }
final Instruction getFirstConditionInstruction() {
if this.hasCondition()
then result = this.getCondition().getFirstInstruction()
else result = this.getBody().getFirstInstruction()
if hasCondition()
then result = getCondition().getFirstInstruction()
else result = getBody().getFirstInstruction()
}
final predicate hasCondition() { exists(stmt.getCondition()) }
override TranslatedElement getChild(int id) {
id = 0 and result = this.getCondition()
id = 0 and result = getCondition()
or
id = 1 and result = this.getBody()
id = 1 and result = getBody()
}
override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) {
@@ -794,31 +792,31 @@ abstract class TranslatedLoop extends TranslatedStmt, ConditionContext {
final override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) { none() }
final override Instruction getChildTrueSuccessor(TranslatedCondition child) {
child = this.getCondition() and result = this.getBody().getFirstInstruction()
child = getCondition() and result = getBody().getFirstInstruction()
}
final override Instruction getChildFalseSuccessor(TranslatedCondition child) {
child = this.getCondition() and result = this.getParent().getChildSuccessor(this)
child = getCondition() and result = getParent().getChildSuccessor(this)
}
}
class TranslatedWhileStmt extends TranslatedLoop {
TranslatedWhileStmt() { stmt instanceof WhileStmt }
override Instruction getFirstInstruction() { result = this.getFirstConditionInstruction() }
override Instruction getFirstInstruction() { result = getFirstConditionInstruction() }
override Instruction getChildSuccessor(TranslatedElement child) {
child = this.getBody() and result = this.getFirstConditionInstruction()
child = getBody() and result = getFirstConditionInstruction()
}
}
class TranslatedDoStmt extends TranslatedLoop {
TranslatedDoStmt() { stmt instanceof DoStmt }
override Instruction getFirstInstruction() { result = this.getBody().getFirstInstruction() }
override Instruction getFirstInstruction() { result = getBody().getFirstInstruction() }
override Instruction getChildSuccessor(TranslatedElement child) {
child = this.getBody() and result = this.getFirstConditionInstruction()
child = getBody() and result = getFirstConditionInstruction()
}
}
@@ -826,13 +824,13 @@ class TranslatedForStmt extends TranslatedLoop {
override ForStmt stmt;
override TranslatedElement getChild(int id) {
id = 0 and result = this.getInitialization()
id = 0 and result = getInitialization()
or
id = 1 and result = this.getCondition()
id = 1 and result = getCondition()
or
id = 2 and result = this.getUpdate()
id = 2 and result = getUpdate()
or
id = 3 and result = this.getBody()
id = 3 and result = getBody()
}
private TranslatedStmt getInitialization() {
@@ -846,23 +844,23 @@ class TranslatedForStmt extends TranslatedLoop {
private predicate hasUpdate() { exists(stmt.getUpdate()) }
override Instruction getFirstInstruction() {
if this.hasInitialization()
then result = this.getInitialization().getFirstInstruction()
else result = this.getFirstConditionInstruction()
if hasInitialization()
then result = getInitialization().getFirstInstruction()
else result = getFirstConditionInstruction()
}
override Instruction getChildSuccessor(TranslatedElement child) {
child = this.getInitialization() and
result = this.getFirstConditionInstruction()
child = getInitialization() and
result = getFirstConditionInstruction()
or
(
child = this.getBody() and
if this.hasUpdate()
then result = this.getUpdate().getFirstInstruction()
else result = this.getFirstConditionInstruction()
child = getBody() and
if hasUpdate()
then result = getUpdate().getFirstInstruction()
else result = getFirstConditionInstruction()
)
or
child = this.getUpdate() and result = this.getFirstConditionInstruction()
child = getUpdate() and result = getFirstConditionInstruction()
}
}
@@ -877,39 +875,39 @@ class TranslatedRangeBasedForStmt extends TranslatedStmt, ConditionContext {
override RangeBasedForStmt stmt;
override TranslatedElement getChild(int id) {
id = 0 and result = this.getRangeVariableDeclStmt()
id = 0 and result = getRangeVariableDeclStmt()
or
// Note: `__begin` and `__end` are declared by the same `DeclStmt`
id = 1 and result = this.getBeginEndVariableDeclStmt()
id = 1 and result = getBeginEndVariableDeclStmt()
or
id = 2 and result = this.getCondition()
id = 2 and result = getCondition()
or
id = 3 and result = this.getUpdate()
id = 3 and result = getUpdate()
or
id = 4 and result = this.getVariableDeclStmt()
id = 4 and result = getVariableDeclStmt()
or
id = 5 and result = this.getBody()
id = 5 and result = getBody()
}
override Instruction getFirstInstruction() {
result = this.getRangeVariableDeclStmt().getFirstInstruction()
result = getRangeVariableDeclStmt().getFirstInstruction()
}
override Instruction getChildSuccessor(TranslatedElement child) {
child = this.getRangeVariableDeclStmt() and
result = this.getBeginEndVariableDeclStmt().getFirstInstruction()
child = getRangeVariableDeclStmt() and
result = getBeginEndVariableDeclStmt().getFirstInstruction()
or
child = this.getBeginEndVariableDeclStmt() and
result = this.getCondition().getFirstInstruction()
child = getBeginEndVariableDeclStmt() and
result = getCondition().getFirstInstruction()
or
child = this.getVariableDeclStmt() and
result = this.getBody().getFirstInstruction()
child = getVariableDeclStmt() and
result = getBody().getFirstInstruction()
or
child = this.getBody() and
result = this.getUpdate().getFirstInstruction()
child = getBody() and
result = getUpdate().getFirstInstruction()
or
child = this.getUpdate() and
result = this.getCondition().getFirstInstruction()
child = getUpdate() and
result = getCondition().getFirstInstruction()
}
override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) {
@@ -919,11 +917,11 @@ class TranslatedRangeBasedForStmt extends TranslatedStmt, ConditionContext {
override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) { none() }
override Instruction getChildTrueSuccessor(TranslatedCondition child) {
child = this.getCondition() and result = this.getVariableDeclStmt().getFirstInstruction()
child = getCondition() and result = getVariableDeclStmt().getFirstInstruction()
}
override Instruction getChildFalseSuccessor(TranslatedCondition child) {
child = this.getCondition() and result = this.getParent().getChildSuccessor(this)
child = getCondition() and result = getParent().getChildSuccessor(this)
}
private TranslatedDeclStmt getRangeVariableDeclStmt() {
@@ -963,7 +961,7 @@ class TranslatedRangeBasedForStmt extends TranslatedStmt, ConditionContext {
class TranslatedJumpStmt extends TranslatedStmt {
override JumpStmt stmt;
override Instruction getFirstInstruction() { result = this.getInstruction(OnlyInstructionTag()) }
override Instruction getFirstInstruction() { result = getInstruction(OnlyInstructionTag()) }
override TranslatedElement getChild(int id) { none() }
@@ -998,22 +996,22 @@ class TranslatedSwitchStmt extends TranslatedStmt {
result = getTranslatedExpr(stmt.getExpr().getFullyConverted())
}
private Instruction getFirstExprInstruction() { result = this.getExpr().getFirstInstruction() }
private Instruction getFirstExprInstruction() { result = getExpr().getFirstInstruction() }
private TranslatedStmt getBody() { result = getTranslatedStmt(stmt.getStmt()) }
override Instruction getFirstInstruction() {
if this.hasInitialization()
then result = this.getInitialization().getFirstInstruction()
else result = this.getFirstExprInstruction()
if hasInitialization()
then result = getInitialization().getFirstInstruction()
else result = getFirstExprInstruction()
}
override TranslatedElement getChild(int id) {
id = 0 and result = this.getInitialization()
id = 0 and result = getInitialization()
or
id = 1 and result = this.getExpr()
id = 1 and result = getExpr()
or
id = 2 and result = this.getBody()
id = 2 and result = getBody()
}
private predicate hasInitialization() { exists(stmt.getInitialization()) }
@@ -1031,7 +1029,7 @@ class TranslatedSwitchStmt extends TranslatedStmt {
override Instruction getInstructionRegisterOperand(InstructionTag tag, OperandTag operandTag) {
tag = SwitchBranchTag() and
operandTag instanceof ConditionOperandTag and
result = this.getExpr().getResult()
result = getExpr().getResult()
}
override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) {
@@ -1045,15 +1043,15 @@ class TranslatedSwitchStmt extends TranslatedStmt {
not stmt.hasDefaultCase() and
tag = SwitchBranchTag() and
kind instanceof DefaultEdge and
result = this.getParent().getChildSuccessor(this)
result = getParent().getChildSuccessor(this)
}
override Instruction getChildSuccessor(TranslatedElement child) {
child = this.getInitialization() and result = this.getFirstExprInstruction()
child = getInitialization() and result = getFirstExprInstruction()
or
child = this.getExpr() and result = this.getInstruction(SwitchBranchTag())
child = getExpr() and result = getInstruction(SwitchBranchTag())
or
child = this.getBody() and result = this.getParent().getChildSuccessor(this)
child = getBody() and result = getParent().getChildSuccessor(this)
}
}
@@ -1065,9 +1063,9 @@ class TranslatedAsmStmt extends TranslatedStmt {
}
override Instruction getFirstInstruction() {
if exists(this.getChild(0))
then result = this.getChild(0).getFirstInstruction()
else result = this.getInstruction(AsmTag())
if exists(getChild(0))
then result = getChild(0).getFirstInstruction()
else result = getInstruction(AsmTag())
}
override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) {
@@ -1080,7 +1078,7 @@ class TranslatedAsmStmt extends TranslatedStmt {
exists(int index |
tag = AsmTag() and
operandTag = asmOperand(index) and
result = this.getChild(index).getResult()
result = getChild(index).getResult()
)
}
@@ -1094,16 +1092,16 @@ class TranslatedAsmStmt extends TranslatedStmt {
override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) {
tag = AsmTag() and
result = this.getParent().getChildSuccessor(this) and
result = getParent().getChildSuccessor(this) and
kind instanceof GotoEdge
}
override Instruction getChildSuccessor(TranslatedElement child) {
exists(int index |
child = this.getChild(index) and
if exists(this.getChild(index + 1))
then result = this.getChild(index + 1).getFirstInstruction()
else result = this.getInstruction(AsmTag())
child = getChild(index) and
if exists(getChild(index + 1))
then result = getChild(index + 1).getFirstInstruction()
else result = getInstruction(AsmTag())
)
}
}

View File

@@ -77,16 +77,4 @@ 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,9 +45,7 @@ class IRFunction extends IRFunctionBase {
* Gets the block containing the entry point of this function.
*/
pragma[noinline]
final IRBlock getEntryBlock() {
result.getFirstInstruction() = this.getEnterFunctionInstruction()
}
final IRBlock getEntryBlock() { result.getFirstInstruction() = 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() { this.getLanguageType().hasType(result, false) }
final Language::Type getType() { getLanguageType().hasType(result, false) }
/**
* Gets the language-neutral type of the variable.
*/
final IRType getIRType() { result = this.getLanguageType().getIRType() }
final IRType getIRType() { result = 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 = this.getAst() }
deprecated Language::AST getAST() { result = 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 = this.getAst().getLocation() }
final Language::Location getLocation() { result = 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 = this.getVariable().toString() }
final override string toString() { result = getVariable().toString() }
final override Language::AST getAst() { result = var }
/** DEPRECATED: Alias for getAst */
deprecated override Language::AST getAST() { result = this.getAst() }
deprecated override Language::AST getAST() { result = getAst() }
final override string getUniqueId() {
result = this.getVariable().toString() + " " + this.getVariable().getLocation().toString()
result = getVariable().toString() + " " + 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 = this.getAst() }
deprecated override Language::AST getAST() { result = getAst() }
override string toString() { result = this.getBaseString() + this.getLocationString() }
override string toString() { result = getBaseString() + 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: " + this.getLocationString() + "=" + Language::getStringLiteralText(literal)
result = "String: " + getLocationString() + "=" + Language::getStringLiteralText(literal)
}
final override string getBaseString() { result = "#string" }
@@ -303,8 +303,7 @@ class IRDynamicInitializationFlag extends IRGeneratedVariable, TIRDynamicInitial
final Language::Variable getVariable() { result = var }
final override string getUniqueId() {
result =
"Init: " + this.getVariable().toString() + " " + this.getVariable().getLocation().toString()
result = "Init: " + getVariable().toString() + " " + getVariable().getLocation().toString()
}
final override string getBaseString() { result = "#init:" + var.toString() + ":" }
@@ -333,5 +332,5 @@ class IRParameter extends IRAutomaticVariable {
* An IR variable representing a positional parameter.
*/
class IRPositionalParameter extends IRParameter, IRAutomaticUserVariable {
final override int getIndex() { result = this.getVariable().(Language::Parameter).getIndex() }
final override int getIndex() { result = getVariable().(Language::Parameter).getIndex() }
}

View File

@@ -210,6 +210,9 @@ class Instruction extends Construction::TStageInstruction {
*/
final Language::AST getAst() { result = Construction::getInstructionAst(this) }
/** DEPRECATED: Alias for getAst */
deprecated Language::AST getAST() { result = this.getAst() }
/**
* Gets the location of the source code for this instruction.
*/
@@ -460,6 +463,9 @@ class VariableInstruction extends Instruction {
* Gets the AST variable that this instruction's IR variable refers to, if one exists.
*/
final Language::Variable getAstVariable() { result = var.(IRUserVariable).getVariable() }
/** DEPRECATED: Alias for getAstVariable */
deprecated Language::Variable getASTVariable() { result = this.getAstVariable() }
}
/**

View File

@@ -42,14 +42,6 @@ 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))
}
@@ -92,9 +84,7 @@ 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) {
shouldPrintInstruction(instr) and shouldPrintFunction(instr.getEnclosingFunction())
}
TPrintableInstruction(Instruction instr) { shouldPrintFunction(instr.getEnclosingFunction()) }
/**
* A node to be emitted in the IR graph.
@@ -137,13 +127,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 = this.getLabel()
key = "semmle.label" and result = getLabel()
or
key = "semmle.order" and result = this.getOrder().toString()
key = "semmle.order" and result = getOrder().toString()
or
key = "semmle.graphKind" and result = this.getGraphKind()
key = "semmle.graphKind" and result = getGraphKind()
or
key = "semmle.forceText" and this.forceText() and result = "true"
key = "semmle.forceText" and forceText() and result = "true"
}
}
@@ -188,7 +178,7 @@ private class PrintableIRBlock extends PrintableIRNode, TPrintableIRBlock {
PrintableIRBlock() { this = TPrintableIRBlock(block) }
override string toString() { result = this.getLabel() }
override string toString() { result = getLabel() }
override Language::Location getLocation() { result = block.getLocation() }
@@ -233,7 +223,7 @@ private class PrintableInstruction extends PrintableIRNode, TPrintableInstructio
|
resultString = instr.getResultString() and
operationString = instr.getOperationString() and
operandsString = this.getOperandsString() and
operandsString = getOperandsString() and
columnWidths(block, resultWidth, operationWidth) and
result =
resultString + getPaddingString(resultWidth - resultString.length()) + " = " +
@@ -262,8 +252,7 @@ private class PrintableInstruction extends PrintableIRNode, TPrintableInstructio
private string getOperandsString() {
result =
concat(Operand operand |
operand = instr.getAnOperand() and
shouldPrintOperand(operand)
operand = instr.getAnOperand()
|
operand.getDumpString() + getOperandPropertyString(operand), ", "
order by

View File

@@ -7,19 +7,17 @@ private import internal.ValueNumberingImports
class ValueNumber extends TValueNumber {
final string toString() { result = "GVN" }
final string getDebugString() {
result = strictconcat(this.getAnInstruction().getResultId(), ", ")
}
final string getDebugString() { result = strictconcat(getAnInstruction().getResultId(), ", ") }
final Language::Location getLocation() {
if
exists(Instruction i |
i = this.getAnInstruction() and not i.getLocation() instanceof Language::UnknownLocation
i = getAnInstruction() and not i.getLocation() instanceof Language::UnknownLocation
)
then
result =
min(Language::Location l |
l = this.getAnInstruction().getLocation() and not l instanceof Language::UnknownLocation
l = getAnInstruction().getLocation() and not l instanceof Language::UnknownLocation
|
l
order by
@@ -42,7 +40,7 @@ class ValueNumber extends TValueNumber {
final Instruction getExampleInstruction() {
result =
min(Instruction instr |
instr = this.getAnInstruction()
instr = 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 = this.toString() }
final string getAllocationString() { result = toString() }
predicate alwaysEscapes() {
// An automatic variable only escapes if its address is taken and escapes.

View File

@@ -422,6 +422,12 @@ private module Cached {
)
}
/** DEPRECATED: Alias for getInstructionAst */
cached
deprecated Language::AST getInstructionAST(Instruction instr) {
result = getInstructionAst(instr)
}
cached
Language::LanguageType getInstructionResultType(Instruction instr) {
result = instr.(RawIR::Instruction).getResultLanguageType()
@@ -987,6 +993,9 @@ predicate canReuseSsaForMemoryResult(Instruction instruction) {
// We don't support reusing SSA for any location that could create a `Chi` instruction.
}
/** DEPRECATED: Alias for canReuseSsaForMemoryResult */
deprecated predicate canReuseSSAForMemoryResult = canReuseSsaForMemoryResult/1;
/**
* Expose some of the internal predicates to PrintSSA.qll. We do this by publicly importing those modules in the
* `DebugSsa` module, which is then imported by PrintSSA.
@@ -996,6 +1005,9 @@ module DebugSsa {
import DefUse
}
/** DEPRECATED: Alias for DebugSsa */
deprecated module DebugSSA = DebugSsa;
import CachedForDebugging
cached

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