mirror of
https://github.com/github/codeql.git
synced 2026-04-25 00:35:20 +02:00
Merge branch 'main' into max-schaefer-patch-1
This commit is contained in:
5
.github/workflows/compile-queries.yml
vendored
5
.github/workflows/compile-queries.yml
vendored
@@ -29,8 +29,6 @@ jobs:
|
||||
key: all-queries
|
||||
- name: check formatting
|
||||
run: find shared */ql -type f \( -name "*.qll" -o -name "*.ql" \) -print0 | xargs -0 -n 3000 -P 10 codeql query format -q --check-only
|
||||
- name: Omit DatabaseQualityDiagnostics.ql from compile checking # Remove me once CodeQL 2.18.0 is released!
|
||||
run: mv java/ql/src/Telemetry/DatabaseQualityDiagnostics.ql{,.hidden}
|
||||
- name: compile queries - check-only
|
||||
# run with --check-only if running in a PR (github.sha != main)
|
||||
if : ${{ github.event_name == 'pull_request' }}
|
||||
@@ -41,6 +39,3 @@ jobs:
|
||||
if : ${{ github.event_name != 'pull_request' }}
|
||||
shell: bash
|
||||
run: codeql query compile -q -j0 */ql/{src,examples} --keep-going --warnings=error --compilation-cache "${{ steps.query-cache.outputs.cache-dir }}" --compilation-cache-size=500
|
||||
- name: Restore DatabaseQualityDiagnostics.ql after compile checking # Remove me once CodeQL 2.18.0 is released
|
||||
run: mv java/ql/src/Telemetry/DatabaseQualityDiagnostics.ql{.hidden,}
|
||||
|
||||
|
||||
@@ -112,6 +112,7 @@ use_repo(
|
||||
"kotlin-compiler-1.9.0-Beta",
|
||||
"kotlin-compiler-1.9.20-Beta",
|
||||
"kotlin-compiler-2.0.0-RC1",
|
||||
"kotlin-compiler-2.0.20-Beta2",
|
||||
"kotlin-compiler-embeddable-1.5.0",
|
||||
"kotlin-compiler-embeddable-1.5.10",
|
||||
"kotlin-compiler-embeddable-1.5.20",
|
||||
@@ -124,6 +125,7 @@ use_repo(
|
||||
"kotlin-compiler-embeddable-1.9.0-Beta",
|
||||
"kotlin-compiler-embeddable-1.9.20-Beta",
|
||||
"kotlin-compiler-embeddable-2.0.0-RC1",
|
||||
"kotlin-compiler-embeddable-2.0.20-Beta2",
|
||||
"kotlin-stdlib-1.5.0",
|
||||
"kotlin-stdlib-1.5.10",
|
||||
"kotlin-stdlib-1.5.20",
|
||||
@@ -136,11 +138,16 @@ use_repo(
|
||||
"kotlin-stdlib-1.9.0-Beta",
|
||||
"kotlin-stdlib-1.9.20-Beta",
|
||||
"kotlin-stdlib-2.0.0-RC1",
|
||||
"kotlin-stdlib-2.0.20-Beta2",
|
||||
)
|
||||
|
||||
go_sdk = use_extension("@rules_go//go:extensions.bzl", "go_sdk")
|
||||
go_sdk.download(version = "1.22.2")
|
||||
|
||||
go_deps = use_extension("@gazelle//:extensions.bzl", "go_deps")
|
||||
go_deps.from_file(go_mod = "//go/extractor:go.mod")
|
||||
use_repo(go_deps, "org_golang_x_mod", "org_golang_x_tools")
|
||||
|
||||
lfs_files = use_repo_rule("//misc/bazel:lfs.bzl", "lfs_files")
|
||||
|
||||
lfs_files(
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
---
|
||||
category: feature
|
||||
---
|
||||
* The class `NewArrayExpr` adds a predicate `getArraySize()` to allow a more convenient way to access the static size of the array when the extent is missing.
|
||||
4
cpp/ql/lib/change-notes/2024-07-16-alert-provenance.md
Normal file
4
cpp/ql/lib/change-notes/2024-07-16-alert-provenance.md
Normal file
@@ -0,0 +1,4 @@
|
||||
---
|
||||
category: feature
|
||||
---
|
||||
* Models-as-data alert provenance information has been extended to the C/C++ language. Any qltests that include the edges relation in their output (for example, `.qlref`s that reference path-problem queries) will need to be have their expected output updated accordingly.
|
||||
@@ -146,7 +146,7 @@ predicate summaryModel(string row) { any(SummaryModelCsv s).row(row) }
|
||||
/** Holds if a source model exists for the given parameters. */
|
||||
predicate sourceModel(
|
||||
string namespace, string type, boolean subtypes, string name, string signature, string ext,
|
||||
string output, string kind, string provenance
|
||||
string output, string kind, string provenance, string model
|
||||
) {
|
||||
exists(string row |
|
||||
sourceModel(row) and
|
||||
@@ -160,16 +160,20 @@ predicate sourceModel(
|
||||
row.splitAt(";", 6) = output and
|
||||
row.splitAt(";", 7) = kind
|
||||
) and
|
||||
provenance = "manual"
|
||||
provenance = "manual" and
|
||||
model = ""
|
||||
or
|
||||
Extensions::sourceModel(namespace, type, subtypes, name, signature, ext, output, kind, provenance,
|
||||
_)
|
||||
exists(QlBuiltins::ExtensionId madId |
|
||||
Extensions::sourceModel(namespace, type, subtypes, name, signature, ext, output, kind,
|
||||
provenance, madId) and
|
||||
model = "MaD:" + madId.toString()
|
||||
)
|
||||
}
|
||||
|
||||
/** Holds if a sink model exists for the given parameters. */
|
||||
predicate sinkModel(
|
||||
string namespace, string type, boolean subtypes, string name, string signature, string ext,
|
||||
string input, string kind, string provenance
|
||||
string input, string kind, string provenance, string model
|
||||
) {
|
||||
exists(string row |
|
||||
sinkModel(row) and
|
||||
@@ -183,9 +187,14 @@ predicate sinkModel(
|
||||
row.splitAt(";", 6) = input and
|
||||
row.splitAt(";", 7) = kind
|
||||
) and
|
||||
provenance = "manual"
|
||||
provenance = "manual" and
|
||||
model = ""
|
||||
or
|
||||
Extensions::sinkModel(namespace, type, subtypes, name, signature, ext, input, kind, provenance, _)
|
||||
exists(QlBuiltins::ExtensionId madId |
|
||||
Extensions::sinkModel(namespace, type, subtypes, name, signature, ext, input, kind, provenance,
|
||||
madId) and
|
||||
model = "MaD:" + madId.toString()
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -195,7 +204,7 @@ predicate sinkModel(
|
||||
*/
|
||||
private predicate summaryModel0(
|
||||
string namespace, string type, boolean subtypes, string name, string signature, string ext,
|
||||
string input, string output, string kind, string provenance
|
||||
string input, string output, string kind, string provenance, string model
|
||||
) {
|
||||
exists(string row |
|
||||
summaryModel(row) and
|
||||
@@ -210,10 +219,14 @@ private predicate summaryModel0(
|
||||
row.splitAt(";", 7) = output and
|
||||
row.splitAt(";", 8) = kind
|
||||
) and
|
||||
provenance = "manual"
|
||||
provenance = "manual" and
|
||||
model = ""
|
||||
or
|
||||
Extensions::summaryModel(namespace, type, subtypes, name, signature, ext, input, output, kind,
|
||||
provenance, _)
|
||||
exists(QlBuiltins::ExtensionId madId |
|
||||
Extensions::summaryModel(namespace, type, subtypes, name, signature, ext, input, output, kind,
|
||||
provenance, madId) and
|
||||
model = "MaD:" + madId.toString()
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -234,19 +247,20 @@ private predicate expandInputAndOutput(
|
||||
*/
|
||||
predicate summaryModel(
|
||||
string namespace, string type, boolean subtypes, string name, string signature, string ext,
|
||||
string input, string output, string kind, string provenance
|
||||
string input, string output, string kind, string provenance, string model
|
||||
) {
|
||||
exists(string input0, string output0 |
|
||||
summaryModel0(namespace, type, subtypes, name, signature, ext, input0, output0, kind, provenance) and
|
||||
summaryModel0(namespace, type, subtypes, name, signature, ext, input0, output0, kind,
|
||||
provenance, model) and
|
||||
expandInputAndOutput(input0, input, output0, output,
|
||||
[0 .. Private::getMaxElementContentIndirectionIndex() - 1])
|
||||
)
|
||||
}
|
||||
|
||||
private predicate relevantNamespace(string namespace) {
|
||||
sourceModel(namespace, _, _, _, _, _, _, _, _) or
|
||||
sinkModel(namespace, _, _, _, _, _, _, _, _) or
|
||||
summaryModel(namespace, _, _, _, _, _, _, _, _, _)
|
||||
sourceModel(namespace, _, _, _, _, _, _, _, _, _) or
|
||||
sinkModel(namespace, _, _, _, _, _, _, _, _, _) or
|
||||
summaryModel(namespace, _, _, _, _, _, _, _, _, _, _)
|
||||
}
|
||||
|
||||
private predicate namespaceLink(string shortns, string longns) {
|
||||
@@ -276,17 +290,17 @@ predicate modelCoverage(string namespace, int namespaces, string kind, string pa
|
||||
part = "source" and
|
||||
n =
|
||||
strictcount(string subns, string type, boolean subtypes, string name, string signature,
|
||||
string ext, string output, string provenance |
|
||||
string ext, string output, string provenance, string model |
|
||||
canonicalNamespaceLink(namespace, subns) and
|
||||
sourceModel(subns, type, subtypes, name, signature, ext, output, kind, provenance)
|
||||
sourceModel(subns, type, subtypes, name, signature, ext, output, kind, provenance, model)
|
||||
)
|
||||
or
|
||||
part = "sink" and
|
||||
n =
|
||||
strictcount(string subns, string type, boolean subtypes, string name, string signature,
|
||||
string ext, string input, string provenance |
|
||||
string ext, string input, string provenance, string model |
|
||||
canonicalNamespaceLink(namespace, subns) and
|
||||
sinkModel(subns, type, subtypes, name, signature, ext, input, kind, provenance)
|
||||
sinkModel(subns, type, subtypes, name, signature, ext, input, kind, provenance, model)
|
||||
)
|
||||
or
|
||||
part = "summary" and
|
||||
@@ -294,7 +308,7 @@ predicate modelCoverage(string namespace, int namespaces, string kind, string pa
|
||||
strictcount(string subns, string type, boolean subtypes, string name, string signature,
|
||||
string ext, string input, string output, string provenance |
|
||||
canonicalNamespaceLink(namespace, subns) and
|
||||
summaryModel(subns, type, subtypes, name, signature, ext, input, output, kind, provenance)
|
||||
summaryModel(subns, type, subtypes, name, signature, ext, input, output, kind, provenance, _)
|
||||
)
|
||||
)
|
||||
}
|
||||
@@ -303,9 +317,9 @@ predicate modelCoverage(string namespace, int namespaces, string kind, string pa
|
||||
module CsvValidation {
|
||||
private string getInvalidModelInput() {
|
||||
exists(string pred, AccessPath input, string part |
|
||||
sinkModel(_, _, _, _, _, _, input, _, _) and pred = "sink"
|
||||
sinkModel(_, _, _, _, _, _, input, _, _, _) and pred = "sink"
|
||||
or
|
||||
summaryModel(_, _, _, _, _, _, input, _, _, _) and pred = "summary"
|
||||
summaryModel(_, _, _, _, _, _, input, _, _, _, _) and pred = "summary"
|
||||
|
|
||||
(
|
||||
invalidSpecComponent(input, part) and
|
||||
@@ -322,9 +336,9 @@ module CsvValidation {
|
||||
|
||||
private string getInvalidModelOutput() {
|
||||
exists(string pred, string output, string part |
|
||||
sourceModel(_, _, _, _, _, _, output, _, _) and pred = "source"
|
||||
sourceModel(_, _, _, _, _, _, output, _, _, _) and pred = "source"
|
||||
or
|
||||
summaryModel(_, _, _, _, _, _, _, output, _, _) and pred = "summary"
|
||||
summaryModel(_, _, _, _, _, _, _, output, _, _, _) and pred = "summary"
|
||||
|
|
||||
invalidSpecComponent(output, part) and
|
||||
not part = "" and
|
||||
@@ -334,11 +348,11 @@ module CsvValidation {
|
||||
}
|
||||
|
||||
private module KindValConfig implements SharedModelVal::KindValidationConfigSig {
|
||||
predicate summaryKind(string kind) { summaryModel(_, _, _, _, _, _, _, _, kind, _) }
|
||||
predicate summaryKind(string kind) { summaryModel(_, _, _, _, _, _, _, _, kind, _, _) }
|
||||
|
||||
predicate sinkKind(string kind) { sinkModel(_, _, _, _, _, _, _, kind, _) }
|
||||
predicate sinkKind(string kind) { sinkModel(_, _, _, _, _, _, _, kind, _, _) }
|
||||
|
||||
predicate sourceKind(string kind) { sourceModel(_, _, _, _, _, _, _, kind, _) }
|
||||
predicate sourceKind(string kind) { sourceModel(_, _, _, _, _, _, _, kind, _, _) }
|
||||
}
|
||||
|
||||
private module KindVal = SharedModelVal::KindValidation<KindValConfig>;
|
||||
@@ -379,11 +393,11 @@ module CsvValidation {
|
||||
|
||||
private string getInvalidModelSignature() {
|
||||
exists(string pred, string namespace, string type, string name, string signature, string ext |
|
||||
sourceModel(namespace, type, _, name, signature, ext, _, _, _) and pred = "source"
|
||||
sourceModel(namespace, type, _, name, signature, ext, _, _, _, _) and pred = "source"
|
||||
or
|
||||
sinkModel(namespace, type, _, name, signature, ext, _, _, _) and pred = "sink"
|
||||
sinkModel(namespace, type, _, name, signature, ext, _, _, _, _) and pred = "sink"
|
||||
or
|
||||
summaryModel(namespace, type, _, name, signature, ext, _, _, _, _) and pred = "summary"
|
||||
summaryModel(namespace, type, _, name, signature, ext, _, _, _, _, _) and pred = "summary"
|
||||
|
|
||||
not namespace.regexpMatch("[a-zA-Z0-9_\\.:]*") and
|
||||
result = "Dubious namespace \"" + namespace + "\" in " + pred + " model."
|
||||
@@ -415,9 +429,9 @@ module CsvValidation {
|
||||
private predicate elementSpec(
|
||||
string namespace, string type, boolean subtypes, string name, string signature, string ext
|
||||
) {
|
||||
sourceModel(namespace, type, subtypes, name, signature, ext, _, _, _) or
|
||||
sinkModel(namespace, type, subtypes, name, signature, ext, _, _, _) or
|
||||
summaryModel(namespace, type, subtypes, name, signature, ext, _, _, _, _)
|
||||
sourceModel(namespace, type, subtypes, name, signature, ext, _, _, _, _) or
|
||||
sinkModel(namespace, type, subtypes, name, signature, ext, _, _, _, _) or
|
||||
summaryModel(namespace, type, subtypes, name, signature, ext, _, _, _, _, _)
|
||||
}
|
||||
|
||||
/** Gets the fully templated version of `f`. */
|
||||
@@ -867,9 +881,9 @@ private module Cached {
|
||||
* model.
|
||||
*/
|
||||
cached
|
||||
predicate sourceNode(DataFlow::Node node, string kind) {
|
||||
predicate sourceNode(DataFlow::Node node, string kind, string model) {
|
||||
exists(SourceSinkInterpretationInput::InterpretNode n |
|
||||
isSourceNode(n, kind, _) and n.asNode() = node // TODO
|
||||
isSourceNode(n, kind, model) and n.asNode() = node
|
||||
)
|
||||
}
|
||||
|
||||
@@ -878,40 +892,57 @@ private module Cached {
|
||||
* model.
|
||||
*/
|
||||
cached
|
||||
predicate sinkNode(DataFlow::Node node, string kind) {
|
||||
predicate sinkNode(DataFlow::Node node, string kind, string model) {
|
||||
exists(SourceSinkInterpretationInput::InterpretNode n |
|
||||
isSinkNode(n, kind, _) and n.asNode() = node // TODO
|
||||
isSinkNode(n, kind, model) and n.asNode() = node
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
import Cached
|
||||
|
||||
/**
|
||||
* Holds if `node` is specified as a source with the given kind in a MaD flow
|
||||
* model.
|
||||
*/
|
||||
predicate sourceNode(DataFlow::Node node, string kind) { sourceNode(node, kind, _) }
|
||||
|
||||
/**
|
||||
* Holds if `node` is specified as a sink with the given kind in a MaD flow
|
||||
* model.
|
||||
*/
|
||||
predicate sinkNode(DataFlow::Node node, string kind) { sinkNode(node, kind, _) }
|
||||
|
||||
private predicate interpretSummary(
|
||||
Function f, string input, string output, string kind, string provenance
|
||||
Function f, string input, string output, string kind, string provenance, string model
|
||||
) {
|
||||
exists(
|
||||
string namespace, string type, boolean subtypes, string name, string signature, string ext
|
||||
|
|
||||
summaryModel(namespace, type, subtypes, name, signature, ext, input, output, kind, provenance) and
|
||||
summaryModel(namespace, type, subtypes, name, signature, ext, input, output, kind, provenance,
|
||||
model) and
|
||||
f = interpretElement(namespace, type, subtypes, name, signature, ext)
|
||||
)
|
||||
}
|
||||
|
||||
// adapter class for converting Mad summaries to `SummarizedCallable`s
|
||||
private class SummarizedCallableAdapter extends SummarizedCallable {
|
||||
SummarizedCallableAdapter() { interpretSummary(this, _, _, _, _) }
|
||||
SummarizedCallableAdapter() { interpretSummary(this, _, _, _, _, _) }
|
||||
|
||||
private predicate relevantSummaryElementManual(string input, string output, string kind) {
|
||||
private predicate relevantSummaryElementManual(
|
||||
string input, string output, string kind, string model
|
||||
) {
|
||||
exists(Provenance provenance |
|
||||
interpretSummary(this, input, output, kind, provenance) and
|
||||
interpretSummary(this, input, output, kind, provenance, model) and
|
||||
provenance.isManual()
|
||||
)
|
||||
}
|
||||
|
||||
private predicate relevantSummaryElementGenerated(string input, string output, string kind) {
|
||||
private predicate relevantSummaryElementGenerated(
|
||||
string input, string output, string kind, string model
|
||||
) {
|
||||
exists(Provenance provenance |
|
||||
interpretSummary(this, input, output, kind, provenance) and
|
||||
interpretSummary(this, input, output, kind, provenance, model) and
|
||||
provenance.isGenerated()
|
||||
)
|
||||
}
|
||||
@@ -920,18 +951,17 @@ private class SummarizedCallableAdapter extends SummarizedCallable {
|
||||
string input, string output, boolean preservesValue, string model
|
||||
) {
|
||||
exists(string kind |
|
||||
this.relevantSummaryElementManual(input, output, kind)
|
||||
this.relevantSummaryElementManual(input, output, kind, model)
|
||||
or
|
||||
not this.relevantSummaryElementManual(_, _, _) and
|
||||
this.relevantSummaryElementGenerated(input, output, kind)
|
||||
not this.relevantSummaryElementManual(_, _, _, _) and
|
||||
this.relevantSummaryElementGenerated(input, output, kind, model)
|
||||
|
|
||||
if kind = "value" then preservesValue = true else preservesValue = false
|
||||
) and
|
||||
model = "" // TODO
|
||||
)
|
||||
}
|
||||
|
||||
override predicate hasProvenance(Provenance provenance) {
|
||||
interpretSummary(this, _, _, _, provenance)
|
||||
interpretSummary(this, _, _, _, provenance, _)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -239,17 +239,7 @@ class CastNode extends Node {
|
||||
CastNode() { none() } // stub implementation
|
||||
}
|
||||
|
||||
class DataFlowCallable extends Function {
|
||||
/** Gets a best-effort total ordering. */
|
||||
int totalorder() {
|
||||
this =
|
||||
rank[result](DataFlowCallable c, string file, int startline, int startcolumn |
|
||||
c.getLocation().hasLocationInfo(file, startline, startcolumn, _, _)
|
||||
|
|
||||
c order by file, startline, startcolumn
|
||||
)
|
||||
}
|
||||
}
|
||||
class DataFlowCallable extends Function { }
|
||||
|
||||
class DataFlowExpr = Expr;
|
||||
|
||||
@@ -269,24 +259,12 @@ class DataFlowCall extends Expr instanceof Call {
|
||||
|
||||
/** Gets the enclosing callable of this call. */
|
||||
DataFlowCallable getEnclosingCallable() { result = this.getEnclosingFunction() }
|
||||
|
||||
/** Gets a best-effort total ordering. */
|
||||
int totalorder() {
|
||||
this =
|
||||
rank[result](DataFlowCall c, int startline, int startcolumn |
|
||||
c.getLocation().hasLocationInfo(_, startline, startcolumn, _, _)
|
||||
|
|
||||
c order by startline, startcolumn
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
class NodeRegion instanceof Unit {
|
||||
string toString() { result = "NodeRegion" }
|
||||
|
||||
predicate contains(Node n) { none() }
|
||||
|
||||
int totalOrder() { result = 1 }
|
||||
}
|
||||
|
||||
predicate isUnreachableInCall(NodeRegion nr, DataFlowCall call) { none() } // stub implementation
|
||||
|
||||
@@ -112,9 +112,8 @@ module SourceSinkInterpretationInput implements
|
||||
exists(
|
||||
string namespace, string type, boolean subtypes, string name, string signature, string ext
|
||||
|
|
||||
sourceModel(namespace, type, subtypes, name, signature, ext, output, kind, provenance) and
|
||||
e = interpretElement(namespace, type, subtypes, name, signature, ext) and
|
||||
model = "" // TODO
|
||||
sourceModel(namespace, type, subtypes, name, signature, ext, output, kind, provenance, model) and
|
||||
e = interpretElement(namespace, type, subtypes, name, signature, ext)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -128,9 +127,8 @@ module SourceSinkInterpretationInput implements
|
||||
exists(
|
||||
string package, string type, boolean subtypes, string name, string signature, string ext
|
||||
|
|
||||
sinkModel(package, type, subtypes, name, signature, ext, input, kind, provenance) and
|
||||
e = interpretElement(package, type, subtypes, name, signature, ext) and
|
||||
model = "" // TODO
|
||||
sinkModel(package, type, subtypes, name, signature, ext, input, kind, provenance, model) and
|
||||
e = interpretElement(package, type, subtypes, name, signature, ext)
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -949,6 +949,16 @@ class NewArrayExpr extends NewOrNewArrayExpr, @new_array_expr {
|
||||
* gives nothing, as the 10 is considered part of the type.
|
||||
*/
|
||||
Expr getExtent() { result = this.getChild(2) }
|
||||
|
||||
/**
|
||||
* Gets the number of elements in the array, if available.
|
||||
*
|
||||
* For example, `new int[]{1,2,3}` has an array size of 3.
|
||||
*/
|
||||
int getArraySize() {
|
||||
result = this.getAllocatedType().(ArrayType).getArraySize() or
|
||||
result = this.getInitializer().(ArrayAggregateLiteral).getArraySize()
|
||||
}
|
||||
}
|
||||
|
||||
private class TDeleteOrDeleteArrayExpr = @delete_expr or @delete_array_expr;
|
||||
|
||||
@@ -11,6 +11,7 @@ private import Node0ToString
|
||||
private import ModelUtil
|
||||
private import semmle.code.cpp.models.interfaces.FunctionInputsAndOutputs as IO
|
||||
private import semmle.code.cpp.models.interfaces.DataFlow as DF
|
||||
private import semmle.code.cpp.dataflow.ExternalFlow as External
|
||||
|
||||
cached
|
||||
private module Cached {
|
||||
@@ -1060,16 +1061,6 @@ class DataFlowCallable extends TDataFlowCallable {
|
||||
result = this.asSummarizedCallable() or // SummarizedCallable = Function (in CPP)
|
||||
result = this.asSourceCallable()
|
||||
}
|
||||
|
||||
/** Gets a best-effort total ordering. */
|
||||
int totalorder() {
|
||||
this =
|
||||
rank[result](DataFlowCallable c, string file, int startline, int startcolumn |
|
||||
c.getLocation().hasLocationInfo(file, startline, startcolumn, _, _)
|
||||
|
|
||||
c order by file, startline, startcolumn
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1167,16 +1158,6 @@ class DataFlowCall extends TDataFlowCall {
|
||||
* Gets the location of this call.
|
||||
*/
|
||||
Location getLocation() { none() }
|
||||
|
||||
/** Gets a best-effort total ordering. */
|
||||
int totalorder() {
|
||||
this =
|
||||
rank[result](DataFlowCall c, int startline, int startcolumn |
|
||||
c.getLocation().hasLocationInfo(_, startline, startcolumn, _, _)
|
||||
|
|
||||
c order by startline, startcolumn
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1269,15 +1250,6 @@ module IsUnreachableInCall {
|
||||
string toString() { result = "NodeRegion" }
|
||||
|
||||
predicate contains(Node n) { this = n.getBasicBlock() }
|
||||
|
||||
int totalOrder() {
|
||||
this =
|
||||
rank[result](IRBlock b, int startline, int startcolumn |
|
||||
b.getLocation().hasLocationInfo(_, startline, startcolumn, _, _)
|
||||
|
|
||||
b order by startline, startcolumn
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
predicate isUnreachableInCall(NodeRegion block, DataFlowCall call) {
|
||||
@@ -1362,9 +1334,9 @@ predicate lambdaCall(DataFlowCall call, LambdaCallKind kind, Node receiver) {
|
||||
/** Extra data-flow steps needed for lambda flow analysis. */
|
||||
predicate additionalLambdaFlowStep(Node nodeFrom, Node nodeTo, boolean preservesValue) { none() }
|
||||
|
||||
predicate knownSourceModel(Node source, string model) { none() }
|
||||
predicate knownSourceModel(Node source, string model) { External::sourceNode(source, _, model) }
|
||||
|
||||
predicate knownSinkModel(Node sink, string model) { none() }
|
||||
predicate knownSinkModel(Node sink, string model) { External::sinkNode(sink, _, model) }
|
||||
|
||||
/**
|
||||
* Holds if flow is allowed to pass from parameter `p` and back to itself as a
|
||||
|
||||
@@ -40,7 +40,8 @@ predicate ignoreInstruction(Instruction instr) {
|
||||
instr instanceof AliasedDefinitionInstruction or
|
||||
instr instanceof AliasedUseInstruction or
|
||||
instr instanceof InitializeNonLocalInstruction or
|
||||
instr instanceof ReturnIndirectionInstruction
|
||||
instr instanceof ReturnIndirectionInstruction or
|
||||
instr instanceof UninitializedGroupInstruction
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -13,7 +13,8 @@ private newtype TMemoryAccessKind =
|
||||
TPhiMemoryAccess() or
|
||||
TUnmodeledMemoryAccess() or
|
||||
TChiTotalMemoryAccess() or
|
||||
TChiPartialMemoryAccess()
|
||||
TChiPartialMemoryAccess() or
|
||||
TGroupedMemoryAccess()
|
||||
|
||||
/**
|
||||
* Describes the set of memory locations memory accessed by a memory operand or
|
||||
@@ -99,3 +100,11 @@ class ChiTotalMemoryAccess extends MemoryAccessKind, TChiTotalMemoryAccess {
|
||||
class ChiPartialMemoryAccess extends MemoryAccessKind, TChiPartialMemoryAccess {
|
||||
override string toString() { result = "chi(partial)" }
|
||||
}
|
||||
|
||||
/**
|
||||
* The result of an `UninitializedGroup` instruction, which initializes a set of
|
||||
* allocations that are each assigned the same virtual variable.
|
||||
*/
|
||||
class GroupedMemoryAccess extends MemoryAccessKind, TGroupedMemoryAccess {
|
||||
override string toString() { result = "group" }
|
||||
}
|
||||
|
||||
@@ -89,6 +89,7 @@ private newtype TOpcode =
|
||||
TSizedBufferMayWriteSideEffect() or
|
||||
TInitializeDynamicAllocation() or
|
||||
TChi() or
|
||||
TUninitializedGroup() or
|
||||
TInlineAsm() or
|
||||
TUnreached() or
|
||||
TNewObj()
|
||||
@@ -1237,6 +1238,17 @@ module Opcode {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The `Opcode` for a `UninitializedGroup`.
|
||||
*
|
||||
* See the `UninitializedGroupInstruction` documentation for more details.
|
||||
*/
|
||||
class UninitializedGroup extends Opcode, TUninitializedGroup {
|
||||
final override string toString() { result = "UninitializedGroup" }
|
||||
|
||||
override GroupedMemoryAccess getWriteMemoryAccess() { any() }
|
||||
}
|
||||
|
||||
/**
|
||||
* The `Opcode` for an `InlineAsmInstruction`.
|
||||
*
|
||||
|
||||
@@ -2142,6 +2142,47 @@ class ChiInstruction extends Instruction {
|
||||
final predicate isPartialUpdate() { Construction::chiOnlyPartiallyUpdatesLocation(this) }
|
||||
}
|
||||
|
||||
/**
|
||||
* An instruction that initializes a set of allocations that are each assigned
|
||||
* the same "virtual variable".
|
||||
*
|
||||
* As an example, consider the following snippet:
|
||||
* ```
|
||||
* int a;
|
||||
* int b;
|
||||
* int* p;
|
||||
* if(b) {
|
||||
* p = &a;
|
||||
* } else {
|
||||
* p = &b;
|
||||
* }
|
||||
* *p = 5;
|
||||
* int x = a;
|
||||
* ```
|
||||
*
|
||||
* Since both the address of `a` and `b` reach `p` at `*p = 5` the IR alias
|
||||
* analysis will create a region that contains both `a` and `b`. The region
|
||||
* containing both `a` and `b` are initialized by an `UninitializedGroup`
|
||||
* instruction in the entry block of the enclosing function.
|
||||
*/
|
||||
class UninitializedGroupInstruction extends Instruction {
|
||||
UninitializedGroupInstruction() { this.getOpcode() instanceof Opcode::UninitializedGroup }
|
||||
|
||||
/**
|
||||
* Gets an `IRVariable` whose memory is initialized by this instruction, if any.
|
||||
* Note: Allocations that are not represented as `IRVariable`s (such as
|
||||
* dynamic allocations) are not returned by this predicate even if this
|
||||
* instruction initializes such memory.
|
||||
*/
|
||||
final IRVariable getAnIRVariable() {
|
||||
result = Construction::getAnUninitializedGroupVariable(this)
|
||||
}
|
||||
|
||||
final override string getImmediateString() {
|
||||
result = strictconcat(this.getAnIRVariable().toString(), ",")
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* An instruction representing unreachable code.
|
||||
*
|
||||
|
||||
@@ -106,8 +106,7 @@ private predicate operandEscapesDomain(Operand operand) {
|
||||
not isArgumentForParameter(_, operand, _) and
|
||||
not isOnlyEscapesViaReturnArgument(operand) and
|
||||
not operand.getUse() instanceof ReturnValueInstruction and
|
||||
not operand.getUse() instanceof ReturnIndirectionInstruction and
|
||||
not operand instanceof PhiInputOperand
|
||||
not operand.getUse() instanceof ReturnIndirectionInstruction
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -191,6 +190,11 @@ private predicate operandIsPropagated(Operand operand, IntValue bitOffset, Instr
|
||||
// A copy propagates the source value.
|
||||
operand = instr.(CopyInstruction).getSourceValueOperand() and bitOffset = 0
|
||||
)
|
||||
or
|
||||
operand = instr.(PhiInstruction).getAnInputOperand() and
|
||||
// Using `unknown` ensures termination since we cannot keep incrementing a bit offset
|
||||
// through the back edge of a loop (or through recursion).
|
||||
bitOffset = Ints::unknown()
|
||||
}
|
||||
|
||||
private predicate operandEscapesNonReturn(Operand operand) {
|
||||
@@ -212,9 +216,6 @@ private predicate operandEscapesNonReturn(Operand operand) {
|
||||
or
|
||||
isOnlyEscapesViaReturnArgument(operand) and resultEscapesNonReturn(operand.getUse())
|
||||
or
|
||||
operand instanceof PhiInputOperand and
|
||||
resultEscapesNonReturn(operand.getUse())
|
||||
or
|
||||
operandEscapesDomain(operand)
|
||||
}
|
||||
|
||||
@@ -236,9 +237,6 @@ private predicate operandMayReachReturn(Operand operand) {
|
||||
operand.getUse() instanceof ReturnValueInstruction
|
||||
or
|
||||
isOnlyEscapesViaReturnArgument(operand) and resultMayReachReturn(operand.getUse())
|
||||
or
|
||||
operand instanceof PhiInputOperand and
|
||||
resultMayReachReturn(operand.getUse())
|
||||
}
|
||||
|
||||
private predicate operandReturned(Operand operand, IntValue bitOffset) {
|
||||
|
||||
@@ -101,6 +101,8 @@ class IndirectParameterAllocation extends Allocation, TIndirectParameterAllocati
|
||||
final override predicate isAlwaysAllocatedOnStack() { none() }
|
||||
|
||||
final override predicate alwaysEscapes() { none() }
|
||||
|
||||
final IRAutomaticVariable getIRVariable() { result = var }
|
||||
}
|
||||
|
||||
class DynamicAllocation extends Allocation, TDynamicAllocation {
|
||||
|
||||
@@ -8,6 +8,7 @@ private import semmle.code.cpp.ir.internal.IntegerConstant as Ints
|
||||
private import semmle.code.cpp.ir.internal.IntegerInterval as Interval
|
||||
private import semmle.code.cpp.ir.implementation.internal.OperandTag
|
||||
private import AliasConfiguration
|
||||
private import codeql.util.Boolean
|
||||
|
||||
private class IntValue = Ints::IntValue;
|
||||
|
||||
@@ -16,49 +17,196 @@ private predicate isIndirectOrBufferMemoryAccess(MemoryAccessKind kind) {
|
||||
kind instanceof BufferMemoryAccess
|
||||
}
|
||||
|
||||
private predicate hasResultMemoryAccess(
|
||||
Instruction instr, Allocation var, IRType type, Language::LanguageType languageType,
|
||||
IntValue startBitOffset, IntValue endBitOffset, boolean isMayAccess
|
||||
private predicate hasMemoryAccess(
|
||||
AddressOperand addrOperand, Allocation var, IntValue startBitOffset, boolean grouped
|
||||
) {
|
||||
exists(AddressOperand addrOperand |
|
||||
addrOperand = instr.getResultAddressOperand() and
|
||||
addressOperandAllocationAndOffset(addrOperand, var, startBitOffset) and
|
||||
languageType = instr.getResultLanguageType() and
|
||||
type = languageType.getIRType() and
|
||||
isIndirectOrBufferMemoryAccess(instr.getResultMemoryAccess()) and
|
||||
(if instr.hasResultMayMemoryAccess() then isMayAccess = true else isMayAccess = false) and
|
||||
if exists(type.getByteSize())
|
||||
then endBitOffset = Ints::add(startBitOffset, Ints::mul(type.getByteSize(), 8))
|
||||
else endBitOffset = Ints::unknown()
|
||||
)
|
||||
addressOperandAllocationAndOffset(addrOperand, var, startBitOffset) and
|
||||
if strictcount(Allocation alloc | addressOperandAllocationAndOffset(addrOperand, alloc, _)) > 1
|
||||
then grouped = true
|
||||
else grouped = false
|
||||
}
|
||||
|
||||
private predicate hasResultMemoryAccess(
|
||||
AddressOperand address, Instruction instr, Allocation var, IRType type,
|
||||
Language::LanguageType languageType, IntValue startBitOffset, IntValue endBitOffset,
|
||||
boolean isMayAccess, boolean grouped
|
||||
) {
|
||||
address = instr.getResultAddressOperand() and
|
||||
hasMemoryAccess(address, var, startBitOffset, grouped) and
|
||||
languageType = instr.getResultLanguageType() and
|
||||
type = languageType.getIRType() and
|
||||
isIndirectOrBufferMemoryAccess(instr.getResultMemoryAccess()) and
|
||||
(if instr.hasResultMayMemoryAccess() then isMayAccess = true else isMayAccess = false) and
|
||||
if exists(type.getByteSize())
|
||||
then endBitOffset = Ints::add(startBitOffset, Ints::mul(type.getByteSize(), 8))
|
||||
else endBitOffset = Ints::unknown()
|
||||
}
|
||||
|
||||
private predicate hasOperandMemoryAccess(
|
||||
MemoryOperand operand, Allocation var, IRType type, Language::LanguageType languageType,
|
||||
IntValue startBitOffset, IntValue endBitOffset, boolean isMayAccess
|
||||
AddressOperand address, MemoryOperand operand, Allocation var, IRType type,
|
||||
Language::LanguageType languageType, IntValue startBitOffset, IntValue endBitOffset,
|
||||
boolean isMayAccess, boolean grouped
|
||||
) {
|
||||
exists(AddressOperand addrOperand |
|
||||
addrOperand = operand.getAddressOperand() and
|
||||
addressOperandAllocationAndOffset(addrOperand, var, startBitOffset) and
|
||||
languageType = operand.getLanguageType() and
|
||||
type = languageType.getIRType() and
|
||||
isIndirectOrBufferMemoryAccess(operand.getMemoryAccess()) and
|
||||
(if operand.hasMayReadMemoryAccess() then isMayAccess = true else isMayAccess = false) and
|
||||
if exists(type.getByteSize())
|
||||
then endBitOffset = Ints::add(startBitOffset, Ints::mul(type.getByteSize(), 8))
|
||||
else endBitOffset = Ints::unknown()
|
||||
address = operand.getAddressOperand() and
|
||||
hasMemoryAccess(address, var, startBitOffset, grouped) and
|
||||
languageType = operand.getLanguageType() and
|
||||
type = languageType.getIRType() and
|
||||
isIndirectOrBufferMemoryAccess(operand.getMemoryAccess()) and
|
||||
(if operand.hasMayReadMemoryAccess() then isMayAccess = true else isMayAccess = false) and
|
||||
if exists(type.getByteSize())
|
||||
then endBitOffset = Ints::add(startBitOffset, Ints::mul(type.getByteSize(), 8))
|
||||
else endBitOffset = Ints::unknown()
|
||||
}
|
||||
|
||||
private Allocation getAnAllocation(AddressOperand address) {
|
||||
hasResultMemoryAccess(address, _, result, _, _, _, _, _, true) or
|
||||
hasOperandMemoryAccess(address, _, result, _, _, _, _, _, true)
|
||||
}
|
||||
|
||||
private module AllocationSet0 =
|
||||
QlBuiltins::InternSets<AddressOperand, Allocation, getAnAllocation/1>;
|
||||
|
||||
/**
|
||||
* A set of allocations containing at least 2 elements.
|
||||
*/
|
||||
private class NonSingletonSets extends AllocationSet0::Set {
|
||||
NonSingletonSets() { strictcount(Allocation var | this.contains(var)) > 1 }
|
||||
|
||||
/** Gets an allocation from this set. */
|
||||
Allocation getAnAllocation() { this.contains(result) }
|
||||
|
||||
/** Gets the string representation of this set. */
|
||||
string toString() { result = "{" + strictconcat(this.getAnAllocation().toString(), ", ") + "}" }
|
||||
}
|
||||
|
||||
/** Holds the instersection of `s1` and `s2` is non-empty. */
|
||||
private predicate hasOverlappingElement(NonSingletonSets s1, NonSingletonSets s2) {
|
||||
exists(Allocation var |
|
||||
s1.contains(var) and
|
||||
s2.contains(var)
|
||||
)
|
||||
}
|
||||
|
||||
private module AllocationSet =
|
||||
QlBuiltins::EquivalenceRelation<NonSingletonSets, hasOverlappingElement/2>;
|
||||
|
||||
/**
|
||||
* Holds if `var` is created by the AST element `e`. Furthermore, the value `d`
|
||||
* represents which branch of the `Allocation` type `var` is from.
|
||||
*/
|
||||
private predicate allocationAst(Allocation var, @element e, int d) {
|
||||
var.(VariableAllocation).getIRVariable().getAst() = e and d = 0
|
||||
or
|
||||
var.(IndirectParameterAllocation).getIRVariable().getAst() = e and d = 1
|
||||
or
|
||||
var.(DynamicAllocation).getABaseInstruction().getAst() = e and d = 2
|
||||
}
|
||||
|
||||
/** Holds if `x = y` and `x` is an AST element that creates an `Allocation`. */
|
||||
private predicate id(@element x, @element y) {
|
||||
allocationAst(_, x, _) and
|
||||
x = y
|
||||
}
|
||||
|
||||
private predicate idOf(@element x, int y) = equivalenceRelation(id/2)(x, y)
|
||||
|
||||
/** Gets a unique integer representation of `var`. */
|
||||
private int getUniqueAllocationId(Allocation var) {
|
||||
exists(int r, @element e, int d |
|
||||
allocationAst(var, e, d) and
|
||||
idOf(e, r) and
|
||||
result = 3 * r + d
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* An equivalence class of a set of allocations.
|
||||
*
|
||||
* Any `VariableGroup` will be completely disjunct from any other
|
||||
* `VariableGroup`.
|
||||
*/
|
||||
class VariableGroup extends AllocationSet::EquivalenceClass {
|
||||
/** Gets the location of this set. */
|
||||
final Location getLocation() { result = this.getIRFunction().getLocation() }
|
||||
|
||||
/** Gets the enclosing `IRFunction` of this set. */
|
||||
final IRFunction getIRFunction() {
|
||||
result = unique( | | this.getAnAllocation().getEnclosingIRFunction())
|
||||
}
|
||||
|
||||
/** Gets the type of elements contained in this set. */
|
||||
final Language::LanguageType getType() {
|
||||
strictcount(Language::LanguageType langType |
|
||||
exists(Allocation var | var = this.getAnAllocation() |
|
||||
hasResultMemoryAccess(_, _, var, _, langType, _, _, _, true) or
|
||||
hasOperandMemoryAccess(_, _, var, _, langType, _, _, _, true)
|
||||
)
|
||||
) = 1 and
|
||||
exists(Allocation var | var = this.getAnAllocation() |
|
||||
hasResultMemoryAccess(_, _, var, _, result, _, _, _, true) or
|
||||
hasOperandMemoryAccess(_, _, var, _, result, _, _, _, true)
|
||||
)
|
||||
or
|
||||
strictcount(Language::LanguageType langType |
|
||||
exists(Allocation var | var = this.getAnAllocation() |
|
||||
hasResultMemoryAccess(_, _, var, _, langType, _, _, _, true) or
|
||||
hasOperandMemoryAccess(_, _, var, _, langType, _, _, _, true)
|
||||
)
|
||||
) > 1 and
|
||||
result = any(IRUnknownType type).getCanonicalLanguageType()
|
||||
}
|
||||
|
||||
/** Gets an allocation of this set. */
|
||||
final Allocation getAnAllocation() {
|
||||
exists(AllocationSet0::Set set |
|
||||
this = AllocationSet::getEquivalenceClass(set) and
|
||||
set.contains(result)
|
||||
)
|
||||
}
|
||||
|
||||
/** Gets a unique string representing this set. */
|
||||
final private string getUniqueId() {
|
||||
result = strictconcat(getUniqueAllocationId(this.getAnAllocation()).toString(), ",")
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the order that this set should be initialized in.
|
||||
*
|
||||
* Note: This is _not_ the order in which the _members_ of the set should be
|
||||
* initialized. Rather, it represents the order in which the set should be
|
||||
* initialized in relation to other sets. That is, if
|
||||
* ```
|
||||
* getInitializationOrder() = 2
|
||||
* ```
|
||||
* then this set will be initialized as the second (third) set in the
|
||||
* enclosing function. In order words, the third `UninitializedGroup`
|
||||
* instruction in the entry block of the enclosing function will initialize
|
||||
* this set of allocations.
|
||||
*/
|
||||
final int getInitializationOrder() {
|
||||
exists(IRFunction func |
|
||||
func = this.getIRFunction() and
|
||||
this =
|
||||
rank[result + 1](VariableGroup vg, string uniq |
|
||||
vg.getIRFunction() = func and uniq = vg.getUniqueId()
|
||||
|
|
||||
vg order by uniq
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
string toString() { result = "{" + strictconcat(this.getAnAllocation().toString(), ", ") + "}" }
|
||||
}
|
||||
|
||||
private newtype TMemoryLocation =
|
||||
TVariableMemoryLocation(
|
||||
Allocation var, IRType type, Language::LanguageType languageType, IntValue startBitOffset,
|
||||
IntValue endBitOffset, boolean isMayAccess
|
||||
) {
|
||||
(
|
||||
hasResultMemoryAccess(_, var, type, _, startBitOffset, endBitOffset, isMayAccess)
|
||||
hasResultMemoryAccess(_, _, var, type, _, startBitOffset, endBitOffset, isMayAccess, false)
|
||||
or
|
||||
hasOperandMemoryAccess(_, var, type, _, startBitOffset, endBitOffset, isMayAccess)
|
||||
hasOperandMemoryAccess(_, _, var, type, _, startBitOffset, endBitOffset, isMayAccess, false)
|
||||
or
|
||||
// For a stack variable, always create a memory location for the entire variable.
|
||||
var.isAlwaysAllocatedOnStack() and
|
||||
@@ -69,22 +217,14 @@ private newtype TMemoryLocation =
|
||||
) and
|
||||
languageType = type.getCanonicalLanguageType()
|
||||
} or
|
||||
TEntireAllocationMemoryLocation(Allocation var, boolean isMayAccess) {
|
||||
(
|
||||
var instanceof IndirectParameterAllocation or
|
||||
var instanceof DynamicAllocation
|
||||
) and
|
||||
(isMayAccess = false or isMayAccess = true)
|
||||
TEntireAllocationMemoryLocation(Allocation var, Boolean isMayAccess) {
|
||||
var instanceof IndirectParameterAllocation or
|
||||
var instanceof DynamicAllocation
|
||||
} or
|
||||
TUnknownMemoryLocation(IRFunction irFunc, boolean isMayAccess) {
|
||||
isMayAccess = false or isMayAccess = true
|
||||
} or
|
||||
TAllNonLocalMemory(IRFunction irFunc, boolean isMayAccess) {
|
||||
isMayAccess = false or isMayAccess = true
|
||||
} or
|
||||
TAllAliasedMemory(IRFunction irFunc, boolean isMayAccess) {
|
||||
isMayAccess = false or isMayAccess = true
|
||||
}
|
||||
TGroupedMemoryLocation(VariableGroup vg, Boolean isMayAccess, Boolean isAll) or
|
||||
TUnknownMemoryLocation(IRFunction irFunc, Boolean isMayAccess) or
|
||||
TAllNonLocalMemory(IRFunction irFunc, Boolean isMayAccess) or
|
||||
TAllAliasedMemory(IRFunction irFunc, Boolean isMayAccess)
|
||||
|
||||
/**
|
||||
* Represents the memory location accessed by a memory operand or memory result. In this implementation, the location is
|
||||
@@ -116,7 +256,14 @@ abstract class MemoryLocation extends TMemoryLocation {
|
||||
|
||||
abstract predicate isMayAccess();
|
||||
|
||||
Allocation getAllocation() { none() }
|
||||
/**
|
||||
* Gets an allocation associated with this `MemoryLocation`.
|
||||
*
|
||||
* This returns zero or one results in all cases except when `this` is an
|
||||
* instance of `GroupedMemoryLocation`. When `this` is an instance of
|
||||
* `GroupedMemoryLocation` this predicate always returns two or more results.
|
||||
*/
|
||||
Allocation getAnAllocation() { none() }
|
||||
|
||||
/**
|
||||
* Holds if the location cannot be overwritten except by definition of a `MemoryLocation` for
|
||||
@@ -153,24 +300,29 @@ abstract class AllocationMemoryLocation extends MemoryLocation {
|
||||
Allocation var;
|
||||
boolean isMayAccess;
|
||||
|
||||
AllocationMemoryLocation() {
|
||||
this instanceof TMemoryLocation and
|
||||
isMayAccess = false
|
||||
or
|
||||
isMayAccess = true // Just ensures that `isMayAccess` is bound.
|
||||
}
|
||||
bindingset[isMayAccess]
|
||||
AllocationMemoryLocation() { any() }
|
||||
|
||||
final override VirtualVariable getVirtualVariable() {
|
||||
if allocationEscapes(var)
|
||||
then result = TAllAliasedMemory(var.getEnclosingIRFunction(), false)
|
||||
else result.(AllocationMemoryLocation).getAllocation() = var
|
||||
else (
|
||||
// It may be that the grouped memory location contains an escaping
|
||||
// allocation. In that case, the virtual variable is still the memory
|
||||
// location that represents all aliased memory. Thus, we need to
|
||||
// call `getVirtualVariable` on the grouped memory location.
|
||||
result = getGroupedMemoryLocation(var, false, false).getVirtualVariable()
|
||||
or
|
||||
not exists(getGroupedMemoryLocation(var, false, false)) and
|
||||
result.(AllocationMemoryLocation).getAnAllocation() = var
|
||||
)
|
||||
}
|
||||
|
||||
final override IRFunction getIRFunction() { result = var.getEnclosingIRFunction() }
|
||||
|
||||
final override Location getLocation() { result = var.getLocation() }
|
||||
|
||||
final override Allocation getAllocation() { result = var }
|
||||
final override Allocation getAnAllocation() { result = var }
|
||||
|
||||
final override predicate isMayAccess() { isMayAccess = true }
|
||||
|
||||
@@ -211,13 +363,13 @@ class VariableMemoryLocation extends TVariableMemoryLocation, AllocationMemoryLo
|
||||
final override Language::LanguageType getType() {
|
||||
if
|
||||
strictcount(Language::LanguageType accessType |
|
||||
hasResultMemoryAccess(_, var, type, accessType, startBitOffset, endBitOffset, _) or
|
||||
hasOperandMemoryAccess(_, var, type, accessType, startBitOffset, endBitOffset, _)
|
||||
hasResultMemoryAccess(_, _, var, type, accessType, startBitOffset, endBitOffset, _, false) or
|
||||
hasOperandMemoryAccess(_, _, var, type, accessType, startBitOffset, endBitOffset, _, false)
|
||||
) = 1
|
||||
then
|
||||
// All of the accesses have the same `LanguageType`, so just use that.
|
||||
hasResultMemoryAccess(_, var, type, result, startBitOffset, endBitOffset, _) or
|
||||
hasOperandMemoryAccess(_, var, type, result, startBitOffset, endBitOffset, _)
|
||||
hasResultMemoryAccess(_, _, var, type, result, startBitOffset, endBitOffset, _, false) or
|
||||
hasOperandMemoryAccess(_, _, var, type, result, startBitOffset, endBitOffset, _, false)
|
||||
else
|
||||
// There is no single type for all accesses, so just use the canonical one for this `IRType`.
|
||||
result = type.getCanonicalLanguageType()
|
||||
@@ -247,6 +399,89 @@ class VariableMemoryLocation extends TVariableMemoryLocation, AllocationMemoryLo
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A group of allocations represented as a single memory location.
|
||||
*
|
||||
* If `isAll()` holds then this memory location represents all the enclosing
|
||||
* allocations, and if `isSome()` holds then this memory location represents
|
||||
* one or more of the enclosing allocations.
|
||||
*
|
||||
* For example, consider the following snippet:
|
||||
* ```
|
||||
* int* p;
|
||||
* int a, b;
|
||||
* if(b) {
|
||||
* p = &a;
|
||||
* } else {
|
||||
* p = &b;
|
||||
* }
|
||||
* *p = 42;
|
||||
* ```
|
||||
*
|
||||
* The write memory location associated with the write to `*p` writes to a
|
||||
* grouped memory location representing the _some_ allocation in the set
|
||||
* `{a, b}`, and the subsequent `Chi` instruction merges the new value of
|
||||
* `{a, b}` into a memory location that represents _all_ of the allocations
|
||||
* in the set.
|
||||
*/
|
||||
class GroupedMemoryLocation extends TGroupedMemoryLocation, MemoryLocation {
|
||||
VariableGroup vg;
|
||||
boolean isMayAccess;
|
||||
boolean isAll;
|
||||
|
||||
GroupedMemoryLocation() { this = TGroupedMemoryLocation(vg, isMayAccess, isAll) }
|
||||
|
||||
final override Location getLocation() { result = vg.getLocation() }
|
||||
|
||||
final override IRFunction getIRFunction() { result = vg.getIRFunction() }
|
||||
|
||||
final override predicate isMayAccess() { isMayAccess = true }
|
||||
|
||||
final override string getUniqueId() {
|
||||
if this.isAll()
|
||||
then result = "All{" + strictconcat(vg.getAnAllocation().getUniqueId(), ", ") + "}"
|
||||
else result = "Some{" + strictconcat(vg.getAnAllocation().getUniqueId(), ", ") + "}"
|
||||
}
|
||||
|
||||
final override string toStringInternal() { result = this.getUniqueId() }
|
||||
|
||||
final override Language::LanguageType getType() { result = vg.getType() }
|
||||
|
||||
final override VirtualVariable getVirtualVariable() {
|
||||
if allocationEscapes(this.getAnAllocation())
|
||||
then result = TAllAliasedMemory(vg.getIRFunction(), false)
|
||||
else result = TGroupedMemoryLocation(vg, false, true)
|
||||
}
|
||||
|
||||
/** Gets an allocation of this memory location. */
|
||||
override Allocation getAnAllocation() { result = vg.getAnAllocation() }
|
||||
|
||||
/** Gets the set of allocations associated with this memory location. */
|
||||
VariableGroup getGroup() { result = vg }
|
||||
|
||||
/** Holds if this memory location represents all the enclosing allocations. */
|
||||
predicate isAll() { isAll = true }
|
||||
|
||||
/** Holds if this memory location represents one or more of the enclosing allocations. */
|
||||
predicate isSome() { isAll = false }
|
||||
}
|
||||
|
||||
private GroupedMemoryLocation getGroupedMemoryLocation(
|
||||
Allocation alloc, boolean isMayAccess, boolean isAll
|
||||
) {
|
||||
result.getAnAllocation() = alloc and
|
||||
(
|
||||
isMayAccess = true and result.isMayAccess()
|
||||
or
|
||||
isMayAccess = false and not result.isMayAccess()
|
||||
) and
|
||||
(
|
||||
isAll = true and result.isAll()
|
||||
or
|
||||
isAll = false and result.isSome()
|
||||
)
|
||||
}
|
||||
|
||||
class EntireAllocationMemoryLocation extends TEntireAllocationMemoryLocation,
|
||||
AllocationMemoryLocation
|
||||
{
|
||||
@@ -282,6 +517,14 @@ class VariableVirtualVariable extends VariableMemoryLocation, VirtualVariable {
|
||||
}
|
||||
}
|
||||
|
||||
class GroupedVirtualVariable extends GroupedMemoryLocation, VirtualVariable {
|
||||
GroupedVirtualVariable() {
|
||||
forex(Allocation var | var = this.getAnAllocation() | not allocationEscapes(var)) and
|
||||
not this.isMayAccess() and
|
||||
this.isAll()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* An access to memory that is not known to be confined to a specific `IRVariable`.
|
||||
*/
|
||||
@@ -446,7 +689,7 @@ private Overlap getExtentOverlap(MemoryLocation def, MemoryLocation use) {
|
||||
result instanceof MustExactlyOverlap
|
||||
or
|
||||
not use instanceof EntireAllocationMemoryLocation and
|
||||
if def.getAllocation() = use.getAllocation()
|
||||
if def.getAnAllocation() = use.getAnAllocation()
|
||||
then
|
||||
// EntireAllocationMemoryLocation totally overlaps any location within
|
||||
// the same allocation.
|
||||
@@ -454,11 +697,48 @@ private Overlap getExtentOverlap(MemoryLocation def, MemoryLocation use) {
|
||||
else (
|
||||
// There is no overlap with a location that's known to belong to a
|
||||
// different allocation, but all other locations may partially overlap.
|
||||
not exists(use.getAllocation()) and
|
||||
not exists(use.getAnAllocation()) and
|
||||
result instanceof MayPartiallyOverlap
|
||||
)
|
||||
)
|
||||
or
|
||||
exists(GroupedMemoryLocation group |
|
||||
group = def and
|
||||
def.getVirtualVariable() = use.getVirtualVariable()
|
||||
|
|
||||
(
|
||||
use instanceof UnknownMemoryLocation or
|
||||
use instanceof AllAliasedMemory
|
||||
) and
|
||||
result instanceof MayPartiallyOverlap
|
||||
or
|
||||
group.isAll() and
|
||||
(
|
||||
group.getAnAllocation() =
|
||||
[
|
||||
use.(EntireAllocationMemoryLocation).getAnAllocation(),
|
||||
use.(VariableMemoryLocation).getAnAllocation()
|
||||
]
|
||||
or
|
||||
use.(GroupedMemoryLocation).isSome()
|
||||
) and
|
||||
result instanceof MustTotallyOverlap
|
||||
or
|
||||
group.isAll() and
|
||||
use.(GroupedMemoryLocation).isAll() and
|
||||
result instanceof MustExactlyOverlap
|
||||
or
|
||||
group.isSome() and
|
||||
(
|
||||
use instanceof EntireAllocationMemoryLocation
|
||||
or
|
||||
use instanceof VariableMemoryLocation
|
||||
or
|
||||
use instanceof GroupedMemoryLocation
|
||||
) and
|
||||
result instanceof MayPartiallyOverlap
|
||||
)
|
||||
or
|
||||
exists(VariableMemoryLocation defVariableLocation |
|
||||
defVariableLocation = def and
|
||||
(
|
||||
@@ -468,7 +748,8 @@ private Overlap getExtentOverlap(MemoryLocation def, MemoryLocation use) {
|
||||
(
|
||||
use instanceof UnknownMemoryLocation or
|
||||
use instanceof AllAliasedMemory or
|
||||
use instanceof EntireAllocationMemoryLocation
|
||||
use instanceof EntireAllocationMemoryLocation or
|
||||
use instanceof GroupedMemoryLocation
|
||||
) and
|
||||
result instanceof MayPartiallyOverlap
|
||||
or
|
||||
@@ -534,7 +815,7 @@ private predicate isCoveredOffset(Allocation var, int offsetRank, VariableMemory
|
||||
exists(int startRank, int endRank, VirtualVariable vvar |
|
||||
vml.getStartBitOffset() = rank[startRank](IntValue offset_ | isRelevantOffset(vvar, offset_)) and
|
||||
vml.getEndBitOffset() = rank[endRank](IntValue offset_ | isRelevantOffset(vvar, offset_)) and
|
||||
var = vml.getAllocation() and
|
||||
var = vml.getAnAllocation() and
|
||||
vvar = vml.getVirtualVariable() and
|
||||
isRelatableMemoryLocation(vml) and
|
||||
offsetRank in [startRank .. endRank]
|
||||
@@ -542,7 +823,7 @@ private predicate isCoveredOffset(Allocation var, int offsetRank, VariableMemory
|
||||
}
|
||||
|
||||
private predicate hasUnknownOffset(Allocation var, VariableMemoryLocation vml) {
|
||||
vml.getAllocation() = var and
|
||||
vml.getAnAllocation() = var and
|
||||
(
|
||||
vml.getStartBitOffset() = Ints::unknown() or
|
||||
vml.getEndBitOffset() = Ints::unknown()
|
||||
@@ -557,9 +838,9 @@ private predicate overlappingIRVariableMemoryLocations(
|
||||
isCoveredOffset(var, offsetRank, use)
|
||||
)
|
||||
or
|
||||
hasUnknownOffset(use.getAllocation(), def)
|
||||
hasUnknownOffset(use.getAnAllocation(), def)
|
||||
or
|
||||
hasUnknownOffset(def.getAllocation(), use)
|
||||
hasUnknownOffset(def.getAnAllocation(), use)
|
||||
}
|
||||
|
||||
private Overlap getVariableMemoryLocationOverlap(
|
||||
@@ -588,13 +869,24 @@ MemoryLocation getResultMemoryLocation(Instruction instr) {
|
||||
(
|
||||
(
|
||||
isIndirectOrBufferMemoryAccess(kind) and
|
||||
if hasResultMemoryAccess(instr, _, _, _, _, _, _)
|
||||
if hasResultMemoryAccess(_, instr, _, _, _, _, _, _, _)
|
||||
then
|
||||
exists(Allocation var, IRType type, IntValue startBitOffset, IntValue endBitOffset |
|
||||
hasResultMemoryAccess(instr, var, type, _, startBitOffset, endBitOffset, isMayAccess) and
|
||||
result =
|
||||
TVariableMemoryLocation(var, type, _, startBitOffset, endBitOffset,
|
||||
unbindBool(isMayAccess))
|
||||
exists(
|
||||
Allocation var, IRType type, IntValue startBitOffset, IntValue endBitOffset,
|
||||
boolean grouped
|
||||
|
|
||||
hasResultMemoryAccess(_, instr, var, type, _, startBitOffset, endBitOffset, isMayAccess,
|
||||
grouped)
|
||||
|
|
||||
// If the instruction is only associated with one allocation we assign it a `VariableMemoryLocation`
|
||||
if grouped = false
|
||||
then
|
||||
result =
|
||||
TVariableMemoryLocation(var, type, _, startBitOffset, endBitOffset,
|
||||
unbindBool(isMayAccess))
|
||||
else
|
||||
// And otherwise we assign it a memory location that groups all the relevant memory locations into one.
|
||||
result = getGroupedMemoryLocation(var, unbindBool(isMayAccess), false)
|
||||
)
|
||||
else result = TUnknownMemoryLocation(instr.getEnclosingIRFunction(), isMayAccess)
|
||||
)
|
||||
@@ -621,12 +913,23 @@ MemoryLocation getOperandMemoryLocation(MemoryOperand operand) {
|
||||
(
|
||||
(
|
||||
isIndirectOrBufferMemoryAccess(kind) and
|
||||
if hasOperandMemoryAccess(operand, _, _, _, _, _, _)
|
||||
if hasOperandMemoryAccess(_, operand, _, _, _, _, _, _, _)
|
||||
then
|
||||
exists(Allocation var, IRType type, IntValue startBitOffset, IntValue endBitOffset |
|
||||
hasOperandMemoryAccess(operand, var, type, _, startBitOffset, endBitOffset, isMayAccess) and
|
||||
result =
|
||||
TVariableMemoryLocation(var, type, _, startBitOffset, endBitOffset, isMayAccess)
|
||||
exists(
|
||||
Allocation var, IRType type, IntValue startBitOffset, IntValue endBitOffset,
|
||||
boolean grouped
|
||||
|
|
||||
hasOperandMemoryAccess(_, operand, var, type, _, startBitOffset, endBitOffset,
|
||||
isMayAccess, grouped)
|
||||
|
|
||||
// If the operand is only associated with one memory location we assign it a `VariableMemoryLocation`
|
||||
if grouped = false
|
||||
then
|
||||
result =
|
||||
TVariableMemoryLocation(var, type, _, startBitOffset, endBitOffset, isMayAccess)
|
||||
else
|
||||
// And otherwise we assign it a memory location that groups all relevant memory locations into one.
|
||||
result = getGroupedMemoryLocation(var, isMayAccess, false)
|
||||
)
|
||||
else result = TUnknownMemoryLocation(operand.getEnclosingIRFunction(), isMayAccess)
|
||||
)
|
||||
|
||||
@@ -15,6 +15,51 @@ private class OldInstruction = Reachability::ReachableInstruction;
|
||||
|
||||
import Cached
|
||||
|
||||
/**
|
||||
* Holds if `instruction` is the first instruction that may be followed by
|
||||
* an `UninitializedGroup` instruction, and the enclosing function of
|
||||
* `instruction` is `func`.
|
||||
*/
|
||||
private predicate isFirstInstructionBeforeUninitializedGroup(
|
||||
Instruction instruction, IRFunction func
|
||||
) {
|
||||
instruction = getChi(any(OldIR::InitializeNonLocalInstruction init)) and
|
||||
func = instruction.getEnclosingIRFunction()
|
||||
}
|
||||
|
||||
/** Gets the `i`'th `UninitializedGroup` instruction in `func`. */
|
||||
private UninitializedGroupInstruction getInitGroupInstruction(int i, IRFunction func) {
|
||||
exists(Alias::VariableGroup vg |
|
||||
vg.getIRFunction() = func and
|
||||
vg.getInitializationOrder() = i and
|
||||
result = uninitializedGroup(vg)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `instruction` is the last instruction in the chain of `UninitializedGroup`
|
||||
* instructions in `func`. The chain of instructions may be empty in which case
|
||||
* `instruction` satisfies
|
||||
* ```
|
||||
* isFirstInstructionBeforeUninitializedGroup(instruction, func)
|
||||
* ```
|
||||
*/
|
||||
predicate isLastInstructionForUninitializedGroups(Instruction instruction, IRFunction func) {
|
||||
exists(int i |
|
||||
instruction = getInitGroupInstruction(i, func) and
|
||||
not exists(getChi(instruction)) and
|
||||
not exists(getInitGroupInstruction(i + 1, func))
|
||||
)
|
||||
or
|
||||
exists(int i |
|
||||
instruction = getChi(getInitGroupInstruction(i, func)) and
|
||||
not exists(getInitGroupInstruction(i + 1, func))
|
||||
)
|
||||
or
|
||||
isFirstInstructionBeforeUninitializedGroup(instruction, func) and
|
||||
not exists(getInitGroupInstruction(0, func))
|
||||
}
|
||||
|
||||
cached
|
||||
private module Cached {
|
||||
cached
|
||||
@@ -32,6 +77,11 @@ private module Cached {
|
||||
hasChiNode(_, primaryInstruction)
|
||||
}
|
||||
|
||||
cached
|
||||
predicate hasChiNodeAfterUninitializedGroup(UninitializedGroupInstruction initGroup) {
|
||||
hasChiNodeAfterUninitializedGroup(_, initGroup)
|
||||
}
|
||||
|
||||
cached
|
||||
predicate hasUnreachedInstructionCached(IRFunction irFunc) {
|
||||
exists(OldIR::Instruction oldInstruction |
|
||||
@@ -45,7 +95,8 @@ private module Cached {
|
||||
}
|
||||
|
||||
class TStageInstruction =
|
||||
TRawInstruction or TPhiInstruction or TChiInstruction or TUnreachedInstruction;
|
||||
TRawInstruction or TPhiInstruction or TChiInstruction or TUnreachedInstruction or
|
||||
TUninitializedGroupInstruction;
|
||||
|
||||
/**
|
||||
* If `oldInstruction` is a `Phi` instruction that has exactly one reachable predecessor block,
|
||||
@@ -78,6 +129,8 @@ private module Cached {
|
||||
or
|
||||
instr instanceof TChiInstruction
|
||||
or
|
||||
instr instanceof TUninitializedGroupInstruction
|
||||
or
|
||||
instr instanceof TUnreachedInstruction
|
||||
}
|
||||
|
||||
@@ -123,7 +176,8 @@ private module Cached {
|
||||
predicate hasModeledMemoryResult(Instruction instruction) {
|
||||
canModelResultForOldInstruction(getOldInstruction(instruction)) or
|
||||
instruction instanceof PhiInstruction or // Phis always have modeled results
|
||||
instruction instanceof ChiInstruction // Chis always have modeled results
|
||||
instruction instanceof ChiInstruction or // Chis always have modeled results
|
||||
instruction instanceof UninitializedGroupInstruction // Group initializers always have modeled results
|
||||
}
|
||||
|
||||
cached
|
||||
@@ -134,16 +188,23 @@ private module Cached {
|
||||
or
|
||||
// Chi instructions track virtual variables, and therefore a chi instruction is
|
||||
// conflated if it's associated with the aliased virtual variable.
|
||||
exists(OldInstruction oldInstruction | instruction = getChi(oldInstruction) |
|
||||
Alias::getResultMemoryLocation(oldInstruction).getVirtualVariable() instanceof
|
||||
exists(Instruction input | instruction = getChi(input) |
|
||||
Alias::getResultMemoryLocation(input).getVirtualVariable() instanceof
|
||||
Alias::AliasedVirtualVariable
|
||||
or
|
||||
// A chi following an `UninitializedGroupInstruction` only happens when the virtual
|
||||
// variable of the grouped memory location is `{AllAliasedMemory}`.
|
||||
exists(Alias::GroupedMemoryLocation gml |
|
||||
input = uninitializedGroup(gml.getGroup()) and
|
||||
gml.getVirtualVariable() instanceof Alias::AliasedVirtualVariable
|
||||
)
|
||||
)
|
||||
or
|
||||
// Phi instructions track locations, and therefore a phi instruction is
|
||||
// conflated if it's associated with a conflated location.
|
||||
exists(Alias::MemoryLocation location |
|
||||
instruction = getPhi(_, location) and
|
||||
not exists(location.getAllocation())
|
||||
not exists(location.getAnAllocation())
|
||||
)
|
||||
}
|
||||
|
||||
@@ -205,7 +266,11 @@ private module Cached {
|
||||
hasMemoryOperandDefinition(oldInstruction, oldOperand, overlap, result)
|
||||
)
|
||||
or
|
||||
instruction = getChi(getOldInstruction(result)) and
|
||||
(
|
||||
instruction = getChi(getOldInstruction(result))
|
||||
or
|
||||
instruction = getChi(result.(UninitializedGroupInstruction))
|
||||
) and
|
||||
tag instanceof ChiPartialOperandTag and
|
||||
overlap instanceof MustExactlyOverlap
|
||||
or
|
||||
@@ -263,6 +328,14 @@ private module Cached {
|
||||
)
|
||||
}
|
||||
|
||||
cached
|
||||
IRVariable getAnUninitializedGroupVariable(UninitializedGroupInstruction init) {
|
||||
exists(Alias::VariableGroup vg |
|
||||
init = uninitializedGroup(vg) and
|
||||
result = vg.getAnAllocation().getABaseInstruction().(VariableInstruction).getIRVariable()
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `instr` is part of a cycle in the operand graph that doesn't go
|
||||
* through a phi instruction and therefore should be impossible.
|
||||
@@ -316,6 +389,19 @@ private module Cached {
|
||||
result = getNewPhiOperandDefinitionFromOldSsa(instr, newPredecessorBlock, overlap)
|
||||
}
|
||||
|
||||
private ChiInstruction getChiAfterUninitializedGroup(int i, IRFunction func) {
|
||||
result =
|
||||
rank[i + 1](VariableGroup vg, UninitializedGroupInstruction initGroup, ChiInstruction chi,
|
||||
int r |
|
||||
initGroup.getEnclosingIRFunction() = func and
|
||||
chi = getChi(initGroup) and
|
||||
initGroup = uninitializedGroup(vg) and
|
||||
r = vg.getInitializationOrder()
|
||||
|
|
||||
chi order by r
|
||||
)
|
||||
}
|
||||
|
||||
cached
|
||||
Instruction getChiInstructionTotalOperand(ChiInstruction chiInstr) {
|
||||
exists(
|
||||
@@ -329,6 +415,19 @@ private module Cached {
|
||||
definitionReachesUse(vvar, defBlock, defRank, useBlock, useRank) and
|
||||
result = getDefinitionOrChiInstruction(defBlock, defOffset, vvar, _)
|
||||
)
|
||||
or
|
||||
exists(UninitializedGroupInstruction initGroup, IRFunction func |
|
||||
chiInstr = getChi(initGroup) and
|
||||
func = initGroup.getEnclosingIRFunction()
|
||||
|
|
||||
chiInstr = getChiAfterUninitializedGroup(0, func) and
|
||||
isFirstInstructionBeforeUninitializedGroup(result, func)
|
||||
or
|
||||
exists(int i |
|
||||
chiInstr = getChiAfterUninitializedGroup(i + 1, func) and
|
||||
result = getChiAfterUninitializedGroup(i, func)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
cached
|
||||
@@ -344,14 +443,40 @@ private module Cached {
|
||||
)
|
||||
}
|
||||
|
||||
/*
|
||||
* This adds Chi nodes to the instruction successor relation; if an instruction has a Chi node,
|
||||
* that node is its successor in the new successor relation, and the Chi node's successors are
|
||||
* the new instructions generated from the successors of the old instruction
|
||||
*/
|
||||
private UninitializedGroupInstruction firstInstructionToUninitializedGroup(
|
||||
Instruction instruction, EdgeKind kind
|
||||
) {
|
||||
exists(IRFunction func |
|
||||
isFirstInstructionBeforeUninitializedGroup(instruction, func) and
|
||||
result = getInitGroupInstruction(0, func) and
|
||||
kind instanceof GotoEdge
|
||||
)
|
||||
}
|
||||
|
||||
cached
|
||||
Instruction getInstructionSuccessor(Instruction instruction, EdgeKind kind) {
|
||||
private Instruction getNextUninitializedGroupInstruction(Instruction instruction, EdgeKind kind) {
|
||||
exists(int i, IRFunction func |
|
||||
func = instruction.getEnclosingIRFunction() and
|
||||
instruction = getInitGroupInstruction(i, func) and
|
||||
kind instanceof GotoEdge
|
||||
|
|
||||
if hasChiNodeAfterUninitializedGroup(_, instruction)
|
||||
then result = getChi(instruction)
|
||||
else result = getInitGroupInstruction(i + 1, func)
|
||||
)
|
||||
or
|
||||
exists(int i, IRFunction func, UninitializedGroupInstruction initGroup |
|
||||
func = instruction.getEnclosingIRFunction() and
|
||||
instruction = getChi(initGroup) and
|
||||
initGroup = getInitGroupInstruction(i, func) and
|
||||
kind instanceof GotoEdge
|
||||
|
|
||||
result = getInitGroupInstruction(i + 1, func)
|
||||
)
|
||||
}
|
||||
|
||||
private Instruction getInstructionSuccessorAfterUninitializedGroup0(
|
||||
Instruction instruction, EdgeKind kind
|
||||
) {
|
||||
if hasChiNode(_, getOldInstruction(instruction))
|
||||
then
|
||||
result = getChi(getOldInstruction(instruction)) and
|
||||
@@ -371,6 +496,107 @@ private module Cached {
|
||||
)
|
||||
}
|
||||
|
||||
private Instruction getInstructionSuccessorAfterUninitializedGroup(
|
||||
Instruction instruction, EdgeKind kind
|
||||
) {
|
||||
exists(IRFunction func, Instruction firstBeforeUninitializedGroup |
|
||||
isLastInstructionForUninitializedGroups(instruction, func) and
|
||||
isFirstInstructionBeforeUninitializedGroup(firstBeforeUninitializedGroup, func) and
|
||||
result = getInstructionSuccessorAfterUninitializedGroup0(firstBeforeUninitializedGroup, kind)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* This adds Chi nodes to the instruction successor relation; if an instruction has a Chi node,
|
||||
* that node is its successor in the new successor relation, and the Chi node's successors are
|
||||
* the new instructions generated from the successors of the old instruction.
|
||||
*
|
||||
* Furthermore, the entry block is augmented with `UninitializedGroup` instructions and `Chi`
|
||||
* instructions. For example, consider this example:
|
||||
* ```cpp
|
||||
* int x, y;
|
||||
* int* p;
|
||||
* if(b) {
|
||||
* p = &x;
|
||||
* escape(&x);
|
||||
* } else {
|
||||
* p = &y;
|
||||
* }
|
||||
* *p = 42;
|
||||
*
|
||||
* int z, w;
|
||||
* int* q;
|
||||
* if(b) {
|
||||
* q = &z;
|
||||
* } else {
|
||||
* q = &w;
|
||||
* }
|
||||
* *q = 43;
|
||||
* ```
|
||||
*
|
||||
* the unaliased IR for the entry block of this snippet is:
|
||||
* ```
|
||||
* v1(void) = EnterFunction :
|
||||
* m1(unknown) = AliasedDefinition :
|
||||
* m2(unknown) = InitializeNonLocal :
|
||||
* r1(glval<bool>) = VariableAddress[b] :
|
||||
* m3(bool) = InitializeParameter[b] : &:r1
|
||||
* r2(glval<int>) = VariableAddress[x] :
|
||||
* m4(int) = Uninitialized[x] : &:r2
|
||||
* r3(glval<int>) = VariableAddress[y] :
|
||||
* m5(int) = Uninitialized[y] : &:r3
|
||||
* r4(glval<int *>) = VariableAddress[p] :
|
||||
* m6(int *) = Uninitialized[p] : &:r4
|
||||
* r5(glval<bool>) = VariableAddress[b] :
|
||||
* r6(bool) = Load[b] : &:r5, m3
|
||||
* v2(void) = ConditionalBranch : r6
|
||||
* ```
|
||||
* and we need to transform this to aliased IR by inserting an `UninitializedGroup`
|
||||
* instruction for every `VariableGroup` memory location in the function. Furthermore,
|
||||
* if the `VariableGroup` memory location contains an allocation that escapes we need
|
||||
* to insert a `Chi` that writes the memory produced by `UninitializedGroup` into
|
||||
* `{AllAliasedMemory}`. For the above snippet we then end up with:
|
||||
* ```
|
||||
* v1(void) = EnterFunction :
|
||||
* m2(unknown) = AliasedDefinition :
|
||||
* m3(unknown) = InitializeNonLocal :
|
||||
* m4(unknown) = Chi : total:m2, partial:m3
|
||||
* m5(int) = UninitializedGroup[x,y] :
|
||||
* m6(unknown) = Chi : total:m4, partial:m5
|
||||
* m7(int) = UninitializedGroup[w,z] :
|
||||
* r1(glval<bool>) = VariableAddress[b] :
|
||||
* m8(bool) = InitializeParameter[b] : &:r1
|
||||
* r2(glval<int>) = VariableAddress[x] :
|
||||
* m10(int) = Uninitialized[x] : &:r2
|
||||
* m11(unknown) = Chi : total:m6, partial:m10
|
||||
* r3(glval<int>) = VariableAddress[y] :
|
||||
* m12(int) = Uninitialized[y] : &:r3
|
||||
* m13(unknown) = Chi : total:m11, partial:m12
|
||||
* r4(glval<int *>) = VariableAddress[p] :
|
||||
* m14(int *) = Uninitialized[p] : &:r4
|
||||
* r5(glval<bool>) = VariableAddress[b] :
|
||||
* r6(bool) = Load[b] : &:r5, m8
|
||||
* v2(void) = ConditionalBranch : r6
|
||||
* ```
|
||||
*
|
||||
* Here, the group `{x, y}` contains an allocation that escapes (`x`), so there
|
||||
* is a `Chi` after the `UninitializedGroup` that initializes the memory for the
|
||||
* `VariableGroup` containing `x`. None of the allocations in `{w, z}` escape so
|
||||
* there is no `Chi` following that the `UninitializedGroup` that initializes the
|
||||
* memory of `{w, z}`.
|
||||
*/
|
||||
cached
|
||||
Instruction getInstructionSuccessor(Instruction instruction, EdgeKind kind) {
|
||||
result = firstInstructionToUninitializedGroup(instruction, kind)
|
||||
or
|
||||
result = getNextUninitializedGroupInstruction(instruction, kind)
|
||||
or
|
||||
result = getInstructionSuccessorAfterUninitializedGroup(instruction, kind)
|
||||
or
|
||||
not isFirstInstructionBeforeUninitializedGroup(instruction, _) and
|
||||
result = getInstructionSuccessorAfterUninitializedGroup0(instruction, kind)
|
||||
}
|
||||
|
||||
cached
|
||||
Instruction getInstructionBackEdgeSuccessor(Instruction instruction, EdgeKind kind) {
|
||||
exists(OldInstruction oldInstruction |
|
||||
@@ -406,6 +632,16 @@ private module Cached {
|
||||
exists(IRFunctionBase irFunc |
|
||||
instr = unreachedInstruction(irFunc) and result = irFunc.getFunction()
|
||||
)
|
||||
or
|
||||
exists(Alias::VariableGroup vg |
|
||||
instr = uninitializedGroup(vg) and
|
||||
result = vg.getIRFunction().getFunction()
|
||||
)
|
||||
or
|
||||
exists(UninitializedGroupInstruction initGroup |
|
||||
instr = chiInstruction(initGroup) and
|
||||
result = getInstructionAst(initGroup)
|
||||
)
|
||||
}
|
||||
|
||||
cached
|
||||
@@ -418,9 +654,16 @@ private module Cached {
|
||||
)
|
||||
or
|
||||
exists(Instruction primaryInstr, Alias::VirtualVariable vvar |
|
||||
instr = chiInstruction(primaryInstr) and
|
||||
hasChiNode(vvar, primaryInstr) and
|
||||
result = vvar.getType()
|
||||
instr = chiInstruction(primaryInstr) and result = vvar.getType()
|
||||
|
|
||||
hasChiNode(vvar, primaryInstr)
|
||||
or
|
||||
hasChiNodeAfterUninitializedGroup(vvar, primaryInstr)
|
||||
)
|
||||
or
|
||||
exists(Alias::VariableGroup vg |
|
||||
instr = uninitializedGroup(vg) and
|
||||
result = vg.getType()
|
||||
)
|
||||
or
|
||||
instr = reusedPhiInstruction(_) and
|
||||
@@ -448,6 +691,8 @@ private module Cached {
|
||||
or
|
||||
instr = chiInstruction(_) and opcode instanceof Opcode::Chi
|
||||
or
|
||||
instr = uninitializedGroup(_) and opcode instanceof Opcode::UninitializedGroup
|
||||
or
|
||||
instr = unreachedInstruction(_) and opcode instanceof Opcode::Unreached
|
||||
}
|
||||
|
||||
@@ -460,10 +705,15 @@ private module Cached {
|
||||
result = blockStartInstr.getEnclosingIRFunction()
|
||||
)
|
||||
or
|
||||
exists(OldInstruction primaryInstr |
|
||||
exists(Instruction primaryInstr |
|
||||
instr = chiInstruction(primaryInstr) and result = primaryInstr.getEnclosingIRFunction()
|
||||
)
|
||||
or
|
||||
exists(Alias::VariableGroup vg |
|
||||
instr = uninitializedGroup(vg) and
|
||||
result = vg.getIRFunction()
|
||||
)
|
||||
or
|
||||
instr = unreachedInstruction(result)
|
||||
}
|
||||
|
||||
@@ -478,6 +728,8 @@ private module Cached {
|
||||
instruction = getChi(oldInstruction) and
|
||||
result = getNewInstruction(oldInstruction)
|
||||
)
|
||||
or
|
||||
instruction = getChi(result.(UninitializedGroupInstruction))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -485,7 +737,7 @@ private Instruction getNewInstruction(OldInstruction instr) { getOldInstruction(
|
||||
|
||||
private OldInstruction getOldInstruction(Instruction instr) { instr = result }
|
||||
|
||||
private ChiInstruction getChi(OldInstruction primaryInstr) { result = chiInstruction(primaryInstr) }
|
||||
private ChiInstruction getChi(Instruction primaryInstr) { result = chiInstruction(primaryInstr) }
|
||||
|
||||
private PhiInstruction getPhi(OldBlock defBlock, Alias::MemoryLocation defLocation) {
|
||||
result = phiInstruction(defBlock.getFirstInstruction(), defLocation)
|
||||
@@ -506,6 +758,16 @@ private predicate hasChiNode(Alias::VirtualVariable vvar, OldInstruction def) {
|
||||
)
|
||||
}
|
||||
|
||||
private predicate hasChiNodeAfterUninitializedGroup(
|
||||
Alias::AliasedVirtualVariable vvar, UninitializedGroupInstruction initGroup
|
||||
) {
|
||||
exists(Alias::GroupedMemoryLocation defLocation |
|
||||
initGroup = uninitializedGroup(defLocation.getGroup()) and
|
||||
defLocation.getVirtualVariable() = vvar and
|
||||
Alias::getOverlap(defLocation, vvar) instanceof MayPartiallyOverlap
|
||||
)
|
||||
}
|
||||
|
||||
private import PhiInsertion
|
||||
|
||||
/**
|
||||
@@ -668,19 +930,33 @@ private import DefUse
|
||||
* potentially very sparse.
|
||||
*/
|
||||
module DefUse {
|
||||
bindingset[index, block]
|
||||
pragma[inline_late]
|
||||
private int getNonChiOffset(int index, OldBlock block) {
|
||||
exists(IRFunction func | func = block.getEnclosingIRFunction() |
|
||||
if
|
||||
getNewBlock(block) = func.getEntryBlock() and
|
||||
not block.getInstruction(index) instanceof InitializeNonLocalInstruction and
|
||||
not block.getInstruction(index) instanceof AliasedDefinitionInstruction
|
||||
then result = 2 * (index + count(VariableGroup vg | vg.getIRFunction() = func))
|
||||
else result = 2 * index
|
||||
)
|
||||
}
|
||||
|
||||
bindingset[index, block]
|
||||
pragma[inline_late]
|
||||
private int getChiOffset(int index, OldBlock block) { result = getNonChiOffset(index, block) + 1 }
|
||||
|
||||
/**
|
||||
* Gets the `Instruction` for the definition at offset `defOffset` in block `defBlock`.
|
||||
*/
|
||||
Instruction getDefinitionOrChiInstruction(
|
||||
private Instruction getDefinitionOrChiInstruction0(
|
||||
OldBlock defBlock, int defOffset, Alias::MemoryLocation defLocation,
|
||||
Alias::MemoryLocation actualDefLocation
|
||||
) {
|
||||
exists(OldInstruction oldInstr, int oldOffset |
|
||||
oldInstr = defBlock.getInstruction(oldOffset) and
|
||||
oldOffset >= 0
|
||||
|
|
||||
exists(OldInstruction oldInstr, int oldOffset | oldInstr = defBlock.getInstruction(oldOffset) |
|
||||
// An odd offset corresponds to the `Chi` instruction.
|
||||
defOffset = oldOffset * 2 + 1 and
|
||||
defOffset = getChiOffset(oldOffset, defBlock) and
|
||||
result = getChi(oldInstr) and
|
||||
(
|
||||
defLocation = Alias::getResultMemoryLocation(oldInstr) or
|
||||
@@ -689,7 +965,7 @@ module DefUse {
|
||||
actualDefLocation = defLocation.getVirtualVariable()
|
||||
or
|
||||
// An even offset corresponds to the original instruction.
|
||||
defOffset = oldOffset * 2 and
|
||||
defOffset = getNonChiOffset(oldOffset, defBlock) and
|
||||
result = getNewInstruction(oldInstr) and
|
||||
(
|
||||
defLocation = Alias::getResultMemoryLocation(oldInstr) or
|
||||
@@ -702,6 +978,54 @@ module DefUse {
|
||||
hasDefinition(_, defLocation, defBlock, defOffset) and
|
||||
result = getPhi(defBlock, defLocation) and
|
||||
actualDefLocation = defLocation
|
||||
or
|
||||
exists(
|
||||
Alias::VariableGroup vg, int index, UninitializedGroupInstruction initGroup,
|
||||
Alias::GroupedMemoryLocation gml
|
||||
|
|
||||
// Add 3 to account for the function prologue:
|
||||
// v1(void) = EnterFunction
|
||||
// m1(unknown) = AliasedDefinition
|
||||
// m2(unknown) = InitializeNonLocal
|
||||
index = 3 + vg.getInitializationOrder() and
|
||||
not gml.isMayAccess() and
|
||||
gml.isSome() and
|
||||
gml.getGroup() = vg and
|
||||
vg.getIRFunction().getEntryBlock() = defBlock and
|
||||
initGroup = uninitializedGroup(vg) and
|
||||
(defLocation = gml or defLocation = gml.getVirtualVariable())
|
||||
|
|
||||
result = initGroup and
|
||||
defOffset = 2 * index and
|
||||
actualDefLocation = defLocation
|
||||
or
|
||||
result = getChi(initGroup) and
|
||||
defOffset = 2 * index + 1 and
|
||||
actualDefLocation = defLocation.getVirtualVariable()
|
||||
)
|
||||
}
|
||||
|
||||
private ChiInstruction remapGetDefinitionOrChiInstruction(Instruction oldResult) {
|
||||
exists(IRFunction func |
|
||||
isFirstInstructionBeforeUninitializedGroup(oldResult, func) and
|
||||
isLastInstructionForUninitializedGroups(result, func)
|
||||
)
|
||||
}
|
||||
|
||||
Instruction getDefinitionOrChiInstruction(
|
||||
OldBlock defBlock, int defOffset, Alias::MemoryLocation defLocation,
|
||||
Alias::MemoryLocation actualDefLocation
|
||||
) {
|
||||
exists(Instruction oldResult |
|
||||
oldResult =
|
||||
getDefinitionOrChiInstruction0(defBlock, defOffset, defLocation, actualDefLocation) and
|
||||
(
|
||||
result = remapGetDefinitionOrChiInstruction(oldResult)
|
||||
or
|
||||
not exists(remapGetDefinitionOrChiInstruction(oldResult)) and
|
||||
result = oldResult
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -842,8 +1166,20 @@ module DefUse {
|
||||
block.getInstruction(index) = def and
|
||||
overlap = Alias::getOverlap(defLocation, useLocation) and
|
||||
if overlap instanceof MayPartiallyOverlap
|
||||
then offset = (index * 2) + 1 // The use will be connected to the definition on the `Chi` instruction.
|
||||
else offset = index * 2 // The use will be connected to the definition on the original instruction.
|
||||
then offset = getChiOffset(index, block) // The use will be connected to the definition on the `Chi` instruction.
|
||||
else offset = getNonChiOffset(index, block) // The use will be connected to the definition on the original instruction.
|
||||
)
|
||||
or
|
||||
exists(UninitializedGroupInstruction initGroup, int index, Overlap overlap, VariableGroup vg |
|
||||
initGroup.getEnclosingIRFunction().getEntryBlock() = getNewBlock(block) and
|
||||
vg = defLocation.(Alias::GroupedMemoryLocation).getGroup() and
|
||||
// EnterFunction + AliasedDefinition + InitializeNonLocal + index
|
||||
index = 3 + vg.getInitializationOrder() and
|
||||
initGroup = uninitializedGroup(vg) and
|
||||
overlap = Alias::getOverlap(defLocation, useLocation) and
|
||||
if overlap instanceof MayPartiallyOverlap and hasChiNodeAfterUninitializedGroup(initGroup)
|
||||
then offset = 2 * index + 1 // The use will be connected to the definition on the `Chi` instruction.
|
||||
else offset = 2 * index // The use will be connected to the definition on the original instruction.
|
||||
)
|
||||
}
|
||||
|
||||
@@ -904,10 +1240,11 @@ module DefUse {
|
||||
block.getInstruction(index) = use and
|
||||
(
|
||||
// A direct use of the location.
|
||||
useLocation = Alias::getOperandMemoryLocation(use.getAnOperand()) and offset = index * 2
|
||||
useLocation = Alias::getOperandMemoryLocation(use.getAnOperand()) and
|
||||
offset = getNonChiOffset(index, block)
|
||||
or
|
||||
// A `Chi` instruction will include a use of the virtual variable.
|
||||
hasChiNode(useLocation, use) and offset = (index * 2) + 1
|
||||
hasChiNode(useLocation, use) and offset = getChiOffset(index, block)
|
||||
)
|
||||
)
|
||||
}
|
||||
@@ -1057,5 +1394,9 @@ module Ssa {
|
||||
|
||||
predicate hasChiInstruction = Cached::hasChiInstructionCached/1;
|
||||
|
||||
predicate hasChiNodeAfterUninitializedGroup = Cached::hasChiNodeAfterUninitializedGroup/1;
|
||||
|
||||
predicate hasUnreachedInstruction = Cached::hasUnreachedInstructionCached/1;
|
||||
|
||||
class VariableGroup = Alias::VariableGroup;
|
||||
}
|
||||
|
||||
@@ -31,6 +31,7 @@ newtype TInstruction =
|
||||
TUnaliasedSsaUnreachedInstruction(IRFunctionBase irFunc) {
|
||||
UnaliasedSsa::Ssa::hasUnreachedInstruction(irFunc)
|
||||
} or
|
||||
TUnaliasedSsaUninitializedGroupInstruction(UnaliasedSsa::Ssa::VariableGroup vg) or
|
||||
TAliasedSsaPhiInstruction(
|
||||
TRawInstruction blockStartInstr, AliasedSsa::Ssa::MemoryLocation memoryLocation
|
||||
) {
|
||||
@@ -41,6 +42,12 @@ newtype TInstruction =
|
||||
} or
|
||||
TAliasedSsaUnreachedInstruction(IRFunctionBase irFunc) {
|
||||
AliasedSsa::Ssa::hasUnreachedInstruction(irFunc)
|
||||
} or
|
||||
TAliasedSsaUninitializedGroupInstruction(AliasedSsa::Ssa::VariableGroup vg) or
|
||||
TAliasedSsaChiAfterUninitializedGroupInstruction(
|
||||
TAliasedSsaUninitializedGroupInstruction initGroup
|
||||
) {
|
||||
AliasedSsa::Ssa::hasChiNodeAfterUninitializedGroup(initGroup)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -62,7 +69,11 @@ module UnaliasedSsaInstructions {
|
||||
|
||||
class TChiInstruction = TUnaliasedSsaChiInstruction;
|
||||
|
||||
TChiInstruction chiInstruction(TRawInstruction primaryInstruction) {
|
||||
class TUninitializedGroupInstruction = TUnaliasedSsaUninitializedGroupInstruction;
|
||||
|
||||
class TRawOrUninitializedGroupInstruction = TRawInstruction or TUninitializedGroupInstruction;
|
||||
|
||||
TChiInstruction chiInstruction(TRawOrUninitializedGroupInstruction primaryInstruction) {
|
||||
result = TUnaliasedSsaChiInstruction(primaryInstruction)
|
||||
}
|
||||
|
||||
@@ -71,6 +82,12 @@ module UnaliasedSsaInstructions {
|
||||
TUnreachedInstruction unreachedInstruction(IRFunctionBase irFunc) {
|
||||
result = TUnaliasedSsaUnreachedInstruction(irFunc)
|
||||
}
|
||||
|
||||
class VariableGroup = UnaliasedSsa::Ssa::VariableGroup;
|
||||
|
||||
// This really should just be `TUnaliasedSsaUninitializedGroupInstruction`, but that makes the
|
||||
// compiler realize that certain expressions in `SSAConstruction` are unsatisfiable.
|
||||
TRawOrUninitializedGroupInstruction uninitializedGroup(VariableGroup vg) { none() }
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -92,10 +109,16 @@ module AliasedSsaInstructions {
|
||||
result = TUnaliasedSsaPhiInstruction(blockStartInstr, _)
|
||||
}
|
||||
|
||||
class TChiInstruction = TAliasedSsaChiInstruction;
|
||||
class TChiInstruction =
|
||||
TAliasedSsaChiInstruction or TAliasedSsaChiAfterUninitializedGroupInstruction;
|
||||
|
||||
TChiInstruction chiInstruction(TRawInstruction primaryInstruction) {
|
||||
class TRawOrInitialzieGroupInstruction =
|
||||
TRawInstruction or TAliasedSsaUninitializedGroupInstruction;
|
||||
|
||||
TChiInstruction chiInstruction(TRawOrInitialzieGroupInstruction primaryInstruction) {
|
||||
result = TAliasedSsaChiInstruction(primaryInstruction)
|
||||
or
|
||||
result = TAliasedSsaChiAfterUninitializedGroupInstruction(primaryInstruction)
|
||||
}
|
||||
|
||||
class TUnreachedInstruction = TAliasedSsaUnreachedInstruction;
|
||||
@@ -103,4 +126,12 @@ module AliasedSsaInstructions {
|
||||
TUnreachedInstruction unreachedInstruction(IRFunctionBase irFunc) {
|
||||
result = TAliasedSsaUnreachedInstruction(irFunc)
|
||||
}
|
||||
|
||||
class VariableGroup = AliasedSsa::Ssa::VariableGroup;
|
||||
|
||||
class TUninitializedGroupInstruction = TAliasedSsaUninitializedGroupInstruction;
|
||||
|
||||
TUninitializedGroupInstruction uninitializedGroup(VariableGroup vg) {
|
||||
result = TAliasedSsaUninitializedGroupInstruction(vg)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,6 +12,9 @@ private import semmle.code.cpp.ir.internal.Overlap
|
||||
* Provides the newtype used to represent operands across all phases of the IR.
|
||||
*/
|
||||
private module Internal {
|
||||
private class TAliasedChiInstruction =
|
||||
TAliasedSsaChiInstruction or TAliasedSsaChiAfterUninitializedGroupInstruction;
|
||||
|
||||
/**
|
||||
* An IR operand. `TOperand` is shared across all phases of the IR. There are branches of this
|
||||
* type for operands created directly from the AST (`TRegisterOperand` and `TNonSSAMemoryOperand`),
|
||||
@@ -52,7 +55,7 @@ private module Internal {
|
||||
) {
|
||||
exists(AliasedConstruction::getPhiOperandDefinition(useInstr, predecessorBlock, overlap))
|
||||
} or
|
||||
TAliasedChiOperand(TAliasedSsaChiInstruction useInstr, ChiOperandTag tag) { any() }
|
||||
TAliasedChiOperand(TAliasedChiInstruction useInstr, ChiOperandTag tag) { any() }
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -198,10 +201,13 @@ module AliasedSsaOperands {
|
||||
)
|
||||
}
|
||||
|
||||
private class TChiInstruction =
|
||||
TAliasedSsaChiInstruction or TAliasedSsaChiAfterUninitializedGroupInstruction;
|
||||
|
||||
/**
|
||||
* Returns the Chi operand with the specified parameters.
|
||||
*/
|
||||
TChiOperand chiOperand(TAliasedSsaChiInstruction useInstr, ChiOperandTag tag) {
|
||||
TChiOperand chiOperand(TChiInstruction useInstr, ChiOperandTag tag) {
|
||||
result = Internal::TAliasedChiOperand(useInstr, tag)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2142,6 +2142,47 @@ class ChiInstruction extends Instruction {
|
||||
final predicate isPartialUpdate() { Construction::chiOnlyPartiallyUpdatesLocation(this) }
|
||||
}
|
||||
|
||||
/**
|
||||
* An instruction that initializes a set of allocations that are each assigned
|
||||
* the same "virtual variable".
|
||||
*
|
||||
* As an example, consider the following snippet:
|
||||
* ```
|
||||
* int a;
|
||||
* int b;
|
||||
* int* p;
|
||||
* if(b) {
|
||||
* p = &a;
|
||||
* } else {
|
||||
* p = &b;
|
||||
* }
|
||||
* *p = 5;
|
||||
* int x = a;
|
||||
* ```
|
||||
*
|
||||
* Since both the address of `a` and `b` reach `p` at `*p = 5` the IR alias
|
||||
* analysis will create a region that contains both `a` and `b`. The region
|
||||
* containing both `a` and `b` are initialized by an `UninitializedGroup`
|
||||
* instruction in the entry block of the enclosing function.
|
||||
*/
|
||||
class UninitializedGroupInstruction extends Instruction {
|
||||
UninitializedGroupInstruction() { this.getOpcode() instanceof Opcode::UninitializedGroup }
|
||||
|
||||
/**
|
||||
* Gets an `IRVariable` whose memory is initialized by this instruction, if any.
|
||||
* Note: Allocations that are not represented as `IRVariable`s (such as
|
||||
* dynamic allocations) are not returned by this predicate even if this
|
||||
* instruction initializes such memory.
|
||||
*/
|
||||
final IRVariable getAnIRVariable() {
|
||||
result = Construction::getAnUninitializedGroupVariable(this)
|
||||
}
|
||||
|
||||
final override string getImmediateString() {
|
||||
result = strictconcat(this.getAnIRVariable().toString(), ",")
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* An instruction representing unreachable code.
|
||||
*
|
||||
|
||||
@@ -407,6 +407,8 @@ predicate hasUnreachedInstruction(IRFunction func) {
|
||||
)
|
||||
}
|
||||
|
||||
IRVariable getAnUninitializedGroupVariable(UninitializedGroupInstruction instr) { none() }
|
||||
|
||||
import CachedForDebugging
|
||||
|
||||
cached
|
||||
|
||||
@@ -2142,6 +2142,47 @@ class ChiInstruction extends Instruction {
|
||||
final predicate isPartialUpdate() { Construction::chiOnlyPartiallyUpdatesLocation(this) }
|
||||
}
|
||||
|
||||
/**
|
||||
* An instruction that initializes a set of allocations that are each assigned
|
||||
* the same "virtual variable".
|
||||
*
|
||||
* As an example, consider the following snippet:
|
||||
* ```
|
||||
* int a;
|
||||
* int b;
|
||||
* int* p;
|
||||
* if(b) {
|
||||
* p = &a;
|
||||
* } else {
|
||||
* p = &b;
|
||||
* }
|
||||
* *p = 5;
|
||||
* int x = a;
|
||||
* ```
|
||||
*
|
||||
* Since both the address of `a` and `b` reach `p` at `*p = 5` the IR alias
|
||||
* analysis will create a region that contains both `a` and `b`. The region
|
||||
* containing both `a` and `b` are initialized by an `UninitializedGroup`
|
||||
* instruction in the entry block of the enclosing function.
|
||||
*/
|
||||
class UninitializedGroupInstruction extends Instruction {
|
||||
UninitializedGroupInstruction() { this.getOpcode() instanceof Opcode::UninitializedGroup }
|
||||
|
||||
/**
|
||||
* Gets an `IRVariable` whose memory is initialized by this instruction, if any.
|
||||
* Note: Allocations that are not represented as `IRVariable`s (such as
|
||||
* dynamic allocations) are not returned by this predicate even if this
|
||||
* instruction initializes such memory.
|
||||
*/
|
||||
final IRVariable getAnIRVariable() {
|
||||
result = Construction::getAnUninitializedGroupVariable(this)
|
||||
}
|
||||
|
||||
final override string getImmediateString() {
|
||||
result = strictconcat(this.getAnIRVariable().toString(), ",")
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* An instruction representing unreachable code.
|
||||
*
|
||||
|
||||
@@ -106,8 +106,7 @@ private predicate operandEscapesDomain(Operand operand) {
|
||||
not isArgumentForParameter(_, operand, _) and
|
||||
not isOnlyEscapesViaReturnArgument(operand) and
|
||||
not operand.getUse() instanceof ReturnValueInstruction and
|
||||
not operand.getUse() instanceof ReturnIndirectionInstruction and
|
||||
not operand instanceof PhiInputOperand
|
||||
not operand.getUse() instanceof ReturnIndirectionInstruction
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -191,6 +190,11 @@ private predicate operandIsPropagated(Operand operand, IntValue bitOffset, Instr
|
||||
// A copy propagates the source value.
|
||||
operand = instr.(CopyInstruction).getSourceValueOperand() and bitOffset = 0
|
||||
)
|
||||
or
|
||||
operand = instr.(PhiInstruction).getAnInputOperand() and
|
||||
// Using `unknown` ensures termination since we cannot keep incrementing a bit offset
|
||||
// through the back edge of a loop (or through recursion).
|
||||
bitOffset = Ints::unknown()
|
||||
}
|
||||
|
||||
private predicate operandEscapesNonReturn(Operand operand) {
|
||||
@@ -212,9 +216,6 @@ private predicate operandEscapesNonReturn(Operand operand) {
|
||||
or
|
||||
isOnlyEscapesViaReturnArgument(operand) and resultEscapesNonReturn(operand.getUse())
|
||||
or
|
||||
operand instanceof PhiInputOperand and
|
||||
resultEscapesNonReturn(operand.getUse())
|
||||
or
|
||||
operandEscapesDomain(operand)
|
||||
}
|
||||
|
||||
@@ -236,9 +237,6 @@ private predicate operandMayReachReturn(Operand operand) {
|
||||
operand.getUse() instanceof ReturnValueInstruction
|
||||
or
|
||||
isOnlyEscapesViaReturnArgument(operand) and resultMayReachReturn(operand.getUse())
|
||||
or
|
||||
operand instanceof PhiInputOperand and
|
||||
resultMayReachReturn(operand.getUse())
|
||||
}
|
||||
|
||||
private predicate operandReturned(Operand operand, IntValue bitOffset) {
|
||||
|
||||
@@ -15,6 +15,51 @@ private class OldInstruction = Reachability::ReachableInstruction;
|
||||
|
||||
import Cached
|
||||
|
||||
/**
|
||||
* Holds if `instruction` is the first instruction that may be followed by
|
||||
* an `UninitializedGroup` instruction, and the enclosing function of
|
||||
* `instruction` is `func`.
|
||||
*/
|
||||
private predicate isFirstInstructionBeforeUninitializedGroup(
|
||||
Instruction instruction, IRFunction func
|
||||
) {
|
||||
instruction = getChi(any(OldIR::InitializeNonLocalInstruction init)) and
|
||||
func = instruction.getEnclosingIRFunction()
|
||||
}
|
||||
|
||||
/** Gets the `i`'th `UninitializedGroup` instruction in `func`. */
|
||||
private UninitializedGroupInstruction getInitGroupInstruction(int i, IRFunction func) {
|
||||
exists(Alias::VariableGroup vg |
|
||||
vg.getIRFunction() = func and
|
||||
vg.getInitializationOrder() = i and
|
||||
result = uninitializedGroup(vg)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `instruction` is the last instruction in the chain of `UninitializedGroup`
|
||||
* instructions in `func`. The chain of instructions may be empty in which case
|
||||
* `instruction` satisfies
|
||||
* ```
|
||||
* isFirstInstructionBeforeUninitializedGroup(instruction, func)
|
||||
* ```
|
||||
*/
|
||||
predicate isLastInstructionForUninitializedGroups(Instruction instruction, IRFunction func) {
|
||||
exists(int i |
|
||||
instruction = getInitGroupInstruction(i, func) and
|
||||
not exists(getChi(instruction)) and
|
||||
not exists(getInitGroupInstruction(i + 1, func))
|
||||
)
|
||||
or
|
||||
exists(int i |
|
||||
instruction = getChi(getInitGroupInstruction(i, func)) and
|
||||
not exists(getInitGroupInstruction(i + 1, func))
|
||||
)
|
||||
or
|
||||
isFirstInstructionBeforeUninitializedGroup(instruction, func) and
|
||||
not exists(getInitGroupInstruction(0, func))
|
||||
}
|
||||
|
||||
cached
|
||||
private module Cached {
|
||||
cached
|
||||
@@ -32,6 +77,11 @@ private module Cached {
|
||||
hasChiNode(_, primaryInstruction)
|
||||
}
|
||||
|
||||
cached
|
||||
predicate hasChiNodeAfterUninitializedGroup(UninitializedGroupInstruction initGroup) {
|
||||
hasChiNodeAfterUninitializedGroup(_, initGroup)
|
||||
}
|
||||
|
||||
cached
|
||||
predicate hasUnreachedInstructionCached(IRFunction irFunc) {
|
||||
exists(OldIR::Instruction oldInstruction |
|
||||
@@ -45,7 +95,8 @@ private module Cached {
|
||||
}
|
||||
|
||||
class TStageInstruction =
|
||||
TRawInstruction or TPhiInstruction or TChiInstruction or TUnreachedInstruction;
|
||||
TRawInstruction or TPhiInstruction or TChiInstruction or TUnreachedInstruction or
|
||||
TUninitializedGroupInstruction;
|
||||
|
||||
/**
|
||||
* If `oldInstruction` is a `Phi` instruction that has exactly one reachable predecessor block,
|
||||
@@ -78,6 +129,8 @@ private module Cached {
|
||||
or
|
||||
instr instanceof TChiInstruction
|
||||
or
|
||||
instr instanceof TUninitializedGroupInstruction
|
||||
or
|
||||
instr instanceof TUnreachedInstruction
|
||||
}
|
||||
|
||||
@@ -123,7 +176,8 @@ private module Cached {
|
||||
predicate hasModeledMemoryResult(Instruction instruction) {
|
||||
canModelResultForOldInstruction(getOldInstruction(instruction)) or
|
||||
instruction instanceof PhiInstruction or // Phis always have modeled results
|
||||
instruction instanceof ChiInstruction // Chis always have modeled results
|
||||
instruction instanceof ChiInstruction or // Chis always have modeled results
|
||||
instruction instanceof UninitializedGroupInstruction // Group initializers always have modeled results
|
||||
}
|
||||
|
||||
cached
|
||||
@@ -134,16 +188,23 @@ private module Cached {
|
||||
or
|
||||
// Chi instructions track virtual variables, and therefore a chi instruction is
|
||||
// conflated if it's associated with the aliased virtual variable.
|
||||
exists(OldInstruction oldInstruction | instruction = getChi(oldInstruction) |
|
||||
Alias::getResultMemoryLocation(oldInstruction).getVirtualVariable() instanceof
|
||||
exists(Instruction input | instruction = getChi(input) |
|
||||
Alias::getResultMemoryLocation(input).getVirtualVariable() instanceof
|
||||
Alias::AliasedVirtualVariable
|
||||
or
|
||||
// A chi following an `UninitializedGroupInstruction` only happens when the virtual
|
||||
// variable of the grouped memory location is `{AllAliasedMemory}`.
|
||||
exists(Alias::GroupedMemoryLocation gml |
|
||||
input = uninitializedGroup(gml.getGroup()) and
|
||||
gml.getVirtualVariable() instanceof Alias::AliasedVirtualVariable
|
||||
)
|
||||
)
|
||||
or
|
||||
// Phi instructions track locations, and therefore a phi instruction is
|
||||
// conflated if it's associated with a conflated location.
|
||||
exists(Alias::MemoryLocation location |
|
||||
instruction = getPhi(_, location) and
|
||||
not exists(location.getAllocation())
|
||||
not exists(location.getAnAllocation())
|
||||
)
|
||||
}
|
||||
|
||||
@@ -205,7 +266,11 @@ private module Cached {
|
||||
hasMemoryOperandDefinition(oldInstruction, oldOperand, overlap, result)
|
||||
)
|
||||
or
|
||||
instruction = getChi(getOldInstruction(result)) and
|
||||
(
|
||||
instruction = getChi(getOldInstruction(result))
|
||||
or
|
||||
instruction = getChi(result.(UninitializedGroupInstruction))
|
||||
) and
|
||||
tag instanceof ChiPartialOperandTag and
|
||||
overlap instanceof MustExactlyOverlap
|
||||
or
|
||||
@@ -263,6 +328,14 @@ private module Cached {
|
||||
)
|
||||
}
|
||||
|
||||
cached
|
||||
IRVariable getAnUninitializedGroupVariable(UninitializedGroupInstruction init) {
|
||||
exists(Alias::VariableGroup vg |
|
||||
init = uninitializedGroup(vg) and
|
||||
result = vg.getAnAllocation().getABaseInstruction().(VariableInstruction).getIRVariable()
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `instr` is part of a cycle in the operand graph that doesn't go
|
||||
* through a phi instruction and therefore should be impossible.
|
||||
@@ -316,6 +389,19 @@ private module Cached {
|
||||
result = getNewPhiOperandDefinitionFromOldSsa(instr, newPredecessorBlock, overlap)
|
||||
}
|
||||
|
||||
private ChiInstruction getChiAfterUninitializedGroup(int i, IRFunction func) {
|
||||
result =
|
||||
rank[i + 1](VariableGroup vg, UninitializedGroupInstruction initGroup, ChiInstruction chi,
|
||||
int r |
|
||||
initGroup.getEnclosingIRFunction() = func and
|
||||
chi = getChi(initGroup) and
|
||||
initGroup = uninitializedGroup(vg) and
|
||||
r = vg.getInitializationOrder()
|
||||
|
|
||||
chi order by r
|
||||
)
|
||||
}
|
||||
|
||||
cached
|
||||
Instruction getChiInstructionTotalOperand(ChiInstruction chiInstr) {
|
||||
exists(
|
||||
@@ -329,6 +415,19 @@ private module Cached {
|
||||
definitionReachesUse(vvar, defBlock, defRank, useBlock, useRank) and
|
||||
result = getDefinitionOrChiInstruction(defBlock, defOffset, vvar, _)
|
||||
)
|
||||
or
|
||||
exists(UninitializedGroupInstruction initGroup, IRFunction func |
|
||||
chiInstr = getChi(initGroup) and
|
||||
func = initGroup.getEnclosingIRFunction()
|
||||
|
|
||||
chiInstr = getChiAfterUninitializedGroup(0, func) and
|
||||
isFirstInstructionBeforeUninitializedGroup(result, func)
|
||||
or
|
||||
exists(int i |
|
||||
chiInstr = getChiAfterUninitializedGroup(i + 1, func) and
|
||||
result = getChiAfterUninitializedGroup(i, func)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
cached
|
||||
@@ -344,14 +443,40 @@ private module Cached {
|
||||
)
|
||||
}
|
||||
|
||||
/*
|
||||
* This adds Chi nodes to the instruction successor relation; if an instruction has a Chi node,
|
||||
* that node is its successor in the new successor relation, and the Chi node's successors are
|
||||
* the new instructions generated from the successors of the old instruction
|
||||
*/
|
||||
private UninitializedGroupInstruction firstInstructionToUninitializedGroup(
|
||||
Instruction instruction, EdgeKind kind
|
||||
) {
|
||||
exists(IRFunction func |
|
||||
isFirstInstructionBeforeUninitializedGroup(instruction, func) and
|
||||
result = getInitGroupInstruction(0, func) and
|
||||
kind instanceof GotoEdge
|
||||
)
|
||||
}
|
||||
|
||||
cached
|
||||
Instruction getInstructionSuccessor(Instruction instruction, EdgeKind kind) {
|
||||
private Instruction getNextUninitializedGroupInstruction(Instruction instruction, EdgeKind kind) {
|
||||
exists(int i, IRFunction func |
|
||||
func = instruction.getEnclosingIRFunction() and
|
||||
instruction = getInitGroupInstruction(i, func) and
|
||||
kind instanceof GotoEdge
|
||||
|
|
||||
if hasChiNodeAfterUninitializedGroup(_, instruction)
|
||||
then result = getChi(instruction)
|
||||
else result = getInitGroupInstruction(i + 1, func)
|
||||
)
|
||||
or
|
||||
exists(int i, IRFunction func, UninitializedGroupInstruction initGroup |
|
||||
func = instruction.getEnclosingIRFunction() and
|
||||
instruction = getChi(initGroup) and
|
||||
initGroup = getInitGroupInstruction(i, func) and
|
||||
kind instanceof GotoEdge
|
||||
|
|
||||
result = getInitGroupInstruction(i + 1, func)
|
||||
)
|
||||
}
|
||||
|
||||
private Instruction getInstructionSuccessorAfterUninitializedGroup0(
|
||||
Instruction instruction, EdgeKind kind
|
||||
) {
|
||||
if hasChiNode(_, getOldInstruction(instruction))
|
||||
then
|
||||
result = getChi(getOldInstruction(instruction)) and
|
||||
@@ -371,6 +496,107 @@ private module Cached {
|
||||
)
|
||||
}
|
||||
|
||||
private Instruction getInstructionSuccessorAfterUninitializedGroup(
|
||||
Instruction instruction, EdgeKind kind
|
||||
) {
|
||||
exists(IRFunction func, Instruction firstBeforeUninitializedGroup |
|
||||
isLastInstructionForUninitializedGroups(instruction, func) and
|
||||
isFirstInstructionBeforeUninitializedGroup(firstBeforeUninitializedGroup, func) and
|
||||
result = getInstructionSuccessorAfterUninitializedGroup0(firstBeforeUninitializedGroup, kind)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* This adds Chi nodes to the instruction successor relation; if an instruction has a Chi node,
|
||||
* that node is its successor in the new successor relation, and the Chi node's successors are
|
||||
* the new instructions generated from the successors of the old instruction.
|
||||
*
|
||||
* Furthermore, the entry block is augmented with `UninitializedGroup` instructions and `Chi`
|
||||
* instructions. For example, consider this example:
|
||||
* ```cpp
|
||||
* int x, y;
|
||||
* int* p;
|
||||
* if(b) {
|
||||
* p = &x;
|
||||
* escape(&x);
|
||||
* } else {
|
||||
* p = &y;
|
||||
* }
|
||||
* *p = 42;
|
||||
*
|
||||
* int z, w;
|
||||
* int* q;
|
||||
* if(b) {
|
||||
* q = &z;
|
||||
* } else {
|
||||
* q = &w;
|
||||
* }
|
||||
* *q = 43;
|
||||
* ```
|
||||
*
|
||||
* the unaliased IR for the entry block of this snippet is:
|
||||
* ```
|
||||
* v1(void) = EnterFunction :
|
||||
* m1(unknown) = AliasedDefinition :
|
||||
* m2(unknown) = InitializeNonLocal :
|
||||
* r1(glval<bool>) = VariableAddress[b] :
|
||||
* m3(bool) = InitializeParameter[b] : &:r1
|
||||
* r2(glval<int>) = VariableAddress[x] :
|
||||
* m4(int) = Uninitialized[x] : &:r2
|
||||
* r3(glval<int>) = VariableAddress[y] :
|
||||
* m5(int) = Uninitialized[y] : &:r3
|
||||
* r4(glval<int *>) = VariableAddress[p] :
|
||||
* m6(int *) = Uninitialized[p] : &:r4
|
||||
* r5(glval<bool>) = VariableAddress[b] :
|
||||
* r6(bool) = Load[b] : &:r5, m3
|
||||
* v2(void) = ConditionalBranch : r6
|
||||
* ```
|
||||
* and we need to transform this to aliased IR by inserting an `UninitializedGroup`
|
||||
* instruction for every `VariableGroup` memory location in the function. Furthermore,
|
||||
* if the `VariableGroup` memory location contains an allocation that escapes we need
|
||||
* to insert a `Chi` that writes the memory produced by `UninitializedGroup` into
|
||||
* `{AllAliasedMemory}`. For the above snippet we then end up with:
|
||||
* ```
|
||||
* v1(void) = EnterFunction :
|
||||
* m2(unknown) = AliasedDefinition :
|
||||
* m3(unknown) = InitializeNonLocal :
|
||||
* m4(unknown) = Chi : total:m2, partial:m3
|
||||
* m5(int) = UninitializedGroup[x,y] :
|
||||
* m6(unknown) = Chi : total:m4, partial:m5
|
||||
* m7(int) = UninitializedGroup[w,z] :
|
||||
* r1(glval<bool>) = VariableAddress[b] :
|
||||
* m8(bool) = InitializeParameter[b] : &:r1
|
||||
* r2(glval<int>) = VariableAddress[x] :
|
||||
* m10(int) = Uninitialized[x] : &:r2
|
||||
* m11(unknown) = Chi : total:m6, partial:m10
|
||||
* r3(glval<int>) = VariableAddress[y] :
|
||||
* m12(int) = Uninitialized[y] : &:r3
|
||||
* m13(unknown) = Chi : total:m11, partial:m12
|
||||
* r4(glval<int *>) = VariableAddress[p] :
|
||||
* m14(int *) = Uninitialized[p] : &:r4
|
||||
* r5(glval<bool>) = VariableAddress[b] :
|
||||
* r6(bool) = Load[b] : &:r5, m8
|
||||
* v2(void) = ConditionalBranch : r6
|
||||
* ```
|
||||
*
|
||||
* Here, the group `{x, y}` contains an allocation that escapes (`x`), so there
|
||||
* is a `Chi` after the `UninitializedGroup` that initializes the memory for the
|
||||
* `VariableGroup` containing `x`. None of the allocations in `{w, z}` escape so
|
||||
* there is no `Chi` following that the `UninitializedGroup` that initializes the
|
||||
* memory of `{w, z}`.
|
||||
*/
|
||||
cached
|
||||
Instruction getInstructionSuccessor(Instruction instruction, EdgeKind kind) {
|
||||
result = firstInstructionToUninitializedGroup(instruction, kind)
|
||||
or
|
||||
result = getNextUninitializedGroupInstruction(instruction, kind)
|
||||
or
|
||||
result = getInstructionSuccessorAfterUninitializedGroup(instruction, kind)
|
||||
or
|
||||
not isFirstInstructionBeforeUninitializedGroup(instruction, _) and
|
||||
result = getInstructionSuccessorAfterUninitializedGroup0(instruction, kind)
|
||||
}
|
||||
|
||||
cached
|
||||
Instruction getInstructionBackEdgeSuccessor(Instruction instruction, EdgeKind kind) {
|
||||
exists(OldInstruction oldInstruction |
|
||||
@@ -406,6 +632,16 @@ private module Cached {
|
||||
exists(IRFunctionBase irFunc |
|
||||
instr = unreachedInstruction(irFunc) and result = irFunc.getFunction()
|
||||
)
|
||||
or
|
||||
exists(Alias::VariableGroup vg |
|
||||
instr = uninitializedGroup(vg) and
|
||||
result = vg.getIRFunction().getFunction()
|
||||
)
|
||||
or
|
||||
exists(UninitializedGroupInstruction initGroup |
|
||||
instr = chiInstruction(initGroup) and
|
||||
result = getInstructionAst(initGroup)
|
||||
)
|
||||
}
|
||||
|
||||
cached
|
||||
@@ -418,9 +654,16 @@ private module Cached {
|
||||
)
|
||||
or
|
||||
exists(Instruction primaryInstr, Alias::VirtualVariable vvar |
|
||||
instr = chiInstruction(primaryInstr) and
|
||||
hasChiNode(vvar, primaryInstr) and
|
||||
result = vvar.getType()
|
||||
instr = chiInstruction(primaryInstr) and result = vvar.getType()
|
||||
|
|
||||
hasChiNode(vvar, primaryInstr)
|
||||
or
|
||||
hasChiNodeAfterUninitializedGroup(vvar, primaryInstr)
|
||||
)
|
||||
or
|
||||
exists(Alias::VariableGroup vg |
|
||||
instr = uninitializedGroup(vg) and
|
||||
result = vg.getType()
|
||||
)
|
||||
or
|
||||
instr = reusedPhiInstruction(_) and
|
||||
@@ -448,6 +691,8 @@ private module Cached {
|
||||
or
|
||||
instr = chiInstruction(_) and opcode instanceof Opcode::Chi
|
||||
or
|
||||
instr = uninitializedGroup(_) and opcode instanceof Opcode::UninitializedGroup
|
||||
or
|
||||
instr = unreachedInstruction(_) and opcode instanceof Opcode::Unreached
|
||||
}
|
||||
|
||||
@@ -460,10 +705,15 @@ private module Cached {
|
||||
result = blockStartInstr.getEnclosingIRFunction()
|
||||
)
|
||||
or
|
||||
exists(OldInstruction primaryInstr |
|
||||
exists(Instruction primaryInstr |
|
||||
instr = chiInstruction(primaryInstr) and result = primaryInstr.getEnclosingIRFunction()
|
||||
)
|
||||
or
|
||||
exists(Alias::VariableGroup vg |
|
||||
instr = uninitializedGroup(vg) and
|
||||
result = vg.getIRFunction()
|
||||
)
|
||||
or
|
||||
instr = unreachedInstruction(result)
|
||||
}
|
||||
|
||||
@@ -478,6 +728,8 @@ private module Cached {
|
||||
instruction = getChi(oldInstruction) and
|
||||
result = getNewInstruction(oldInstruction)
|
||||
)
|
||||
or
|
||||
instruction = getChi(result.(UninitializedGroupInstruction))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -485,7 +737,7 @@ private Instruction getNewInstruction(OldInstruction instr) { getOldInstruction(
|
||||
|
||||
private OldInstruction getOldInstruction(Instruction instr) { instr = result }
|
||||
|
||||
private ChiInstruction getChi(OldInstruction primaryInstr) { result = chiInstruction(primaryInstr) }
|
||||
private ChiInstruction getChi(Instruction primaryInstr) { result = chiInstruction(primaryInstr) }
|
||||
|
||||
private PhiInstruction getPhi(OldBlock defBlock, Alias::MemoryLocation defLocation) {
|
||||
result = phiInstruction(defBlock.getFirstInstruction(), defLocation)
|
||||
@@ -506,6 +758,16 @@ private predicate hasChiNode(Alias::VirtualVariable vvar, OldInstruction def) {
|
||||
)
|
||||
}
|
||||
|
||||
private predicate hasChiNodeAfterUninitializedGroup(
|
||||
Alias::AliasedVirtualVariable vvar, UninitializedGroupInstruction initGroup
|
||||
) {
|
||||
exists(Alias::GroupedMemoryLocation defLocation |
|
||||
initGroup = uninitializedGroup(defLocation.getGroup()) and
|
||||
defLocation.getVirtualVariable() = vvar and
|
||||
Alias::getOverlap(defLocation, vvar) instanceof MayPartiallyOverlap
|
||||
)
|
||||
}
|
||||
|
||||
private import PhiInsertion
|
||||
|
||||
/**
|
||||
@@ -668,19 +930,33 @@ private import DefUse
|
||||
* potentially very sparse.
|
||||
*/
|
||||
module DefUse {
|
||||
bindingset[index, block]
|
||||
pragma[inline_late]
|
||||
private int getNonChiOffset(int index, OldBlock block) {
|
||||
exists(IRFunction func | func = block.getEnclosingIRFunction() |
|
||||
if
|
||||
getNewBlock(block) = func.getEntryBlock() and
|
||||
not block.getInstruction(index) instanceof InitializeNonLocalInstruction and
|
||||
not block.getInstruction(index) instanceof AliasedDefinitionInstruction
|
||||
then result = 2 * (index + count(VariableGroup vg | vg.getIRFunction() = func))
|
||||
else result = 2 * index
|
||||
)
|
||||
}
|
||||
|
||||
bindingset[index, block]
|
||||
pragma[inline_late]
|
||||
private int getChiOffset(int index, OldBlock block) { result = getNonChiOffset(index, block) + 1 }
|
||||
|
||||
/**
|
||||
* Gets the `Instruction` for the definition at offset `defOffset` in block `defBlock`.
|
||||
*/
|
||||
Instruction getDefinitionOrChiInstruction(
|
||||
private Instruction getDefinitionOrChiInstruction0(
|
||||
OldBlock defBlock, int defOffset, Alias::MemoryLocation defLocation,
|
||||
Alias::MemoryLocation actualDefLocation
|
||||
) {
|
||||
exists(OldInstruction oldInstr, int oldOffset |
|
||||
oldInstr = defBlock.getInstruction(oldOffset) and
|
||||
oldOffset >= 0
|
||||
|
|
||||
exists(OldInstruction oldInstr, int oldOffset | oldInstr = defBlock.getInstruction(oldOffset) |
|
||||
// An odd offset corresponds to the `Chi` instruction.
|
||||
defOffset = oldOffset * 2 + 1 and
|
||||
defOffset = getChiOffset(oldOffset, defBlock) and
|
||||
result = getChi(oldInstr) and
|
||||
(
|
||||
defLocation = Alias::getResultMemoryLocation(oldInstr) or
|
||||
@@ -689,7 +965,7 @@ module DefUse {
|
||||
actualDefLocation = defLocation.getVirtualVariable()
|
||||
or
|
||||
// An even offset corresponds to the original instruction.
|
||||
defOffset = oldOffset * 2 and
|
||||
defOffset = getNonChiOffset(oldOffset, defBlock) and
|
||||
result = getNewInstruction(oldInstr) and
|
||||
(
|
||||
defLocation = Alias::getResultMemoryLocation(oldInstr) or
|
||||
@@ -702,6 +978,54 @@ module DefUse {
|
||||
hasDefinition(_, defLocation, defBlock, defOffset) and
|
||||
result = getPhi(defBlock, defLocation) and
|
||||
actualDefLocation = defLocation
|
||||
or
|
||||
exists(
|
||||
Alias::VariableGroup vg, int index, UninitializedGroupInstruction initGroup,
|
||||
Alias::GroupedMemoryLocation gml
|
||||
|
|
||||
// Add 3 to account for the function prologue:
|
||||
// v1(void) = EnterFunction
|
||||
// m1(unknown) = AliasedDefinition
|
||||
// m2(unknown) = InitializeNonLocal
|
||||
index = 3 + vg.getInitializationOrder() and
|
||||
not gml.isMayAccess() and
|
||||
gml.isSome() and
|
||||
gml.getGroup() = vg and
|
||||
vg.getIRFunction().getEntryBlock() = defBlock and
|
||||
initGroup = uninitializedGroup(vg) and
|
||||
(defLocation = gml or defLocation = gml.getVirtualVariable())
|
||||
|
|
||||
result = initGroup and
|
||||
defOffset = 2 * index and
|
||||
actualDefLocation = defLocation
|
||||
or
|
||||
result = getChi(initGroup) and
|
||||
defOffset = 2 * index + 1 and
|
||||
actualDefLocation = defLocation.getVirtualVariable()
|
||||
)
|
||||
}
|
||||
|
||||
private ChiInstruction remapGetDefinitionOrChiInstruction(Instruction oldResult) {
|
||||
exists(IRFunction func |
|
||||
isFirstInstructionBeforeUninitializedGroup(oldResult, func) and
|
||||
isLastInstructionForUninitializedGroups(result, func)
|
||||
)
|
||||
}
|
||||
|
||||
Instruction getDefinitionOrChiInstruction(
|
||||
OldBlock defBlock, int defOffset, Alias::MemoryLocation defLocation,
|
||||
Alias::MemoryLocation actualDefLocation
|
||||
) {
|
||||
exists(Instruction oldResult |
|
||||
oldResult =
|
||||
getDefinitionOrChiInstruction0(defBlock, defOffset, defLocation, actualDefLocation) and
|
||||
(
|
||||
result = remapGetDefinitionOrChiInstruction(oldResult)
|
||||
or
|
||||
not exists(remapGetDefinitionOrChiInstruction(oldResult)) and
|
||||
result = oldResult
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -842,8 +1166,20 @@ module DefUse {
|
||||
block.getInstruction(index) = def and
|
||||
overlap = Alias::getOverlap(defLocation, useLocation) and
|
||||
if overlap instanceof MayPartiallyOverlap
|
||||
then offset = (index * 2) + 1 // The use will be connected to the definition on the `Chi` instruction.
|
||||
else offset = index * 2 // The use will be connected to the definition on the original instruction.
|
||||
then offset = getChiOffset(index, block) // The use will be connected to the definition on the `Chi` instruction.
|
||||
else offset = getNonChiOffset(index, block) // The use will be connected to the definition on the original instruction.
|
||||
)
|
||||
or
|
||||
exists(UninitializedGroupInstruction initGroup, int index, Overlap overlap, VariableGroup vg |
|
||||
initGroup.getEnclosingIRFunction().getEntryBlock() = getNewBlock(block) and
|
||||
vg = defLocation.(Alias::GroupedMemoryLocation).getGroup() and
|
||||
// EnterFunction + AliasedDefinition + InitializeNonLocal + index
|
||||
index = 3 + vg.getInitializationOrder() and
|
||||
initGroup = uninitializedGroup(vg) and
|
||||
overlap = Alias::getOverlap(defLocation, useLocation) and
|
||||
if overlap instanceof MayPartiallyOverlap and hasChiNodeAfterUninitializedGroup(initGroup)
|
||||
then offset = 2 * index + 1 // The use will be connected to the definition on the `Chi` instruction.
|
||||
else offset = 2 * index // The use will be connected to the definition on the original instruction.
|
||||
)
|
||||
}
|
||||
|
||||
@@ -904,10 +1240,11 @@ module DefUse {
|
||||
block.getInstruction(index) = use and
|
||||
(
|
||||
// A direct use of the location.
|
||||
useLocation = Alias::getOperandMemoryLocation(use.getAnOperand()) and offset = index * 2
|
||||
useLocation = Alias::getOperandMemoryLocation(use.getAnOperand()) and
|
||||
offset = getNonChiOffset(index, block)
|
||||
or
|
||||
// A `Chi` instruction will include a use of the virtual variable.
|
||||
hasChiNode(useLocation, use) and offset = (index * 2) + 1
|
||||
hasChiNode(useLocation, use) and offset = getChiOffset(index, block)
|
||||
)
|
||||
)
|
||||
}
|
||||
@@ -1057,5 +1394,9 @@ module Ssa {
|
||||
|
||||
predicate hasChiInstruction = Cached::hasChiInstructionCached/1;
|
||||
|
||||
predicate hasChiNodeAfterUninitializedGroup = Cached::hasChiNodeAfterUninitializedGroup/1;
|
||||
|
||||
predicate hasUnreachedInstruction = Cached::hasUnreachedInstructionCached/1;
|
||||
|
||||
class VariableGroup = Alias::VariableGroup;
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ import AliasAnalysis
|
||||
private import SimpleSSAImports
|
||||
import SimpleSSAPublicImports
|
||||
private import AliasConfiguration
|
||||
private import codeql.util.Unit
|
||||
|
||||
private predicate isTotalAccess(Allocation var, AddressOperand addrOperand, IRType type) {
|
||||
exists(Instruction constantBase, int bitOffset |
|
||||
@@ -48,7 +49,7 @@ predicate canReuseSsaForVariable(IRAutomaticVariable var) {
|
||||
|
||||
private newtype TMemoryLocation = MkMemoryLocation(Allocation var) { isVariableModeled(var) }
|
||||
|
||||
private MemoryLocation getMemoryLocation(Allocation var) { result.getAllocation() = var }
|
||||
private MemoryLocation getMemoryLocation(Allocation var) { result.getAnAllocation() = var }
|
||||
|
||||
class MemoryLocation extends TMemoryLocation {
|
||||
Allocation var;
|
||||
@@ -57,7 +58,7 @@ class MemoryLocation extends TMemoryLocation {
|
||||
|
||||
final string toString() { result = var.getAllocationString() }
|
||||
|
||||
final Allocation getAllocation() { result = var }
|
||||
final Allocation getAnAllocation() { result = var }
|
||||
|
||||
final Language::Location getLocation() { result = var.getLocation() }
|
||||
|
||||
@@ -77,6 +78,40 @@ class MemoryLocation extends TMemoryLocation {
|
||||
|
||||
predicate canReuseSsaForOldResult(Instruction instr) { none() }
|
||||
|
||||
abstract class VariableGroup extends Unit {
|
||||
abstract Allocation getAnAllocation();
|
||||
|
||||
string toString() { result = "{" + strictconcat(this.getAnAllocation().toString(), ", ") + "}" }
|
||||
|
||||
abstract Language::Location getLocation();
|
||||
|
||||
abstract IRFunction getIRFunction();
|
||||
|
||||
abstract Language::LanguageType getType();
|
||||
|
||||
abstract int getInitializationOrder();
|
||||
}
|
||||
|
||||
class GroupedMemoryLocation extends MemoryLocation {
|
||||
VariableGroup vg;
|
||||
|
||||
GroupedMemoryLocation() { none() }
|
||||
|
||||
/** Gets an allocation of this memory location. */
|
||||
Allocation getAnAllocation() { result = vg.getAnAllocation() }
|
||||
|
||||
/** Gets the set of allocations associated with this memory location. */
|
||||
VariableGroup getGroup() { result = vg }
|
||||
|
||||
predicate isMayAccess() { none() }
|
||||
|
||||
/** Holds if this memory location represents all the enclosing allocations. */
|
||||
predicate isAll() { none() }
|
||||
|
||||
/** Holds if this memory location represents one or more of the enclosing allocations. */
|
||||
predicate isSome() { none() }
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents a set of `MemoryLocation`s that cannot overlap with
|
||||
* `MemoryLocation`s outside of the set. The `VirtualVariable` will be
|
||||
|
||||
@@ -66,7 +66,7 @@ abstract private class StdStringTaintFunction extends TaintFunction {
|
||||
* Gets the index of a parameter to this function that is an iterator.
|
||||
*/
|
||||
final int getAnIteratorParameterIndex() {
|
||||
this.getParameter(result).getType() instanceof Iterator
|
||||
this.getParameter(result).getUnspecifiedType() instanceof Iterator
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -172,5 +172,5 @@ where
|
||||
not arg.isFromUninstantiatedTemplate(_) and
|
||||
not actual.getUnspecifiedType() instanceof ErroneousType
|
||||
select arg,
|
||||
"This argument should be of type '" + expected.getName() + "' but is of type '" +
|
||||
"This format specifier for type '" + expected.getName() + "' does not match the argument type '" +
|
||||
actual.getUnspecifiedType().getName() + "'."
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
Record* fixRecord(Record* r) {
|
||||
Record myRecord = *r;
|
||||
delete r;
|
||||
|
||||
myRecord.fix();
|
||||
return &myRecord; //returns reference to myRecord, which is a stack-allocated object
|
||||
}
|
||||
@@ -5,22 +5,23 @@
|
||||
|
||||
|
||||
<overview>
|
||||
<p>This rule finds return statements that return pointers to an object allocated on the stack.
|
||||
The lifetime of a stack allocated memory location only lasts until the function returns, and
|
||||
the contents of that memory become undefined after that. Clearly, using a pointer to stack
|
||||
<p>This rule finds return statements that return pointers to an object allocated on the stack.
|
||||
The lifetime of a stack allocated memory location only lasts until the function returns, and
|
||||
the contents of that memory become undefined after that. Clearly, using a pointer to stack
|
||||
memory after the function has already returned will have undefined results. </p>
|
||||
|
||||
</overview>
|
||||
<recommendation>
|
||||
<p>Use the functions of the <tt>malloc</tt> family to dynamically allocate memory on the heap for data that is used across function calls.</p>
|
||||
<p>Use the functions of the <tt>malloc</tt> family, or <tt>new</tt>, to dynamically allocate memory on the heap for data that is used across function calls.</p>
|
||||
|
||||
</recommendation>
|
||||
<example><sample src="ReturnStackAllocatedMemory.cpp" />
|
||||
|
||||
|
||||
|
||||
|
||||
<example>
|
||||
<p>The following example allocates an object on the stack and returns a pointer to it. This is incorrect because the object is deallocated
|
||||
when the function returns, and the pointer becomes invalid.</p>
|
||||
<sample src="ReturnStackAllocatedMemoryBad.cpp" />
|
||||
|
||||
<p>To fix this, allocate the object on the heap using <tt>new</tt> and return a pointer to the heap-allocated object.</p>
|
||||
<sample src="ReturnStackAllocatedMemoryGood.cpp" />
|
||||
</example>
|
||||
|
||||
<references>
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
Record *mkRecord(int value) {
|
||||
Record myRecord(value);
|
||||
|
||||
return &myRecord; // BAD: returns a pointer to `myRecord`, which is a stack-allocated object.
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
Record *mkRecord(int value) {
|
||||
Record *myRecord = new Record(value);
|
||||
|
||||
return myRecord; // GOOD: returns a pointer to a `myRecord`, which is a heap-allocated object.
|
||||
}
|
||||
@@ -1,5 +1,14 @@
|
||||
unsigned limit = get_limit();
|
||||
unsigned total = 0;
|
||||
while (limit - total > 0) { // wrong: if `total` is greater than `limit` this will underflow and continue executing the loop.
|
||||
uint32_t limit = get_limit();
|
||||
uint32_t total = 0;
|
||||
|
||||
while (limit - total > 0) { // BAD: if `total` is greater than `limit` this will underflow and continue executing the loop.
|
||||
total += get_data();
|
||||
}
|
||||
}
|
||||
|
||||
while (total < limit) { // GOOD: never underflows here because there is no arithmetic.
|
||||
total += get_data();
|
||||
}
|
||||
|
||||
while ((int64_t)limit - total > 0) { // GOOD: never underflows here because the result always fits in an `int64_t`.
|
||||
total += get_data();
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@ import semmle.code.cpp.rangeanalysis.SimpleRangeAnalysis
|
||||
import semmle.code.cpp.rangeanalysis.RangeAnalysisUtils
|
||||
import semmle.code.cpp.controlflow.Guards
|
||||
import semmle.code.cpp.ir.dataflow.DataFlow
|
||||
import semmle.code.cpp.valuenumbering.GlobalValueNumbering
|
||||
|
||||
/**
|
||||
* Holds if `sub` is guarded by a condition which ensures that
|
||||
@@ -33,46 +34,109 @@ predicate isGuarded(SubExpr sub, Expr left, Expr right) {
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets an expression that is less than or equal to `sub.getLeftOperand()`.
|
||||
* These serve as the base cases for `exprIsSubLeftOrLess`.
|
||||
*/
|
||||
Expr exprIsLeftOrLessBase(SubExpr sub) {
|
||||
interestingSubExpr(sub, _) and // Manual magic
|
||||
exists(Expr e | globalValueNumber(e).getAnExpr() = sub.getLeftOperand() |
|
||||
// sub = e - x
|
||||
// result = e
|
||||
// so:
|
||||
// result <= e
|
||||
result = e
|
||||
or
|
||||
// sub = e - x
|
||||
// result = e & y
|
||||
// so:
|
||||
// result = e & y <= e
|
||||
result.(BitwiseAndExpr).getAnOperand() = e
|
||||
or
|
||||
exists(SubExpr s |
|
||||
// sub = e - x
|
||||
// result = s
|
||||
// s = e - y
|
||||
// y >= 0
|
||||
// so:
|
||||
// result = e - y <= e
|
||||
result = s and
|
||||
s.getLeftOperand() = e and
|
||||
lowerBound(s.getRightOperand().getFullyConverted()) >= 0
|
||||
)
|
||||
or
|
||||
exists(Expr other |
|
||||
// sub = e - x
|
||||
// result = a
|
||||
// a = e + y
|
||||
// y <= 0
|
||||
// so:
|
||||
// result = e + y <= e + 0 = e
|
||||
result.(AddExpr).hasOperands(e, other) and
|
||||
upperBound(other.getFullyConverted()) <= 0
|
||||
)
|
||||
or
|
||||
exists(DivExpr d |
|
||||
// sub = e - x
|
||||
// result = d
|
||||
// d = e / y
|
||||
// y >= 1
|
||||
// so:
|
||||
// result = e / y <= e / 1 = e
|
||||
result = d and
|
||||
d.getLeftOperand() = e and
|
||||
lowerBound(d.getRightOperand().getFullyConverted()) >= 1
|
||||
)
|
||||
or
|
||||
exists(RShiftExpr rs |
|
||||
// sub = e - x
|
||||
// result = rs
|
||||
// rs = e >> y
|
||||
// so:
|
||||
// result = e >> y <= e
|
||||
result = rs and
|
||||
rs.getLeftOperand() = e
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `n` is known or suspected to be less than or equal to
|
||||
* `sub.getLeftOperand()`.
|
||||
*/
|
||||
predicate exprIsSubLeftOrLess(SubExpr sub, DataFlow::Node n) {
|
||||
interestingSubExpr(sub, _) and // Manual magic
|
||||
(
|
||||
n.asExpr() = sub.getLeftOperand()
|
||||
or
|
||||
exists(DataFlow::Node other |
|
||||
// dataflow
|
||||
exprIsSubLeftOrLess(sub, other) and
|
||||
(
|
||||
DataFlow::localFlowStep(n, other) or
|
||||
DataFlow::localFlowStep(other, n)
|
||||
)
|
||||
)
|
||||
or
|
||||
exists(DataFlow::Node other |
|
||||
// guard constraining `sub`
|
||||
exprIsSubLeftOrLess(sub, other) and
|
||||
isGuarded(sub, other.asExpr(), n.asExpr()) // other >= n
|
||||
)
|
||||
or
|
||||
exists(DataFlow::Node other, float p, float q |
|
||||
// linear access of `other`
|
||||
exprIsSubLeftOrLess(sub, other) and
|
||||
linearAccess(n.asExpr(), other.asExpr(), p, q) and // n = p * other + q
|
||||
p <= 1 and
|
||||
q <= 0
|
||||
)
|
||||
or
|
||||
exists(DataFlow::Node other, float p, float q |
|
||||
// linear access of `n`
|
||||
exprIsSubLeftOrLess(sub, other) and
|
||||
linearAccess(other.asExpr(), n.asExpr(), p, q) and // other = p * n + q
|
||||
p >= 1 and
|
||||
q >= 0
|
||||
n.asExpr() = exprIsLeftOrLessBase(sub)
|
||||
or
|
||||
exists(DataFlow::Node other |
|
||||
// dataflow
|
||||
exprIsSubLeftOrLess(sub, other) and
|
||||
(
|
||||
DataFlow::localFlowStep(n, other) or
|
||||
DataFlow::localFlowStep(other, n)
|
||||
)
|
||||
)
|
||||
or
|
||||
exists(DataFlow::Node other |
|
||||
// guard constraining `sub`
|
||||
exprIsSubLeftOrLess(sub, other) and
|
||||
isGuarded(sub, other.asExpr(), n.asExpr()) // other >= n
|
||||
)
|
||||
or
|
||||
exists(DataFlow::Node other, float p, float q |
|
||||
// linear access of `other`
|
||||
exprIsSubLeftOrLess(sub, other) and
|
||||
linearAccess(n.asExpr(), other.asExpr(), p, q) and // n = p * other + q
|
||||
p <= 1 and
|
||||
q <= 0
|
||||
)
|
||||
or
|
||||
exists(DataFlow::Node other, float p, float q |
|
||||
// linear access of `n`
|
||||
exprIsSubLeftOrLess(sub, other) and
|
||||
linearAccess(other.asExpr(), n.asExpr(), p, q) and // other = p * n + q
|
||||
p >= 1 and
|
||||
q >= 0
|
||||
)
|
||||
}
|
||||
|
||||
predicate interestingSubExpr(SubExpr sub, RelationalOperation ro) {
|
||||
|
||||
@@ -1,15 +1,17 @@
|
||||
char *file_name;
|
||||
FILE *f_ptr;
|
||||
|
||||
|
||||
/* Initialize file_name */
|
||||
|
||||
|
||||
f_ptr = fopen(file_name, "w");
|
||||
if (f_ptr == NULL) {
|
||||
/* Handle error */
|
||||
}
|
||||
|
||||
|
||||
/* ... */
|
||||
|
||||
|
||||
if (chmod(file_name, S_IRUSR) == -1) {
|
||||
/* Handle error */
|
||||
}
|
||||
}
|
||||
|
||||
fclose(f_ptr);
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
char *file_name;
|
||||
int fd;
|
||||
|
||||
|
||||
/* Initialize file_name */
|
||||
|
||||
|
||||
fd = open(
|
||||
file_name,
|
||||
O_WRONLY | O_CREAT | O_EXCL,
|
||||
@@ -11,9 +11,11 @@ fd = open(
|
||||
if (fd == -1) {
|
||||
/* Handle error */
|
||||
}
|
||||
|
||||
|
||||
/* ... */
|
||||
|
||||
|
||||
if (fchmod(fd, S_IRUSR) == -1) {
|
||||
/* Handle error */
|
||||
}
|
||||
}
|
||||
|
||||
close(fd);
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* @name Iterator to expired container
|
||||
* @description Using an iterator owned by a container whose lifetime has expired may lead to unexpected behavior.
|
||||
* @kind problem
|
||||
* @precision medium
|
||||
* @precision high
|
||||
* @id cpp/iterator-to-expired-container
|
||||
* @problem.severity warning
|
||||
* @security-severity 8.8
|
||||
|
||||
@@ -34,7 +34,7 @@ void good1(std::size_t length) noexcept {
|
||||
|
||||
// GOOD: the allocation failure is handled appropriately.
|
||||
void good2(std::size_t length) noexcept {
|
||||
int* dest = new int[length];
|
||||
int* dest = new(std::nothrow) int[length];
|
||||
if(!dest) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1,11 +1,38 @@
|
||||
void write_default_config_bad() {
|
||||
// BAD - this is world-writable so any user can overwrite the config
|
||||
int out = creat(OUTFILE, 0666);
|
||||
dprintf(out, DEFAULT_CONFIG);
|
||||
if (out < 0) {
|
||||
// handle error
|
||||
}
|
||||
|
||||
dprintf(out, "%s", DEFAULT_CONFIG);
|
||||
close(out);
|
||||
}
|
||||
|
||||
void write_default_config_good() {
|
||||
// GOOD - this allows only the current user to modify the file
|
||||
int out = creat(OUTFILE, S_IWUSR | S_IRUSR);
|
||||
dprintf(out, DEFAULT_CONFIG);
|
||||
if (out < 0) {
|
||||
// handle error
|
||||
}
|
||||
|
||||
dprintf(out, "%s", DEFAULT_CONFIG);
|
||||
close(out);
|
||||
}
|
||||
|
||||
void write_default_config_good_2() {
|
||||
// GOOD - this allows only the current user to modify the file
|
||||
int out = open(OUTFILE, O_WRONLY | O_CREAT, S_IWUSR | S_IRUSR);
|
||||
if (out < 0) {
|
||||
// handle error
|
||||
}
|
||||
|
||||
FILE *fd = fdopen(out, "w");
|
||||
if (fd == NULL) {
|
||||
close(out);
|
||||
// handle error
|
||||
}
|
||||
|
||||
fprintf(fd, "%s", DEFAULT_CONFIG);
|
||||
fclose(fd);
|
||||
}
|
||||
|
||||
@@ -29,10 +29,11 @@ so it is important that they cannot be controlled by an attacker.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
The first example creates the default configuration file with the usual "default" Unix permissions, <code>0666</code>. This makes the
|
||||
The first example creates the default configuration file with the usual "default" Unix permissions, <code>0666</code>. This makes the
|
||||
file world-writable, so that an attacker could write in their own configuration that would be read by the program. The second example uses
|
||||
more restrictive permissions: a combination of the standard Unix constants <code>S_IWUSR</code> and <code>S_IRUSR</code> which means that
|
||||
only the current user will have read and write access to the file.
|
||||
only the current user will have read and write access to the file. The third example shows another way to create a file with more restrictive
|
||||
permissions if a <code>FILE *</code> stream pointer is required rather than a file descriptor.
|
||||
</p>
|
||||
|
||||
<sample src="DoNotCreateWorldWritable.c" />
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
---
|
||||
category: queryMetadata
|
||||
---
|
||||
* The precision of `cpp/iterator-to-expired-container` ("Iterator to expired container") has been increased to `high`. As a result, it will be run by default as part of the Code Scanning suite.
|
||||
@@ -0,0 +1,4 @@
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
* The `cpp/unsigned-difference-expression-compared-zero` ("Unsigned difference expression compared to zero") query now produces fewer false positives.
|
||||
@@ -1,5 +1,11 @@
|
||||
| file://:0:0:0:0 | char[6] | 6 |
|
||||
| file://:0:0:0:0 | char[26] | 26 |
|
||||
| file://:0:0:0:0 | char[] | |
|
||||
| file://:0:0:0:0 | const char[6] | 6 |
|
||||
| file://:0:0:0:0 | double[0] | 0 |
|
||||
| file://:0:0:0:0 | double[3] | 3 |
|
||||
| file://:0:0:0:0 | double[4] | 4 |
|
||||
| file://:0:0:0:0 | double[] | |
|
||||
| file://:0:0:0:0 | int[1] | 1 |
|
||||
| file://:0:0:0:0 | int[11] | 11 |
|
||||
| file://:0:0:0:0 | long[] | |
|
||||
|
||||
10
cpp/ql/test/library-tests/array_sizes/implicit_sizes.cpp
Normal file
10
cpp/ql/test/library-tests/array_sizes/implicit_sizes.cpp
Normal file
@@ -0,0 +1,10 @@
|
||||
// semmle-extractor-options: -std=c++20
|
||||
double a1[]{1,2,3};
|
||||
double* p1 = new double[]{1,2,3};
|
||||
double* p2 = new double[0]{};
|
||||
double* p3 = new double[]{};
|
||||
char c[]{"Hello"};
|
||||
char* d = new char[]{"Hello"};
|
||||
double a2[](1,2,3);
|
||||
double* p4 = new double[](1,2,3);
|
||||
double* p5 = new double[4]{1,2}; // Size mismatch
|
||||
6
cpp/ql/test/library-tests/array_sizes/new.expected
Normal file
6
cpp/ql/test/library-tests/array_sizes/new.expected
Normal file
@@ -0,0 +1,6 @@
|
||||
| implicit_sizes.cpp:3:14:3:32 | new[] | 3 |
|
||||
| implicit_sizes.cpp:4:14:4:28 | new[] | 0 |
|
||||
| implicit_sizes.cpp:5:14:5:27 | new[] | 0 |
|
||||
| implicit_sizes.cpp:7:11:7:29 | new[] | 6 |
|
||||
| implicit_sizes.cpp:9:14:9:32 | new[] | 3 |
|
||||
| implicit_sizes.cpp:10:14:10:31 | new[] | 4 |
|
||||
4
cpp/ql/test/library-tests/array_sizes/new.ql
Normal file
4
cpp/ql/test/library-tests/array_sizes/new.ql
Normal file
@@ -0,0 +1,4 @@
|
||||
import cpp
|
||||
|
||||
from NewArrayExpr nae
|
||||
select nae, nae.getArraySize()
|
||||
@@ -1,7 +1,5 @@
|
||||
| (unnamed parameter 0) | __va_list_tag && | rvalue reference to {struct __va_list_tag} |
|
||||
| (unnamed parameter 0) | atomic_box<int> && | rvalue reference to {struct atomic_box<int>} |
|
||||
| (unnamed parameter 0) | const __va_list_tag & | reference to {const {struct __va_list_tag}} |
|
||||
| (unnamed parameter 0) | const atomic_box<int> & | reference to {const {struct atomic_box<int>}} |
|
||||
| a | _Atomic(int) | atomic {int} |
|
||||
| b | _Atomic(int) | atomic {int} |
|
||||
| c | _Atomic(int) * | pointer to {atomic {int}} |
|
||||
|
||||
@@ -1,2 +1,46 @@
|
||||
testFailures
|
||||
failures
|
||||
edges
|
||||
| asio_streams.cpp:56:18:56:23 | [summary param] *0 in buffer | asio_streams.cpp:56:18:56:23 | [summary] to write: ReturnValue in buffer | provenance | MaD:10 |
|
||||
| asio_streams.cpp:87:34:87:44 | read_until output argument | asio_streams.cpp:91:7:91:17 | recv_buffer | provenance | Src:MaD:2 |
|
||||
| asio_streams.cpp:87:34:87:44 | read_until output argument | asio_streams.cpp:93:29:93:39 | *recv_buffer | provenance | Src:MaD:2 Sink:MaD:6 |
|
||||
| asio_streams.cpp:97:37:97:44 | call to source | asio_streams.cpp:98:7:98:14 | send_str | provenance | TaintFunction |
|
||||
| asio_streams.cpp:97:37:97:44 | call to source | asio_streams.cpp:100:64:100:71 | *send_str | provenance | TaintFunction |
|
||||
| asio_streams.cpp:100:44:100:62 | call to buffer | asio_streams.cpp:100:44:100:62 | call to buffer | provenance | |
|
||||
| asio_streams.cpp:100:44:100:62 | call to buffer | asio_streams.cpp:101:7:101:17 | send_buffer | provenance | |
|
||||
| asio_streams.cpp:100:44:100:62 | call to buffer | asio_streams.cpp:103:29:103:39 | *send_buffer | provenance | Sink:MaD:6 |
|
||||
| asio_streams.cpp:100:64:100:71 | *send_str | asio_streams.cpp:56:18:56:23 | [summary param] *0 in buffer | provenance | |
|
||||
| asio_streams.cpp:100:64:100:71 | *send_str | asio_streams.cpp:100:44:100:62 | call to buffer | provenance | MaD:10 |
|
||||
| test.cpp:4:5:4:11 | [summary param] 0 in ymlStep | test.cpp:4:5:4:11 | [summary] to write: ReturnValue in ymlStep | provenance | MaD:2 |
|
||||
| test.cpp:7:10:7:18 | call to ymlSource | test.cpp:7:10:7:18 | call to ymlSource | provenance | Src:MaD:0 |
|
||||
| test.cpp:7:10:7:18 | call to ymlSource | test.cpp:11:10:11:10 | x | provenance | Sink:MaD:1 |
|
||||
| test.cpp:7:10:7:18 | call to ymlSource | test.cpp:13:18:13:18 | x | provenance | |
|
||||
| test.cpp:13:10:13:16 | call to ymlStep | test.cpp:13:10:13:16 | call to ymlStep | provenance | |
|
||||
| test.cpp:13:10:13:16 | call to ymlStep | test.cpp:15:10:15:10 | y | provenance | Sink:MaD:1 |
|
||||
| test.cpp:13:18:13:18 | x | test.cpp:4:5:4:11 | [summary param] 0 in ymlStep | provenance | |
|
||||
| test.cpp:13:18:13:18 | x | test.cpp:13:10:13:16 | call to ymlStep | provenance | MaD:2 |
|
||||
nodes
|
||||
| asio_streams.cpp:56:18:56:23 | [summary param] *0 in buffer | semmle.label | [summary param] *0 in buffer |
|
||||
| asio_streams.cpp:56:18:56:23 | [summary] to write: ReturnValue in buffer | semmle.label | [summary] to write: ReturnValue in buffer |
|
||||
| asio_streams.cpp:87:34:87:44 | read_until output argument | semmle.label | read_until output argument |
|
||||
| asio_streams.cpp:91:7:91:17 | recv_buffer | semmle.label | recv_buffer |
|
||||
| asio_streams.cpp:93:29:93:39 | *recv_buffer | semmle.label | *recv_buffer |
|
||||
| asio_streams.cpp:97:37:97:44 | call to source | semmle.label | call to source |
|
||||
| asio_streams.cpp:98:7:98:14 | send_str | semmle.label | send_str |
|
||||
| asio_streams.cpp:100:44:100:62 | call to buffer | semmle.label | call to buffer |
|
||||
| asio_streams.cpp:100:44:100:62 | call to buffer | semmle.label | call to buffer |
|
||||
| asio_streams.cpp:100:64:100:71 | *send_str | semmle.label | *send_str |
|
||||
| asio_streams.cpp:101:7:101:17 | send_buffer | semmle.label | send_buffer |
|
||||
| asio_streams.cpp:103:29:103:39 | *send_buffer | semmle.label | *send_buffer |
|
||||
| test.cpp:4:5:4:11 | [summary param] 0 in ymlStep | semmle.label | [summary param] 0 in ymlStep |
|
||||
| test.cpp:4:5:4:11 | [summary] to write: ReturnValue in ymlStep | semmle.label | [summary] to write: ReturnValue in ymlStep |
|
||||
| test.cpp:7:10:7:18 | call to ymlSource | semmle.label | call to ymlSource |
|
||||
| test.cpp:7:10:7:18 | call to ymlSource | semmle.label | call to ymlSource |
|
||||
| test.cpp:11:10:11:10 | x | semmle.label | x |
|
||||
| test.cpp:13:10:13:16 | call to ymlStep | semmle.label | call to ymlStep |
|
||||
| test.cpp:13:10:13:16 | call to ymlStep | semmle.label | call to ymlStep |
|
||||
| test.cpp:13:18:13:18 | x | semmle.label | x |
|
||||
| test.cpp:15:10:15:10 | y | semmle.label | y |
|
||||
subpaths
|
||||
| asio_streams.cpp:100:64:100:71 | *send_str | asio_streams.cpp:56:18:56:23 | [summary param] *0 in buffer | asio_streams.cpp:56:18:56:23 | [summary] to write: ReturnValue in buffer | asio_streams.cpp:100:44:100:62 | call to buffer |
|
||||
| test.cpp:13:18:13:18 | x | test.cpp:4:5:4:11 | [summary param] 0 in ymlStep | test.cpp:4:5:4:11 | [summary] to write: ReturnValue in ymlStep | test.cpp:13:10:13:16 | call to ymlStep |
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import TestUtilities.dataflow.FlowTestCommon
|
||||
import cpp
|
||||
import semmle.code.cpp.security.FlowSources
|
||||
import IRTest::IRFlow::PathGraph
|
||||
|
||||
module IRTest {
|
||||
private import semmle.code.cpp.ir.IR
|
||||
|
||||
@@ -301,27 +301,6 @@ WARNING: module 'TaintTracking' has been deprecated and may be removed in future
|
||||
| file://:0:0:0:0 | (unnamed parameter 0) | file://:0:0:0:0 | (unnamed parameter 0) | |
|
||||
| file://:0:0:0:0 | (unnamed parameter 0) | file://:0:0:0:0 | (unnamed parameter 0) | |
|
||||
| file://:0:0:0:0 | (unnamed parameter 0) | file://:0:0:0:0 | (unnamed parameter 0) | |
|
||||
| file://:0:0:0:0 | (unnamed parameter 0) | file://:0:0:0:0 | (unnamed parameter 0) | |
|
||||
| file://:0:0:0:0 | (unnamed parameter 0) | file://:0:0:0:0 | (unnamed parameter 0) | |
|
||||
| file://:0:0:0:0 | (unnamed parameter 0) | file://:0:0:0:0 | (unnamed parameter 0) | |
|
||||
| file://:0:0:0:0 | (unnamed parameter 0) | file://:0:0:0:0 | (unnamed parameter 0) | |
|
||||
| file://:0:0:0:0 | (unnamed parameter 0) | file://:0:0:0:0 | (unnamed parameter 0) | |
|
||||
| file://:0:0:0:0 | (unnamed parameter 0) | file://:0:0:0:0 | (unnamed parameter 0) | |
|
||||
| file://:0:0:0:0 | (unnamed parameter 0) | file://:0:0:0:0 | (unnamed parameter 0) | |
|
||||
| file://:0:0:0:0 | (unnamed parameter 0) | file://:0:0:0:0 | (unnamed parameter 0) | |
|
||||
| file://:0:0:0:0 | (unnamed parameter 0) | file://:0:0:0:0 | (unnamed parameter 0) | |
|
||||
| file://:0:0:0:0 | (unnamed parameter 0) | stl.h:75:8:75:8 | (unnamed parameter 0) | |
|
||||
| file://:0:0:0:0 | (unnamed parameter 0) | stl.h:75:8:75:8 | (unnamed parameter 0) | |
|
||||
| file://:0:0:0:0 | (unnamed parameter 0) | stl.h:389:9:389:9 | (unnamed parameter 0) | |
|
||||
| file://:0:0:0:0 | (unnamed parameter 0) | stl.h:389:9:389:9 | (unnamed parameter 0) | |
|
||||
| file://:0:0:0:0 | (unnamed parameter 0) | stl.h:389:9:389:9 | (unnamed parameter 0) | |
|
||||
| file://:0:0:0:0 | (unnamed parameter 0) | stl.h:389:9:389:9 | (unnamed parameter 0) | |
|
||||
| file://:0:0:0:0 | (unnamed parameter 0) | stl.h:389:9:389:9 | (unnamed parameter 0) | |
|
||||
| file://:0:0:0:0 | (unnamed parameter 0) | stl.h:389:9:389:9 | (unnamed parameter 0) | |
|
||||
| file://:0:0:0:0 | (unnamed parameter 0) | stl.h:389:9:389:9 | (unnamed parameter 0) | |
|
||||
| file://:0:0:0:0 | (unnamed parameter 0) | stl.h:389:9:389:9 | (unnamed parameter 0) | |
|
||||
| file://:0:0:0:0 | (unnamed parameter 0) | stl.h:389:9:389:9 | (unnamed parameter 0) | |
|
||||
| file://:0:0:0:0 | (unnamed parameter 0) | stl.h:389:9:389:9 | (unnamed parameter 0) | |
|
||||
| file://:0:0:0:0 | (unnamed parameter 0) | structlikeclass.cpp:5:7:5:7 | (unnamed parameter 0) | |
|
||||
| file://:0:0:0:0 | (unnamed parameter 0) | structlikeclass.cpp:5:7:5:7 | (unnamed parameter 0) | |
|
||||
| file://:0:0:0:0 | (unnamed parameter 0) | taint.cpp:228:11:228:11 | (unnamed parameter 0) | |
|
||||
@@ -3599,12 +3578,6 @@ WARNING: module 'TaintTracking' has been deprecated and may be removed in future
|
||||
| standalone_iterators.cpp:128:2:128:3 | it | standalone_iterators.cpp:128:5:128:5 | call to operator+= | TAINT |
|
||||
| standalone_iterators.cpp:128:2:128:3 | ref arg it | standalone_iterators.cpp:129:7:129:8 | it | |
|
||||
| standalone_iterators.cpp:128:8:128:13 | call to source | standalone_iterators.cpp:128:2:128:3 | ref arg it | TAINT |
|
||||
| stl.h:75:8:75:8 | container | stl.h:75:8:75:8 | constructor init of field container | TAINT |
|
||||
| stl.h:75:8:75:8 | container | stl.h:75:8:75:8 | constructor init of field container | TAINT |
|
||||
| stl.h:75:8:75:8 | container | stl.h:75:8:75:8 | container | |
|
||||
| stl.h:75:8:75:8 | container | stl.h:75:8:75:8 | container | |
|
||||
| stl.h:75:8:75:8 | this | stl.h:75:8:75:8 | constructor init of field container [pre-this] | |
|
||||
| stl.h:75:8:75:8 | this | stl.h:75:8:75:8 | constructor init of field container [pre-this] | |
|
||||
| stl.h:95:69:95:69 | x | stl.h:95:69:95:69 | x | |
|
||||
| stl.h:95:69:95:69 | x | stl.h:95:69:95:69 | x | |
|
||||
| stl.h:95:69:95:69 | x | stl.h:95:69:95:69 | x | |
|
||||
@@ -3620,41 +3593,6 @@ WARNING: module 'TaintTracking' has been deprecated and may be removed in future
|
||||
| stl.h:292:30:292:40 | call to allocator | stl.h:292:21:292:41 | noexcept(...) | TAINT |
|
||||
| stl.h:292:30:292:40 | call to allocator | stl.h:292:21:292:41 | noexcept(...) | TAINT |
|
||||
| stl.h:292:53:292:63 | 0 | stl.h:292:46:292:64 | (no string representation) | TAINT |
|
||||
| stl.h:389:9:389:9 | constructor init of field first [post-this] | stl.h:389:9:389:9 | constructor init of field second [pre-this] | |
|
||||
| stl.h:389:9:389:9 | constructor init of field first [post-this] | stl.h:389:9:389:9 | constructor init of field second [pre-this] | |
|
||||
| stl.h:389:9:389:9 | constructor init of field first [post-this] | stl.h:389:9:389:9 | constructor init of field second [pre-this] | |
|
||||
| stl.h:389:9:389:9 | constructor init of field first [post-this] | stl.h:389:9:389:9 | constructor init of field second [pre-this] | |
|
||||
| stl.h:389:9:389:9 | constructor init of field first [post-this] | stl.h:389:9:389:9 | constructor init of field second [pre-this] | |
|
||||
| stl.h:389:9:389:9 | constructor init of field first [pre-this] | stl.h:389:9:389:9 | constructor init of field second [pre-this] | |
|
||||
| stl.h:389:9:389:9 | constructor init of field first [pre-this] | stl.h:389:9:389:9 | constructor init of field second [pre-this] | |
|
||||
| stl.h:389:9:389:9 | constructor init of field first [pre-this] | stl.h:389:9:389:9 | constructor init of field second [pre-this] | |
|
||||
| stl.h:389:9:389:9 | constructor init of field first [pre-this] | stl.h:389:9:389:9 | constructor init of field second [pre-this] | |
|
||||
| stl.h:389:9:389:9 | constructor init of field first [pre-this] | stl.h:389:9:389:9 | constructor init of field second [pre-this] | |
|
||||
| stl.h:389:9:389:9 | first | stl.h:389:9:389:9 | constructor init of field first | TAINT |
|
||||
| stl.h:389:9:389:9 | first | stl.h:389:9:389:9 | constructor init of field first | TAINT |
|
||||
| stl.h:389:9:389:9 | first | stl.h:389:9:389:9 | constructor init of field first | TAINT |
|
||||
| stl.h:389:9:389:9 | first | stl.h:389:9:389:9 | constructor init of field first | TAINT |
|
||||
| stl.h:389:9:389:9 | first | stl.h:389:9:389:9 | constructor init of field first | TAINT |
|
||||
| stl.h:389:9:389:9 | first | stl.h:389:9:389:9 | first | |
|
||||
| stl.h:389:9:389:9 | first | stl.h:389:9:389:9 | first | |
|
||||
| stl.h:389:9:389:9 | first | stl.h:389:9:389:9 | first | |
|
||||
| stl.h:389:9:389:9 | first | stl.h:389:9:389:9 | first | |
|
||||
| stl.h:389:9:389:9 | first | stl.h:389:9:389:9 | first | |
|
||||
| stl.h:389:9:389:9 | second | stl.h:389:9:389:9 | constructor init of field second | TAINT |
|
||||
| stl.h:389:9:389:9 | second | stl.h:389:9:389:9 | constructor init of field second | TAINT |
|
||||
| stl.h:389:9:389:9 | second | stl.h:389:9:389:9 | constructor init of field second | TAINT |
|
||||
| stl.h:389:9:389:9 | second | stl.h:389:9:389:9 | constructor init of field second | TAINT |
|
||||
| stl.h:389:9:389:9 | second | stl.h:389:9:389:9 | constructor init of field second | TAINT |
|
||||
| stl.h:389:9:389:9 | second | stl.h:389:9:389:9 | second | |
|
||||
| stl.h:389:9:389:9 | second | stl.h:389:9:389:9 | second | |
|
||||
| stl.h:389:9:389:9 | second | stl.h:389:9:389:9 | second | |
|
||||
| stl.h:389:9:389:9 | second | stl.h:389:9:389:9 | second | |
|
||||
| stl.h:389:9:389:9 | second | stl.h:389:9:389:9 | second | |
|
||||
| stl.h:389:9:389:9 | this | stl.h:389:9:389:9 | constructor init of field first [pre-this] | |
|
||||
| stl.h:389:9:389:9 | this | stl.h:389:9:389:9 | constructor init of field first [pre-this] | |
|
||||
| stl.h:389:9:389:9 | this | stl.h:389:9:389:9 | constructor init of field first [pre-this] | |
|
||||
| stl.h:389:9:389:9 | this | stl.h:389:9:389:9 | constructor init of field first [pre-this] | |
|
||||
| stl.h:389:9:389:9 | this | stl.h:389:9:389:9 | constructor init of field first [pre-this] | |
|
||||
| stl.h:396:3:396:3 | this | stl.h:396:36:396:43 | constructor init of field first [pre-this] | |
|
||||
| stl.h:396:3:396:3 | this | stl.h:396:36:396:43 | constructor init of field first [pre-this] | |
|
||||
| stl.h:396:3:396:3 | this | stl.h:396:36:396:43 | constructor init of field first [pre-this] | |
|
||||
@@ -4361,6 +4299,8 @@ WARNING: module 'TaintTracking' has been deprecated and may be removed in future
|
||||
| string.cpp:446:17:446:17 | a | string.cpp:446:19:446:23 | call to begin | TAINT |
|
||||
| string.cpp:446:17:446:17 | ref arg a | string.cpp:446:8:446:8 | a | |
|
||||
| string.cpp:446:17:446:17 | ref arg a | string.cpp:447:8:447:8 | a | |
|
||||
| string.cpp:446:17:446:25 | call to iterator | string.cpp:446:8:446:8 | ref arg a | TAINT |
|
||||
| string.cpp:446:17:446:25 | call to iterator | string.cpp:446:10:446:15 | call to insert | TAINT |
|
||||
| string.cpp:446:19:446:23 | call to begin | string.cpp:446:17:446:25 | call to iterator | TAINT |
|
||||
| string.cpp:446:32:446:34 | 120 | string.cpp:446:8:446:8 | ref arg a | TAINT |
|
||||
| string.cpp:446:32:446:34 | 120 | string.cpp:446:10:446:15 | call to insert | TAINT |
|
||||
@@ -4369,6 +4309,8 @@ WARNING: module 'TaintTracking' has been deprecated and may be removed in future
|
||||
| string.cpp:449:17:449:17 | b | string.cpp:449:19:449:23 | call to begin | TAINT |
|
||||
| string.cpp:449:17:449:17 | ref arg b | string.cpp:449:8:449:8 | b | |
|
||||
| string.cpp:449:17:449:17 | ref arg b | string.cpp:450:8:450:8 | b | |
|
||||
| string.cpp:449:17:449:25 | call to iterator | string.cpp:449:8:449:8 | ref arg b | TAINT |
|
||||
| string.cpp:449:17:449:25 | call to iterator | string.cpp:449:10:449:15 | call to insert | TAINT |
|
||||
| string.cpp:449:19:449:23 | call to begin | string.cpp:449:17:449:25 | call to iterator | TAINT |
|
||||
| string.cpp:449:32:449:46 | call to source | string.cpp:449:8:449:8 | ref arg b | TAINT |
|
||||
| string.cpp:449:32:449:46 | call to source | string.cpp:449:10:449:15 | call to insert | TAINT |
|
||||
@@ -4396,6 +4338,8 @@ WARNING: module 'TaintTracking' has been deprecated and may be removed in future
|
||||
| string.cpp:459:17:459:17 | c | string.cpp:459:19:459:21 | call to end | TAINT |
|
||||
| string.cpp:459:17:459:17 | ref arg c | string.cpp:459:8:459:8 | c | |
|
||||
| string.cpp:459:17:459:17 | ref arg c | string.cpp:460:8:460:8 | c | |
|
||||
| string.cpp:459:17:459:23 | call to iterator | string.cpp:459:8:459:8 | ref arg c | TAINT |
|
||||
| string.cpp:459:17:459:23 | call to iterator | string.cpp:459:10:459:15 | call to insert | TAINT |
|
||||
| string.cpp:459:19:459:21 | call to end | string.cpp:459:17:459:23 | call to iterator | TAINT |
|
||||
| string.cpp:459:26:459:27 | ref arg s1 | string.cpp:459:38:459:39 | s1 | |
|
||||
| string.cpp:459:26:459:27 | ref arg s1 | string.cpp:465:28:465:29 | s1 | |
|
||||
@@ -4413,6 +4357,8 @@ WARNING: module 'TaintTracking' has been deprecated and may be removed in future
|
||||
| string.cpp:462:17:462:17 | d | string.cpp:462:19:462:21 | call to end | TAINT |
|
||||
| string.cpp:462:17:462:17 | ref arg d | string.cpp:462:8:462:8 | d | |
|
||||
| string.cpp:462:17:462:17 | ref arg d | string.cpp:463:8:463:8 | d | |
|
||||
| string.cpp:462:17:462:23 | call to iterator | string.cpp:462:8:462:8 | ref arg d | TAINT |
|
||||
| string.cpp:462:17:462:23 | call to iterator | string.cpp:462:10:462:15 | call to insert | TAINT |
|
||||
| string.cpp:462:19:462:21 | call to end | string.cpp:462:17:462:23 | call to iterator | TAINT |
|
||||
| string.cpp:462:26:462:27 | ref arg s2 | string.cpp:462:38:462:39 | s2 | |
|
||||
| string.cpp:462:26:462:27 | ref arg s2 | string.cpp:465:8:465:9 | s2 | |
|
||||
@@ -4432,6 +4378,8 @@ WARNING: module 'TaintTracking' has been deprecated and may be removed in future
|
||||
| string.cpp:465:18:465:19 | ref arg s2 | string.cpp:465:8:465:9 | s2 | |
|
||||
| string.cpp:465:18:465:19 | ref arg s2 | string.cpp:466:8:466:9 | s2 | |
|
||||
| string.cpp:465:18:465:19 | s2 | string.cpp:465:21:465:23 | call to end | TAINT |
|
||||
| string.cpp:465:18:465:25 | call to iterator | string.cpp:465:8:465:9 | ref arg s2 | TAINT |
|
||||
| string.cpp:465:18:465:25 | call to iterator | string.cpp:465:11:465:16 | call to insert | TAINT |
|
||||
| string.cpp:465:21:465:23 | call to end | string.cpp:465:18:465:25 | call to iterator | TAINT |
|
||||
| string.cpp:465:28:465:29 | ref arg s1 | string.cpp:465:40:465:41 | s1 | |
|
||||
| string.cpp:465:28:465:29 | s1 | string.cpp:465:31:465:35 | call to begin | TAINT |
|
||||
|
||||
@@ -377,7 +377,6 @@ getParameterTypeName
|
||||
| stl.h:88:25:88:33 | operator= | 0 | value_type && |
|
||||
| stl.h:91:24:91:33 | operator++ | 0 | int |
|
||||
| stl.h:91:24:91:33 | operator++ | 0 | int |
|
||||
| stl.h:139:8:139:8 | basic_string | 0 | basic_string & |
|
||||
| stl.h:148:3:148:14 | basic_string | 0 | const class:2 & |
|
||||
| stl.h:149:33:149:44 | basic_string | 0 | const class:0 * |
|
||||
| stl.h:149:33:149:44 | basic_string | 1 | const class:2 & |
|
||||
|
||||
@@ -17,10 +17,6 @@
|
||||
| declaration.cpp:51:7:51:7 | operator= |
|
||||
| declaration.cpp:52:7:52:14 | myField0 |
|
||||
| declaration.cpp:53:9:53:17 | myPointer |
|
||||
| declaration.cpp:62:7:62:7 | operator= |
|
||||
| declaration.cpp:62:7:62:7 | operator= |
|
||||
| declaration.cpp:62:7:62:7 | operator= |
|
||||
| declaration.cpp:62:7:62:7 | operator= |
|
||||
| declaration.cpp:65:5:65:20 | myMemberVariable |
|
||||
| declaration.cpp:65:5:65:20 | myMemberVariable |
|
||||
| declaration.cpp:65:5:65:20 | myMemberVariable |
|
||||
@@ -36,10 +32,6 @@
|
||||
| declaration.cpp:105:9:105:21 | myNestedField |
|
||||
| declaration.cpp:108:3:108:10 | MyClass1 |
|
||||
| declaration.cpp:110:7:110:17 | getMyField1 |
|
||||
| declaration.cpp:119:7:119:7 | operator= |
|
||||
| declaration.cpp:119:7:119:7 | operator= |
|
||||
| declaration.cpp:119:7:119:7 | operator= |
|
||||
| declaration.cpp:119:7:119:7 | operator= |
|
||||
| declaration.cpp:122:5:122:20 | myMemberVariable |
|
||||
| declaration.cpp:122:5:122:20 | myMemberVariable |
|
||||
| declaration.cpp:122:5:122:20 | myMemberVariable |
|
||||
|
||||
@@ -15,10 +15,6 @@
|
||||
| declarationEntry.cpp:20:6:20:11 | myEnum | declarationEntry.cpp:18:6:18:11 | declaration of myEnum | 1 | 1 |
|
||||
| declarationEntry.cpp:20:6:20:11 | myEnum | declarationEntry.cpp:20:6:20:11 | definition of myEnum | 1 | 1 |
|
||||
| declarationEntry.cpp:27:20:27:20 | T | declarationEntry.cpp:27:20:27:20 | definition of T | 1 | 1 |
|
||||
| declarationEntry.cpp:28:7:28:7 | operator= | declarationEntry.cpp:28:7:28:7 | declaration of operator= | 1 | 1 |
|
||||
| declarationEntry.cpp:28:7:28:7 | operator= | declarationEntry.cpp:28:7:28:7 | declaration of operator= | 1 | 1 |
|
||||
| declarationEntry.cpp:28:7:28:7 | operator= | declarationEntry.cpp:28:7:28:7 | declaration of operator= | 1 | 1 |
|
||||
| declarationEntry.cpp:28:7:28:7 | operator= | declarationEntry.cpp:28:7:28:7 | declaration of operator= | 1 | 1 |
|
||||
| declarationEntry.cpp:28:7:28:21 | myTemplateClass<T> | declarationEntry.cpp:28:7:28:21 | definition of myTemplateClass<T> | 1 | 1 |
|
||||
| declarationEntry.cpp:28:7:28:21 | myTemplateClass<int> | declarationEntry.cpp:28:7:28:21 | definition of myTemplateClass<T> | 1 | 0 |
|
||||
| declarationEntry.cpp:28:7:28:21 | myTemplateClass<short> | declarationEntry.cpp:28:7:28:21 | definition of myTemplateClass<T> | 1 | 0 |
|
||||
|
||||
@@ -6,10 +6,6 @@
|
||||
| declarationEntry.c:17:6:17:21 | declaration of myFourthFunction | | 1 | c_linkage |
|
||||
| declarationEntry.cpp:9:6:9:15 | declaration of myFunction | | 0 | |
|
||||
| declarationEntry.cpp:11:6:11:15 | definition of myFunction | | 0 | |
|
||||
| declarationEntry.cpp:28:7:28:7 | declaration of operator= | | 0 | |
|
||||
| declarationEntry.cpp:28:7:28:7 | declaration of operator= | | 0 | |
|
||||
| declarationEntry.cpp:28:7:28:7 | declaration of operator= | | 0 | |
|
||||
| declarationEntry.cpp:28:7:28:7 | declaration of operator= | | 0 | |
|
||||
| declarationEntry.cpp:39:7:39:7 | declaration of operator= | | 0 | |
|
||||
| declarationEntry.cpp:39:7:39:7 | declaration of operator= | | 0 | |
|
||||
| macro.c:2:1:2:3 | declaration of foo | | 2 | c_linkage, static |
|
||||
|
||||
@@ -15,10 +15,6 @@
|
||||
| declarationEntry.cpp:18:6:18:11 | declaration of myEnum | declarationEntry.cpp:20:6:20:11 | myEnum | yes |
|
||||
| declarationEntry.cpp:20:6:20:11 | definition of myEnum | declarationEntry.cpp:20:6:20:11 | myEnum | yes |
|
||||
| declarationEntry.cpp:27:20:27:20 | definition of T | declarationEntry.cpp:27:20:27:20 | T | yes |
|
||||
| declarationEntry.cpp:28:7:28:7 | declaration of operator= | declarationEntry.cpp:28:7:28:7 | operator= | yes |
|
||||
| declarationEntry.cpp:28:7:28:7 | declaration of operator= | declarationEntry.cpp:28:7:28:7 | operator= | yes |
|
||||
| declarationEntry.cpp:28:7:28:7 | declaration of operator= | declarationEntry.cpp:28:7:28:7 | operator= | yes |
|
||||
| declarationEntry.cpp:28:7:28:7 | declaration of operator= | declarationEntry.cpp:28:7:28:7 | operator= | yes |
|
||||
| declarationEntry.cpp:28:7:28:21 | definition of myTemplateClass<T> | declarationEntry.cpp:28:7:28:21 | myTemplateClass<T> | yes |
|
||||
| declarationEntry.cpp:31:4:31:19 | definition of myMemberVariable | declarationEntry.cpp:31:4:31:19 | myMemberVariable | yes |
|
||||
| declarationEntry.cpp:31:4:31:19 | definition of myMemberVariable | declarationEntry.cpp:31:4:31:19 | myMemberVariable | yes |
|
||||
@@ -31,10 +27,6 @@
|
||||
| declarationEntry.cpp:42:6:42:21 | definition of myMemberVariable | declarationEntry.cpp:42:6:42:21 | myMemberVariable | yes |
|
||||
| file://:0:0:0:0 | declaration of 1st parameter | file://:0:0:0:0 | (unnamed parameter 0) | yes |
|
||||
| file://:0:0:0:0 | declaration of 1st parameter | file://:0:0:0:0 | (unnamed parameter 0) | yes |
|
||||
| file://:0:0:0:0 | declaration of 1st parameter | file://:0:0:0:0 | (unnamed parameter 0) | yes |
|
||||
| file://:0:0:0:0 | declaration of 1st parameter | file://:0:0:0:0 | (unnamed parameter 0) | yes |
|
||||
| file://:0:0:0:0 | declaration of 1st parameter | file://:0:0:0:0 | (unnamed parameter 0) | yes |
|
||||
| file://:0:0:0:0 | declaration of 1st parameter | file://:0:0:0:0 | (unnamed parameter 0) | yes |
|
||||
| file://:0:0:0:0 | definition of fp_offset | file://:0:0:0:0 | fp_offset | yes |
|
||||
| file://:0:0:0:0 | definition of gp_offset | file://:0:0:0:0 | gp_offset | yes |
|
||||
| file://:0:0:0:0 | definition of overflow_arg_area | file://:0:0:0:0 | overflow_arg_area | yes |
|
||||
|
||||
@@ -2,10 +2,6 @@
|
||||
| file://:0:0:0:0 | declaration of 1st parameter |
|
||||
| file://:0:0:0:0 | declaration of 1st parameter |
|
||||
| file://:0:0:0:0 | declaration of 1st parameter |
|
||||
| file://:0:0:0:0 | declaration of 1st parameter |
|
||||
| file://:0:0:0:0 | declaration of 1st parameter |
|
||||
| file://:0:0:0:0 | declaration of 1st parameter |
|
||||
| file://:0:0:0:0 | declaration of 1st parameter |
|
||||
| file://:0:0:0:0 | definition of fp_offset |
|
||||
| file://:0:0:0:0 | definition of gp_offset |
|
||||
| file://:0:0:0:0 | definition of overflow_arg_area |
|
||||
@@ -72,12 +68,6 @@
|
||||
| test.cpp:64:19:64:19 | definition of T |
|
||||
| test.cpp:65:7:65:27 | declaration of tmplInstantiatedClass<T> |
|
||||
| test.cpp:66:19:66:19 | definition of T |
|
||||
| test.cpp:67:7:67:7 | declaration of operator= |
|
||||
| test.cpp:67:7:67:7 | declaration of operator= |
|
||||
| test.cpp:67:7:67:7 | declaration of operator= |
|
||||
| test.cpp:67:7:67:7 | declaration of operator= |
|
||||
| test.cpp:67:7:67:7 | definition of tmplInstantiatedClass |
|
||||
| test.cpp:67:7:67:7 | definition of tmplInstantiatedClass |
|
||||
| test.cpp:67:7:67:27 | definition of tmplInstantiatedClass<T> |
|
||||
| test.cpp:68:7:68:7 | definition of t |
|
||||
| test.cpp:68:7:68:7 | definition of t |
|
||||
|
||||
@@ -6,8 +6,6 @@
|
||||
| file://:0:0:0:0 | (unnamed parameter 0) | 0 | 0 |
|
||||
| file://:0:0:0:0 | (unnamed parameter 0) | 0 | 0 |
|
||||
| file://:0:0:0:0 | (unnamed parameter 0) | 0 | 0 |
|
||||
| file://:0:0:0:0 | (unnamed parameter 0) | 0 | 0 |
|
||||
| file://:0:0:0:0 | (unnamed parameter 0) | 0 | 0 |
|
||||
| file://:0:0:0:0 | fp_offset | 0 | 0 |
|
||||
| file://:0:0:0:0 | gp_offset | 0 | 0 |
|
||||
| file://:0:0:0:0 | overflow_arg_area | 0 | 0 |
|
||||
|
||||
@@ -1,11 +1,6 @@
|
||||
| ODASA-5186.cpp:4:8:4:8 | MyClass | MyClass | | declaration:ODASA-5186.cpp:4:8:4:8, definition:ODASA-5186.cpp:4:8:4:8 |
|
||||
| ODASA-5186.cpp:4:8:4:8 | operator= | operator= | MyClass<int> && (unnamed parameter 0) | declaration:ODASA-5186.cpp:4:8:4:8 |
|
||||
| ODASA-5186.cpp:4:8:4:8 | operator= | operator= | const MyClass<int> & (unnamed parameter 0) | declaration:ODASA-5186.cpp:4:8:4:8 |
|
||||
| ODASA-5186.cpp:5:8:5:8 | operator== | operator== | const MyClass<int> & other | declaration:ODASA-5186.cpp:5:8:5:8, definition:ODASA-5186.cpp:5:8:5:8 |
|
||||
| ODASA-5186.cpp:5:8:5:17 | operator== | operator== | const MyClass<T> & other | declaration:ODASA-5186.cpp:5:8:5:17, definition:ODASA-5186.cpp:5:8:5:17 |
|
||||
| ODASA-5186.cpp:8:6:8:9 | test | test | | TopLevelFunction, declaration:ODASA-5186.cpp:8:6:8:9, definition:ODASA-5186.cpp:8:6:8:9, isTopLevel |
|
||||
| ODASA-5186.hpp:2:8:2:8 | operator= | operator= | NEQ_helper<MyClass<int>> && (unnamed parameter 0) | declaration:ODASA-5186.hpp:2:8:2:8 |
|
||||
| ODASA-5186.hpp:2:8:2:8 | operator= | operator= | const NEQ_helper<MyClass<int>> & (unnamed parameter 0) | declaration:ODASA-5186.hpp:2:8:2:8 |
|
||||
| ODASA-5186.hpp:4:18:4:27 | operator!= | operator!= | const MyClass<int> & x, const MyClass<int> & y | TopLevelFunction, declaration:ODASA-5186.hpp:4:18:4:27, definition:ODASA-5186.hpp:4:18:4:27, isTopLevel |
|
||||
| ODASA-5186.hpp:4:18:4:27 | operator!= | operator!= | const T & x, const T & y | TopLevelFunction, declaration:ODASA-5186.hpp:4:18:4:27, definition:ODASA-5186.hpp:4:18:4:27, isTopLevel |
|
||||
| functions.cpp:1:6:1:6 | f | f | int a, int b | TopLevelFunction, declaration:functions.cpp:1:6:1:6, definition:functions.cpp:1:6:1:6, isTopLevel |
|
||||
|
||||
@@ -1,10 +1,5 @@
|
||||
| ODASA-5186.cpp:4:8:4:14 | MyClass<T> | Class | ODASA-5186.cpp:5:8:5:17 | operator== | |
|
||||
| ODASA-5186.cpp:4:8:4:14 | MyClass<int> | Struct | ODASA-5186.cpp:4:8:4:8 | MyClass | Constructor, NoArgConstructor, getAConstructor() |
|
||||
| ODASA-5186.cpp:4:8:4:14 | MyClass<int> | Struct | ODASA-5186.cpp:4:8:4:8 | operator= | |
|
||||
| ODASA-5186.cpp:4:8:4:14 | MyClass<int> | Struct | ODASA-5186.cpp:4:8:4:8 | operator= | |
|
||||
| ODASA-5186.cpp:4:8:4:14 | MyClass<int> | Struct | ODASA-5186.cpp:5:8:5:8 | operator== | |
|
||||
| ODASA-5186.hpp:2:8:2:17 | NEQ_helper<MyClass<int>> | Struct | ODASA-5186.hpp:2:8:2:8 | operator= | |
|
||||
| ODASA-5186.hpp:2:8:2:17 | NEQ_helper<MyClass<int>> | Struct | ODASA-5186.hpp:2:8:2:8 | operator= | |
|
||||
| file://:0:0:0:0 | __va_list_tag | Struct | file://:0:0:0:0 | operator= | |
|
||||
| file://:0:0:0:0 | __va_list_tag | Struct | file://:0:0:0:0 | operator= | |
|
||||
| functions.cpp:7:8:7:8 | A | Struct | functions.cpp:7:8:7:8 | operator= | |
|
||||
|
||||
@@ -39,8 +39,6 @@
|
||||
| qualifiedNames.cpp:39:3:39:19 | typedefStructName | typedefStructName | | | typedefStructName | typedefStructName |
|
||||
| qualifiedNames.cpp:39:23:39:40 | ptypedefStructName | ptypedefStructName | | | ptypedefStructName | ptypedefStructName |
|
||||
| qualifiedNames.cpp:41:11:41:18 | typedefC | typedefC | | | typedefC | typedefC |
|
||||
| qualifiedNames.cpp:45:10:45:10 | operator= | templates::TemplateClass<unsigned long>::operator= | templates | TemplateClass | operator= | (not global) |
|
||||
| qualifiedNames.cpp:45:10:45:10 | operator= | templates::TemplateClass<unsigned long>::operator= | templates | TemplateClass | operator= | (not global) |
|
||||
| qualifiedNames.cpp:45:10:45:22 | TemplateClass<T> | templates::TemplateClass<T> | templates | | TemplateClass | (not global) |
|
||||
| qualifiedNames.cpp:45:10:45:22 | TemplateClass<T> | templates::TemplateClass<T> | templates | | TemplateClass | (not global) |
|
||||
| qualifiedNames.cpp:45:10:45:22 | TemplateClass<unsigned long> | templates::TemplateClass<unsigned long> | templates | | TemplateClass | (not global) |
|
||||
|
||||
@@ -25,10 +25,6 @@
|
||||
| test.cpp:16:7:16:7 | operator= |
|
||||
| test.cpp:16:32:16:35 | vfun |
|
||||
| test.cpp:19:7:19:7 | C |
|
||||
| test.cpp:19:7:19:7 | C |
|
||||
| test.cpp:19:7:19:7 | C |
|
||||
| test.cpp:19:7:19:7 | operator= |
|
||||
| test.cpp:19:7:19:7 | operator= |
|
||||
| test.cpp:21:18:21:18 | vfun |
|
||||
| test.cpp:21:18:21:21 | vfun |
|
||||
| test.cpp:27:6:27:6 | f |
|
||||
|
||||
@@ -1729,30 +1729,6 @@ complex.c:
|
||||
# 144| ValueCategory = prvalue
|
||||
# 145| getStmt(72): [ReturnStmt] return ...
|
||||
coroutines.cpp:
|
||||
# 4| [CopyAssignmentOperator] std::coroutine_traits<co_returnable_value, int>& std::coroutine_traits<co_returnable_value, int>::operator=(std::coroutine_traits<co_returnable_value, int> const&)
|
||||
# 4| <params>:
|
||||
#-----| getParameter(0): [Parameter] (unnamed parameter 0)
|
||||
#-----| Type = [LValueReferenceType] const coroutine_traits<co_returnable_value, int> &
|
||||
# 4| [MoveAssignmentOperator] std::coroutine_traits<co_returnable_value, int>& std::coroutine_traits<co_returnable_value, int>::operator=(std::coroutine_traits<co_returnable_value, int>&&)
|
||||
# 4| <params>:
|
||||
#-----| getParameter(0): [Parameter] (unnamed parameter 0)
|
||||
#-----| Type = [RValueReferenceType] coroutine_traits<co_returnable_value, int> &&
|
||||
# 4| [CopyAssignmentOperator] std::coroutine_traits<co_returnable_void, int>& std::coroutine_traits<co_returnable_void, int>::operator=(std::coroutine_traits<co_returnable_void, int> const&)
|
||||
# 4| <params>:
|
||||
#-----| getParameter(0): [Parameter] (unnamed parameter 0)
|
||||
#-----| Type = [LValueReferenceType] const coroutine_traits<co_returnable_void, int> &
|
||||
# 4| [MoveAssignmentOperator] std::coroutine_traits<co_returnable_void, int>& std::coroutine_traits<co_returnable_void, int>::operator=(std::coroutine_traits<co_returnable_void, int>&&)
|
||||
# 4| <params>:
|
||||
#-----| getParameter(0): [Parameter] (unnamed parameter 0)
|
||||
#-----| Type = [RValueReferenceType] coroutine_traits<co_returnable_void, int> &&
|
||||
# 4| [CopyAssignmentOperator] std::coroutine_traits<co_returnable_void>& std::coroutine_traits<co_returnable_void>::operator=(std::coroutine_traits<co_returnable_void> const&)
|
||||
# 4| <params>:
|
||||
#-----| getParameter(0): [Parameter] (unnamed parameter 0)
|
||||
#-----| Type = [LValueReferenceType] const coroutine_traits<co_returnable_void> &
|
||||
# 4| [MoveAssignmentOperator] std::coroutine_traits<co_returnable_void>& std::coroutine_traits<co_returnable_void>::operator=(std::coroutine_traits<co_returnable_void>&&)
|
||||
# 4| <params>:
|
||||
#-----| getParameter(0): [Parameter] (unnamed parameter 0)
|
||||
#-----| Type = [RValueReferenceType] coroutine_traits<co_returnable_void> &&
|
||||
# 12| [Constructor] void std::coroutine_handle<Promise>::coroutine_handle()
|
||||
# 12| <params>:
|
||||
# 13| [Constructor] void std::coroutine_handle<Promise>::coroutine_handle(std::nullptr_t)
|
||||
@@ -8629,14 +8605,6 @@ ir.cpp:
|
||||
# 709| getArgument(1): [VariableAccess] y
|
||||
# 709| Type = [IntType] int
|
||||
# 709| ValueCategory = prvalue(load)
|
||||
# 713| [CopyAssignmentOperator] Outer<long>& Outer<long>::operator=(Outer<long> const&)
|
||||
# 713| <params>:
|
||||
#-----| getParameter(0): [Parameter] (unnamed parameter 0)
|
||||
#-----| Type = [LValueReferenceType] const Outer<long> &
|
||||
# 713| [MoveAssignmentOperator] Outer<long>& Outer<long>::operator=(Outer<long>&&)
|
||||
# 713| <params>:
|
||||
#-----| getParameter(0): [Parameter] (unnamed parameter 0)
|
||||
#-----| Type = [RValueReferenceType] Outer<long> &&
|
||||
# 715| [MemberFunction,TemplateFunction] T Outer<T>::Func<U, V>(U, V)
|
||||
# 715| <params>:
|
||||
# 715| getParameter(0): [Parameter] x
|
||||
@@ -11941,22 +11909,6 @@ ir.cpp:
|
||||
# 1054| getRightOperand().getFullyConverted(): [ReferenceDereferenceExpr] (reference dereference)
|
||||
# 1054| Type = [IntType] int
|
||||
# 1054| ValueCategory = prvalue(load)
|
||||
# 1078| [CopyAssignmentOperator] std::iterator<std::random_access_iterator_tag, ClassWithDestructor, std::ptrdiff_t, ClassWithDestructor*, ClassWithDestructor&>& std::iterator<std::random_access_iterator_tag, ClassWithDestructor, std::ptrdiff_t, ClassWithDestructor*, ClassWithDestructor&>::operator=(std::iterator<std::random_access_iterator_tag, ClassWithDestructor, std::ptrdiff_t, ClassWithDestructor*, ClassWithDestructor&> const&)
|
||||
# 1078| <params>:
|
||||
#-----| getParameter(0): [Parameter] (unnamed parameter 0)
|
||||
#-----| Type = [LValueReferenceType] const iterator<random_access_iterator_tag, ClassWithDestructor, ptrdiff_t, ClassWithDestructor *, ClassWithDestructor &> &
|
||||
# 1078| [CopyAssignmentOperator] std::iterator<std::random_access_iterator_tag, String, std::ptrdiff_t, String*, String&>& std::iterator<std::random_access_iterator_tag, String, std::ptrdiff_t, String*, String&>::operator=(std::iterator<std::random_access_iterator_tag, String, std::ptrdiff_t, String*, String&> const&)
|
||||
# 1078| <params>:
|
||||
#-----| getParameter(0): [Parameter] (unnamed parameter 0)
|
||||
#-----| Type = [LValueReferenceType] const iterator<random_access_iterator_tag, String, ptrdiff_t, String *, String &> &
|
||||
# 1078| [CopyAssignmentOperator] std::iterator<std::random_access_iterator_tag, char, std::ptrdiff_t, char*, char&>& std::iterator<std::random_access_iterator_tag, char, std::ptrdiff_t, char*, char&>::operator=(std::iterator<std::random_access_iterator_tag, char, std::ptrdiff_t, char*, char&> const&)
|
||||
# 1078| <params>:
|
||||
#-----| getParameter(0): [Parameter] (unnamed parameter 0)
|
||||
#-----| Type = [LValueReferenceType] const iterator<random_access_iterator_tag, char, ptrdiff_t, char *, char &> &
|
||||
# 1078| [CopyAssignmentOperator] std::iterator<std::random_access_iterator_tag, int, std::ptrdiff_t, int*, int&>& std::iterator<std::random_access_iterator_tag, int, std::ptrdiff_t, int*, int&>::operator=(std::iterator<std::random_access_iterator_tag, int, std::ptrdiff_t, int*, int&> const&)
|
||||
# 1078| <params>:
|
||||
#-----| getParameter(0): [Parameter] (unnamed parameter 0)
|
||||
#-----| Type = [LValueReferenceType] const iterator<random_access_iterator_tag, int, ptrdiff_t, int *, int &> &
|
||||
# 1081| [Constructor] void std::iterator<Category, value_type, difference_type, pointer_type, reference_type>::iterator()
|
||||
# 1081| <params>:
|
||||
# 1082| [Constructor] void std::iterator<Category, value_type, difference_type, pointer_type, reference_type>::iterator(std::iterator<Category, type, std::ptrdiff_t, type*, type&> const&)
|
||||
@@ -12105,38 +12057,6 @@ ir.cpp:
|
||||
# 1105| <params>:
|
||||
#-----| getParameter(0): [Parameter] (unnamed parameter 0)
|
||||
#-----| Type = [RValueReferenceType] output_iterator_tag &&
|
||||
# 1108| [CopyAssignmentOperator] std::vector<ClassWithDestructor>& std::vector<ClassWithDestructor>::operator=(std::vector<ClassWithDestructor> const&)
|
||||
# 1108| <params>:
|
||||
#-----| getParameter(0): [Parameter] (unnamed parameter 0)
|
||||
#-----| Type = [LValueReferenceType] const vector<ClassWithDestructor> &
|
||||
# 1108| [CopyAssignmentOperator] std::vector<String>& std::vector<String>::operator=(std::vector<String> const&)
|
||||
# 1108| <params>:
|
||||
#-----| getParameter(0): [Parameter] (unnamed parameter 0)
|
||||
#-----| Type = [LValueReferenceType] const vector<String> &
|
||||
# 1108| [CopyAssignmentOperator] std::vector<char>& std::vector<char>::operator=(std::vector<char> const&)
|
||||
# 1108| <params>:
|
||||
#-----| getParameter(0): [Parameter] (unnamed parameter 0)
|
||||
#-----| Type = [LValueReferenceType] const vector<char> &
|
||||
# 1108| [CopyAssignmentOperator] std::vector<int>& std::vector<int>::operator=(std::vector<int> const&)
|
||||
# 1108| <params>:
|
||||
#-----| getParameter(0): [Parameter] (unnamed parameter 0)
|
||||
#-----| Type = [LValueReferenceType] const vector<int> &
|
||||
# 1108| [CopyConstructor] void std::vector<ClassWithDestructor>::vector(std::vector<ClassWithDestructor> const&)
|
||||
# 1108| <params>:
|
||||
#-----| getParameter(0): [Parameter] (unnamed parameter 0)
|
||||
#-----| Type = [LValueReferenceType] const vector<ClassWithDestructor> &
|
||||
# 1108| [CopyConstructor] void std::vector<String>::vector(std::vector<String> const&)
|
||||
# 1108| <params>:
|
||||
#-----| getParameter(0): [Parameter] (unnamed parameter 0)
|
||||
#-----| Type = [LValueReferenceType] const vector<String> &
|
||||
# 1108| [CopyConstructor] void std::vector<char>::vector(std::vector<char> const&)
|
||||
# 1108| <params>:
|
||||
#-----| getParameter(0): [Parameter] (unnamed parameter 0)
|
||||
#-----| Type = [LValueReferenceType] const vector<char> &
|
||||
# 1108| [CopyConstructor] void std::vector<int>::vector(std::vector<int> const&)
|
||||
# 1108| <params>:
|
||||
#-----| getParameter(0): [Parameter] (unnamed parameter 0)
|
||||
#-----| Type = [LValueReferenceType] const vector<int> &
|
||||
# 1109| [Constructor] void std::vector<ClassWithDestructor>::vector(ClassWithDestructor)
|
||||
# 1109| <params>:
|
||||
# 1109| getParameter(0): [Parameter] (unnamed parameter 0)
|
||||
@@ -17431,14 +17351,6 @@ ir.cpp:
|
||||
# 1904| <params>:
|
||||
#-----| getParameter(0): [Parameter] (unnamed parameter 0)
|
||||
#-----| Type = [RValueReferenceType] S &&
|
||||
# 1908| [CopyAssignmentOperator] missing_declaration_entries::Bar1<int>& missing_declaration_entries::Bar1<int>::operator=(missing_declaration_entries::Bar1<int> const&)
|
||||
# 1908| <params>:
|
||||
#-----| getParameter(0): [Parameter] (unnamed parameter 0)
|
||||
#-----| Type = [LValueReferenceType] const Bar1<int> &
|
||||
# 1908| [MoveAssignmentOperator] missing_declaration_entries::Bar1<int>& missing_declaration_entries::Bar1<int>::operator=(missing_declaration_entries::Bar1<int>&&)
|
||||
# 1908| <params>:
|
||||
#-----| getParameter(0): [Parameter] (unnamed parameter 0)
|
||||
#-----| Type = [RValueReferenceType] Bar1<int> &&
|
||||
# 1911| [MemberFunction] void* missing_declaration_entries::Bar1<T>::missing_type_decl_entry(missing_declaration_entries::Bar1<T>::pointer)
|
||||
# 1911| <params>:
|
||||
# 1911| getParameter(0): [Parameter] p
|
||||
@@ -17494,14 +17406,6 @@ ir.cpp:
|
||||
# 1919| Value = [CStyleCast] 0
|
||||
# 1919| ValueCategory = prvalue
|
||||
# 1920| getStmt(2): [ReturnStmt] return ...
|
||||
# 1922| [CopyAssignmentOperator] missing_declaration_entries::Bar2<int>& missing_declaration_entries::Bar2<int>::operator=(missing_declaration_entries::Bar2<int> const&)
|
||||
# 1922| <params>:
|
||||
#-----| getParameter(0): [Parameter] (unnamed parameter 0)
|
||||
#-----| Type = [LValueReferenceType] const Bar2<int> &
|
||||
# 1922| [MoveAssignmentOperator] missing_declaration_entries::Bar2<int>& missing_declaration_entries::Bar2<int>::operator=(missing_declaration_entries::Bar2<int>&&)
|
||||
# 1922| <params>:
|
||||
#-----| getParameter(0): [Parameter] (unnamed parameter 0)
|
||||
#-----| Type = [RValueReferenceType] Bar2<int> &&
|
||||
# 1924| [MemberFunction] int missing_declaration_entries::Bar2<T>::two_missing_variable_declaration_entries()
|
||||
# 1924| <params>:
|
||||
# 1924| getEntryPoint(): [BlockStmt] { ... }
|
||||
@@ -17644,14 +17548,6 @@ ir.cpp:
|
||||
# 1934| Type = [ClassTemplateInstantiation,Struct] Bar2<int>
|
||||
# 1934| ValueCategory = lvalue
|
||||
# 1935| getStmt(2): [ReturnStmt] return ...
|
||||
# 1937| [CopyAssignmentOperator] missing_declaration_entries::Bar3<int>& missing_declaration_entries::Bar3<int>::operator=(missing_declaration_entries::Bar3<int> const&)
|
||||
# 1937| <params>:
|
||||
#-----| getParameter(0): [Parameter] (unnamed parameter 0)
|
||||
#-----| Type = [LValueReferenceType] const Bar3<int> &
|
||||
# 1937| [MoveAssignmentOperator] missing_declaration_entries::Bar3<int>& missing_declaration_entries::Bar3<int>::operator=(missing_declaration_entries::Bar3<int>&&)
|
||||
# 1937| <params>:
|
||||
#-----| getParameter(0): [Parameter] (unnamed parameter 0)
|
||||
#-----| Type = [RValueReferenceType] Bar3<int> &&
|
||||
# 1939| [MemberFunction] int missing_declaration_entries::Bar3<T>::two_more_missing_variable_declaration_entries()
|
||||
# 1939| <params>:
|
||||
# 1939| getEntryPoint(): [BlockStmt] { ... }
|
||||
@@ -22753,6 +22649,616 @@ ir.cpp:
|
||||
# 2556| Type = [LongType] unsigned long
|
||||
# 2556| ValueCategory = prvalue(load)
|
||||
# 2557| getStmt(1): [ReturnStmt] return ...
|
||||
# 2559| [TopLevelFunction] void p_points_to_x_or_y(int, int)
|
||||
# 2559| <params>:
|
||||
# 2559| getParameter(0): [Parameter] a
|
||||
# 2559| Type = [IntType] int
|
||||
# 2559| getParameter(1): [Parameter] b
|
||||
# 2559| Type = [IntType] int
|
||||
# 2559| getEntryPoint(): [BlockStmt] { ... }
|
||||
# 2560| getStmt(0): [DeclStmt] declaration
|
||||
# 2560| getDeclarationEntry(0): [VariableDeclarationEntry] definition of x
|
||||
# 2560| Type = [IntType] int
|
||||
# 2561| getStmt(1): [DeclStmt] declaration
|
||||
# 2561| getDeclarationEntry(0): [VariableDeclarationEntry] definition of y
|
||||
# 2561| Type = [IntType] int
|
||||
# 2562| getStmt(2): [DeclStmt] declaration
|
||||
# 2562| getDeclarationEntry(0): [VariableDeclarationEntry] definition of p
|
||||
# 2562| Type = [IntPointerType] int *
|
||||
# 2563| getStmt(3): [IfStmt] if (...) ...
|
||||
# 2563| getCondition(): [LTExpr] ... < ...
|
||||
# 2563| Type = [BoolType] bool
|
||||
# 2563| ValueCategory = prvalue
|
||||
# 2563| getLesserOperand(): [VariableAccess] a
|
||||
# 2563| Type = [IntType] int
|
||||
# 2563| ValueCategory = prvalue(load)
|
||||
# 2563| getGreaterOperand(): [VariableAccess] b
|
||||
# 2563| Type = [IntType] int
|
||||
# 2563| ValueCategory = prvalue(load)
|
||||
# 2563| getThen(): [BlockStmt] { ... }
|
||||
# 2564| getStmt(0): [ExprStmt] ExprStmt
|
||||
# 2564| getExpr(): [AssignExpr] ... = ...
|
||||
# 2564| Type = [IntPointerType] int *
|
||||
# 2564| ValueCategory = lvalue
|
||||
# 2564| getLValue(): [VariableAccess] p
|
||||
# 2564| Type = [IntPointerType] int *
|
||||
# 2564| ValueCategory = lvalue
|
||||
# 2564| getRValue(): [AddressOfExpr] & ...
|
||||
# 2564| Type = [IntPointerType] int *
|
||||
# 2564| ValueCategory = prvalue
|
||||
# 2564| getOperand(): [VariableAccess] x
|
||||
# 2564| Type = [IntType] int
|
||||
# 2564| ValueCategory = lvalue
|
||||
# 2565| getElse(): [BlockStmt] { ... }
|
||||
# 2566| getStmt(0): [ExprStmt] ExprStmt
|
||||
# 2566| getExpr(): [AssignExpr] ... = ...
|
||||
# 2566| Type = [IntPointerType] int *
|
||||
# 2566| ValueCategory = lvalue
|
||||
# 2566| getLValue(): [VariableAccess] p
|
||||
# 2566| Type = [IntPointerType] int *
|
||||
# 2566| ValueCategory = lvalue
|
||||
# 2566| getRValue(): [AddressOfExpr] & ...
|
||||
# 2566| Type = [IntPointerType] int *
|
||||
# 2566| ValueCategory = prvalue
|
||||
# 2566| getOperand(): [VariableAccess] y
|
||||
# 2566| Type = [IntType] int
|
||||
# 2566| ValueCategory = lvalue
|
||||
# 2568| getStmt(4): [ExprStmt] ExprStmt
|
||||
# 2568| getExpr(): [AssignExpr] ... = ...
|
||||
# 2568| Type = [IntType] int
|
||||
# 2568| ValueCategory = lvalue
|
||||
# 2568| getLValue(): [PointerDereferenceExpr] * ...
|
||||
# 2568| Type = [IntType] int
|
||||
# 2568| ValueCategory = lvalue
|
||||
# 2568| getOperand(): [VariableAccess] p
|
||||
# 2568| Type = [IntPointerType] int *
|
||||
# 2568| ValueCategory = prvalue(load)
|
||||
# 2568| getRValue(): [Literal] 5
|
||||
# 2568| Type = [IntType] int
|
||||
# 2568| Value = [Literal] 5
|
||||
# 2568| ValueCategory = prvalue
|
||||
# 2569| getStmt(5): [DeclStmt] declaration
|
||||
# 2569| getDeclarationEntry(0): [VariableDeclarationEntry] definition of z
|
||||
# 2569| Type = [IntType] int
|
||||
# 2569| getVariable().getInitializer(): [Initializer] initializer for z
|
||||
# 2569| getExpr(): [VariableAccess] x
|
||||
# 2569| Type = [IntType] int
|
||||
# 2569| ValueCategory = prvalue(load)
|
||||
# 2570| getStmt(6): [DeclStmt] declaration
|
||||
# 2570| getDeclarationEntry(0): [VariableDeclarationEntry] definition of w
|
||||
# 2570| Type = [IntType] int
|
||||
# 2570| getVariable().getInitializer(): [Initializer] initializer for w
|
||||
# 2570| getExpr(): [VariableAccess] y
|
||||
# 2570| Type = [IntType] int
|
||||
# 2570| ValueCategory = prvalue(load)
|
||||
# 2571| getStmt(7): [ReturnStmt] return ...
|
||||
# 2573| [TopLevelFunction] int phi_after_while()
|
||||
# 2573| <params>:
|
||||
# 2573| getEntryPoint(): [BlockStmt] { ... }
|
||||
# 2574| getStmt(0): [DeclStmt] declaration
|
||||
# 2574| getDeclarationEntry(0): [VariableDeclarationEntry] definition of r
|
||||
# 2574| Type = [IntType] int
|
||||
# 2575| getStmt(1): [DeclStmt] declaration
|
||||
# 2575| getDeclarationEntry(0): [VariableDeclarationEntry] definition of rP
|
||||
# 2575| Type = [IntPointerType] int *
|
||||
# 2575| getVariable().getInitializer(): [Initializer] initializer for rP
|
||||
# 2575| getExpr(): [AddressOfExpr] & ...
|
||||
# 2575| Type = [IntPointerType] int *
|
||||
# 2575| ValueCategory = prvalue
|
||||
# 2575| getOperand(): [VariableAccess] r
|
||||
# 2575| Type = [IntType] int
|
||||
# 2575| ValueCategory = lvalue
|
||||
# 2577| getStmt(2): [WhileStmt] while (...) ...
|
||||
# 2577| getCondition(): [FunctionCall] call to predicateA
|
||||
# 2577| Type = [BoolType] bool
|
||||
# 2577| ValueCategory = prvalue
|
||||
# 2577| getStmt(): [BlockStmt] { ... }
|
||||
# 2578| getStmt(0): [DeclStmt] declaration
|
||||
# 2578| getDeclarationEntry(0): [VariableDeclarationEntry] definition of s
|
||||
# 2578| Type = [IntType] int
|
||||
# 2578| getVariable().getInitializer(): [Initializer] initializer for s
|
||||
# 2578| getExpr(): [Literal] 0
|
||||
# 2578| Type = [IntType] int
|
||||
# 2578| Value = [Literal] 0
|
||||
# 2578| ValueCategory = prvalue
|
||||
# 2579| getStmt(1): [ExprStmt] ExprStmt
|
||||
# 2579| getExpr(): [AssignExpr] ... = ...
|
||||
# 2579| Type = [IntType] int
|
||||
# 2579| ValueCategory = lvalue
|
||||
# 2579| getLValue(): [PointerDereferenceExpr] * ...
|
||||
# 2579| Type = [IntType] int
|
||||
# 2579| ValueCategory = lvalue
|
||||
# 2579| getOperand(): [VariableAccess] rP
|
||||
# 2579| Type = [IntPointerType] int *
|
||||
# 2579| ValueCategory = prvalue(load)
|
||||
# 2579| getRValue(): [VariableAccess] s
|
||||
# 2579| Type = [IntType] int
|
||||
# 2579| ValueCategory = prvalue(load)
|
||||
# 2580| getStmt(2): [ExprStmt] ExprStmt
|
||||
# 2580| getExpr(): [AssignExpr] ... = ...
|
||||
# 2580| Type = [IntPointerType] int *
|
||||
# 2580| ValueCategory = lvalue
|
||||
# 2580| getLValue(): [VariableAccess] rP
|
||||
# 2580| Type = [IntPointerType] int *
|
||||
# 2580| ValueCategory = lvalue
|
||||
# 2580| getRValue(): [AddressOfExpr] & ...
|
||||
# 2580| Type = [IntPointerType] int *
|
||||
# 2580| ValueCategory = prvalue
|
||||
# 2580| getOperand(): [VariableAccess] s
|
||||
# 2580| Type = [IntType] int
|
||||
# 2580| ValueCategory = lvalue
|
||||
# 2583| getStmt(3): [ReturnStmt] return ...
|
||||
# 2583| getExpr(): [VariableAccess] r
|
||||
# 2583| Type = [IntType] int
|
||||
# 2583| ValueCategory = prvalue(load)
|
||||
# 2588| [TopLevelFunction] char* recursive_conditional_call_with_increment(char*, bool)
|
||||
# 2588| <params>:
|
||||
# 2588| getParameter(0): [Parameter] d
|
||||
# 2588| Type = [CharPointerType] char *
|
||||
# 2588| getParameter(1): [Parameter] b
|
||||
# 2588| Type = [BoolType] bool
|
||||
# 2589| getEntryPoint(): [BlockStmt] { ... }
|
||||
# 2590| getStmt(0): [IfStmt] if (...) ...
|
||||
# 2590| getCondition(): [VariableAccess] b
|
||||
# 2590| Type = [BoolType] bool
|
||||
# 2590| ValueCategory = prvalue(load)
|
||||
# 2590| getThen(): [BlockStmt] { ... }
|
||||
# 2591| getStmt(0): [ExprStmt] ExprStmt
|
||||
# 2591| getExpr(): [AssignExpr] ... = ...
|
||||
# 2591| Type = [CharPointerType] char *
|
||||
# 2591| ValueCategory = lvalue
|
||||
# 2591| getLValue(): [VariableAccess] d
|
||||
# 2591| Type = [CharPointerType] char *
|
||||
# 2591| ValueCategory = lvalue
|
||||
# 2591| getRValue(): [FunctionCall] call to recursive_conditional_call_with_increment
|
||||
# 2591| Type = [CharPointerType] char *
|
||||
# 2591| ValueCategory = prvalue
|
||||
# 2591| getArgument(0): [VariableAccess] d
|
||||
# 2591| Type = [CharPointerType] char *
|
||||
# 2591| ValueCategory = prvalue(load)
|
||||
# 2591| getArgument(1): [VariableAccess] b
|
||||
# 2591| Type = [BoolType] bool
|
||||
# 2591| ValueCategory = prvalue(load)
|
||||
# 2593| getStmt(1): [ExprStmt] ExprStmt
|
||||
# 2593| getExpr(): [PostfixIncrExpr] ... ++
|
||||
# 2593| Type = [CharPointerType] char *
|
||||
# 2593| ValueCategory = prvalue
|
||||
# 2593| getOperand(): [VariableAccess] d
|
||||
# 2593| Type = [CharPointerType] char *
|
||||
# 2593| ValueCategory = lvalue
|
||||
# 2594| getStmt(2): [ReturnStmt] return ...
|
||||
# 2594| getExpr(): [VariableAccess] d
|
||||
# 2594| Type = [CharPointerType] char *
|
||||
# 2594| ValueCategory = prvalue(load)
|
||||
# 2597| [CopyAssignmentOperator] Recursive& Recursive::operator=(Recursive const&)
|
||||
# 2597| <params>:
|
||||
#-----| getParameter(0): [Parameter] (unnamed parameter 0)
|
||||
#-----| Type = [LValueReferenceType] const Recursive &
|
||||
# 2597| [MoveAssignmentOperator] Recursive& Recursive::operator=(Recursive&&)
|
||||
# 2597| <params>:
|
||||
#-----| getParameter(0): [Parameter] (unnamed parameter 0)
|
||||
#-----| Type = [RValueReferenceType] Recursive &&
|
||||
# 2602| [TopLevelFunction] Recursive* merge(Recursive*)
|
||||
# 2602| <params>:
|
||||
# 2602| getParameter(0): [Parameter] a
|
||||
# 2602| Type = [PointerType] Recursive *
|
||||
# 2603| getEntryPoint(): [BlockStmt] { ... }
|
||||
# 2604| getStmt(0): [DeclStmt] declaration
|
||||
# 2604| getDeclarationEntry(0): [VariableDeclarationEntry] definition of b
|
||||
# 2604| Type = [PointerType] Recursive *
|
||||
# 2605| getStmt(1): [DeclStmt] declaration
|
||||
# 2605| getDeclarationEntry(0): [VariableDeclarationEntry] definition of p
|
||||
# 2605| Type = [PointerType] Recursive **
|
||||
# 2605| getVariable().getInitializer(): [Initializer] initializer for p
|
||||
# 2605| getExpr(): [AddressOfExpr] & ...
|
||||
# 2605| Type = [PointerType] Recursive **
|
||||
# 2605| ValueCategory = prvalue
|
||||
# 2605| getOperand(): [VariableAccess] b
|
||||
# 2605| Type = [PointerType] Recursive *
|
||||
# 2605| ValueCategory = lvalue
|
||||
# 2607| getStmt(2): [WhileStmt] while (...) ...
|
||||
# 2607| getCondition(): [FunctionCall] call to predicateA
|
||||
# 2607| Type = [BoolType] bool
|
||||
# 2607| ValueCategory = prvalue
|
||||
# 2608| getStmt(): [BlockStmt] { ... }
|
||||
# 2609| getStmt(0): [ExprStmt] ExprStmt
|
||||
# 2609| getExpr(): [AssignExpr] ... = ...
|
||||
# 2609| Type = [PointerType] Recursive *
|
||||
# 2609| ValueCategory = lvalue
|
||||
# 2609| getLValue(): [PointerDereferenceExpr] * ...
|
||||
# 2609| Type = [PointerType] Recursive *
|
||||
# 2609| ValueCategory = lvalue
|
||||
# 2609| getOperand(): [VariableAccess] p
|
||||
# 2609| Type = [PointerType] Recursive **
|
||||
# 2609| ValueCategory = prvalue(load)
|
||||
# 2609| getRValue(): [VariableAccess] a
|
||||
# 2609| Type = [PointerType] Recursive *
|
||||
# 2609| ValueCategory = prvalue(load)
|
||||
# 2610| getStmt(1): [ExprStmt] ExprStmt
|
||||
# 2610| getExpr(): [AssignExpr] ... = ...
|
||||
# 2610| Type = [PointerType] Recursive **
|
||||
# 2610| ValueCategory = lvalue
|
||||
# 2610| getLValue(): [VariableAccess] p
|
||||
# 2610| Type = [PointerType] Recursive **
|
||||
# 2610| ValueCategory = lvalue
|
||||
# 2610| getRValue(): [AddressOfExpr] & ...
|
||||
# 2610| Type = [PointerType] Recursive **
|
||||
# 2610| ValueCategory = prvalue
|
||||
# 2610| getOperand(): [PointerFieldAccess] next
|
||||
# 2610| Type = [PointerType] Recursive *
|
||||
# 2610| ValueCategory = lvalue
|
||||
# 2610| getQualifier(): [VariableAccess] a
|
||||
# 2610| Type = [PointerType] Recursive *
|
||||
# 2610| ValueCategory = prvalue(load)
|
||||
# 2613| getStmt(3): [ReturnStmt] return ...
|
||||
# 2613| getExpr(): [VariableAccess] b
|
||||
# 2613| Type = [PointerType] Recursive *
|
||||
# 2613| ValueCategory = prvalue(load)
|
||||
# 2616| [TopLevelFunction] void use_const_int(int const*)
|
||||
# 2616| <params>:
|
||||
# 2616| getParameter(0): [Parameter] (unnamed parameter 0)
|
||||
# 2616| Type = [PointerType] const int *
|
||||
# 2618| [TopLevelFunction] void escaping_pointer(bool)
|
||||
# 2618| <params>:
|
||||
# 2618| getParameter(0): [Parameter] b
|
||||
# 2618| Type = [BoolType] bool
|
||||
# 2619| getEntryPoint(): [BlockStmt] { ... }
|
||||
# 2620| getStmt(0): [DeclStmt] declaration
|
||||
# 2620| getDeclarationEntry(0): [VariableDeclarationEntry] definition of data
|
||||
# 2620| Type = [IntPointerType] int *
|
||||
# 2621| getStmt(1): [DeclStmt] declaration
|
||||
# 2621| getDeclarationEntry(0): [VariableDeclarationEntry] definition of l1
|
||||
# 2621| Type = [IntType] int
|
||||
# 2621| getDeclarationEntry(1): [VariableDeclarationEntry] definition of l2
|
||||
# 2621| Type = [IntType] int
|
||||
# 2622| getStmt(2): [IfStmt] if (...) ...
|
||||
# 2622| getCondition(): [VariableAccess] b
|
||||
# 2622| Type = [BoolType] bool
|
||||
# 2622| ValueCategory = prvalue(load)
|
||||
# 2623| getThen(): [BlockStmt] { ... }
|
||||
# 2624| getStmt(0): [ExprStmt] ExprStmt
|
||||
# 2624| getExpr(): [AssignExpr] ... = ...
|
||||
# 2624| Type = [IntPointerType] int *
|
||||
# 2624| ValueCategory = lvalue
|
||||
# 2624| getLValue(): [VariableAccess] data
|
||||
# 2624| Type = [IntPointerType] int *
|
||||
# 2624| ValueCategory = lvalue
|
||||
# 2624| getRValue(): [AddressOfExpr] & ...
|
||||
# 2624| Type = [IntPointerType] int *
|
||||
# 2624| ValueCategory = prvalue
|
||||
# 2624| getOperand(): [VariableAccess] l1
|
||||
# 2624| Type = [IntType] int
|
||||
# 2624| ValueCategory = lvalue
|
||||
# 2627| getElse(): [BlockStmt] { ... }
|
||||
# 2628| getStmt(0): [ExprStmt] ExprStmt
|
||||
# 2628| getExpr(): [AssignExpr] ... = ...
|
||||
# 2628| Type = [IntPointerType] int *
|
||||
# 2628| ValueCategory = lvalue
|
||||
# 2628| getLValue(): [VariableAccess] data
|
||||
# 2628| Type = [IntPointerType] int *
|
||||
# 2628| ValueCategory = lvalue
|
||||
# 2628| getRValue(): [AddressOfExpr] & ...
|
||||
# 2628| Type = [IntPointerType] int *
|
||||
# 2628| ValueCategory = prvalue
|
||||
# 2628| getOperand(): [VariableAccess] l2
|
||||
# 2628| Type = [IntType] int
|
||||
# 2628| ValueCategory = lvalue
|
||||
# 2630| getStmt(3): [ExprStmt] ExprStmt
|
||||
# 2630| getExpr(): [FunctionCall] call to use_const_int
|
||||
# 2630| Type = [VoidType] void
|
||||
# 2630| ValueCategory = prvalue
|
||||
# 2630| getArgument(0): [VariableAccess] data
|
||||
# 2630| Type = [IntPointerType] int *
|
||||
# 2630| ValueCategory = prvalue(load)
|
||||
# 2630| getArgument(0).getFullyConverted(): [CStyleCast] (const int *)...
|
||||
# 2630| Conversion = [PointerConversion] pointer conversion
|
||||
# 2630| Type = [PointerType] const int *
|
||||
# 2630| ValueCategory = prvalue
|
||||
# 2631| getStmt(4): [ReturnStmt] return ...
|
||||
# 2636| [TopLevelFunction] void* malloc(unsigned long)
|
||||
# 2636| <params>:
|
||||
# 2636| getParameter(0): [Parameter] (unnamed parameter 0)
|
||||
# 2636| Type = [LongType] unsigned long
|
||||
# 2637| [TopLevelFunction] void use_const_void_pointer(void const*)
|
||||
# 2637| <params>:
|
||||
# 2637| getParameter(0): [Parameter] (unnamed parameter 0)
|
||||
# 2637| Type = [PointerType] const void *
|
||||
# 2639| [TopLevelFunction] void needs_chi_for_initialize_groups()
|
||||
# 2639| <params>:
|
||||
# 2640| getEntryPoint(): [BlockStmt] { ... }
|
||||
# 2641| getStmt(0): [IfStmt] if (...) ...
|
||||
# 2641| getCondition(): [FunctionCall] call to predicateA
|
||||
# 2641| Type = [BoolType] bool
|
||||
# 2641| ValueCategory = prvalue
|
||||
# 2642| getThen(): [BlockStmt] { ... }
|
||||
# 2643| getStmt(0): [DeclStmt] declaration
|
||||
# 2643| getDeclarationEntry(0): [VariableDeclarationEntry] definition of data
|
||||
# 2643| Type = [PointerType] int64_t *
|
||||
# 2643| getVariable().getInitializer(): [Initializer] initializer for data
|
||||
# 2643| getExpr(): [FunctionCall] call to malloc
|
||||
# 2643| Type = [VoidPointerType] void *
|
||||
# 2643| ValueCategory = prvalue
|
||||
# 2643| getArgument(0): [Literal] 100
|
||||
# 2643| Type = [IntType] int
|
||||
# 2643| Value = [Literal] 100
|
||||
# 2643| ValueCategory = prvalue
|
||||
# 2643| getArgument(0).getFullyConverted(): [CStyleCast] (unsigned long)...
|
||||
# 2643| Conversion = [IntegralConversion] integral conversion
|
||||
# 2643| Type = [LongType] unsigned long
|
||||
# 2643| Value = [CStyleCast] 100
|
||||
# 2643| ValueCategory = prvalue
|
||||
# 2643| getExpr().getFullyConverted(): [CStyleCast] (int64_t *)...
|
||||
# 2643| Conversion = [PointerConversion] pointer conversion
|
||||
# 2643| Type = [PointerType] int64_t *
|
||||
# 2643| ValueCategory = prvalue
|
||||
# 2644| getStmt(1): [IfStmt] if (...) ...
|
||||
# 2644| getCondition(): [NEExpr] ... != ...
|
||||
# 2644| Type = [BoolType] bool
|
||||
# 2644| ValueCategory = prvalue
|
||||
# 2644| getLeftOperand(): [VariableAccess] data
|
||||
# 2644| Type = [PointerType] int64_t *
|
||||
# 2644| ValueCategory = prvalue(load)
|
||||
# 2644| getRightOperand(): [Literal] 0
|
||||
# 2644| Type = [IntType] int
|
||||
# 2644| Value = [Literal] 0
|
||||
# 2644| ValueCategory = prvalue
|
||||
# 2644| getLeftOperand().getFullyConverted(): [CStyleCast] (void *)...
|
||||
# 2644| Conversion = [PointerConversion] pointer conversion
|
||||
# 2644| Type = [VoidPointerType] void *
|
||||
# 2644| ValueCategory = prvalue
|
||||
# 2644| getRightOperand().getFullyConverted(): [ParenthesisExpr] (...)
|
||||
# 2644| Type = [VoidPointerType] void *
|
||||
# 2644| Value = [ParenthesisExpr] 0
|
||||
# 2644| ValueCategory = prvalue
|
||||
# 2644| getExpr(): [CStyleCast] (void *)...
|
||||
# 2644| Conversion = [IntegralToPointerConversion] integral to pointer conversion
|
||||
# 2644| Type = [VoidPointerType] void *
|
||||
# 2644| Value = [CStyleCast] 0
|
||||
# 2644| ValueCategory = prvalue
|
||||
# 2645| getThen(): [BlockStmt] { ... }
|
||||
# 2646| getStmt(0): [ExprStmt] ExprStmt
|
||||
# 2646| getExpr(): [AssignExpr] ... = ...
|
||||
# 2646| Type = [PointerType] int64_t *
|
||||
# 2646| ValueCategory = lvalue
|
||||
# 2646| getLValue(): [VariableAccess] data
|
||||
# 2646| Type = [PointerType] int64_t *
|
||||
# 2646| ValueCategory = lvalue
|
||||
# 2646| getRValue(): [FunctionCall] call to malloc
|
||||
# 2646| Type = [VoidPointerType] void *
|
||||
# 2646| ValueCategory = prvalue
|
||||
# 2646| getArgument(0): [Literal] 100
|
||||
# 2646| Type = [IntType] int
|
||||
# 2646| Value = [Literal] 100
|
||||
# 2646| ValueCategory = prvalue
|
||||
# 2646| getArgument(0).getFullyConverted(): [CStyleCast] (unsigned long)...
|
||||
# 2646| Conversion = [IntegralConversion] integral conversion
|
||||
# 2646| Type = [LongType] unsigned long
|
||||
# 2646| Value = [CStyleCast] 100
|
||||
# 2646| ValueCategory = prvalue
|
||||
# 2646| getRValue().getFullyConverted(): [CStyleCast] (int64_t *)...
|
||||
# 2646| Conversion = [PointerConversion] pointer conversion
|
||||
# 2646| Type = [PointerType] int64_t *
|
||||
# 2646| ValueCategory = prvalue
|
||||
# 2648| getStmt(2): [ExprStmt] ExprStmt
|
||||
# 2648| getExpr(): [FunctionCall] call to use_const_void_pointer
|
||||
# 2648| Type = [VoidType] void
|
||||
# 2648| ValueCategory = prvalue
|
||||
# 2648| getArgument(0): [VariableAccess] data
|
||||
# 2648| Type = [PointerType] int64_t *
|
||||
# 2648| ValueCategory = prvalue(load)
|
||||
# 2648| getArgument(0).getFullyConverted(): [CStyleCast] (const void *)...
|
||||
# 2648| Conversion = [PointerConversion] pointer conversion
|
||||
# 2648| Type = [PointerType] const void *
|
||||
# 2648| ValueCategory = prvalue
|
||||
# 2651| getElse(): [BlockStmt] { ... }
|
||||
# 2652| getStmt(0): [DeclStmt] declaration
|
||||
# 2652| getDeclarationEntry(0): [VariableDeclarationEntry] definition of data
|
||||
# 2652| Type = [PointerType] int64_t *
|
||||
# 2652| getVariable().getInitializer(): [Initializer] initializer for data
|
||||
# 2652| getExpr(): [FunctionCall] call to malloc
|
||||
# 2652| Type = [VoidPointerType] void *
|
||||
# 2652| ValueCategory = prvalue
|
||||
# 2652| getArgument(0): [Literal] 100
|
||||
# 2652| Type = [IntType] int
|
||||
# 2652| Value = [Literal] 100
|
||||
# 2652| ValueCategory = prvalue
|
||||
# 2652| getArgument(0).getFullyConverted(): [CStyleCast] (unsigned long)...
|
||||
# 2652| Conversion = [IntegralConversion] integral conversion
|
||||
# 2652| Type = [LongType] unsigned long
|
||||
# 2652| Value = [CStyleCast] 100
|
||||
# 2652| ValueCategory = prvalue
|
||||
# 2652| getExpr().getFullyConverted(): [CStyleCast] (int64_t *)...
|
||||
# 2652| Conversion = [PointerConversion] pointer conversion
|
||||
# 2652| Type = [PointerType] int64_t *
|
||||
# 2652| ValueCategory = prvalue
|
||||
# 2653| getStmt(1): [IfStmt] if (...) ...
|
||||
# 2653| getCondition(): [NEExpr] ... != ...
|
||||
# 2653| Type = [BoolType] bool
|
||||
# 2653| ValueCategory = prvalue
|
||||
# 2653| getLeftOperand(): [VariableAccess] data
|
||||
# 2653| Type = [PointerType] int64_t *
|
||||
# 2653| ValueCategory = prvalue(load)
|
||||
# 2653| getRightOperand(): [Literal] 0
|
||||
# 2653| Type = [IntType] int
|
||||
# 2653| Value = [Literal] 0
|
||||
# 2653| ValueCategory = prvalue
|
||||
# 2653| getLeftOperand().getFullyConverted(): [CStyleCast] (void *)...
|
||||
# 2653| Conversion = [PointerConversion] pointer conversion
|
||||
# 2653| Type = [VoidPointerType] void *
|
||||
# 2653| ValueCategory = prvalue
|
||||
# 2653| getRightOperand().getFullyConverted(): [ParenthesisExpr] (...)
|
||||
# 2653| Type = [VoidPointerType] void *
|
||||
# 2653| Value = [ParenthesisExpr] 0
|
||||
# 2653| ValueCategory = prvalue
|
||||
# 2653| getExpr(): [CStyleCast] (void *)...
|
||||
# 2653| Conversion = [IntegralToPointerConversion] integral to pointer conversion
|
||||
# 2653| Type = [VoidPointerType] void *
|
||||
# 2653| Value = [CStyleCast] 0
|
||||
# 2653| ValueCategory = prvalue
|
||||
# 2654| getThen(): [BlockStmt] { ... }
|
||||
# 2655| getStmt(0): [ExprStmt] ExprStmt
|
||||
# 2655| getExpr(): [AssignExpr] ... = ...
|
||||
# 2655| Type = [PointerType] int64_t *
|
||||
# 2655| ValueCategory = lvalue
|
||||
# 2655| getLValue(): [VariableAccess] data
|
||||
# 2655| Type = [PointerType] int64_t *
|
||||
# 2655| ValueCategory = lvalue
|
||||
# 2655| getRValue(): [FunctionCall] call to malloc
|
||||
# 2655| Type = [VoidPointerType] void *
|
||||
# 2655| ValueCategory = prvalue
|
||||
# 2655| getArgument(0): [Literal] 200
|
||||
# 2655| Type = [IntType] int
|
||||
# 2655| Value = [Literal] 200
|
||||
# 2655| ValueCategory = prvalue
|
||||
# 2655| getArgument(0).getFullyConverted(): [CStyleCast] (unsigned long)...
|
||||
# 2655| Conversion = [IntegralConversion] integral conversion
|
||||
# 2655| Type = [LongType] unsigned long
|
||||
# 2655| Value = [CStyleCast] 200
|
||||
# 2655| ValueCategory = prvalue
|
||||
# 2655| getRValue().getFullyConverted(): [CStyleCast] (int64_t *)...
|
||||
# 2655| Conversion = [PointerConversion] pointer conversion
|
||||
# 2655| Type = [PointerType] int64_t *
|
||||
# 2655| ValueCategory = prvalue
|
||||
# 2657| getStmt(2): [ExprStmt] ExprStmt
|
||||
# 2657| getExpr(): [FunctionCall] call to use_const_void_pointer
|
||||
# 2657| Type = [VoidType] void
|
||||
# 2657| ValueCategory = prvalue
|
||||
# 2657| getArgument(0): [VariableAccess] data
|
||||
# 2657| Type = [PointerType] int64_t *
|
||||
# 2657| ValueCategory = prvalue(load)
|
||||
# 2657| getArgument(0).getFullyConverted(): [CStyleCast] (const void *)...
|
||||
# 2657| Conversion = [PointerConversion] pointer conversion
|
||||
# 2657| Type = [PointerType] const void *
|
||||
# 2657| ValueCategory = prvalue
|
||||
# 2659| getStmt(1): [ReturnStmt] return ...
|
||||
# 2661| [TopLevelFunction] void use_int(int)
|
||||
# 2661| <params>:
|
||||
# 2661| getParameter(0): [Parameter] (unnamed parameter 0)
|
||||
# 2661| Type = [IntType] int
|
||||
# 2663| [TopLevelFunction] void phi_with_single_input_at_merge(bool)
|
||||
# 2663| <params>:
|
||||
# 2663| getParameter(0): [Parameter] b
|
||||
# 2663| Type = [BoolType] bool
|
||||
# 2664| getEntryPoint(): [BlockStmt] { ... }
|
||||
# 2665| getStmt(0): [DeclStmt] declaration
|
||||
# 2665| getDeclarationEntry(0): [VariableDeclarationEntry] definition of data
|
||||
# 2665| Type = [IntPointerType] int *
|
||||
# 2665| getVariable().getInitializer(): [Initializer] initializer for data
|
||||
# 2665| getExpr(): [Literal] 0
|
||||
# 2665| Type = [NullPointerType] decltype(nullptr)
|
||||
# 2665| Value = [Literal] 0
|
||||
# 2665| ValueCategory = prvalue
|
||||
# 2665| getExpr().getFullyConverted(): [CStyleCast] (int *)...
|
||||
# 2665| Conversion = [PointerConversion] pointer conversion
|
||||
# 2665| Type = [IntPointerType] int *
|
||||
# 2665| Value = [CStyleCast] 0
|
||||
# 2665| ValueCategory = prvalue
|
||||
# 2666| getStmt(1): [IfStmt] if (...) ...
|
||||
# 2666| getCondition(): [VariableAccess] b
|
||||
# 2666| Type = [BoolType] bool
|
||||
# 2666| ValueCategory = prvalue(load)
|
||||
# 2666| getThen(): [BlockStmt] { ... }
|
||||
# 2667| getStmt(0): [DeclStmt] declaration
|
||||
# 2667| getDeclarationEntry(0): [VariableDeclarationEntry] definition of intBuffer
|
||||
# 2667| Type = [IntType] int
|
||||
# 2667| getVariable().getInitializer(): [Initializer] initializer for intBuffer
|
||||
# 2667| getExpr(): [Literal] 8
|
||||
# 2667| Type = [IntType] int
|
||||
# 2667| Value = [Literal] 8
|
||||
# 2667| ValueCategory = prvalue
|
||||
# 2668| getStmt(1): [ExprStmt] ExprStmt
|
||||
# 2668| getExpr(): [AssignExpr] ... = ...
|
||||
# 2668| Type = [IntPointerType] int *
|
||||
# 2668| ValueCategory = lvalue
|
||||
# 2668| getLValue(): [VariableAccess] data
|
||||
# 2668| Type = [IntPointerType] int *
|
||||
# 2668| ValueCategory = lvalue
|
||||
# 2668| getRValue(): [AddressOfExpr] & ...
|
||||
# 2668| Type = [IntPointerType] int *
|
||||
# 2668| ValueCategory = prvalue
|
||||
# 2668| getOperand(): [VariableAccess] intBuffer
|
||||
# 2668| Type = [IntType] int
|
||||
# 2668| ValueCategory = lvalue
|
||||
# 2670| getStmt(2): [ExprStmt] ExprStmt
|
||||
# 2670| getExpr(): [FunctionCall] call to use_int
|
||||
# 2670| Type = [VoidType] void
|
||||
# 2670| ValueCategory = prvalue
|
||||
# 2670| getArgument(0): [PointerDereferenceExpr] * ...
|
||||
# 2670| Type = [IntType] int
|
||||
# 2670| ValueCategory = prvalue(load)
|
||||
# 2670| getOperand(): [VariableAccess] data
|
||||
# 2670| Type = [IntPointerType] int *
|
||||
# 2670| ValueCategory = prvalue(load)
|
||||
# 2671| getStmt(3): [ReturnStmt] return ...
|
||||
# 2673| [TopLevelFunction] void use(char const*)
|
||||
# 2673| <params>:
|
||||
# 2673| getParameter(0): [Parameter] fmt
|
||||
# 2673| Type = [PointerType] const char *
|
||||
# 2684| [TopLevelFunction] void test(bool)
|
||||
# 2684| <params>:
|
||||
# 2684| getParameter(0): [Parameter] b
|
||||
# 2684| Type = [BoolType] bool
|
||||
# 2685| getEntryPoint(): [BlockStmt] { ... }
|
||||
# 2686| getStmt(0): [DoStmt] do (...) ...
|
||||
# 2686| getCondition(): [Literal] 0
|
||||
# 2686| Type = [IntType] int
|
||||
# 2686| Value = [Literal] 0
|
||||
# 2686| ValueCategory = prvalue
|
||||
# 2686| getStmt(): [BlockStmt] { ... }
|
||||
# 2686| getStmt(0): [ExprStmt] ExprStmt
|
||||
# 2686| getExpr(): [FunctionCall] call to use
|
||||
# 2686| Type = [VoidType] void
|
||||
# 2686| ValueCategory = prvalue
|
||||
# 2686| getArgument(0): [ConditionalExpr] ... ? ... : ...
|
||||
# 2686| Type = [PointerType] const char *
|
||||
# 2686| ValueCategory = prvalue
|
||||
# 2686| getCondition(): [VariableAccess] b
|
||||
# 2686| Type = [BoolType] bool
|
||||
# 2686| ValueCategory = prvalue(load)
|
||||
# 2686| getThen():
|
||||
# 2686| Type = [ArrayType] const char[1]
|
||||
# 2686| Value = [StringLiteral] ""
|
||||
# 2686| ValueCategory = lvalue
|
||||
# 2686| getElse():
|
||||
# 2686| Type = [ArrayType] const char[1]
|
||||
# 2686| Value = [StringLiteral] ""
|
||||
# 2686| ValueCategory = lvalue
|
||||
# 2686| getThen().getFullyConverted(): [ArrayToPointerConversion] array to pointer conversion
|
||||
# 2686| Type = [PointerType] const char *
|
||||
# 2686| ValueCategory = prvalue
|
||||
# 2686| getElse().getFullyConverted(): [ArrayToPointerConversion] array to pointer conversion
|
||||
# 2686| Type = [PointerType] const char *
|
||||
# 2686| ValueCategory = prvalue
|
||||
# 2686| getStmt(1): [ExprStmt] ExprStmt
|
||||
# 2686| getExpr(): [FunctionCall] call to use
|
||||
# 2686| Type = [VoidType] void
|
||||
# 2686| ValueCategory = prvalue
|
||||
# 2686| getArgument(0): [ConditionalExpr] ... ? ... : ...
|
||||
# 2686| Type = [PointerType] const char *
|
||||
# 2686| ValueCategory = prvalue
|
||||
# 2686| getCondition(): [VariableAccess] b
|
||||
# 2686| Type = [BoolType] bool
|
||||
# 2686| ValueCategory = prvalue(load)
|
||||
# 2686| getThen():
|
||||
# 2686| Type = [ArrayType] const char[1]
|
||||
# 2686| Value = [StringLiteral] ""
|
||||
# 2686| ValueCategory = lvalue
|
||||
# 2686| getElse():
|
||||
# 2686| Type = [ArrayType] const char[1]
|
||||
# 2686| Value = [StringLiteral] ""
|
||||
# 2686| ValueCategory = lvalue
|
||||
# 2686| getThen().getFullyConverted(): [ArrayToPointerConversion] array to pointer conversion
|
||||
# 2686| Type = [PointerType] const char *
|
||||
# 2686| ValueCategory = prvalue
|
||||
# 2686| getElse().getFullyConverted(): [ArrayToPointerConversion] array to pointer conversion
|
||||
# 2686| Type = [PointerType] const char *
|
||||
# 2686| ValueCategory = prvalue
|
||||
# 2686| getCondition().getFullyConverted(): [CStyleCast] (bool)...
|
||||
# 2686| Conversion = [BoolConversion] conversion to bool
|
||||
# 2686| Type = [BoolType] bool
|
||||
# 2686| Value = [CStyleCast] 0
|
||||
# 2686| ValueCategory = prvalue
|
||||
# 2687| getStmt(1): [ReturnStmt] return ...
|
||||
perf-regression.cpp:
|
||||
# 4| [CopyAssignmentOperator] Big& Big::operator=(Big const&)
|
||||
# 4| <params>:
|
||||
|
||||
@@ -5263,20 +5263,23 @@ ir.cpp:
|
||||
|
||||
# 486| void Conditional_LValue(bool)
|
||||
# 486| Block 0
|
||||
# 486| v486_1(void) = EnterFunction :
|
||||
# 486| m486_2(unknown) = AliasedDefinition :
|
||||
# 486| m486_3(unknown) = InitializeNonLocal :
|
||||
# 486| m486_4(unknown) = Chi : total:m486_2, partial:m486_3
|
||||
# 486| r486_5(glval<bool>) = VariableAddress[a] :
|
||||
# 486| m486_6(bool) = InitializeParameter[a] : &:r486_5
|
||||
# 487| r487_1(glval<int>) = VariableAddress[x] :
|
||||
# 487| m487_2(int) = Uninitialized[x] : &:r487_1
|
||||
# 488| r488_1(glval<int>) = VariableAddress[y] :
|
||||
# 488| m488_2(int) = Uninitialized[y] : &:r488_1
|
||||
# 489| r489_1(int) = Constant[5] :
|
||||
# 489| r489_2(glval<bool>) = VariableAddress[a] :
|
||||
# 489| r489_3(bool) = Load[a] : &:r489_2, m486_6
|
||||
# 489| v489_4(void) = ConditionalBranch : r489_3
|
||||
# 486| v486_1(void) = EnterFunction :
|
||||
# 486| m486_2(unknown) = AliasedDefinition :
|
||||
# 486| m486_3(unknown) = InitializeNonLocal :
|
||||
# 486| m486_4(unknown) = Chi : total:m486_2, partial:m486_3
|
||||
# 486| m486_5(int) = UninitializedGroup[x,y] :
|
||||
# 486| r486_6(glval<bool>) = VariableAddress[a] :
|
||||
# 486| m486_7(bool) = InitializeParameter[a] : &:r486_6
|
||||
# 487| r487_1(glval<int>) = VariableAddress[x] :
|
||||
# 487| m487_2(int) = Uninitialized[x] : &:r487_1
|
||||
# 487| m487_3(int) = Chi : total:m486_5, partial:m487_2
|
||||
# 488| r488_1(glval<int>) = VariableAddress[y] :
|
||||
# 488| m488_2(int) = Uninitialized[y] : &:r488_1
|
||||
# 488| m488_3(int) = Chi : total:m487_3, partial:m488_2
|
||||
# 489| r489_1(int) = Constant[5] :
|
||||
# 489| r489_2(glval<bool>) = VariableAddress[a] :
|
||||
# 489| r489_3(bool) = Load[a] : &:r489_2, m486_7
|
||||
# 489| v489_4(void) = ConditionalBranch : r489_3
|
||||
#-----| False -> Block 3
|
||||
#-----| True -> Block 2
|
||||
|
||||
@@ -5285,11 +5288,11 @@ ir.cpp:
|
||||
# 489| r489_6(glval<unknown>) = VariableAddress[#temp489:6] :
|
||||
# 489| r489_7(glval<int>) = Load[#temp489:6] : &:r489_6, m489_5
|
||||
# 489| m489_8(int) = Store[?] : &:r489_7, r489_1
|
||||
# 489| m489_9(unknown) = Chi : total:m486_4, partial:m489_8
|
||||
# 489| m489_9(int) = Chi : total:m488_3, partial:m489_8
|
||||
# 490| v490_1(void) = NoOp :
|
||||
# 486| v486_7(void) = ReturnVoid :
|
||||
# 486| v486_8(void) = AliasedUse : ~m489_9
|
||||
# 486| v486_9(void) = ExitFunction :
|
||||
# 486| v486_8(void) = ReturnVoid :
|
||||
# 486| v486_9(void) = AliasedUse : m486_3
|
||||
# 486| v486_10(void) = ExitFunction :
|
||||
|
||||
# 489| Block 2
|
||||
# 489| r489_10(glval<int>) = VariableAddress[x] :
|
||||
@@ -14072,21 +14075,24 @@ ir.cpp:
|
||||
|
||||
# 2059| void TernaryTestInt(bool, int, int, int)
|
||||
# 2059| Block 0
|
||||
# 2059| v2059_1(void) = EnterFunction :
|
||||
# 2059| m2059_2(unknown) = AliasedDefinition :
|
||||
# 2059| m2059_3(unknown) = InitializeNonLocal :
|
||||
# 2059| m2059_4(unknown) = Chi : total:m2059_2, partial:m2059_3
|
||||
# 2059| r2059_5(glval<bool>) = VariableAddress[a] :
|
||||
# 2059| m2059_6(bool) = InitializeParameter[a] : &:r2059_5
|
||||
# 2059| r2059_7(glval<int>) = VariableAddress[x] :
|
||||
# 2059| m2059_8(int) = InitializeParameter[x] : &:r2059_7
|
||||
# 2059| r2059_9(glval<int>) = VariableAddress[y] :
|
||||
# 2059| m2059_10(int) = InitializeParameter[y] : &:r2059_9
|
||||
# 2059| r2059_11(glval<int>) = VariableAddress[z] :
|
||||
# 2059| m2059_12(int) = InitializeParameter[z] : &:r2059_11
|
||||
# 2060| r2060_1(glval<bool>) = VariableAddress[a] :
|
||||
# 2060| r2060_2(bool) = Load[a] : &:r2060_1, m2059_6
|
||||
# 2060| v2060_3(void) = ConditionalBranch : r2060_2
|
||||
# 2059| v2059_1(void) = EnterFunction :
|
||||
# 2059| m2059_2(unknown) = AliasedDefinition :
|
||||
# 2059| m2059_3(unknown) = InitializeNonLocal :
|
||||
# 2059| m2059_4(unknown) = Chi : total:m2059_2, partial:m2059_3
|
||||
# 2059| m2059_5(int) = UninitializedGroup[x,y] :
|
||||
# 2059| r2059_6(glval<bool>) = VariableAddress[a] :
|
||||
# 2059| m2059_7(bool) = InitializeParameter[a] : &:r2059_6
|
||||
# 2059| r2059_8(glval<int>) = VariableAddress[x] :
|
||||
# 2059| m2059_9(int) = InitializeParameter[x] : &:r2059_8
|
||||
# 2059| m2059_10(int) = Chi : total:m2059_5, partial:m2059_9
|
||||
# 2059| r2059_11(glval<int>) = VariableAddress[y] :
|
||||
# 2059| m2059_12(int) = InitializeParameter[y] : &:r2059_11
|
||||
# 2059| m2059_13(int) = Chi : total:m2059_10, partial:m2059_12
|
||||
# 2059| r2059_14(glval<int>) = VariableAddress[z] :
|
||||
# 2059| m2059_15(int) = InitializeParameter[z] : &:r2059_14
|
||||
# 2060| r2060_1(glval<bool>) = VariableAddress[a] :
|
||||
# 2060| r2060_2(bool) = Load[a] : &:r2060_1, m2059_7
|
||||
# 2060| v2060_3(void) = ConditionalBranch : r2060_2
|
||||
#-----| False -> Block 3
|
||||
#-----| True -> Block 2
|
||||
|
||||
@@ -14097,21 +14103,21 @@ ir.cpp:
|
||||
# 2060| r2060_7(glval<int>) = VariableAddress[z] :
|
||||
# 2060| m2060_8(int) = Store[z] : &:r2060_7, r2060_6
|
||||
# 2061| r2061_1(glval<bool>) = VariableAddress[a] :
|
||||
# 2061| r2061_2(bool) = Load[a] : &:r2061_1, m2059_6
|
||||
# 2061| r2061_2(bool) = Load[a] : &:r2061_1, m2059_7
|
||||
# 2061| v2061_3(void) = ConditionalBranch : r2061_2
|
||||
#-----| False -> Block 6
|
||||
#-----| True -> Block 5
|
||||
|
||||
# 2060| Block 2
|
||||
# 2060| r2060_9(glval<int>) = VariableAddress[x] :
|
||||
# 2060| r2060_10(int) = Load[x] : &:r2060_9, m2059_8
|
||||
# 2060| r2060_10(int) = Load[x] : &:r2060_9, m2059_9
|
||||
# 2060| r2060_11(glval<int>) = VariableAddress[#temp2060:9] :
|
||||
# 2060| m2060_12(int) = Store[#temp2060:9] : &:r2060_11, r2060_10
|
||||
#-----| Goto -> Block 1
|
||||
|
||||
# 2060| Block 3
|
||||
# 2060| r2060_13(glval<int>) = VariableAddress[y] :
|
||||
# 2060| r2060_14(int) = Load[y] : &:r2060_13, m2059_10
|
||||
# 2060| r2060_14(int) = Load[y] : &:r2060_13, m2059_12
|
||||
# 2060| r2060_15(glval<int>) = VariableAddress[#temp2060:9] :
|
||||
# 2060| m2060_16(int) = Store[#temp2060:9] : &:r2060_15, r2060_14
|
||||
#-----| Goto -> Block 1
|
||||
@@ -14123,14 +14129,14 @@ ir.cpp:
|
||||
# 2061| r2061_7(glval<int>) = VariableAddress[z] :
|
||||
# 2061| m2061_8(int) = Store[z] : &:r2061_7, r2061_6
|
||||
# 2062| r2062_1(glval<bool>) = VariableAddress[a] :
|
||||
# 2062| r2062_2(bool) = Load[a] : &:r2062_1, m2059_6
|
||||
# 2062| r2062_2(bool) = Load[a] : &:r2062_1, m2059_7
|
||||
# 2062| v2062_3(void) = ConditionalBranch : r2062_2
|
||||
#-----| False -> Block 9
|
||||
#-----| True -> Block 8
|
||||
|
||||
# 2061| Block 5
|
||||
# 2061| r2061_9(glval<int>) = VariableAddress[x] :
|
||||
# 2061| r2061_10(int) = Load[x] : &:r2061_9, m2059_8
|
||||
# 2061| r2061_10(int) = Load[x] : &:r2061_9, m2059_9
|
||||
# 2061| r2061_11(glval<int>) = VariableAddress[#temp2061:9] :
|
||||
# 2061| m2061_12(int) = Store[#temp2061:9] : &:r2061_11, r2061_10
|
||||
#-----| Goto -> Block 4
|
||||
@@ -14149,7 +14155,7 @@ ir.cpp:
|
||||
# 2062| m2062_8(int) = Store[z] : &:r2062_7, r2062_6
|
||||
# 2063| r2063_1(int) = Constant[7] :
|
||||
# 2063| r2063_2(glval<bool>) = VariableAddress[a] :
|
||||
# 2063| r2063_3(bool) = Load[a] : &:r2063_2, m2059_6
|
||||
# 2063| r2063_3(bool) = Load[a] : &:r2063_2, m2059_7
|
||||
# 2063| v2063_4(void) = ConditionalBranch : r2063_3
|
||||
#-----| False -> Block 12
|
||||
#-----| True -> Block 11
|
||||
@@ -14171,11 +14177,11 @@ ir.cpp:
|
||||
# 2063| r2063_6(glval<unknown>) = VariableAddress[#temp2063:6] :
|
||||
# 2063| r2063_7(glval<int>) = Load[#temp2063:6] : &:r2063_6, m2063_5
|
||||
# 2063| m2063_8(int) = Store[?] : &:r2063_7, r2063_1
|
||||
# 2063| m2063_9(unknown) = Chi : total:m2059_4, partial:m2063_8
|
||||
# 2063| m2063_9(int) = Chi : total:m2059_13, partial:m2063_8
|
||||
# 2064| v2064_1(void) = NoOp :
|
||||
# 2059| v2059_13(void) = ReturnVoid :
|
||||
# 2059| v2059_14(void) = AliasedUse : ~m2063_9
|
||||
# 2059| v2059_15(void) = ExitFunction :
|
||||
# 2059| v2059_16(void) = ReturnVoid :
|
||||
# 2059| v2059_17(void) = AliasedUse : m2059_3
|
||||
# 2059| v2059_18(void) = ExitFunction :
|
||||
|
||||
# 2063| Block 11
|
||||
# 2063| r2063_10(glval<int>) = VariableAddress[x] :
|
||||
@@ -14419,18 +14425,21 @@ ir.cpp:
|
||||
# 2080| m2080_2(unknown) = AliasedDefinition :
|
||||
# 2080| m2080_3(unknown) = InitializeNonLocal :
|
||||
# 2080| m2080_4(unknown) = Chi : total:m2080_2, partial:m2080_3
|
||||
# 2080| r2080_5(glval<bool>) = VariableAddress[a] :
|
||||
# 2080| m2080_6(bool) = InitializeParameter[a] : &:r2080_5
|
||||
# 2080| r2080_7(glval<TernaryNonPodObj>) = VariableAddress[x] :
|
||||
# 2080| m2080_8(TernaryNonPodObj) = InitializeParameter[x] : &:r2080_7
|
||||
# 2080| r2080_9(glval<TernaryNonPodObj>) = VariableAddress[y] :
|
||||
# 2080| m2080_10(TernaryNonPodObj) = InitializeParameter[y] : &:r2080_9
|
||||
# 2080| r2080_11(glval<TernaryNonPodObj>) = VariableAddress[z] :
|
||||
# 2080| m2080_12(TernaryNonPodObj) = InitializeParameter[z] : &:r2080_11
|
||||
# 2080| m2080_5(unknown) = UninitializedGroup[x,y] :
|
||||
# 2080| r2080_6(glval<bool>) = VariableAddress[a] :
|
||||
# 2080| m2080_7(bool) = InitializeParameter[a] : &:r2080_6
|
||||
# 2080| r2080_8(glval<TernaryNonPodObj>) = VariableAddress[x] :
|
||||
# 2080| m2080_9(TernaryNonPodObj) = InitializeParameter[x] : &:r2080_8
|
||||
# 2080| m2080_10(unknown) = Chi : total:m2080_5, partial:m2080_9
|
||||
# 2080| r2080_11(glval<TernaryNonPodObj>) = VariableAddress[y] :
|
||||
# 2080| m2080_12(TernaryNonPodObj) = InitializeParameter[y] : &:r2080_11
|
||||
# 2080| m2080_13(unknown) = Chi : total:m2080_10, partial:m2080_12
|
||||
# 2080| r2080_14(glval<TernaryNonPodObj>) = VariableAddress[z] :
|
||||
# 2080| m2080_15(TernaryNonPodObj) = InitializeParameter[z] : &:r2080_14
|
||||
# 2081| r2081_1(glval<TernaryNonPodObj>) = VariableAddress[z] :
|
||||
# 2081| r2081_2(glval<unknown>) = FunctionAddress[operator=] :
|
||||
# 2081| r2081_3(glval<bool>) = VariableAddress[a] :
|
||||
# 2081| r2081_4(bool) = Load[a] : &:r2081_3, m2080_6
|
||||
# 2081| r2081_4(bool) = Load[a] : &:r2081_3, m2080_7
|
||||
# 2081| v2081_5(void) = ConditionalBranch : r2081_4
|
||||
#-----| False -> Block 3
|
||||
#-----| True -> Block 2
|
||||
@@ -14444,16 +14453,16 @@ ir.cpp:
|
||||
# 2081| r2081_11(TernaryNonPodObj &) = Call[operator=] : func:r2081_2, this:r2081_1, 0:r2081_10
|
||||
# 2081| m2081_12(unknown) = ^CallSideEffect : ~m2080_4
|
||||
# 2081| m2081_13(unknown) = Chi : total:m2080_4, partial:m2081_12
|
||||
# 2081| v2081_14(void) = ^IndirectReadSideEffect[-1] : &:r2081_1, m2080_12
|
||||
# 2081| v2081_15(void) = ^BufferReadSideEffect[0] : &:r2081_10, ~m2081_13
|
||||
# 2081| v2081_14(void) = ^IndirectReadSideEffect[-1] : &:r2081_1, m2080_15
|
||||
# 2081| v2081_15(void) = ^BufferReadSideEffect[0] : &:r2081_10, ~m2080_13
|
||||
# 2081| m2081_16(TernaryNonPodObj) = ^IndirectMayWriteSideEffect[-1] : &:r2081_1
|
||||
# 2081| m2081_17(TernaryNonPodObj) = Chi : total:m2080_12, partial:m2081_16
|
||||
# 2081| m2081_17(TernaryNonPodObj) = Chi : total:m2080_15, partial:m2081_16
|
||||
# 2081| r2081_18(glval<TernaryNonPodObj>) = CopyValue : r2081_11
|
||||
# 2082| r2082_1(glval<TernaryNonPodObj>) = VariableAddress[z] :
|
||||
# 2082| r2082_2(glval<unknown>) = FunctionAddress[operator=] :
|
||||
# 2082| r2082_3(glval<TernaryNonPodObj>) = VariableAddress[#temp2082:9] :
|
||||
# 2082| r2082_4(glval<bool>) = VariableAddress[a] :
|
||||
# 2082| r2082_5(bool) = Load[a] : &:r2082_4, m2080_6
|
||||
# 2082| r2082_5(bool) = Load[a] : &:r2082_4, m2080_7
|
||||
# 2082| v2082_6(void) = ConditionalBranch : r2082_5
|
||||
#-----| False -> Block 6
|
||||
#-----| True -> Block 5
|
||||
@@ -14499,7 +14508,7 @@ ir.cpp:
|
||||
# 2083| r2083_2(glval<unknown>) = FunctionAddress[operator=] :
|
||||
# 2083| r2083_3(glval<TernaryNonPodObj>) = VariableAddress[#temp2083:9] :
|
||||
# 2083| r2083_4(glval<bool>) = VariableAddress[a] :
|
||||
# 2083| r2083_5(bool) = Load[a] : &:r2083_4, m2080_6
|
||||
# 2083| r2083_5(bool) = Load[a] : &:r2083_4, m2080_7
|
||||
# 2083| v2083_6(void) = ConditionalBranch : r2083_5
|
||||
#-----| False -> Block 9
|
||||
#-----| True -> Block 8
|
||||
@@ -14514,7 +14523,7 @@ ir.cpp:
|
||||
# 2082| v2082_37(void) = Call[TernaryNonPodObj] : func:r2082_33, this:r2082_31, 0:r2082_36
|
||||
# 2082| m2082_38(unknown) = ^CallSideEffect : ~m2081_13
|
||||
# 2082| m2082_39(unknown) = Chi : total:m2081_13, partial:m2082_38
|
||||
# 2082| v2082_40(void) = ^BufferReadSideEffect[0] : &:r2082_36, ~m2080_8
|
||||
# 2082| v2082_40(void) = ^BufferReadSideEffect[0] : &:r2082_36, ~m2080_9
|
||||
# 2082| m2082_41(TernaryNonPodObj) = ^IndirectMayWriteSideEffect[-1] : &:r2082_31
|
||||
# 2082| m2082_42(TernaryNonPodObj) = Chi : total:m2082_32, partial:m2082_41
|
||||
# 2082| r2082_43(TernaryNonPodObj) = Load[#temp2082:13] : &:r2082_31, m2082_42
|
||||
@@ -14564,7 +14573,7 @@ ir.cpp:
|
||||
# 2084| r2084_1(glval<TernaryNonPodObj>) = VariableAddress[z] :
|
||||
# 2084| r2084_2(glval<unknown>) = FunctionAddress[operator=] :
|
||||
# 2084| r2084_3(glval<bool>) = VariableAddress[a] :
|
||||
# 2084| r2084_4(bool) = Load[a] : &:r2084_3, m2080_6
|
||||
# 2084| r2084_4(bool) = Load[a] : &:r2084_3, m2080_7
|
||||
# 2084| v2084_5(void) = ConditionalBranch : r2084_4
|
||||
#-----| False -> Block 12
|
||||
#-----| True -> Block 11
|
||||
@@ -14607,7 +14616,7 @@ ir.cpp:
|
||||
# 2084| m2084_12(unknown) = ^CallSideEffect : ~m2083_29
|
||||
# 2084| m2084_13(unknown) = Chi : total:m2083_29, partial:m2084_12
|
||||
# 2084| v2084_14(void) = ^IndirectReadSideEffect[-1] : &:r2084_1, m2083_21
|
||||
# 2084| v2084_15(void) = ^BufferReadSideEffect[0] : &:r2084_10, ~m2084_13
|
||||
# 2084| v2084_15(void) = ^BufferReadSideEffect[0] : &:r2084_10, ~m2080_13
|
||||
# 2084| m2084_16(TernaryNonPodObj) = ^IndirectMayWriteSideEffect[-1] : &:r2084_1
|
||||
# 2084| m2084_17(TernaryNonPodObj) = Chi : total:m2083_21, partial:m2084_16
|
||||
# 2084| r2084_18(glval<TernaryNonPodObj>) = CopyValue : r2084_11
|
||||
@@ -14640,9 +14649,9 @@ ir.cpp:
|
||||
# 2084| m2084_45(unknown) = Chi : total:m2084_42, partial:m2084_44
|
||||
# 2084| r2084_46(glval<TernaryNonPodObj>) = CopyValue : r2084_31
|
||||
# 2085| v2085_1(void) = NoOp :
|
||||
# 2080| v2080_13(void) = ReturnVoid :
|
||||
# 2080| v2080_14(void) = AliasedUse : ~m2084_42
|
||||
# 2080| v2080_15(void) = ExitFunction :
|
||||
# 2080| v2080_16(void) = ReturnVoid :
|
||||
# 2080| v2080_17(void) = AliasedUse : ~m2084_42
|
||||
# 2080| v2080_18(void) = ExitFunction :
|
||||
|
||||
# 2084| Block 11
|
||||
# 2084| r2084_47(glval<TernaryNonPodObj>) = VariableAddress[x] :
|
||||
@@ -18395,6 +18404,534 @@ ir.cpp:
|
||||
# 2555| v2555_8(void) = AliasedUse : m2555_3
|
||||
# 2555| v2555_9(void) = ExitFunction :
|
||||
|
||||
# 2559| void p_points_to_x_or_y(int, int)
|
||||
# 2559| Block 0
|
||||
# 2559| v2559_1(void) = EnterFunction :
|
||||
# 2559| m2559_2(unknown) = AliasedDefinition :
|
||||
# 2559| m2559_3(unknown) = InitializeNonLocal :
|
||||
# 2559| m2559_4(unknown) = Chi : total:m2559_2, partial:m2559_3
|
||||
# 2559| m2559_5(int) = UninitializedGroup[x,y] :
|
||||
# 2559| r2559_6(glval<int>) = VariableAddress[a] :
|
||||
# 2559| m2559_7(int) = InitializeParameter[a] : &:r2559_6
|
||||
# 2559| r2559_8(glval<int>) = VariableAddress[b] :
|
||||
# 2559| m2559_9(int) = InitializeParameter[b] : &:r2559_8
|
||||
# 2560| r2560_1(glval<int>) = VariableAddress[x] :
|
||||
# 2560| m2560_2(int) = Uninitialized[x] : &:r2560_1
|
||||
# 2560| m2560_3(int) = Chi : total:m2559_5, partial:m2560_2
|
||||
# 2561| r2561_1(glval<int>) = VariableAddress[y] :
|
||||
# 2561| m2561_2(int) = Uninitialized[y] : &:r2561_1
|
||||
# 2561| m2561_3(int) = Chi : total:m2560_3, partial:m2561_2
|
||||
# 2562| r2562_1(glval<int *>) = VariableAddress[p] :
|
||||
# 2562| m2562_2(int *) = Uninitialized[p] : &:r2562_1
|
||||
# 2563| r2563_1(glval<int>) = VariableAddress[a] :
|
||||
# 2563| r2563_2(int) = Load[a] : &:r2563_1, m2559_7
|
||||
# 2563| r2563_3(glval<int>) = VariableAddress[b] :
|
||||
# 2563| r2563_4(int) = Load[b] : &:r2563_3, m2559_9
|
||||
# 2563| r2563_5(bool) = CompareLT : r2563_2, r2563_4
|
||||
# 2563| v2563_6(void) = ConditionalBranch : r2563_5
|
||||
#-----| False -> Block 2
|
||||
#-----| True -> Block 1
|
||||
|
||||
# 2564| Block 1
|
||||
# 2564| r2564_1(glval<int>) = VariableAddress[x] :
|
||||
# 2564| r2564_2(int *) = CopyValue : r2564_1
|
||||
# 2564| r2564_3(glval<int *>) = VariableAddress[p] :
|
||||
# 2564| m2564_4(int *) = Store[p] : &:r2564_3, r2564_2
|
||||
#-----| Goto -> Block 3
|
||||
|
||||
# 2566| Block 2
|
||||
# 2566| r2566_1(glval<int>) = VariableAddress[y] :
|
||||
# 2566| r2566_2(int *) = CopyValue : r2566_1
|
||||
# 2566| r2566_3(glval<int *>) = VariableAddress[p] :
|
||||
# 2566| m2566_4(int *) = Store[p] : &:r2566_3, r2566_2
|
||||
#-----| Goto -> Block 3
|
||||
|
||||
# 2568| Block 3
|
||||
# 2568| m2568_1(int *) = Phi : from 1:m2564_4, from 2:m2566_4
|
||||
# 2568| r2568_2(int) = Constant[5] :
|
||||
# 2568| r2568_3(glval<int *>) = VariableAddress[p] :
|
||||
# 2568| r2568_4(int *) = Load[p] : &:r2568_3, m2568_1
|
||||
# 2568| r2568_5(glval<int>) = CopyValue : r2568_4
|
||||
# 2568| m2568_6(int) = Store[?] : &:r2568_5, r2568_2
|
||||
# 2568| m2568_7(int) = Chi : total:m2561_3, partial:m2568_6
|
||||
# 2569| r2569_1(glval<int>) = VariableAddress[z] :
|
||||
# 2569| r2569_2(glval<int>) = VariableAddress[x] :
|
||||
# 2569| r2569_3(int) = Load[x] : &:r2569_2, ~m2568_7
|
||||
# 2569| m2569_4(int) = Store[z] : &:r2569_1, r2569_3
|
||||
# 2570| r2570_1(glval<int>) = VariableAddress[w] :
|
||||
# 2570| r2570_2(glval<int>) = VariableAddress[y] :
|
||||
# 2570| r2570_3(int) = Load[y] : &:r2570_2, ~m2568_7
|
||||
# 2570| m2570_4(int) = Store[w] : &:r2570_1, r2570_3
|
||||
# 2571| v2571_1(void) = NoOp :
|
||||
# 2559| v2559_10(void) = ReturnVoid :
|
||||
# 2559| v2559_11(void) = AliasedUse : m2559_3
|
||||
# 2559| v2559_12(void) = ExitFunction :
|
||||
|
||||
# 2573| int phi_after_while()
|
||||
# 2573| Block 0
|
||||
# 2573| v2573_1(void) = EnterFunction :
|
||||
# 2573| m2573_2(unknown) = AliasedDefinition :
|
||||
# 2573| m2573_3(unknown) = InitializeNonLocal :
|
||||
# 2573| m2573_4(unknown) = Chi : total:m2573_2, partial:m2573_3
|
||||
# 2573| m2573_5(int) = UninitializedGroup[r,s] :
|
||||
# 2574| r2574_1(glval<int>) = VariableAddress[r] :
|
||||
# 2574| m2574_2(int) = Uninitialized[r] : &:r2574_1
|
||||
# 2574| m2574_3(int) = Chi : total:m2573_5, partial:m2574_2
|
||||
# 2575| r2575_1(glval<int *>) = VariableAddress[rP] :
|
||||
# 2575| r2575_2(glval<int>) = VariableAddress[r] :
|
||||
# 2575| r2575_3(int *) = CopyValue : r2575_2
|
||||
# 2575| m2575_4(int *) = Store[rP] : &:r2575_1, r2575_3
|
||||
#-----| Goto -> Block 1
|
||||
|
||||
# 2577| Block 1
|
||||
# 2577| m2577_1(int) = Phi : from 0:m2574_3, from 2:m2579_7
|
||||
# 2577| m2577_2(unknown) = Phi : from 0:~m2573_4, from 2:~m2577_7
|
||||
# 2577| m2577_3(int *) = Phi : from 0:m2575_4, from 2:m2580_4
|
||||
# 2577| r2577_4(glval<unknown>) = FunctionAddress[predicateA] :
|
||||
# 2577| r2577_5(bool) = Call[predicateA] : func:r2577_4
|
||||
# 2577| m2577_6(unknown) = ^CallSideEffect : ~m2577_2
|
||||
# 2577| m2577_7(unknown) = Chi : total:m2577_2, partial:m2577_6
|
||||
# 2577| v2577_8(void) = ConditionalBranch : r2577_5
|
||||
#-----| False -> Block 3
|
||||
#-----| True -> Block 2
|
||||
|
||||
# 2578| Block 2
|
||||
# 2578| r2578_1(glval<int>) = VariableAddress[s] :
|
||||
# 2578| r2578_2(int) = Constant[0] :
|
||||
# 2578| m2578_3(int) = Store[s] : &:r2578_1, r2578_2
|
||||
# 2578| m2578_4(int) = Chi : total:m2577_1, partial:m2578_3
|
||||
# 2579| r2579_1(glval<int>) = VariableAddress[s] :
|
||||
# 2579| r2579_2(int) = Load[s] : &:r2579_1, m2578_3
|
||||
# 2579| r2579_3(glval<int *>) = VariableAddress[rP] :
|
||||
# 2579| r2579_4(int *) = Load[rP] : &:r2579_3, m2577_3
|
||||
# 2579| r2579_5(glval<int>) = CopyValue : r2579_4
|
||||
# 2579| m2579_6(int) = Store[?] : &:r2579_5, r2579_2
|
||||
# 2579| m2579_7(int) = Chi : total:m2578_4, partial:m2579_6
|
||||
# 2580| r2580_1(glval<int>) = VariableAddress[s] :
|
||||
# 2580| r2580_2(int *) = CopyValue : r2580_1
|
||||
# 2580| r2580_3(glval<int *>) = VariableAddress[rP] :
|
||||
# 2580| m2580_4(int *) = Store[rP] : &:r2580_3, r2580_2
|
||||
#-----| Goto (back edge) -> Block 1
|
||||
|
||||
# 2583| Block 3
|
||||
# 2583| r2583_1(glval<int>) = VariableAddress[#return] :
|
||||
# 2583| r2583_2(glval<int>) = VariableAddress[r] :
|
||||
# 2583| r2583_3(int) = Load[r] : &:r2583_2, ~m2577_1
|
||||
# 2583| m2583_4(int) = Store[#return] : &:r2583_1, r2583_3
|
||||
# 2573| r2573_6(glval<int>) = VariableAddress[#return] :
|
||||
# 2573| v2573_7(void) = ReturnValue : &:r2573_6, m2583_4
|
||||
# 2573| v2573_8(void) = AliasedUse : ~m2577_7
|
||||
# 2573| v2573_9(void) = ExitFunction :
|
||||
|
||||
# 2588| char* recursive_conditional_call_with_increment(char*, bool)
|
||||
# 2588| Block 0
|
||||
# 2588| v2588_1(void) = EnterFunction :
|
||||
# 2588| m2588_2(unknown) = AliasedDefinition :
|
||||
# 2588| m2588_3(unknown) = InitializeNonLocal :
|
||||
# 2588| m2588_4(unknown) = Chi : total:m2588_2, partial:m2588_3
|
||||
# 2588| r2588_5(glval<char *>) = VariableAddress[d] :
|
||||
# 2588| m2588_6(char *) = InitializeParameter[d] : &:r2588_5
|
||||
# 2588| r2588_7(char *) = Load[d] : &:r2588_5, m2588_6
|
||||
# 2588| m2588_8(unknown) = InitializeIndirection[d] : &:r2588_7
|
||||
# 2588| r2588_9(glval<bool>) = VariableAddress[b] :
|
||||
# 2588| m2588_10(bool) = InitializeParameter[b] : &:r2588_9
|
||||
# 2590| r2590_1(glval<bool>) = VariableAddress[b] :
|
||||
# 2590| r2590_2(bool) = Load[b] : &:r2590_1, m2588_10
|
||||
# 2590| v2590_3(void) = ConditionalBranch : r2590_2
|
||||
#-----| False -> Block 2
|
||||
#-----| True -> Block 1
|
||||
|
||||
# 2591| Block 1
|
||||
# 2591| r2591_1(glval<unknown>) = FunctionAddress[recursive_conditional_call_with_increment] :
|
||||
# 2591| r2591_2(glval<char *>) = VariableAddress[d] :
|
||||
# 2591| r2591_3(char *) = Load[d] : &:r2591_2, m2588_6
|
||||
# 2591| r2591_4(glval<bool>) = VariableAddress[b] :
|
||||
# 2591| r2591_5(bool) = Load[b] : &:r2591_4, m2588_10
|
||||
# 2591| r2591_6(char *) = Call[recursive_conditional_call_with_increment] : func:r2591_1, 0:r2591_3, 1:r2591_5
|
||||
# 2591| m2591_7(unknown) = ^CallSideEffect : ~m2588_4
|
||||
# 2591| m2591_8(unknown) = Chi : total:m2588_4, partial:m2591_7
|
||||
# 2591| v2591_9(void) = ^BufferReadSideEffect[0] : &:r2591_3, ~m2588_8
|
||||
# 2591| m2591_10(unknown) = ^BufferMayWriteSideEffect[0] : &:r2591_3
|
||||
# 2591| m2591_11(unknown) = Chi : total:m2588_8, partial:m2591_10
|
||||
# 2591| r2591_12(glval<char *>) = VariableAddress[d] :
|
||||
# 2591| m2591_13(char *) = Store[d] : &:r2591_12, r2591_6
|
||||
#-----| Goto -> Block 2
|
||||
|
||||
# 2593| Block 2
|
||||
# 2593| m2593_1(unknown) = Phi : from 0:m2588_8, from 1:m2591_11
|
||||
# 2593| m2593_2(unknown) = Phi : from 0:~m2588_4, from 1:~m2591_8
|
||||
# 2593| m2593_3(char *) = Phi : from 0:m2588_6, from 1:m2591_13
|
||||
# 2593| r2593_4(glval<char *>) = VariableAddress[d] :
|
||||
# 2593| r2593_5(char *) = Load[d] : &:r2593_4, m2593_3
|
||||
# 2593| r2593_6(int) = Constant[1] :
|
||||
# 2593| r2593_7(char *) = PointerAdd[1] : r2593_5, r2593_6
|
||||
# 2593| m2593_8(char *) = Store[d] : &:r2593_4, r2593_7
|
||||
# 2594| r2594_1(glval<char *>) = VariableAddress[#return] :
|
||||
# 2594| r2594_2(glval<char *>) = VariableAddress[d] :
|
||||
# 2594| r2594_3(char *) = Load[d] : &:r2594_2, m2593_8
|
||||
# 2594| m2594_4(char *) = Store[#return] : &:r2594_1, r2594_3
|
||||
# 2588| v2588_11(void) = ReturnIndirection[d] : &:r2588_7, m2593_1
|
||||
# 2588| r2588_12(glval<char *>) = VariableAddress[#return] :
|
||||
# 2588| v2588_13(void) = ReturnValue : &:r2588_12, m2594_4
|
||||
# 2588| v2588_14(void) = AliasedUse : ~m2593_2
|
||||
# 2588| v2588_15(void) = ExitFunction :
|
||||
|
||||
# 2602| Recursive* merge(Recursive*)
|
||||
# 2602| Block 0
|
||||
# 2602| v2602_1(void) = EnterFunction :
|
||||
# 2602| m2602_2(unknown) = AliasedDefinition :
|
||||
# 2602| m2602_3(unknown) = InitializeNonLocal :
|
||||
# 2602| m2602_4(unknown) = Chi : total:m2602_2, partial:m2602_3
|
||||
# 2602| m2602_5(Recursive *) = UninitializedGroup[a,b] :
|
||||
# 2602| m2602_6(unknown) = Chi : total:m2602_4, partial:m2602_5
|
||||
# 2602| r2602_7(glval<Recursive *>) = VariableAddress[a] :
|
||||
# 2602| m2602_8(Recursive *) = InitializeParameter[a] : &:r2602_7
|
||||
# 2602| r2602_9(Recursive *) = Load[a] : &:r2602_7, m2602_8
|
||||
# 2602| m2602_10(unknown) = InitializeIndirection[a] : &:r2602_9
|
||||
# 2602| m2602_11(unknown) = Chi : total:m2602_6, partial:m2602_10
|
||||
# 2604| r2604_1(glval<Recursive *>) = VariableAddress[b] :
|
||||
# 2604| m2604_2(Recursive *) = Uninitialized[b] : &:r2604_1
|
||||
# 2604| m2604_3(unknown) = Chi : total:m2602_11, partial:m2604_2
|
||||
# 2605| r2605_1(glval<Recursive **>) = VariableAddress[p] :
|
||||
# 2605| r2605_2(glval<Recursive *>) = VariableAddress[b] :
|
||||
# 2605| r2605_3(Recursive **) = CopyValue : r2605_2
|
||||
# 2605| m2605_4(Recursive **) = Store[p] : &:r2605_1, r2605_3
|
||||
#-----| Goto -> Block 1
|
||||
|
||||
# 2607| Block 1
|
||||
# 2607| m2607_1(unknown) = Phi : from 0:~m2604_3, from 2:~m2609_7
|
||||
# 2607| m2607_2(Recursive **) = Phi : from 0:m2605_4, from 2:m2610_6
|
||||
# 2607| r2607_3(glval<unknown>) = FunctionAddress[predicateA] :
|
||||
# 2607| r2607_4(bool) = Call[predicateA] : func:r2607_3
|
||||
# 2607| m2607_5(unknown) = ^CallSideEffect : ~m2607_1
|
||||
# 2607| m2607_6(unknown) = Chi : total:m2607_1, partial:m2607_5
|
||||
# 2607| v2607_7(void) = ConditionalBranch : r2607_4
|
||||
#-----| False -> Block 3
|
||||
#-----| True -> Block 2
|
||||
|
||||
# 2609| Block 2
|
||||
# 2609| r2609_1(glval<Recursive *>) = VariableAddress[a] :
|
||||
# 2609| r2609_2(Recursive *) = Load[a] : &:r2609_1, m2602_8
|
||||
# 2609| r2609_3(glval<Recursive **>) = VariableAddress[p] :
|
||||
# 2609| r2609_4(Recursive **) = Load[p] : &:r2609_3, m2607_2
|
||||
# 2609| r2609_5(glval<Recursive *>) = CopyValue : r2609_4
|
||||
# 2609| m2609_6(Recursive *) = Store[?] : &:r2609_5, r2609_2
|
||||
# 2609| m2609_7(unknown) = Chi : total:m2607_6, partial:m2609_6
|
||||
# 2610| r2610_1(glval<Recursive *>) = VariableAddress[a] :
|
||||
# 2610| r2610_2(Recursive *) = Load[a] : &:r2610_1, m2602_8
|
||||
# 2610| r2610_3(glval<Recursive *>) = FieldAddress[next] : r2610_2
|
||||
# 2610| r2610_4(Recursive **) = CopyValue : r2610_3
|
||||
# 2610| r2610_5(glval<Recursive **>) = VariableAddress[p] :
|
||||
# 2610| m2610_6(Recursive **) = Store[p] : &:r2610_5, r2610_4
|
||||
#-----| Goto (back edge) -> Block 1
|
||||
|
||||
# 2613| Block 3
|
||||
# 2613| r2613_1(glval<Recursive *>) = VariableAddress[#return] :
|
||||
# 2613| r2613_2(glval<Recursive *>) = VariableAddress[b] :
|
||||
# 2613| r2613_3(Recursive *) = Load[b] : &:r2613_2, ~m2607_6
|
||||
# 2613| m2613_4(Recursive *) = Store[#return] : &:r2613_1, r2613_3
|
||||
# 2602| v2602_12(void) = ReturnIndirection[a] : &:r2602_9, ~m2607_6
|
||||
# 2602| r2602_13(glval<Recursive *>) = VariableAddress[#return] :
|
||||
# 2602| v2602_14(void) = ReturnValue : &:r2602_13, m2613_4
|
||||
# 2602| v2602_15(void) = AliasedUse : ~m2607_6
|
||||
# 2602| v2602_16(void) = ExitFunction :
|
||||
|
||||
# 2618| void escaping_pointer(bool)
|
||||
# 2618| Block 0
|
||||
# 2618| v2618_1(void) = EnterFunction :
|
||||
# 2618| m2618_2(unknown) = AliasedDefinition :
|
||||
# 2618| m2618_3(unknown) = InitializeNonLocal :
|
||||
# 2618| m2618_4(unknown) = Chi : total:m2618_2, partial:m2618_3
|
||||
# 2618| m2618_5(unknown) = UninitializedGroup[l1,l2] :
|
||||
# 2618| m2618_6(unknown) = Chi : total:m2618_4, partial:m2618_5
|
||||
# 2618| r2618_7(glval<bool>) = VariableAddress[b] :
|
||||
# 2618| m2618_8(bool) = InitializeParameter[b] : &:r2618_7
|
||||
# 2620| r2620_1(glval<int *>) = VariableAddress[data] :
|
||||
# 2620| m2620_2(int *) = Uninitialized[data] : &:r2620_1
|
||||
# 2621| r2621_1(glval<int>) = VariableAddress[l1] :
|
||||
# 2621| m2621_2(int) = Uninitialized[l1] : &:r2621_1
|
||||
# 2621| m2621_3(unknown) = Chi : total:m2618_6, partial:m2621_2
|
||||
# 2621| r2621_4(glval<int>) = VariableAddress[l2] :
|
||||
# 2621| m2621_5(int) = Uninitialized[l2] : &:r2621_4
|
||||
# 2621| m2621_6(unknown) = Chi : total:m2621_3, partial:m2621_5
|
||||
# 2622| r2622_1(glval<bool>) = VariableAddress[b] :
|
||||
# 2622| r2622_2(bool) = Load[b] : &:r2622_1, m2618_8
|
||||
# 2622| v2622_3(void) = ConditionalBranch : r2622_2
|
||||
#-----| False -> Block 2
|
||||
#-----| True -> Block 1
|
||||
|
||||
# 2624| Block 1
|
||||
# 2624| r2624_1(glval<int>) = VariableAddress[l1] :
|
||||
# 2624| r2624_2(int *) = CopyValue : r2624_1
|
||||
# 2624| r2624_3(glval<int *>) = VariableAddress[data] :
|
||||
# 2624| m2624_4(int *) = Store[data] : &:r2624_3, r2624_2
|
||||
#-----| Goto -> Block 3
|
||||
|
||||
# 2628| Block 2
|
||||
# 2628| r2628_1(glval<int>) = VariableAddress[l2] :
|
||||
# 2628| r2628_2(int *) = CopyValue : r2628_1
|
||||
# 2628| r2628_3(glval<int *>) = VariableAddress[data] :
|
||||
# 2628| m2628_4(int *) = Store[data] : &:r2628_3, r2628_2
|
||||
#-----| Goto -> Block 3
|
||||
|
||||
# 2630| Block 3
|
||||
# 2630| m2630_1(int *) = Phi : from 1:m2624_4, from 2:m2628_4
|
||||
# 2630| r2630_2(glval<unknown>) = FunctionAddress[use_const_int] :
|
||||
# 2630| r2630_3(glval<int *>) = VariableAddress[data] :
|
||||
# 2630| r2630_4(int *) = Load[data] : &:r2630_3, m2630_1
|
||||
# 2630| r2630_5(int *) = Convert : r2630_4
|
||||
# 2630| v2630_6(void) = Call[use_const_int] : func:r2630_2, 0:r2630_5
|
||||
# 2630| m2630_7(unknown) = ^CallSideEffect : ~m2621_6
|
||||
# 2630| m2630_8(unknown) = Chi : total:m2621_6, partial:m2630_7
|
||||
# 2630| v2630_9(void) = ^BufferReadSideEffect[0] : &:r2630_5, ~m2630_8
|
||||
# 2631| v2631_1(void) = NoOp :
|
||||
# 2618| v2618_9(void) = ReturnVoid :
|
||||
# 2618| v2618_10(void) = AliasedUse : ~m2630_8
|
||||
# 2618| v2618_11(void) = ExitFunction :
|
||||
|
||||
# 2639| void needs_chi_for_initialize_groups()
|
||||
# 2639| Block 0
|
||||
# 2639| v2639_1(void) = EnterFunction :
|
||||
# 2639| m2639_2(unknown) = AliasedDefinition :
|
||||
# 2639| m2639_3(unknown) = InitializeNonLocal :
|
||||
# 2639| m2639_4(unknown) = Chi : total:m2639_2, partial:m2639_3
|
||||
# 2639| m2639_5(unknown) = UninitializedGroup :
|
||||
# 2639| m2639_6(unknown) = Chi : total:m2639_4, partial:m2639_5
|
||||
# 2639| m2639_7(unknown) = UninitializedGroup :
|
||||
# 2639| m2639_8(unknown) = Chi : total:m2639_6, partial:m2639_7
|
||||
# 2641| r2641_1(glval<unknown>) = FunctionAddress[predicateA] :
|
||||
# 2641| r2641_2(bool) = Call[predicateA] : func:r2641_1
|
||||
# 2641| m2641_3(unknown) = ^CallSideEffect : ~m2639_8
|
||||
# 2641| m2641_4(unknown) = Chi : total:m2639_8, partial:m2641_3
|
||||
# 2641| v2641_5(void) = ConditionalBranch : r2641_2
|
||||
#-----| False -> Block 4
|
||||
#-----| True -> Block 1
|
||||
|
||||
# 2643| Block 1
|
||||
# 2643| r2643_1(glval<long long *>) = VariableAddress[data] :
|
||||
# 2643| r2643_2(glval<unknown>) = FunctionAddress[malloc] :
|
||||
# 2643| r2643_3(unsigned long) = Constant[100] :
|
||||
# 2643| r2643_4(void *) = Call[malloc] : func:r2643_2, 0:r2643_3
|
||||
# 2643| m2643_5(unknown) = ^CallSideEffect : ~m2641_4
|
||||
# 2643| m2643_6(unknown) = Chi : total:m2641_4, partial:m2643_5
|
||||
# 2643| m2643_7(unknown) = ^InitializeDynamicAllocation : &:r2643_4
|
||||
# 2643| m2643_8(unknown) = Chi : total:m2643_6, partial:m2643_7
|
||||
# 2643| r2643_9(long long *) = Convert : r2643_4
|
||||
# 2643| m2643_10(long long *) = Store[data] : &:r2643_1, r2643_9
|
||||
# 2644| r2644_1(glval<long long *>) = VariableAddress[data] :
|
||||
# 2644| r2644_2(long long *) = Load[data] : &:r2644_1, m2643_10
|
||||
# 2644| r2644_3(void *) = Convert : r2644_2
|
||||
# 2644| r2644_4(void *) = Constant[0] :
|
||||
# 2644| r2644_5(bool) = CompareNE : r2644_3, r2644_4
|
||||
# 2644| v2644_6(void) = ConditionalBranch : r2644_5
|
||||
#-----| False -> Block 3
|
||||
#-----| True -> Block 2
|
||||
|
||||
# 2646| Block 2
|
||||
# 2646| r2646_1(glval<unknown>) = FunctionAddress[malloc] :
|
||||
# 2646| r2646_2(unsigned long) = Constant[100] :
|
||||
# 2646| r2646_3(void *) = Call[malloc] : func:r2646_1, 0:r2646_2
|
||||
# 2646| m2646_4(unknown) = ^CallSideEffect : ~m2643_8
|
||||
# 2646| m2646_5(unknown) = Chi : total:m2643_8, partial:m2646_4
|
||||
# 2646| m2646_6(unknown) = ^InitializeDynamicAllocation : &:r2646_3
|
||||
# 2646| m2646_7(unknown) = Chi : total:m2646_5, partial:m2646_6
|
||||
# 2646| r2646_8(long long *) = Convert : r2646_3
|
||||
# 2646| r2646_9(glval<long long *>) = VariableAddress[data] :
|
||||
# 2646| m2646_10(long long *) = Store[data] : &:r2646_9, r2646_8
|
||||
#-----| Goto -> Block 3
|
||||
|
||||
# 2648| Block 3
|
||||
# 2648| m2648_1(unknown) = Phi : from 1:~m2643_8, from 2:~m2646_7
|
||||
# 2648| m2648_2(long long *) = Phi : from 1:m2643_10, from 2:m2646_10
|
||||
# 2648| r2648_3(glval<unknown>) = FunctionAddress[use_const_void_pointer] :
|
||||
# 2648| r2648_4(glval<long long *>) = VariableAddress[data] :
|
||||
# 2648| r2648_5(long long *) = Load[data] : &:r2648_4, m2648_2
|
||||
# 2648| r2648_6(void *) = Convert : r2648_5
|
||||
# 2648| v2648_7(void) = Call[use_const_void_pointer] : func:r2648_3, 0:r2648_6
|
||||
# 2648| m2648_8(unknown) = ^CallSideEffect : ~m2648_1
|
||||
# 2648| m2648_9(unknown) = Chi : total:m2648_1, partial:m2648_8
|
||||
# 2648| v2648_10(void) = ^BufferReadSideEffect[0] : &:r2648_6, ~m2648_9
|
||||
#-----| Goto -> Block 7
|
||||
|
||||
# 2652| Block 4
|
||||
# 2652| r2652_1(glval<long long *>) = VariableAddress[data] :
|
||||
# 2652| r2652_2(glval<unknown>) = FunctionAddress[malloc] :
|
||||
# 2652| r2652_3(unsigned long) = Constant[100] :
|
||||
# 2652| r2652_4(void *) = Call[malloc] : func:r2652_2, 0:r2652_3
|
||||
# 2652| m2652_5(unknown) = ^CallSideEffect : ~m2641_4
|
||||
# 2652| m2652_6(unknown) = Chi : total:m2641_4, partial:m2652_5
|
||||
# 2652| m2652_7(unknown) = ^InitializeDynamicAllocation : &:r2652_4
|
||||
# 2652| m2652_8(unknown) = Chi : total:m2652_6, partial:m2652_7
|
||||
# 2652| r2652_9(long long *) = Convert : r2652_4
|
||||
# 2652| m2652_10(long long *) = Store[data] : &:r2652_1, r2652_9
|
||||
# 2653| r2653_1(glval<long long *>) = VariableAddress[data] :
|
||||
# 2653| r2653_2(long long *) = Load[data] : &:r2653_1, m2652_10
|
||||
# 2653| r2653_3(void *) = Convert : r2653_2
|
||||
# 2653| r2653_4(void *) = Constant[0] :
|
||||
# 2653| r2653_5(bool) = CompareNE : r2653_3, r2653_4
|
||||
# 2653| v2653_6(void) = ConditionalBranch : r2653_5
|
||||
#-----| False -> Block 6
|
||||
#-----| True -> Block 5
|
||||
|
||||
# 2655| Block 5
|
||||
# 2655| r2655_1(glval<unknown>) = FunctionAddress[malloc] :
|
||||
# 2655| r2655_2(unsigned long) = Constant[200] :
|
||||
# 2655| r2655_3(void *) = Call[malloc] : func:r2655_1, 0:r2655_2
|
||||
# 2655| m2655_4(unknown) = ^CallSideEffect : ~m2652_8
|
||||
# 2655| m2655_5(unknown) = Chi : total:m2652_8, partial:m2655_4
|
||||
# 2655| m2655_6(unknown) = ^InitializeDynamicAllocation : &:r2655_3
|
||||
# 2655| m2655_7(unknown) = Chi : total:m2655_5, partial:m2655_6
|
||||
# 2655| r2655_8(long long *) = Convert : r2655_3
|
||||
# 2655| r2655_9(glval<long long *>) = VariableAddress[data] :
|
||||
# 2655| m2655_10(long long *) = Store[data] : &:r2655_9, r2655_8
|
||||
#-----| Goto -> Block 6
|
||||
|
||||
# 2657| Block 6
|
||||
# 2657| m2657_1(unknown) = Phi : from 4:~m2652_8, from 5:~m2655_7
|
||||
# 2657| m2657_2(long long *) = Phi : from 4:m2652_10, from 5:m2655_10
|
||||
# 2657| r2657_3(glval<unknown>) = FunctionAddress[use_const_void_pointer] :
|
||||
# 2657| r2657_4(glval<long long *>) = VariableAddress[data] :
|
||||
# 2657| r2657_5(long long *) = Load[data] : &:r2657_4, m2657_2
|
||||
# 2657| r2657_6(void *) = Convert : r2657_5
|
||||
# 2657| v2657_7(void) = Call[use_const_void_pointer] : func:r2657_3, 0:r2657_6
|
||||
# 2657| m2657_8(unknown) = ^CallSideEffect : ~m2657_1
|
||||
# 2657| m2657_9(unknown) = Chi : total:m2657_1, partial:m2657_8
|
||||
# 2657| v2657_10(void) = ^BufferReadSideEffect[0] : &:r2657_6, ~m2657_9
|
||||
#-----| Goto -> Block 7
|
||||
|
||||
# 2659| Block 7
|
||||
# 2659| m2659_1(unknown) = Phi : from 3:~m2648_9, from 6:~m2657_9
|
||||
# 2659| v2659_2(void) = NoOp :
|
||||
# 2639| v2639_9(void) = ReturnVoid :
|
||||
# 2639| v2639_10(void) = AliasedUse : ~m2659_1
|
||||
# 2639| v2639_11(void) = ExitFunction :
|
||||
|
||||
# 2663| void phi_with_single_input_at_merge(bool)
|
||||
# 2663| Block 0
|
||||
# 2663| v2663_1(void) = EnterFunction :
|
||||
# 2663| m2663_2(unknown) = AliasedDefinition :
|
||||
# 2663| m2663_3(unknown) = InitializeNonLocal :
|
||||
# 2663| m2663_4(unknown) = Chi : total:m2663_2, partial:m2663_3
|
||||
# 2663| r2663_5(glval<bool>) = VariableAddress[b] :
|
||||
# 2663| m2663_6(bool) = InitializeParameter[b] : &:r2663_5
|
||||
# 2665| r2665_1(glval<int *>) = VariableAddress[data] :
|
||||
# 2665| r2665_2(int *) = Constant[0] :
|
||||
# 2665| m2665_3(int *) = Store[data] : &:r2665_1, r2665_2
|
||||
# 2666| r2666_1(glval<bool>) = VariableAddress[b] :
|
||||
# 2666| r2666_2(bool) = Load[b] : &:r2666_1, m2663_6
|
||||
# 2666| v2666_3(void) = ConditionalBranch : r2666_2
|
||||
#-----| False -> Block 2
|
||||
#-----| True -> Block 1
|
||||
|
||||
# 2667| Block 1
|
||||
# 2667| r2667_1(glval<int>) = VariableAddress[intBuffer] :
|
||||
# 2667| r2667_2(int) = Constant[8] :
|
||||
# 2667| m2667_3(int) = Store[intBuffer] : &:r2667_1, r2667_2
|
||||
# 2668| r2668_1(glval<int>) = VariableAddress[intBuffer] :
|
||||
# 2668| r2668_2(int *) = CopyValue : r2668_1
|
||||
# 2668| r2668_3(glval<int *>) = VariableAddress[data] :
|
||||
# 2668| m2668_4(int *) = Store[data] : &:r2668_3, r2668_2
|
||||
#-----| Goto -> Block 2
|
||||
|
||||
# 2670| Block 2
|
||||
# 2670| m2670_1(int) = Phi : from 1:m2667_3
|
||||
# 2670| m2670_2(int *) = Phi : from 0:m2665_3, from 1:m2668_4
|
||||
# 2670| r2670_3(glval<unknown>) = FunctionAddress[use_int] :
|
||||
# 2670| r2670_4(glval<int *>) = VariableAddress[data] :
|
||||
# 2670| r2670_5(int *) = Load[data] : &:r2670_4, m2670_2
|
||||
# 2670| r2670_6(int) = Load[?] : &:r2670_5, ~m2670_1
|
||||
# 2670| v2670_7(void) = Call[use_int] : func:r2670_3, 0:r2670_6
|
||||
# 2670| m2670_8(unknown) = ^CallSideEffect : ~m2663_4
|
||||
# 2670| m2670_9(unknown) = Chi : total:m2663_4, partial:m2670_8
|
||||
# 2671| v2671_1(void) = NoOp :
|
||||
# 2663| v2663_7(void) = ReturnVoid :
|
||||
# 2663| v2663_8(void) = AliasedUse : ~m2670_9
|
||||
# 2663| v2663_9(void) = ExitFunction :
|
||||
|
||||
# 2684| void test(bool)
|
||||
# 2684| Block 0
|
||||
# 2684| v2684_1(void) = EnterFunction :
|
||||
# 2684| m2684_2(unknown) = AliasedDefinition :
|
||||
# 2684| m2684_3(unknown) = InitializeNonLocal :
|
||||
# 2684| m2684_4(unknown) = Chi : total:m2684_2, partial:m2684_3
|
||||
# 2684| m2684_5(unknown) = UninitializedGroup[#string2686:22,#string2686:27] :
|
||||
# 2684| m2684_6(unknown) = Chi : total:m2684_4, partial:m2684_5
|
||||
# 2684| m2684_7(unknown) = UninitializedGroup[#string2686:22,#string2686:27] :
|
||||
# 2684| m2684_8(unknown) = Chi : total:m2684_6, partial:m2684_7
|
||||
# 2684| r2684_9(glval<bool>) = VariableAddress[b] :
|
||||
# 2684| m2684_10(bool) = InitializeParameter[b] : &:r2684_9
|
||||
# 2686| r2686_1(glval<unknown>) = FunctionAddress[use] :
|
||||
# 2686| r2686_2(glval<bool>) = VariableAddress[b] :
|
||||
# 2686| r2686_3(bool) = Load[b] : &:r2686_2, m2684_10
|
||||
# 2686| v2686_4(void) = ConditionalBranch : r2686_3
|
||||
#-----| False -> Block 3
|
||||
#-----| True -> Block 2
|
||||
|
||||
# 2686| Block 1
|
||||
# 2686| m2686_5(char *) = Phi : from 2:m2686_19, from 3:m2686_23
|
||||
# 2686| r2686_6(glval<char *>) = VariableAddress[#temp2686:18] :
|
||||
# 2686| r2686_7(char *) = Load[#temp2686:18] : &:r2686_6, m2686_5
|
||||
# 2686| v2686_8(void) = Call[use] : func:r2686_1, 0:r2686_7
|
||||
# 2686| m2686_9(unknown) = ^CallSideEffect : ~m2684_8
|
||||
# 2686| m2686_10(unknown) = Chi : total:m2684_8, partial:m2686_9
|
||||
# 2686| v2686_11(void) = ^BufferReadSideEffect[0] : &:r2686_7, ~m2686_10
|
||||
# 2686| r2686_12(glval<unknown>) = FunctionAddress[use] :
|
||||
# 2686| r2686_13(glval<bool>) = VariableAddress[b] :
|
||||
# 2686| r2686_14(bool) = Load[b] : &:r2686_13, m2684_10
|
||||
# 2686| v2686_15(void) = ConditionalBranch : r2686_14
|
||||
#-----| False -> Block 6
|
||||
#-----| True -> Block 5
|
||||
|
||||
# 2686| Block 2
|
||||
# 2686| r2686_16(glval<char[1]>) = StringConstant[] :
|
||||
# 2686| r2686_17(char *) = Convert : r2686_16
|
||||
# 2686| r2686_18(glval<char *>) = VariableAddress[#temp2686:18] :
|
||||
# 2686| m2686_19(char *) = Store[#temp2686:18] : &:r2686_18, r2686_17
|
||||
#-----| Goto -> Block 1
|
||||
|
||||
# 2686| Block 3
|
||||
# 2686| r2686_20(glval<char[1]>) = StringConstant[] :
|
||||
# 2686| r2686_21(char *) = Convert : r2686_20
|
||||
# 2686| r2686_22(glval<char *>) = VariableAddress[#temp2686:18] :
|
||||
# 2686| m2686_23(char *) = Store[#temp2686:18] : &:r2686_22, r2686_21
|
||||
#-----| Goto -> Block 1
|
||||
|
||||
# 2686| Block 4
|
||||
# 2686| m2686_24(char *) = Phi : from 5:m2686_36, from 6:m2686_40
|
||||
# 2686| r2686_25(glval<char *>) = VariableAddress[#temp2686:18] :
|
||||
# 2686| r2686_26(char *) = Load[#temp2686:18] : &:r2686_25, m2686_24
|
||||
# 2686| v2686_27(void) = Call[use] : func:r2686_12, 0:r2686_26
|
||||
# 2686| m2686_28(unknown) = ^CallSideEffect : ~m2686_10
|
||||
# 2686| m2686_29(unknown) = Chi : total:m2686_10, partial:m2686_28
|
||||
# 2686| v2686_30(void) = ^BufferReadSideEffect[0] : &:r2686_26, ~m2686_29
|
||||
# 2686| r2686_31(bool) = Constant[0] :
|
||||
# 2686| v2686_32(void) = ConditionalBranch : r2686_31
|
||||
#-----| False -> Block 7
|
||||
#-----| True -> Block 8
|
||||
|
||||
# 2686| Block 5
|
||||
# 2686| r2686_33(glval<char[1]>) = StringConstant[] :
|
||||
# 2686| r2686_34(char *) = Convert : r2686_33
|
||||
# 2686| r2686_35(glval<char *>) = VariableAddress[#temp2686:18] :
|
||||
# 2686| m2686_36(char *) = Store[#temp2686:18] : &:r2686_35, r2686_34
|
||||
#-----| Goto -> Block 4
|
||||
|
||||
# 2686| Block 6
|
||||
# 2686| r2686_37(glval<char[1]>) = StringConstant[] :
|
||||
# 2686| r2686_38(char *) = Convert : r2686_37
|
||||
# 2686| r2686_39(glval<char *>) = VariableAddress[#temp2686:18] :
|
||||
# 2686| m2686_40(char *) = Store[#temp2686:18] : &:r2686_39, r2686_38
|
||||
#-----| Goto -> Block 4
|
||||
|
||||
# 2687| Block 7
|
||||
# 2687| v2687_1(void) = NoOp :
|
||||
# 2684| v2684_11(void) = ReturnVoid :
|
||||
# 2684| v2684_12(void) = AliasedUse : ~m2686_29
|
||||
# 2684| v2684_13(void) = ExitFunction :
|
||||
|
||||
# 2684| Block 8
|
||||
# 2684| v2684_14(void) = Unreached :
|
||||
|
||||
perf-regression.cpp:
|
||||
# 6| void Big::Big()
|
||||
# 6| Block 0
|
||||
|
||||
@@ -2,6 +2,7 @@ missingOperand
|
||||
unexpectedOperand
|
||||
duplicateOperand
|
||||
missingPhiOperand
|
||||
| ir.cpp:2670:3:2670:9 | Phi: call to use_int | Instruction 'Phi: call to use_int' is missing an operand for predecessor block 'EnterFunction: phi_with_single_input_at_merge' in function '$@'. | ir.cpp:2663:13:2663:42 | void phi_with_single_input_at_merge(bool) | void phi_with_single_input_at_merge(bool) |
|
||||
missingOperandType
|
||||
duplicateChiOperand
|
||||
sideEffectWithoutPrimary
|
||||
|
||||
@@ -2,6 +2,7 @@ missingOperand
|
||||
unexpectedOperand
|
||||
duplicateOperand
|
||||
missingPhiOperand
|
||||
| ir.cpp:2670:3:2670:9 | Phi: call to use_int | Instruction 'Phi: call to use_int' is missing an operand for predecessor block 'EnterFunction: phi_with_single_input_at_merge' in function '$@'. | ir.cpp:2663:13:2663:42 | void phi_with_single_input_at_merge(bool) | void phi_with_single_input_at_merge(bool) |
|
||||
missingOperandType
|
||||
duplicateChiOperand
|
||||
sideEffectWithoutPrimary
|
||||
|
||||
@@ -2556,4 +2556,134 @@ void builtin_bitcast(unsigned long ul) {
|
||||
double d = __builtin_bit_cast(double, ul);
|
||||
}
|
||||
|
||||
void p_points_to_x_or_y(int a, int b) {
|
||||
int x;
|
||||
int y;
|
||||
int* p;
|
||||
if (a < b) {
|
||||
p = &x;
|
||||
} else {
|
||||
p = &y;
|
||||
}
|
||||
*p = 5;
|
||||
int z = x;
|
||||
int w = y;
|
||||
}
|
||||
|
||||
int phi_after_while() {
|
||||
int r;
|
||||
int *rP = &r;
|
||||
|
||||
while(predicateA()) {
|
||||
int s = 0;
|
||||
*rP = s;
|
||||
rP = &s;
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
// This testcase will loop infinitely if the analysis attempts to propagate
|
||||
// phi inputs with a non-unknown bit offset.
|
||||
char *recursive_conditional_call_with_increment(char *d, bool b)
|
||||
{
|
||||
if (b) {
|
||||
d = recursive_conditional_call_with_increment(d, b);
|
||||
}
|
||||
d++;
|
||||
return d;
|
||||
}
|
||||
|
||||
struct Recursive
|
||||
{
|
||||
Recursive *next;
|
||||
};
|
||||
|
||||
static Recursive *merge(Recursive *a)
|
||||
{
|
||||
Recursive *b;
|
||||
Recursive **p = &b;
|
||||
|
||||
while (predicateA())
|
||||
{
|
||||
*p = a;
|
||||
p = &a->next;
|
||||
}
|
||||
|
||||
return b;
|
||||
}
|
||||
|
||||
void use_const_int(const int*);
|
||||
|
||||
void escaping_pointer(bool b)
|
||||
{
|
||||
int *data;
|
||||
int l1, l2;
|
||||
if (b)
|
||||
{
|
||||
data = &l1;
|
||||
}
|
||||
else
|
||||
{
|
||||
data = &l2;
|
||||
}
|
||||
use_const_int(data);
|
||||
}
|
||||
|
||||
using int64_t = long long;
|
||||
#define NULL ((void *)0)
|
||||
|
||||
void *malloc(unsigned long);
|
||||
void use_const_void_pointer(const void *);
|
||||
|
||||
static void needs_chi_for_initialize_groups()
|
||||
{
|
||||
if (predicateA())
|
||||
{
|
||||
int64_t *data = (int64_t *)malloc(100);
|
||||
if (data != NULL)
|
||||
{
|
||||
data = (int64_t *)malloc(100);
|
||||
}
|
||||
use_const_void_pointer(data);
|
||||
}
|
||||
else
|
||||
{
|
||||
int64_t *data = (int64_t *)malloc(100);
|
||||
if (data != NULL)
|
||||
{
|
||||
data = (int64_t *)malloc(200);
|
||||
}
|
||||
use_const_void_pointer(data);
|
||||
}
|
||||
}
|
||||
|
||||
void use_int(int);
|
||||
|
||||
static void phi_with_single_input_at_merge(bool b)
|
||||
{
|
||||
int *data = nullptr;
|
||||
if(b) {
|
||||
int intBuffer = 8;
|
||||
data = &intBuffer;
|
||||
}
|
||||
use_int(*data);
|
||||
}
|
||||
|
||||
void use(const char *fmt);
|
||||
|
||||
#define call_use(format) use(format)
|
||||
|
||||
#define twice_call_use(format) \
|
||||
do \
|
||||
{ \
|
||||
call_use(format); \
|
||||
call_use(format); \
|
||||
} while (0)
|
||||
|
||||
void test(bool b)
|
||||
{
|
||||
twice_call_use(b ? "" : "");
|
||||
}
|
||||
|
||||
// semmle-extractor-options: -std=c++20 --clang
|
||||
|
||||
@@ -16734,6 +16734,463 @@ ir.cpp:
|
||||
# 2555| v2555_7(void) = AliasedUse : ~m?
|
||||
# 2555| v2555_8(void) = ExitFunction :
|
||||
|
||||
# 2559| void p_points_to_x_or_y(int, int)
|
||||
# 2559| Block 0
|
||||
# 2559| v2559_1(void) = EnterFunction :
|
||||
# 2559| mu2559_2(unknown) = AliasedDefinition :
|
||||
# 2559| mu2559_3(unknown) = InitializeNonLocal :
|
||||
# 2559| r2559_4(glval<int>) = VariableAddress[a] :
|
||||
# 2559| mu2559_5(int) = InitializeParameter[a] : &:r2559_4
|
||||
# 2559| r2559_6(glval<int>) = VariableAddress[b] :
|
||||
# 2559| mu2559_7(int) = InitializeParameter[b] : &:r2559_6
|
||||
# 2560| r2560_1(glval<int>) = VariableAddress[x] :
|
||||
# 2560| mu2560_2(int) = Uninitialized[x] : &:r2560_1
|
||||
# 2561| r2561_1(glval<int>) = VariableAddress[y] :
|
||||
# 2561| mu2561_2(int) = Uninitialized[y] : &:r2561_1
|
||||
# 2562| r2562_1(glval<int *>) = VariableAddress[p] :
|
||||
# 2562| mu2562_2(int *) = Uninitialized[p] : &:r2562_1
|
||||
# 2563| r2563_1(glval<int>) = VariableAddress[a] :
|
||||
# 2563| r2563_2(int) = Load[a] : &:r2563_1, ~m?
|
||||
# 2563| r2563_3(glval<int>) = VariableAddress[b] :
|
||||
# 2563| r2563_4(int) = Load[b] : &:r2563_3, ~m?
|
||||
# 2563| r2563_5(bool) = CompareLT : r2563_2, r2563_4
|
||||
# 2563| v2563_6(void) = ConditionalBranch : r2563_5
|
||||
#-----| False -> Block 2
|
||||
#-----| True -> Block 1
|
||||
|
||||
# 2564| Block 1
|
||||
# 2564| r2564_1(glval<int>) = VariableAddress[x] :
|
||||
# 2564| r2564_2(int *) = CopyValue : r2564_1
|
||||
# 2564| r2564_3(glval<int *>) = VariableAddress[p] :
|
||||
# 2564| mu2564_4(int *) = Store[p] : &:r2564_3, r2564_2
|
||||
#-----| Goto -> Block 3
|
||||
|
||||
# 2566| Block 2
|
||||
# 2566| r2566_1(glval<int>) = VariableAddress[y] :
|
||||
# 2566| r2566_2(int *) = CopyValue : r2566_1
|
||||
# 2566| r2566_3(glval<int *>) = VariableAddress[p] :
|
||||
# 2566| mu2566_4(int *) = Store[p] : &:r2566_3, r2566_2
|
||||
#-----| Goto -> Block 3
|
||||
|
||||
# 2568| Block 3
|
||||
# 2568| r2568_1(int) = Constant[5] :
|
||||
# 2568| r2568_2(glval<int *>) = VariableAddress[p] :
|
||||
# 2568| r2568_3(int *) = Load[p] : &:r2568_2, ~m?
|
||||
# 2568| r2568_4(glval<int>) = CopyValue : r2568_3
|
||||
# 2568| mu2568_5(int) = Store[?] : &:r2568_4, r2568_1
|
||||
# 2569| r2569_1(glval<int>) = VariableAddress[z] :
|
||||
# 2569| r2569_2(glval<int>) = VariableAddress[x] :
|
||||
# 2569| r2569_3(int) = Load[x] : &:r2569_2, ~m?
|
||||
# 2569| mu2569_4(int) = Store[z] : &:r2569_1, r2569_3
|
||||
# 2570| r2570_1(glval<int>) = VariableAddress[w] :
|
||||
# 2570| r2570_2(glval<int>) = VariableAddress[y] :
|
||||
# 2570| r2570_3(int) = Load[y] : &:r2570_2, ~m?
|
||||
# 2570| mu2570_4(int) = Store[w] : &:r2570_1, r2570_3
|
||||
# 2571| v2571_1(void) = NoOp :
|
||||
# 2559| v2559_8(void) = ReturnVoid :
|
||||
# 2559| v2559_9(void) = AliasedUse : ~m?
|
||||
# 2559| v2559_10(void) = ExitFunction :
|
||||
|
||||
# 2573| int phi_after_while()
|
||||
# 2573| Block 0
|
||||
# 2573| v2573_1(void) = EnterFunction :
|
||||
# 2573| mu2573_2(unknown) = AliasedDefinition :
|
||||
# 2573| mu2573_3(unknown) = InitializeNonLocal :
|
||||
# 2574| r2574_1(glval<int>) = VariableAddress[r] :
|
||||
# 2574| mu2574_2(int) = Uninitialized[r] : &:r2574_1
|
||||
# 2575| r2575_1(glval<int *>) = VariableAddress[rP] :
|
||||
# 2575| r2575_2(glval<int>) = VariableAddress[r] :
|
||||
# 2575| r2575_3(int *) = CopyValue : r2575_2
|
||||
# 2575| mu2575_4(int *) = Store[rP] : &:r2575_1, r2575_3
|
||||
#-----| Goto -> Block 1
|
||||
|
||||
# 2577| Block 1
|
||||
# 2577| r2577_1(glval<unknown>) = FunctionAddress[predicateA] :
|
||||
# 2577| r2577_2(bool) = Call[predicateA] : func:r2577_1
|
||||
# 2577| mu2577_3(unknown) = ^CallSideEffect : ~m?
|
||||
# 2577| v2577_4(void) = ConditionalBranch : r2577_2
|
||||
#-----| False -> Block 3
|
||||
#-----| True -> Block 2
|
||||
|
||||
# 2578| Block 2
|
||||
# 2578| r2578_1(glval<int>) = VariableAddress[s] :
|
||||
# 2578| r2578_2(int) = Constant[0] :
|
||||
# 2578| mu2578_3(int) = Store[s] : &:r2578_1, r2578_2
|
||||
# 2579| r2579_1(glval<int>) = VariableAddress[s] :
|
||||
# 2579| r2579_2(int) = Load[s] : &:r2579_1, ~m?
|
||||
# 2579| r2579_3(glval<int *>) = VariableAddress[rP] :
|
||||
# 2579| r2579_4(int *) = Load[rP] : &:r2579_3, ~m?
|
||||
# 2579| r2579_5(glval<int>) = CopyValue : r2579_4
|
||||
# 2579| mu2579_6(int) = Store[?] : &:r2579_5, r2579_2
|
||||
# 2580| r2580_1(glval<int>) = VariableAddress[s] :
|
||||
# 2580| r2580_2(int *) = CopyValue : r2580_1
|
||||
# 2580| r2580_3(glval<int *>) = VariableAddress[rP] :
|
||||
# 2580| mu2580_4(int *) = Store[rP] : &:r2580_3, r2580_2
|
||||
#-----| Goto (back edge) -> Block 1
|
||||
|
||||
# 2583| Block 3
|
||||
# 2583| r2583_1(glval<int>) = VariableAddress[#return] :
|
||||
# 2583| r2583_2(glval<int>) = VariableAddress[r] :
|
||||
# 2583| r2583_3(int) = Load[r] : &:r2583_2, ~m?
|
||||
# 2583| mu2583_4(int) = Store[#return] : &:r2583_1, r2583_3
|
||||
# 2573| r2573_4(glval<int>) = VariableAddress[#return] :
|
||||
# 2573| v2573_5(void) = ReturnValue : &:r2573_4, ~m?
|
||||
# 2573| v2573_6(void) = AliasedUse : ~m?
|
||||
# 2573| v2573_7(void) = ExitFunction :
|
||||
|
||||
# 2588| char* recursive_conditional_call_with_increment(char*, bool)
|
||||
# 2588| Block 0
|
||||
# 2588| v2588_1(void) = EnterFunction :
|
||||
# 2588| mu2588_2(unknown) = AliasedDefinition :
|
||||
# 2588| mu2588_3(unknown) = InitializeNonLocal :
|
||||
# 2588| r2588_4(glval<char *>) = VariableAddress[d] :
|
||||
# 2588| mu2588_5(char *) = InitializeParameter[d] : &:r2588_4
|
||||
# 2588| r2588_6(char *) = Load[d] : &:r2588_4, ~m?
|
||||
# 2588| mu2588_7(unknown) = InitializeIndirection[d] : &:r2588_6
|
||||
# 2588| r2588_8(glval<bool>) = VariableAddress[b] :
|
||||
# 2588| mu2588_9(bool) = InitializeParameter[b] : &:r2588_8
|
||||
# 2590| r2590_1(glval<bool>) = VariableAddress[b] :
|
||||
# 2590| r2590_2(bool) = Load[b] : &:r2590_1, ~m?
|
||||
# 2590| v2590_3(void) = ConditionalBranch : r2590_2
|
||||
#-----| False -> Block 2
|
||||
#-----| True -> Block 1
|
||||
|
||||
# 2591| Block 1
|
||||
# 2591| r2591_1(glval<unknown>) = FunctionAddress[recursive_conditional_call_with_increment] :
|
||||
# 2591| r2591_2(glval<char *>) = VariableAddress[d] :
|
||||
# 2591| r2591_3(char *) = Load[d] : &:r2591_2, ~m?
|
||||
# 2591| r2591_4(glval<bool>) = VariableAddress[b] :
|
||||
# 2591| r2591_5(bool) = Load[b] : &:r2591_4, ~m?
|
||||
# 2591| r2591_6(char *) = Call[recursive_conditional_call_with_increment] : func:r2591_1, 0:r2591_3, 1:r2591_5
|
||||
# 2591| mu2591_7(unknown) = ^CallSideEffect : ~m?
|
||||
# 2591| v2591_8(void) = ^BufferReadSideEffect[0] : &:r2591_3, ~m?
|
||||
# 2591| mu2591_9(unknown) = ^BufferMayWriteSideEffect[0] : &:r2591_3
|
||||
# 2591| r2591_10(glval<char *>) = VariableAddress[d] :
|
||||
# 2591| mu2591_11(char *) = Store[d] : &:r2591_10, r2591_6
|
||||
#-----| Goto -> Block 2
|
||||
|
||||
# 2593| Block 2
|
||||
# 2593| r2593_1(glval<char *>) = VariableAddress[d] :
|
||||
# 2593| r2593_2(char *) = Load[d] : &:r2593_1, ~m?
|
||||
# 2593| r2593_3(int) = Constant[1] :
|
||||
# 2593| r2593_4(char *) = PointerAdd[1] : r2593_2, r2593_3
|
||||
# 2593| mu2593_5(char *) = Store[d] : &:r2593_1, r2593_4
|
||||
# 2594| r2594_1(glval<char *>) = VariableAddress[#return] :
|
||||
# 2594| r2594_2(glval<char *>) = VariableAddress[d] :
|
||||
# 2594| r2594_3(char *) = Load[d] : &:r2594_2, ~m?
|
||||
# 2594| mu2594_4(char *) = Store[#return] : &:r2594_1, r2594_3
|
||||
# 2588| v2588_10(void) = ReturnIndirection[d] : &:r2588_6, ~m?
|
||||
# 2588| r2588_11(glval<char *>) = VariableAddress[#return] :
|
||||
# 2588| v2588_12(void) = ReturnValue : &:r2588_11, ~m?
|
||||
# 2588| v2588_13(void) = AliasedUse : ~m?
|
||||
# 2588| v2588_14(void) = ExitFunction :
|
||||
|
||||
# 2602| Recursive* merge(Recursive*)
|
||||
# 2602| Block 0
|
||||
# 2602| v2602_1(void) = EnterFunction :
|
||||
# 2602| mu2602_2(unknown) = AliasedDefinition :
|
||||
# 2602| mu2602_3(unknown) = InitializeNonLocal :
|
||||
# 2602| r2602_4(glval<Recursive *>) = VariableAddress[a] :
|
||||
# 2602| mu2602_5(Recursive *) = InitializeParameter[a] : &:r2602_4
|
||||
# 2602| r2602_6(Recursive *) = Load[a] : &:r2602_4, ~m?
|
||||
# 2602| mu2602_7(unknown) = InitializeIndirection[a] : &:r2602_6
|
||||
# 2604| r2604_1(glval<Recursive *>) = VariableAddress[b] :
|
||||
# 2604| mu2604_2(Recursive *) = Uninitialized[b] : &:r2604_1
|
||||
# 2605| r2605_1(glval<Recursive **>) = VariableAddress[p] :
|
||||
# 2605| r2605_2(glval<Recursive *>) = VariableAddress[b] :
|
||||
# 2605| r2605_3(Recursive **) = CopyValue : r2605_2
|
||||
# 2605| mu2605_4(Recursive **) = Store[p] : &:r2605_1, r2605_3
|
||||
#-----| Goto -> Block 1
|
||||
|
||||
# 2607| Block 1
|
||||
# 2607| r2607_1(glval<unknown>) = FunctionAddress[predicateA] :
|
||||
# 2607| r2607_2(bool) = Call[predicateA] : func:r2607_1
|
||||
# 2607| mu2607_3(unknown) = ^CallSideEffect : ~m?
|
||||
# 2607| v2607_4(void) = ConditionalBranch : r2607_2
|
||||
#-----| False -> Block 3
|
||||
#-----| True -> Block 2
|
||||
|
||||
# 2609| Block 2
|
||||
# 2609| r2609_1(glval<Recursive *>) = VariableAddress[a] :
|
||||
# 2609| r2609_2(Recursive *) = Load[a] : &:r2609_1, ~m?
|
||||
# 2609| r2609_3(glval<Recursive **>) = VariableAddress[p] :
|
||||
# 2609| r2609_4(Recursive **) = Load[p] : &:r2609_3, ~m?
|
||||
# 2609| r2609_5(glval<Recursive *>) = CopyValue : r2609_4
|
||||
# 2609| mu2609_6(Recursive *) = Store[?] : &:r2609_5, r2609_2
|
||||
# 2610| r2610_1(glval<Recursive *>) = VariableAddress[a] :
|
||||
# 2610| r2610_2(Recursive *) = Load[a] : &:r2610_1, ~m?
|
||||
# 2610| r2610_3(glval<Recursive *>) = FieldAddress[next] : r2610_2
|
||||
# 2610| r2610_4(Recursive **) = CopyValue : r2610_3
|
||||
# 2610| r2610_5(glval<Recursive **>) = VariableAddress[p] :
|
||||
# 2610| mu2610_6(Recursive **) = Store[p] : &:r2610_5, r2610_4
|
||||
#-----| Goto (back edge) -> Block 1
|
||||
|
||||
# 2613| Block 3
|
||||
# 2613| r2613_1(glval<Recursive *>) = VariableAddress[#return] :
|
||||
# 2613| r2613_2(glval<Recursive *>) = VariableAddress[b] :
|
||||
# 2613| r2613_3(Recursive *) = Load[b] : &:r2613_2, ~m?
|
||||
# 2613| mu2613_4(Recursive *) = Store[#return] : &:r2613_1, r2613_3
|
||||
# 2602| v2602_8(void) = ReturnIndirection[a] : &:r2602_6, ~m?
|
||||
# 2602| r2602_9(glval<Recursive *>) = VariableAddress[#return] :
|
||||
# 2602| v2602_10(void) = ReturnValue : &:r2602_9, ~m?
|
||||
# 2602| v2602_11(void) = AliasedUse : ~m?
|
||||
# 2602| v2602_12(void) = ExitFunction :
|
||||
|
||||
# 2618| void escaping_pointer(bool)
|
||||
# 2618| Block 0
|
||||
# 2618| v2618_1(void) = EnterFunction :
|
||||
# 2618| mu2618_2(unknown) = AliasedDefinition :
|
||||
# 2618| mu2618_3(unknown) = InitializeNonLocal :
|
||||
# 2618| r2618_4(glval<bool>) = VariableAddress[b] :
|
||||
# 2618| mu2618_5(bool) = InitializeParameter[b] : &:r2618_4
|
||||
# 2620| r2620_1(glval<int *>) = VariableAddress[data] :
|
||||
# 2620| mu2620_2(int *) = Uninitialized[data] : &:r2620_1
|
||||
# 2621| r2621_1(glval<int>) = VariableAddress[l1] :
|
||||
# 2621| mu2621_2(int) = Uninitialized[l1] : &:r2621_1
|
||||
# 2621| r2621_3(glval<int>) = VariableAddress[l2] :
|
||||
# 2621| mu2621_4(int) = Uninitialized[l2] : &:r2621_3
|
||||
# 2622| r2622_1(glval<bool>) = VariableAddress[b] :
|
||||
# 2622| r2622_2(bool) = Load[b] : &:r2622_1, ~m?
|
||||
# 2622| v2622_3(void) = ConditionalBranch : r2622_2
|
||||
#-----| False -> Block 2
|
||||
#-----| True -> Block 1
|
||||
|
||||
# 2624| Block 1
|
||||
# 2624| r2624_1(glval<int>) = VariableAddress[l1] :
|
||||
# 2624| r2624_2(int *) = CopyValue : r2624_1
|
||||
# 2624| r2624_3(glval<int *>) = VariableAddress[data] :
|
||||
# 2624| mu2624_4(int *) = Store[data] : &:r2624_3, r2624_2
|
||||
#-----| Goto -> Block 3
|
||||
|
||||
# 2628| Block 2
|
||||
# 2628| r2628_1(glval<int>) = VariableAddress[l2] :
|
||||
# 2628| r2628_2(int *) = CopyValue : r2628_1
|
||||
# 2628| r2628_3(glval<int *>) = VariableAddress[data] :
|
||||
# 2628| mu2628_4(int *) = Store[data] : &:r2628_3, r2628_2
|
||||
#-----| Goto -> Block 3
|
||||
|
||||
# 2630| Block 3
|
||||
# 2630| r2630_1(glval<unknown>) = FunctionAddress[use_const_int] :
|
||||
# 2630| r2630_2(glval<int *>) = VariableAddress[data] :
|
||||
# 2630| r2630_3(int *) = Load[data] : &:r2630_2, ~m?
|
||||
# 2630| r2630_4(int *) = Convert : r2630_3
|
||||
# 2630| v2630_5(void) = Call[use_const_int] : func:r2630_1, 0:r2630_4
|
||||
# 2630| mu2630_6(unknown) = ^CallSideEffect : ~m?
|
||||
# 2630| v2630_7(void) = ^BufferReadSideEffect[0] : &:r2630_4, ~m?
|
||||
# 2631| v2631_1(void) = NoOp :
|
||||
# 2618| v2618_6(void) = ReturnVoid :
|
||||
# 2618| v2618_7(void) = AliasedUse : ~m?
|
||||
# 2618| v2618_8(void) = ExitFunction :
|
||||
|
||||
# 2639| void needs_chi_for_initialize_groups()
|
||||
# 2639| Block 0
|
||||
# 2639| v2639_1(void) = EnterFunction :
|
||||
# 2639| mu2639_2(unknown) = AliasedDefinition :
|
||||
# 2639| mu2639_3(unknown) = InitializeNonLocal :
|
||||
# 2641| r2641_1(glval<unknown>) = FunctionAddress[predicateA] :
|
||||
# 2641| r2641_2(bool) = Call[predicateA] : func:r2641_1
|
||||
# 2641| mu2641_3(unknown) = ^CallSideEffect : ~m?
|
||||
# 2641| v2641_4(void) = ConditionalBranch : r2641_2
|
||||
#-----| False -> Block 4
|
||||
#-----| True -> Block 1
|
||||
|
||||
# 2643| Block 1
|
||||
# 2643| r2643_1(glval<long long *>) = VariableAddress[data] :
|
||||
# 2643| r2643_2(glval<unknown>) = FunctionAddress[malloc] :
|
||||
# 2643| r2643_3(unsigned long) = Constant[100] :
|
||||
# 2643| r2643_4(void *) = Call[malloc] : func:r2643_2, 0:r2643_3
|
||||
# 2643| mu2643_5(unknown) = ^CallSideEffect : ~m?
|
||||
# 2643| mu2643_6(unknown) = ^InitializeDynamicAllocation : &:r2643_4
|
||||
# 2643| r2643_7(long long *) = Convert : r2643_4
|
||||
# 2643| mu2643_8(long long *) = Store[data] : &:r2643_1, r2643_7
|
||||
# 2644| r2644_1(glval<long long *>) = VariableAddress[data] :
|
||||
# 2644| r2644_2(long long *) = Load[data] : &:r2644_1, ~m?
|
||||
# 2644| r2644_3(void *) = Convert : r2644_2
|
||||
# 2644| r2644_4(void *) = Constant[0] :
|
||||
# 2644| r2644_5(bool) = CompareNE : r2644_3, r2644_4
|
||||
# 2644| v2644_6(void) = ConditionalBranch : r2644_5
|
||||
#-----| False -> Block 3
|
||||
#-----| True -> Block 2
|
||||
|
||||
# 2646| Block 2
|
||||
# 2646| r2646_1(glval<unknown>) = FunctionAddress[malloc] :
|
||||
# 2646| r2646_2(unsigned long) = Constant[100] :
|
||||
# 2646| r2646_3(void *) = Call[malloc] : func:r2646_1, 0:r2646_2
|
||||
# 2646| mu2646_4(unknown) = ^CallSideEffect : ~m?
|
||||
# 2646| mu2646_5(unknown) = ^InitializeDynamicAllocation : &:r2646_3
|
||||
# 2646| r2646_6(long long *) = Convert : r2646_3
|
||||
# 2646| r2646_7(glval<long long *>) = VariableAddress[data] :
|
||||
# 2646| mu2646_8(long long *) = Store[data] : &:r2646_7, r2646_6
|
||||
#-----| Goto -> Block 3
|
||||
|
||||
# 2648| Block 3
|
||||
# 2648| r2648_1(glval<unknown>) = FunctionAddress[use_const_void_pointer] :
|
||||
# 2648| r2648_2(glval<long long *>) = VariableAddress[data] :
|
||||
# 2648| r2648_3(long long *) = Load[data] : &:r2648_2, ~m?
|
||||
# 2648| r2648_4(void *) = Convert : r2648_3
|
||||
# 2648| v2648_5(void) = Call[use_const_void_pointer] : func:r2648_1, 0:r2648_4
|
||||
# 2648| mu2648_6(unknown) = ^CallSideEffect : ~m?
|
||||
# 2648| v2648_7(void) = ^BufferReadSideEffect[0] : &:r2648_4, ~m?
|
||||
#-----| Goto -> Block 7
|
||||
|
||||
# 2652| Block 4
|
||||
# 2652| r2652_1(glval<long long *>) = VariableAddress[data] :
|
||||
# 2652| r2652_2(glval<unknown>) = FunctionAddress[malloc] :
|
||||
# 2652| r2652_3(unsigned long) = Constant[100] :
|
||||
# 2652| r2652_4(void *) = Call[malloc] : func:r2652_2, 0:r2652_3
|
||||
# 2652| mu2652_5(unknown) = ^CallSideEffect : ~m?
|
||||
# 2652| mu2652_6(unknown) = ^InitializeDynamicAllocation : &:r2652_4
|
||||
# 2652| r2652_7(long long *) = Convert : r2652_4
|
||||
# 2652| mu2652_8(long long *) = Store[data] : &:r2652_1, r2652_7
|
||||
# 2653| r2653_1(glval<long long *>) = VariableAddress[data] :
|
||||
# 2653| r2653_2(long long *) = Load[data] : &:r2653_1, ~m?
|
||||
# 2653| r2653_3(void *) = Convert : r2653_2
|
||||
# 2653| r2653_4(void *) = Constant[0] :
|
||||
# 2653| r2653_5(bool) = CompareNE : r2653_3, r2653_4
|
||||
# 2653| v2653_6(void) = ConditionalBranch : r2653_5
|
||||
#-----| False -> Block 6
|
||||
#-----| True -> Block 5
|
||||
|
||||
# 2655| Block 5
|
||||
# 2655| r2655_1(glval<unknown>) = FunctionAddress[malloc] :
|
||||
# 2655| r2655_2(unsigned long) = Constant[200] :
|
||||
# 2655| r2655_3(void *) = Call[malloc] : func:r2655_1, 0:r2655_2
|
||||
# 2655| mu2655_4(unknown) = ^CallSideEffect : ~m?
|
||||
# 2655| mu2655_5(unknown) = ^InitializeDynamicAllocation : &:r2655_3
|
||||
# 2655| r2655_6(long long *) = Convert : r2655_3
|
||||
# 2655| r2655_7(glval<long long *>) = VariableAddress[data] :
|
||||
# 2655| mu2655_8(long long *) = Store[data] : &:r2655_7, r2655_6
|
||||
#-----| Goto -> Block 6
|
||||
|
||||
# 2657| Block 6
|
||||
# 2657| r2657_1(glval<unknown>) = FunctionAddress[use_const_void_pointer] :
|
||||
# 2657| r2657_2(glval<long long *>) = VariableAddress[data] :
|
||||
# 2657| r2657_3(long long *) = Load[data] : &:r2657_2, ~m?
|
||||
# 2657| r2657_4(void *) = Convert : r2657_3
|
||||
# 2657| v2657_5(void) = Call[use_const_void_pointer] : func:r2657_1, 0:r2657_4
|
||||
# 2657| mu2657_6(unknown) = ^CallSideEffect : ~m?
|
||||
# 2657| v2657_7(void) = ^BufferReadSideEffect[0] : &:r2657_4, ~m?
|
||||
#-----| Goto -> Block 7
|
||||
|
||||
# 2659| Block 7
|
||||
# 2659| v2659_1(void) = NoOp :
|
||||
# 2639| v2639_4(void) = ReturnVoid :
|
||||
# 2639| v2639_5(void) = AliasedUse : ~m?
|
||||
# 2639| v2639_6(void) = ExitFunction :
|
||||
|
||||
# 2663| void phi_with_single_input_at_merge(bool)
|
||||
# 2663| Block 0
|
||||
# 2663| v2663_1(void) = EnterFunction :
|
||||
# 2663| mu2663_2(unknown) = AliasedDefinition :
|
||||
# 2663| mu2663_3(unknown) = InitializeNonLocal :
|
||||
# 2663| r2663_4(glval<bool>) = VariableAddress[b] :
|
||||
# 2663| mu2663_5(bool) = InitializeParameter[b] : &:r2663_4
|
||||
# 2665| r2665_1(glval<int *>) = VariableAddress[data] :
|
||||
# 2665| r2665_2(int *) = Constant[0] :
|
||||
# 2665| mu2665_3(int *) = Store[data] : &:r2665_1, r2665_2
|
||||
# 2666| r2666_1(glval<bool>) = VariableAddress[b] :
|
||||
# 2666| r2666_2(bool) = Load[b] : &:r2666_1, ~m?
|
||||
# 2666| v2666_3(void) = ConditionalBranch : r2666_2
|
||||
#-----| False -> Block 2
|
||||
#-----| True -> Block 1
|
||||
|
||||
# 2667| Block 1
|
||||
# 2667| r2667_1(glval<int>) = VariableAddress[intBuffer] :
|
||||
# 2667| r2667_2(int) = Constant[8] :
|
||||
# 2667| mu2667_3(int) = Store[intBuffer] : &:r2667_1, r2667_2
|
||||
# 2668| r2668_1(glval<int>) = VariableAddress[intBuffer] :
|
||||
# 2668| r2668_2(int *) = CopyValue : r2668_1
|
||||
# 2668| r2668_3(glval<int *>) = VariableAddress[data] :
|
||||
# 2668| mu2668_4(int *) = Store[data] : &:r2668_3, r2668_2
|
||||
#-----| Goto -> Block 2
|
||||
|
||||
# 2670| Block 2
|
||||
# 2670| r2670_1(glval<unknown>) = FunctionAddress[use_int] :
|
||||
# 2670| r2670_2(glval<int *>) = VariableAddress[data] :
|
||||
# 2670| r2670_3(int *) = Load[data] : &:r2670_2, ~m?
|
||||
# 2670| r2670_4(int) = Load[?] : &:r2670_3, ~m?
|
||||
# 2670| v2670_5(void) = Call[use_int] : func:r2670_1, 0:r2670_4
|
||||
# 2670| mu2670_6(unknown) = ^CallSideEffect : ~m?
|
||||
# 2671| v2671_1(void) = NoOp :
|
||||
# 2663| v2663_6(void) = ReturnVoid :
|
||||
# 2663| v2663_7(void) = AliasedUse : ~m?
|
||||
# 2663| v2663_8(void) = ExitFunction :
|
||||
|
||||
# 2684| void test(bool)
|
||||
# 2684| Block 0
|
||||
# 2684| v2684_1(void) = EnterFunction :
|
||||
# 2684| mu2684_2(unknown) = AliasedDefinition :
|
||||
# 2684| mu2684_3(unknown) = InitializeNonLocal :
|
||||
# 2684| r2684_4(glval<bool>) = VariableAddress[b] :
|
||||
# 2684| mu2684_5(bool) = InitializeParameter[b] : &:r2684_4
|
||||
#-----| Goto -> Block 1
|
||||
|
||||
# 2686| Block 1
|
||||
# 2686| r2686_1(glval<unknown>) = FunctionAddress[use] :
|
||||
# 2686| r2686_2(glval<bool>) = VariableAddress[b] :
|
||||
# 2686| r2686_3(bool) = Load[b] : &:r2686_2, ~m?
|
||||
# 2686| v2686_4(void) = ConditionalBranch : r2686_3
|
||||
#-----| False -> Block 4
|
||||
#-----| True -> Block 3
|
||||
|
||||
# 2686| Block 2
|
||||
# 2686| r2686_5(glval<char *>) = VariableAddress[#temp2686:18] :
|
||||
# 2686| r2686_6(char *) = Load[#temp2686:18] : &:r2686_5, ~m?
|
||||
# 2686| v2686_7(void) = Call[use] : func:r2686_1, 0:r2686_6
|
||||
# 2686| mu2686_8(unknown) = ^CallSideEffect : ~m?
|
||||
# 2686| v2686_9(void) = ^BufferReadSideEffect[0] : &:r2686_6, ~m?
|
||||
# 2686| r2686_10(glval<unknown>) = FunctionAddress[use] :
|
||||
# 2686| r2686_11(glval<bool>) = VariableAddress[b] :
|
||||
# 2686| r2686_12(bool) = Load[b] : &:r2686_11, ~m?
|
||||
# 2686| v2686_13(void) = ConditionalBranch : r2686_12
|
||||
#-----| False -> Block 7
|
||||
#-----| True -> Block 6
|
||||
|
||||
# 2686| Block 3
|
||||
# 2686| r2686_14(glval<char[1]>) = StringConstant[] :
|
||||
# 2686| r2686_15(char *) = Convert : r2686_14
|
||||
# 2686| r2686_16(glval<char *>) = VariableAddress[#temp2686:18] :
|
||||
# 2686| mu2686_17(char *) = Store[#temp2686:18] : &:r2686_16, r2686_15
|
||||
#-----| Goto -> Block 2
|
||||
|
||||
# 2686| Block 4
|
||||
# 2686| r2686_18(glval<char[1]>) = StringConstant[] :
|
||||
# 2686| r2686_19(char *) = Convert : r2686_18
|
||||
# 2686| r2686_20(glval<char *>) = VariableAddress[#temp2686:18] :
|
||||
# 2686| mu2686_21(char *) = Store[#temp2686:18] : &:r2686_20, r2686_19
|
||||
#-----| Goto -> Block 2
|
||||
|
||||
# 2686| Block 5
|
||||
# 2686| r2686_22(glval<char *>) = VariableAddress[#temp2686:18] :
|
||||
# 2686| r2686_23(char *) = Load[#temp2686:18] : &:r2686_22, ~m?
|
||||
# 2686| v2686_24(void) = Call[use] : func:r2686_10, 0:r2686_23
|
||||
# 2686| mu2686_25(unknown) = ^CallSideEffect : ~m?
|
||||
# 2686| v2686_26(void) = ^BufferReadSideEffect[0] : &:r2686_23, ~m?
|
||||
# 2686| r2686_27(bool) = Constant[0] :
|
||||
# 2686| v2686_28(void) = ConditionalBranch : r2686_27
|
||||
#-----| False -> Block 8
|
||||
#-----| True (back edge) -> Block 1
|
||||
|
||||
# 2686| Block 6
|
||||
# 2686| r2686_29(glval<char[1]>) = StringConstant[] :
|
||||
# 2686| r2686_30(char *) = Convert : r2686_29
|
||||
# 2686| r2686_31(glval<char *>) = VariableAddress[#temp2686:18] :
|
||||
# 2686| mu2686_32(char *) = Store[#temp2686:18] : &:r2686_31, r2686_30
|
||||
#-----| Goto -> Block 5
|
||||
|
||||
# 2686| Block 7
|
||||
# 2686| r2686_33(glval<char[1]>) = StringConstant[] :
|
||||
# 2686| r2686_34(char *) = Convert : r2686_33
|
||||
# 2686| r2686_35(glval<char *>) = VariableAddress[#temp2686:18] :
|
||||
# 2686| mu2686_36(char *) = Store[#temp2686:18] : &:r2686_35, r2686_34
|
||||
#-----| Goto -> Block 5
|
||||
|
||||
# 2687| Block 8
|
||||
# 2687| v2687_1(void) = NoOp :
|
||||
# 2684| v2684_6(void) = ReturnVoid :
|
||||
# 2684| v2684_7(void) = AliasedUse : ~m?
|
||||
# 2684| v2684_8(void) = ExitFunction :
|
||||
|
||||
perf-regression.cpp:
|
||||
# 6| void Big::Big()
|
||||
# 6| Block 0
|
||||
|
||||
@@ -1,2 +1 @@
|
||||
testFailures
|
||||
failures
|
||||
ERROR: getAllocation() cannot be resolved for type SimpleSSA::MemoryLocation (points_to.ql:31,42-55)
|
||||
|
||||
@@ -56,7 +56,7 @@ module UnaliasedSsa {
|
||||
not memLocation.getVirtualVariable() instanceof AliasedVirtualVariable and
|
||||
not memLocation instanceof AllNonLocalMemory and
|
||||
tag = "ussa" and
|
||||
not ignoreAllocation(memLocation.getAllocation().getAllocationString()) and
|
||||
not ignoreAllocation(memLocation.getAnAllocation().getAllocationString()) and
|
||||
value = memLocation.toString() and
|
||||
element = instr.toString() and
|
||||
location = instr.getLocation() and
|
||||
|
||||
@@ -381,7 +381,7 @@ ssa.cpp:
|
||||
#-----| Goto -> Block 1
|
||||
|
||||
# 69| Block 1
|
||||
# 69| m69_1(unknown) = Phi : from 0:~m68_4, from 2:~m70_10
|
||||
# 69| m69_1(unknown) = Phi : from 0:m68_10, from 2:m70_10
|
||||
# 69| m69_2(char *) = Phi : from 0:m68_8, from 2:m70_6
|
||||
# 69| m69_3(int) = Phi : from 0:m68_6, from 2:m69_8
|
||||
# 69| r69_4(glval<int>) = VariableAddress[n] :
|
||||
@@ -411,9 +411,9 @@ ssa.cpp:
|
||||
|
||||
# 71| Block 3
|
||||
# 71| v71_1(void) = NoOp :
|
||||
# 68| v68_11(void) = ReturnIndirection[p] : &:r68_9, m68_10
|
||||
# 68| v68_11(void) = ReturnIndirection[p] : &:r68_9, m69_1
|
||||
# 68| v68_12(void) = ReturnVoid :
|
||||
# 68| v68_13(void) = AliasedUse : ~m69_1
|
||||
# 68| v68_13(void) = AliasedUse : m68_3
|
||||
# 68| v68_14(void) = ExitFunction :
|
||||
|
||||
# 75| void ScalarPhi(bool)
|
||||
|
||||
@@ -381,7 +381,7 @@ ssa.cpp:
|
||||
#-----| Goto -> Block 1
|
||||
|
||||
# 69| Block 1
|
||||
# 69| m69_1(unknown) = Phi : from 0:~m68_4, from 2:~m70_10
|
||||
# 69| m69_1(unknown) = Phi : from 0:m68_10, from 2:m70_10
|
||||
# 69| m69_2(char *) = Phi : from 0:m68_8, from 2:m70_6
|
||||
# 69| m69_3(int) = Phi : from 0:m68_6, from 2:m69_8
|
||||
# 69| r69_4(glval<int>) = VariableAddress[n] :
|
||||
@@ -411,9 +411,9 @@ ssa.cpp:
|
||||
|
||||
# 71| Block 3
|
||||
# 71| v71_1(void) = NoOp :
|
||||
# 68| v68_11(void) = ReturnIndirection[p] : &:r68_9, m68_10
|
||||
# 68| v68_11(void) = ReturnIndirection[p] : &:r68_9, m69_1
|
||||
# 68| v68_12(void) = ReturnVoid :
|
||||
# 68| v68_13(void) = AliasedUse : ~m69_1
|
||||
# 68| v68_13(void) = AliasedUse : m68_3
|
||||
# 68| v68_14(void) = ExitFunction :
|
||||
|
||||
# 75| void ScalarPhi(bool)
|
||||
|
||||
@@ -19,7 +19,5 @@
|
||||
| test.cpp:14:7:14:7 | D | test.cpp:23:10:23:12 | f_D | D::f_D() | getAMember(), getAMember(3), getAMemberFunction(), getCanonicalMember(3), getDeclaringType() |
|
||||
| test.cpp:27:7:27:7 | E<T> | test.cpp:29:10:29:12 | f_E | E<T>::f_E() | getAMember(), getAMember(0), getAMemberFunction(), getCanonicalMember(0), getDeclaringType() |
|
||||
| test.cpp:27:7:27:7 | E<T> | test.cpp:31:10:31:16 | f_E_arg | E<T>::f_E_arg(E<T>) | getAMember(), getAMember(1), getAMemberFunction(), getCanonicalMember(1), getDeclaringType() |
|
||||
| test.cpp:27:7:27:7 | E<int> | test.cpp:27:7:27:7 | operator= | E<int>::operator=(E<int> &&) | getAMember(), getAMember(3), getAMemberFunction(), getCanonicalMember(3), getDeclaringType() |
|
||||
| test.cpp:27:7:27:7 | E<int> | test.cpp:27:7:27:7 | operator= | E<int>::operator=(const E<int> &) | getAMember(), getAMember(2), getAMemberFunction(), getCanonicalMember(2), getDeclaringType() |
|
||||
| test.cpp:27:7:27:7 | E<int> | test.cpp:29:10:29:10 | f_E | E<int>::f_E() | getAMember(), getAMember(0), getAMemberFunction(), getCanonicalMember(0), getDeclaringType() |
|
||||
| test.cpp:27:7:27:7 | E<int> | test.cpp:31:10:31:10 | f_E_arg | E<int>::f_E_arg(E<int>) | getAMember(), getAMember(1), getAMemberFunction(), getCanonicalMember(1), getDeclaringType() |
|
||||
|
||||
@@ -4,4 +4,7 @@
|
||||
static void f(void) {
|
||||
CA::CB<int> x;
|
||||
CA::CB<float> y;
|
||||
|
||||
x.operator=(x);
|
||||
x.operator=(static_cast<CA::CB<int>&&>(x));
|
||||
}
|
||||
|
||||
@@ -11,9 +11,7 @@
|
||||
| h.h:2:7:2:8 | CA | 1 CA::operator= |
|
||||
| h.h:2:7:2:8 | CA | 2 CA::operator= |
|
||||
| h.h:5:11:5:12 | CB<TB> | <none> |
|
||||
| h.h:5:11:5:12 | CB<double> | 0 CA::CB<double>::operator= |
|
||||
| h.h:5:11:5:12 | CB<double> | 1 CA::CB<double>::operator= |
|
||||
| h.h:5:11:5:12 | CB<float> | 0 CA::CB<float>::operator= |
|
||||
| h.h:5:11:5:12 | CB<float> | 1 CA::CB<float>::operator= |
|
||||
| h.h:5:11:5:12 | CB<double> | <none> |
|
||||
| h.h:5:11:5:12 | CB<float> | <none> |
|
||||
| h.h:5:11:5:12 | CB<int> | 0 CA::CB<int>::operator= |
|
||||
| h.h:5:11:5:12 | CB<int> | 1 CA::CB<int>::operator= |
|
||||
|
||||
@@ -1,7 +1,3 @@
|
||||
| copy_from_prototype.cpp:3:7:3:7 | a | void a<int>::a(a<int> const&) | copy_from_prototype.cpp:3:7:3:7 | a<int> | <no expr> |
|
||||
| copy_from_prototype.cpp:3:7:3:7 | a | void a<int>::a(a<int>&&) | copy_from_prototype.cpp:3:7:3:7 | a<int> | <no expr> |
|
||||
| copy_from_prototype.cpp:3:7:3:7 | operator= | a<int>& a<int>::operator=(a<int> const&) | copy_from_prototype.cpp:3:7:3:7 | a<int> | <no expr> |
|
||||
| copy_from_prototype.cpp:3:7:3:7 | operator= | a<int>& a<int>::operator=(a<int>&&) | copy_from_prototype.cpp:3:7:3:7 | a<int> | <no expr> |
|
||||
| copy_from_prototype.cpp:4:26:4:26 | a | void a<(unnamed template parameter)>::a<(unnamed template parameter)>() | copy_from_prototype.cpp:3:7:3:7 | a<<unnamed>> | 123 |
|
||||
| copy_from_prototype.cpp:4:26:4:26 | a | void a<int>::a<(unnamed template parameter)>() | copy_from_prototype.cpp:3:7:3:7 | a<int> | <no expr> |
|
||||
| copy_from_prototype.cpp:7:7:7:7 | b | void b::b() | copy_from_prototype.cpp:7:7:7:7 | b | <no expr> |
|
||||
@@ -9,10 +5,6 @@
|
||||
| copy_from_prototype.cpp:7:7:7:7 | b | void b::b(b&&) | copy_from_prototype.cpp:7:7:7:7 | b | <no expr> |
|
||||
| copy_from_prototype.cpp:7:7:7:7 | operator= | b& b::operator=(b const&) | copy_from_prototype.cpp:7:7:7:7 | b | <no expr> |
|
||||
| copy_from_prototype.cpp:7:7:7:7 | operator= | b& b::operator=(b&&) | copy_from_prototype.cpp:7:7:7:7 | b | <no expr> |
|
||||
| copy_from_prototype.cpp:13:7:13:7 | c | void c<int>::c(c<int> const&) | copy_from_prototype.cpp:13:7:13:7 | c<int> | <no expr> |
|
||||
| copy_from_prototype.cpp:13:7:13:7 | c | void c<int>::c(c<int>&&) | copy_from_prototype.cpp:13:7:13:7 | c<int> | <no expr> |
|
||||
| copy_from_prototype.cpp:13:7:13:7 | operator= | c<int>& c<int>::operator=(c<int> const&) | copy_from_prototype.cpp:13:7:13:7 | c<int> | <no expr> |
|
||||
| copy_from_prototype.cpp:13:7:13:7 | operator= | c<int>& c<int>::operator=(c<int>&&) | copy_from_prototype.cpp:13:7:13:7 | c<int> | <no expr> |
|
||||
| copy_from_prototype.cpp:14:26:14:26 | c | void c<T>::c<(unnamed template parameter)>() | copy_from_prototype.cpp:13:7:13:7 | c<T> | X |
|
||||
| copy_from_prototype.cpp:14:26:14:26 | c | void c<int>::c<(unnamed template parameter)>() | copy_from_prototype.cpp:13:7:13:7 | c<int> | <no expr> |
|
||||
| copy_from_prototype.cpp:17:7:17:7 | d | void d::d() | copy_from_prototype.cpp:17:7:17:7 | d | <no expr> |
|
||||
@@ -20,10 +12,6 @@
|
||||
| copy_from_prototype.cpp:17:7:17:7 | d | void d::d(d&&) | copy_from_prototype.cpp:17:7:17:7 | d | <no expr> |
|
||||
| copy_from_prototype.cpp:17:7:17:7 | operator= | d& d::operator=(d const&) | copy_from_prototype.cpp:17:7:17:7 | d | <no expr> |
|
||||
| copy_from_prototype.cpp:17:7:17:7 | operator= | d& d::operator=(d&&) | copy_from_prototype.cpp:17:7:17:7 | d | <no expr> |
|
||||
| copy_from_prototype.cpp:22:8:22:8 | e | void e<int>::e(e<int> const&) | copy_from_prototype.cpp:22:8:22:8 | e<int> | <no expr> |
|
||||
| copy_from_prototype.cpp:22:8:22:8 | e | void e<int>::e(e<int>&&) | copy_from_prototype.cpp:22:8:22:8 | e<int> | <no expr> |
|
||||
| copy_from_prototype.cpp:22:8:22:8 | operator= | e<int>& e<int>::operator=(e<int> const&) | copy_from_prototype.cpp:22:8:22:8 | e<int> | <no expr> |
|
||||
| copy_from_prototype.cpp:22:8:22:8 | operator= | e<int>& e<int>::operator=(e<int>&&) | copy_from_prototype.cpp:22:8:22:8 | e<int> | <no expr> |
|
||||
| copy_from_prototype.cpp:23:26:23:26 | e | void e<T>::e<(unnamed template parameter)>() | copy_from_prototype.cpp:22:8:22:8 | e<T> | 456 |
|
||||
| copy_from_prototype.cpp:26:35:26:43 | e | void e<int>::e<(unnamed template parameter)>() | copy_from_prototype.cpp:22:8:22:8 | e<int> | 456 |
|
||||
| file://:0:0:0:0 | operator= | __va_list_tag& __va_list_tag::operator=(__va_list_tag const&) | file://:0:0:0:0 | __va_list_tag | <none> |
|
||||
|
||||
@@ -1,20 +1,4 @@
|
||||
| box.cpp:3:6:3:6 | definition of h | -------- | --- |
|
||||
| box.h:2:8:2:8 | declaration of Box | -------- | --- |
|
||||
| box.h:2:8:2:8 | declaration of Box | -------- | --- |
|
||||
| box.h:2:8:2:8 | declaration of Box | -------- | --- |
|
||||
| box.h:2:8:2:8 | declaration of Box | -------- | --- |
|
||||
| box.h:2:8:2:8 | declaration of operator= | -------- | --- |
|
||||
| box.h:2:8:2:8 | declaration of operator= | -------- | --- |
|
||||
| box.h:2:8:2:8 | declaration of operator= | -------- | --- |
|
||||
| box.h:2:8:2:8 | declaration of operator= | -------- | --- |
|
||||
| box.h:2:8:2:8 | declaration of operator= | -------- | --- |
|
||||
| box.h:2:8:2:8 | declaration of operator= | -------- | --- |
|
||||
| box.h:2:8:2:8 | declaration of operator= | -------- | --- |
|
||||
| box.h:2:8:2:8 | declaration of operator= | -------- | --- |
|
||||
| box.h:2:8:2:8 | definition of Box | no except | --- |
|
||||
| box.h:2:8:2:8 | definition of Box | no except | --- |
|
||||
| box.h:2:8:2:8 | definition of Box | no except | --- |
|
||||
| box.h:2:8:2:8 | definition of Box | no except | --- |
|
||||
| box.h:3:3:3:3 | definition of Box | -------- | __has_nothrow_copy |
|
||||
| box.h:3:3:3:3 | definition of Box | -------- | __has_nothrow_copy |
|
||||
| box.h:3:3:3:3 | definition of Box | -------- | __has_nothrow_copy |
|
||||
|
||||
@@ -63,13 +63,7 @@
|
||||
| scopes.cpp:74:11:74:13 | One | Namespace | scopes.cpp:95:8:95:8 | I | Class |
|
||||
| scopes.cpp:77:8:77:8 | H<T> | Class | scopes.cpp:76:18:76:18 | T | |
|
||||
| scopes.cpp:77:8:77:8 | H<T> | Class | scopes.cpp:79:5:79:5 | t | |
|
||||
| scopes.cpp:77:8:77:8 | H<long> | Class | scopes.cpp:77:8:77:8 | H | |
|
||||
| scopes.cpp:77:8:77:8 | H<long> | Class | scopes.cpp:77:8:77:8 | operator= | |
|
||||
| scopes.cpp:77:8:77:8 | H<long> | Class | scopes.cpp:77:8:77:8 | operator= | |
|
||||
| scopes.cpp:77:8:77:8 | H<long> | Class | scopes.cpp:79:5:79:5 | t | |
|
||||
| scopes.cpp:77:8:77:8 | H<short> | Class | scopes.cpp:77:8:77:8 | H | |
|
||||
| scopes.cpp:77:8:77:8 | H<short> | Class | scopes.cpp:77:8:77:8 | operator= | |
|
||||
| scopes.cpp:77:8:77:8 | H<short> | Class | scopes.cpp:77:8:77:8 | operator= | |
|
||||
| scopes.cpp:77:8:77:8 | H<short> | Class | scopes.cpp:79:5:79:5 | t | |
|
||||
| scopes.cpp:85:12:85:14 | One::Two | Namespace | scopes.cpp:87:8:87:13 | myEnum | |
|
||||
| scopes.cpp:95:8:95:8 | I | Class | scopes.cpp:95:8:95:8 | operator= | |
|
||||
|
||||
@@ -31,11 +31,5 @@
|
||||
| scopes.cpp:67:3:67:8 | ~Table | | scopes.cpp:62:7:62:11 | Table | 8 |
|
||||
| scopes.cpp:68:9:68:14 | lookup | | scopes.cpp:62:7:62:11 | Table | 8 |
|
||||
| scopes.cpp:69:8:69:13 | insert | | scopes.cpp:62:7:62:11 | Table | 8 |
|
||||
| scopes.cpp:77:8:77:8 | H | Constructor | scopes.cpp:77:8:77:8 | H<long> | 4 |
|
||||
| scopes.cpp:77:8:77:8 | H | Constructor | scopes.cpp:77:8:77:8 | H<short> | 4 |
|
||||
| scopes.cpp:77:8:77:8 | operator= | | scopes.cpp:77:8:77:8 | H<long> | 4 |
|
||||
| scopes.cpp:77:8:77:8 | operator= | | scopes.cpp:77:8:77:8 | H<long> | 4 |
|
||||
| scopes.cpp:77:8:77:8 | operator= | | scopes.cpp:77:8:77:8 | H<short> | 4 |
|
||||
| scopes.cpp:77:8:77:8 | operator= | | scopes.cpp:77:8:77:8 | H<short> | 4 |
|
||||
| scopes.cpp:95:8:95:8 | operator= | | scopes.cpp:95:8:95:8 | I | 3 |
|
||||
| scopes.cpp:95:8:95:8 | operator= | | scopes.cpp:95:8:95:8 | I | 3 |
|
||||
|
||||
@@ -36,11 +36,5 @@
|
||||
| scopes.cpp:68:9:68:14 | lookup | | 1 | 1 |
|
||||
| scopes.cpp:69:8:69:13 | insert | | 1 | 1 |
|
||||
| scopes.cpp:72:16:72:21 | strlen | isTopLevel() | 1 | 1 |
|
||||
| scopes.cpp:77:8:77:8 | H | | 1 | 0 |
|
||||
| scopes.cpp:77:8:77:8 | H | | 1 | 0 |
|
||||
| scopes.cpp:77:8:77:8 | operator= | | 1 | 0 |
|
||||
| scopes.cpp:77:8:77:8 | operator= | | 1 | 0 |
|
||||
| scopes.cpp:77:8:77:8 | operator= | | 1 | 0 |
|
||||
| scopes.cpp:77:8:77:8 | operator= | | 1 | 0 |
|
||||
| scopes.cpp:95:8:95:8 | operator= | | 1 | 0 |
|
||||
| scopes.cpp:95:8:95:8 | operator= | | 1 | 0 |
|
||||
|
||||
@@ -34,13 +34,6 @@
|
||||
| copy.cpp:59:9:59:9 | HasArray2D | void private_cc::HasArray2D::HasArray2D(private_cc::HasArray2D&) | deleted | |
|
||||
| copy.cpp:59:9:59:9 | operator= | private_cc::HasArray2D& private_cc::HasArray2D::operator=(private_cc::HasArray2D const&) | | |
|
||||
| copy.cpp:59:9:59:9 | operator= | private_cc::HasArray2D& private_cc::HasArray2D::operator=(private_cc::HasArray2D&&) | | |
|
||||
| copy.cpp:67:9:67:9 | Wrapper | void container::Wrapper<container::Copyable>::Wrapper() | | |
|
||||
| copy.cpp:67:9:67:9 | Wrapper | void container::Wrapper<container::NotCopyable>::Wrapper() | deleted | |
|
||||
| copy.cpp:67:9:67:9 | Wrapper | void container::Wrapper<container::NotCopyable>::Wrapper(container::Wrapper<container::NotCopyable> const&) | deleted | |
|
||||
| copy.cpp:67:9:67:9 | Wrapper | void container::Wrapper<container::NotCopyable>::Wrapper(container::Wrapper<container::NotCopyable>&&) | | |
|
||||
| copy.cpp:67:9:67:9 | operator= | container::Wrapper<container::Copyable>& container::Wrapper<container::Copyable>::operator=(container::Wrapper<container::Copyable> const&) | | |
|
||||
| copy.cpp:67:9:67:9 | operator= | container::Wrapper<container::Copyable>& container::Wrapper<container::Copyable>::operator=(container::Wrapper<container::Copyable>&&) | | |
|
||||
| copy.cpp:67:9:67:9 | operator= | container::Wrapper<container::NotCopyable>& container::Wrapper<container::NotCopyable>::operator=(container::Wrapper<container::NotCopyable> const&) | deleted | |
|
||||
| copy.cpp:71:9:71:9 | operator= | container::Copyable& container::Copyable::operator=(container::Copyable const&) | | |
|
||||
| copy.cpp:71:9:71:9 | operator= | container::Copyable& container::Copyable::operator=(container::Copyable&&) | | |
|
||||
| copy.cpp:72:9:72:9 | NotCopyable | void container::NotCopyable::NotCopyable() | deleted | |
|
||||
@@ -85,7 +78,6 @@
|
||||
| copy.cpp:131:9:131:9 | OnlyAssign | void difference::OnlyAssign::OnlyAssign(difference::OnlyAssign const&) | deleted | |
|
||||
| copy.cpp:131:9:131:9 | operator= | difference::OnlyAssign& difference::OnlyAssign::operator=(difference::OnlyAssign const&) | | |
|
||||
| copy.cpp:131:9:131:9 | operator= | difference::OnlyAssign& difference::OnlyAssign::operator=(difference::OnlyAssign&&) | | |
|
||||
| copy.cpp:137:9:137:9 | operator= | instantiated_explicit_ctor::Wrapper<int>& instantiated_explicit_ctor::Wrapper<int>::operator=(instantiated_explicit_ctor::Wrapper<int> const&) | | |
|
||||
| copy.cpp:139:5:139:11 | Wrapper | void instantiated_explicit_ctor::Wrapper<T>::Wrapper(instantiated_explicit_ctor::Wrapper<T>&) | | |
|
||||
| copy.cpp:143:5:143:5 | Wrapper | void instantiated_explicit_ctor::Wrapper<int>::Wrapper() | | |
|
||||
| copy.cpp:143:5:143:11 | Wrapper | void instantiated_explicit_ctor::Wrapper<T>::Wrapper() | | |
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
| file://:0:0:0:0 | (unnamed parameter 0) |
|
||||
| file://:0:0:0:0 | (unnamed parameter 0) |
|
||||
| file://:0:0:0:0 | (unnamed parameter 0) |
|
||||
| file://:0:0:0:0 | (unnamed parameter 0) |
|
||||
| file://:0:0:0:0 | __va_list_tag |
|
||||
| file://:0:0:0:0 | auto |
|
||||
| file://:0:0:0:0 | fp_offset |
|
||||
@@ -11,8 +9,6 @@
|
||||
| file://:0:0:0:0 | overflow_arg_area |
|
||||
| file://:0:0:0:0 | reg_save_area |
|
||||
| test.cpp:2:16:2:16 | T |
|
||||
| test.cpp:3:8:3:8 | operator= |
|
||||
| test.cpp:3:8:3:8 | operator= |
|
||||
| test.cpp:3:8:3:10 | Str<T> |
|
||||
| test.cpp:3:8:3:10 | Str<int> |
|
||||
| test.cpp:7:16:7:16 | T |
|
||||
|
||||
@@ -1,9 +1,5 @@
|
||||
| file://:0:0:0:0 | (unnamed parameter 0) |
|
||||
| file://:0:0:0:0 | (unnamed parameter 0) |
|
||||
| file://:0:0:0:0 | (unnamed parameter 0) |
|
||||
| file://:0:0:0:0 | (unnamed parameter 0) |
|
||||
| file://:0:0:0:0 | (unnamed parameter 0) |
|
||||
| file://:0:0:0:0 | (unnamed parameter 0) |
|
||||
| file://:0:0:0:0 | C<char>'s friend |
|
||||
| file://:0:0:0:0 | C<int>'s friend |
|
||||
| file://:0:0:0:0 | auto |
|
||||
@@ -24,10 +20,6 @@
|
||||
| friends.cpp:7:9:7:9 | C<TTT> |
|
||||
| friends.cpp:7:9:7:9 | C<char> |
|
||||
| friends.cpp:7:9:7:9 | C<int> |
|
||||
| friends.cpp:7:9:7:9 | operator= |
|
||||
| friends.cpp:7:9:7:9 | operator= |
|
||||
| friends.cpp:7:9:7:9 | operator= |
|
||||
| friends.cpp:7:9:7:9 | operator= |
|
||||
| friends.cpp:9:17:9:17 | f |
|
||||
| friends.cpp:9:17:9:19 | C<TTT>'s friend |
|
||||
| friends.cpp:9:21:9:26 | (unnamed parameter 0) |
|
||||
|
||||
@@ -1,13 +1,5 @@
|
||||
| h.h:3:7:3:7 | C<T> | h.h:4:10:4:12 | fun | 0 |
|
||||
| h.h:3:7:3:7 | C<char> | h.h:3:7:3:7 | operator= | 0 |
|
||||
| h.h:3:7:3:7 | C<char> | h.h:3:7:3:7 | operator= | 0 |
|
||||
| h.h:3:7:3:7 | C<int> | h.h:3:7:3:7 | operator= | 0 |
|
||||
| h.h:3:7:3:7 | C<int> | h.h:3:7:3:7 | operator= | 0 |
|
||||
| h.h:8:7:8:7 | D<T> | h.h:10:10:10:12 | fun | 2 |
|
||||
| h.h:8:7:8:7 | D<int> | h.h:8:7:8:7 | operator= | 0 |
|
||||
| h.h:8:7:8:7 | D<int> | h.h:8:7:8:7 | operator= | 0 |
|
||||
| h.h:8:7:8:7 | D<int> | h.h:10:10:10:10 | fun | 2 |
|
||||
| h.h:14:7:14:7 | E<T> | h.h:16:10:16:12 | fun | 2 |
|
||||
| h.h:14:7:14:7 | E<int> | h.h:14:7:14:7 | operator= | 0 |
|
||||
| h.h:14:7:14:7 | E<int> | h.h:14:7:14:7 | operator= | 0 |
|
||||
| h.h:14:7:14:7 | E<int> | h.h:16:10:16:10 | fun | 2 |
|
||||
|
||||
@@ -45,12 +45,6 @@
|
||||
| isfromtemplateinstantiation.cpp:38:26:38:26 | definition of a_template_method | isfromtemplateinstantiation.cpp:38:26:38:26 | normal_class::a_template_method<short>() |
|
||||
| isfromtemplateinstantiation.cpp:39:2:40:2 | { ... } | isfromtemplateinstantiation.cpp:38:26:38:26 | normal_class::a_template_method<short>() |
|
||||
| isfromtemplateinstantiation.cpp:40:2:40:2 | return ... | isfromtemplateinstantiation.cpp:38:26:38:26 | normal_class::a_template_method<short>() |
|
||||
| isfromtemplateinstantiation.cpp:44:26:44:26 | declaration of operator= | isfromtemplateinstantiation.cpp:44:26:44:39 | template_class<char> |
|
||||
| isfromtemplateinstantiation.cpp:44:26:44:26 | declaration of operator= | isfromtemplateinstantiation.cpp:44:26:44:39 | template_class<char> |
|
||||
| isfromtemplateinstantiation.cpp:44:26:44:26 | definition of template_class | isfromtemplateinstantiation.cpp:44:26:44:39 | template_class<char> |
|
||||
| isfromtemplateinstantiation.cpp:44:26:44:26 | template_class<char>::operator=(const template_class<char> &) | isfromtemplateinstantiation.cpp:44:26:44:39 | template_class<char> |
|
||||
| isfromtemplateinstantiation.cpp:44:26:44:26 | template_class<char>::operator=(template_class<char> &&) | isfromtemplateinstantiation.cpp:44:26:44:39 | template_class<char> |
|
||||
| isfromtemplateinstantiation.cpp:44:26:44:26 | template_class<char>::template_class() | isfromtemplateinstantiation.cpp:44:26:44:39 | template_class<char> |
|
||||
| isfromtemplateinstantiation.cpp:46:4:46:4 | definition of t | isfromtemplateinstantiation.cpp:44:26:44:39 | template_class<char> |
|
||||
| isfromtemplateinstantiation.cpp:46:4:46:4 | t | isfromtemplateinstantiation.cpp:44:26:44:39 | template_class<char> |
|
||||
| isfromtemplateinstantiation.cpp:49:7:49:7 | definition of b_method | isfromtemplateinstantiation.cpp:44:26:44:39 | template_class<char> |
|
||||
@@ -75,22 +69,6 @@
|
||||
| isfromtemplateinstantiation.cpp:54:2:55:2 | { ... } | isfromtemplateinstantiation.cpp:53:26:53:26 | template_class<char>::b_template_method<long>(long) |
|
||||
| isfromtemplateinstantiation.cpp:55:2:55:2 | return ... | isfromtemplateinstantiation.cpp:44:26:44:39 | template_class<char> |
|
||||
| isfromtemplateinstantiation.cpp:55:2:55:2 | return ... | isfromtemplateinstantiation.cpp:53:26:53:26 | template_class<char>::b_template_method<long>(long) |
|
||||
| isfromtemplateinstantiation.cpp:77:26:77:26 | AnotherTemplateClass<int>::operator=(AnotherTemplateClass<int> &&) | isfromtemplateinstantiation.cpp:77:26:77:45 | AnotherTemplateClass<int> |
|
||||
| isfromtemplateinstantiation.cpp:77:26:77:26 | AnotherTemplateClass<int>::operator=(const AnotherTemplateClass<int> &) | isfromtemplateinstantiation.cpp:77:26:77:45 | AnotherTemplateClass<int> |
|
||||
| isfromtemplateinstantiation.cpp:77:26:77:26 | AnotherTemplateClass<long *>::operator=(AnotherTemplateClass<long *> &&) | isfromtemplateinstantiation.cpp:128:7:128:30 | AnotherTemplateClass<long *> |
|
||||
| isfromtemplateinstantiation.cpp:77:26:77:26 | AnotherTemplateClass<long *>::operator=(const AnotherTemplateClass<long *> &) | isfromtemplateinstantiation.cpp:128:7:128:30 | AnotherTemplateClass<long *> |
|
||||
| isfromtemplateinstantiation.cpp:77:26:77:26 | declaration of operator= | isfromtemplateinstantiation.cpp:77:26:77:45 | AnotherTemplateClass<int> |
|
||||
| isfromtemplateinstantiation.cpp:77:26:77:26 | declaration of operator= | isfromtemplateinstantiation.cpp:77:26:77:45 | AnotherTemplateClass<int> |
|
||||
| isfromtemplateinstantiation.cpp:77:26:77:26 | declaration of operator= | isfromtemplateinstantiation.cpp:128:7:128:30 | AnotherTemplateClass<long *> |
|
||||
| isfromtemplateinstantiation.cpp:77:26:77:26 | declaration of operator= | isfromtemplateinstantiation.cpp:128:7:128:30 | AnotherTemplateClass<long *> |
|
||||
| isfromtemplateinstantiation.cpp:82:9:82:9 | AnotherTemplateClass<int>::MyClassStruct::operator=(MyClassStruct &&) | isfromtemplateinstantiation.cpp:77:26:77:45 | AnotherTemplateClass<int> |
|
||||
| isfromtemplateinstantiation.cpp:82:9:82:9 | AnotherTemplateClass<int>::MyClassStruct::operator=(MyClassStruct &&) | isfromtemplateinstantiation.cpp:82:9:82:21 | MyClassStruct |
|
||||
| isfromtemplateinstantiation.cpp:82:9:82:9 | AnotherTemplateClass<int>::MyClassStruct::operator=(const MyClassStruct &) | isfromtemplateinstantiation.cpp:77:26:77:45 | AnotherTemplateClass<int> |
|
||||
| isfromtemplateinstantiation.cpp:82:9:82:9 | AnotherTemplateClass<int>::MyClassStruct::operator=(const MyClassStruct &) | isfromtemplateinstantiation.cpp:82:9:82:21 | MyClassStruct |
|
||||
| isfromtemplateinstantiation.cpp:82:9:82:9 | declaration of operator= | isfromtemplateinstantiation.cpp:77:26:77:45 | AnotherTemplateClass<int> |
|
||||
| isfromtemplateinstantiation.cpp:82:9:82:9 | declaration of operator= | isfromtemplateinstantiation.cpp:77:26:77:45 | AnotherTemplateClass<int> |
|
||||
| isfromtemplateinstantiation.cpp:82:9:82:9 | declaration of operator= | isfromtemplateinstantiation.cpp:82:9:82:21 | MyClassStruct |
|
||||
| isfromtemplateinstantiation.cpp:82:9:82:9 | declaration of operator= | isfromtemplateinstantiation.cpp:82:9:82:21 | MyClassStruct |
|
||||
| isfromtemplateinstantiation.cpp:82:9:82:21 | MyClassStruct | isfromtemplateinstantiation.cpp:77:26:77:45 | AnotherTemplateClass<int> |
|
||||
| isfromtemplateinstantiation.cpp:84:6:84:10 | definition of value | isfromtemplateinstantiation.cpp:77:26:77:45 | AnotherTemplateClass<int> |
|
||||
| isfromtemplateinstantiation.cpp:84:6:84:10 | definition of value | isfromtemplateinstantiation.cpp:82:9:82:21 | MyClassStruct |
|
||||
@@ -126,26 +104,12 @@
|
||||
| isfromtemplateinstantiation.cpp:99:1:99:1 | return ... | isfromtemplateinstantiation.cpp:77:26:77:45 | AnotherTemplateClass<int> |
|
||||
| isfromtemplateinstantiation.cpp:99:1:99:1 | return ... | isfromtemplateinstantiation.cpp:97:52:97:52 | AnotherTemplateClass<int>::myMethod2(MyClassEnum) |
|
||||
| isfromtemplateinstantiation.cpp:110:3:110:3 | definition of var_template | isfromtemplateinstantiation.cpp:110:3:110:3 | var_template |
|
||||
| isfromtemplateinstantiation.cpp:134:29:134:29 | Outer<int>::operator=(Outer<int> &&) | isfromtemplateinstantiation.cpp:134:29:134:33 | Outer<int> |
|
||||
| isfromtemplateinstantiation.cpp:134:29:134:29 | Outer<int>::operator=(const Outer<int> &) | isfromtemplateinstantiation.cpp:134:29:134:33 | Outer<int> |
|
||||
| isfromtemplateinstantiation.cpp:134:29:134:29 | declaration of operator= | isfromtemplateinstantiation.cpp:134:29:134:33 | Outer<int> |
|
||||
| isfromtemplateinstantiation.cpp:134:29:134:29 | declaration of operator= | isfromtemplateinstantiation.cpp:134:29:134:33 | Outer<int> |
|
||||
| isfromtemplateinstantiation.cpp:135:31:135:31 | Outer<T>::Inner<long>::operator=(Inner<long> &&) | isfromtemplateinstantiation.cpp:135:31:135:35 | Inner<long> |
|
||||
| isfromtemplateinstantiation.cpp:135:31:135:31 | Outer<T>::Inner<long>::operator=(const Inner<long> &) | isfromtemplateinstantiation.cpp:135:31:135:35 | Inner<long> |
|
||||
| isfromtemplateinstantiation.cpp:135:31:135:31 | declaration of operator= | isfromtemplateinstantiation.cpp:135:31:135:35 | Inner<long> |
|
||||
| isfromtemplateinstantiation.cpp:135:31:135:31 | declaration of operator= | isfromtemplateinstantiation.cpp:135:31:135:35 | Inner<long> |
|
||||
| isfromtemplateinstantiation.cpp:135:31:135:35 | Inner<U> | isfromtemplateinstantiation.cpp:134:29:134:33 | Outer<int> |
|
||||
| isfromtemplateinstantiation.cpp:135:31:135:35 | declaration of Inner<U> | isfromtemplateinstantiation.cpp:134:29:134:33 | Outer<int> |
|
||||
| isfromtemplateinstantiation.cpp:136:7:136:7 | definition of x | isfromtemplateinstantiation.cpp:135:31:135:35 | Inner<long> |
|
||||
| isfromtemplateinstantiation.cpp:136:7:136:7 | x | isfromtemplateinstantiation.cpp:135:31:135:35 | Inner<long> |
|
||||
| isfromtemplateinstantiation.cpp:137:7:137:7 | definition of y | isfromtemplateinstantiation.cpp:135:31:135:35 | Inner<long> |
|
||||
| isfromtemplateinstantiation.cpp:137:7:137:7 | y | isfromtemplateinstantiation.cpp:135:31:135:35 | Inner<long> |
|
||||
| load.cpp:13:7:13:7 | basic_text_iprimitive<std_istream_mockup>::basic_text_iprimitive(basic_text_iprimitive<std_istream_mockup> &&) | load.cpp:13:7:13:27 | basic_text_iprimitive<std_istream_mockup> |
|
||||
| load.cpp:13:7:13:7 | basic_text_iprimitive<std_istream_mockup>::basic_text_iprimitive(const basic_text_iprimitive<std_istream_mockup> &) | load.cpp:13:7:13:27 | basic_text_iprimitive<std_istream_mockup> |
|
||||
| load.cpp:13:7:13:7 | basic_text_iprimitive<std_istream_mockup>::operator=(const basic_text_iprimitive<std_istream_mockup> &) | load.cpp:13:7:13:27 | basic_text_iprimitive<std_istream_mockup> |
|
||||
| load.cpp:13:7:13:7 | declaration of basic_text_iprimitive | load.cpp:13:7:13:27 | basic_text_iprimitive<std_istream_mockup> |
|
||||
| load.cpp:13:7:13:7 | declaration of basic_text_iprimitive | load.cpp:13:7:13:27 | basic_text_iprimitive<std_istream_mockup> |
|
||||
| load.cpp:13:7:13:7 | definition of operator= | load.cpp:13:7:13:27 | basic_text_iprimitive<std_istream_mockup> |
|
||||
| load.cpp:15:14:15:15 | definition of is | load.cpp:13:7:13:27 | basic_text_iprimitive<std_istream_mockup> |
|
||||
| load.cpp:15:14:15:15 | is | load.cpp:13:7:13:27 | basic_text_iprimitive<std_istream_mockup> |
|
||||
| load.cpp:22:10:22:13 | basic_text_iprimitive<std_istream_mockup>::load<T>(T &) | load.cpp:13:7:13:27 | basic_text_iprimitive<std_istream_mockup> |
|
||||
|
||||
@@ -1,10 +1,6 @@
|
||||
isFromUninstantiatedTemplate
|
||||
| file://:0:0:0:0 | 0 | isfromtemplateinstantiation.cpp:77:26:77:45 | AnotherTemplateClass<T> |
|
||||
| file://:0:0:0:0 | (int)... | isfromtemplateinstantiation.cpp:77:26:77:45 | AnotherTemplateClass<T> |
|
||||
| file://:0:0:0:0 | (unnamed parameter 0) | isfromtemplateinstantiation.cpp:134:29:134:33 | Outer<T> |
|
||||
| file://:0:0:0:0 | (unnamed parameter 0) | isfromtemplateinstantiation.cpp:134:29:134:33 | Outer<T> |
|
||||
| file://:0:0:0:0 | declaration of 1st parameter | isfromtemplateinstantiation.cpp:134:29:134:33 | Outer<T> |
|
||||
| file://:0:0:0:0 | declaration of 1st parameter | isfromtemplateinstantiation.cpp:134:29:134:33 | Outer<T> |
|
||||
| file://:0:0:0:0 | initializer for MyClassEnumConst | isfromtemplateinstantiation.cpp:77:26:77:45 | AnotherTemplateClass<T> |
|
||||
| isfromtemplateinstantiation.cpp:12:24:12:46 | definition of inner_template_function | isfromtemplateinstantiation.cpp:12:24:12:46 | inner_template_function |
|
||||
| isfromtemplateinstantiation.cpp:12:24:12:46 | inner_template_function | isfromtemplateinstantiation.cpp:12:24:12:46 | inner_template_function |
|
||||
@@ -141,10 +137,6 @@ isFromUninstantiatedTemplate
|
||||
| isfromtemplateinstantiation.cpp:129:19:129:19 | 1 | isfromtemplateinstantiation.cpp:129:6:129:6 | f |
|
||||
| isfromtemplateinstantiation.cpp:134:29:134:33 | Outer<T> | isfromtemplateinstantiation.cpp:134:29:134:33 | Outer<T> |
|
||||
| isfromtemplateinstantiation.cpp:134:29:134:33 | definition of Outer<T> | isfromtemplateinstantiation.cpp:134:29:134:33 | Outer<T> |
|
||||
| isfromtemplateinstantiation.cpp:135:31:135:31 | declaration of operator= | isfromtemplateinstantiation.cpp:134:29:134:33 | Outer<T> |
|
||||
| isfromtemplateinstantiation.cpp:135:31:135:31 | declaration of operator= | isfromtemplateinstantiation.cpp:134:29:134:33 | Outer<T> |
|
||||
| isfromtemplateinstantiation.cpp:135:31:135:31 | operator= | isfromtemplateinstantiation.cpp:134:29:134:33 | Outer<T> |
|
||||
| isfromtemplateinstantiation.cpp:135:31:135:31 | operator= | isfromtemplateinstantiation.cpp:134:29:134:33 | Outer<T> |
|
||||
| isfromtemplateinstantiation.cpp:135:31:135:35 | Inner<U> | isfromtemplateinstantiation.cpp:134:29:134:33 | Outer<T> |
|
||||
| isfromtemplateinstantiation.cpp:135:31:135:35 | Inner<U> | isfromtemplateinstantiation.cpp:135:31:135:35 | Inner<U> |
|
||||
| isfromtemplateinstantiation.cpp:135:31:135:35 | Inner<U> | isfromtemplateinstantiation.cpp:135:31:135:35 | Inner<U> |
|
||||
@@ -358,11 +350,6 @@ isFromUninstantiatedTemplate
|
||||
| isfromtemplateinstantiation.cpp:39:2:40:2 | { ... } | I | | Stmt | |
|
||||
| isfromtemplateinstantiation.cpp:40:2:40:2 | return ... | | T | Stmt | |
|
||||
| isfromtemplateinstantiation.cpp:40:2:40:2 | return ... | I | | Stmt | |
|
||||
| isfromtemplateinstantiation.cpp:44:26:44:26 | declaration of operator= | I | | DeclarationEntry | |
|
||||
| isfromtemplateinstantiation.cpp:44:26:44:26 | declaration of operator= | I | | DeclarationEntry | |
|
||||
| isfromtemplateinstantiation.cpp:44:26:44:26 | operator= | I | | Declaration | |
|
||||
| isfromtemplateinstantiation.cpp:44:26:44:26 | operator= | I | | Declaration | |
|
||||
| isfromtemplateinstantiation.cpp:44:26:44:26 | template_class | I | | Declaration | |
|
||||
| isfromtemplateinstantiation.cpp:44:26:44:39 | template_class<T> | | T | Declaration | |
|
||||
| isfromtemplateinstantiation.cpp:44:26:44:39 | template_class<char> | I | | Declaration | |
|
||||
| isfromtemplateinstantiation.cpp:46:4:46:4 | definition of t | | T | Definition | |
|
||||
@@ -390,20 +377,8 @@ isFromUninstantiatedTemplate
|
||||
| isfromtemplateinstantiation.cpp:59:5:59:8 | main | | | Declaration | |
|
||||
| isfromtemplateinstantiation.cpp:72:30:72:32 | 97 | | | Expr | |
|
||||
| isfromtemplateinstantiation.cpp:72:30:72:32 | (long)... | | | Expr | |
|
||||
| isfromtemplateinstantiation.cpp:77:26:77:26 | declaration of operator= | I | | DeclarationEntry | |
|
||||
| isfromtemplateinstantiation.cpp:77:26:77:26 | declaration of operator= | I | | DeclarationEntry | |
|
||||
| isfromtemplateinstantiation.cpp:77:26:77:26 | declaration of operator= | I | | DeclarationEntry | |
|
||||
| isfromtemplateinstantiation.cpp:77:26:77:26 | declaration of operator= | I | | DeclarationEntry | |
|
||||
| isfromtemplateinstantiation.cpp:77:26:77:26 | operator= | I | | Declaration | |
|
||||
| isfromtemplateinstantiation.cpp:77:26:77:26 | operator= | I | | Declaration | |
|
||||
| isfromtemplateinstantiation.cpp:77:26:77:26 | operator= | I | | Declaration | |
|
||||
| isfromtemplateinstantiation.cpp:77:26:77:26 | operator= | I | | Declaration | |
|
||||
| isfromtemplateinstantiation.cpp:77:26:77:45 | AnotherTemplateClass<T> | | T | Declaration | |
|
||||
| isfromtemplateinstantiation.cpp:77:26:77:45 | AnotherTemplateClass<int> | I | | Declaration | |
|
||||
| isfromtemplateinstantiation.cpp:82:9:82:9 | declaration of operator= | I | | DeclarationEntry | |
|
||||
| isfromtemplateinstantiation.cpp:82:9:82:9 | declaration of operator= | I | | DeclarationEntry | |
|
||||
| isfromtemplateinstantiation.cpp:82:9:82:9 | operator= | I | | Declaration | |
|
||||
| isfromtemplateinstantiation.cpp:82:9:82:9 | operator= | I | | Declaration | |
|
||||
| isfromtemplateinstantiation.cpp:82:9:82:21 | MyClassStruct | | T | Declaration | |
|
||||
| isfromtemplateinstantiation.cpp:82:9:82:21 | MyClassStruct | I | | Declaration | |
|
||||
| isfromtemplateinstantiation.cpp:84:6:84:10 | definition of value | | T | Definition | |
|
||||
@@ -451,16 +426,8 @@ isFromUninstantiatedTemplate
|
||||
| isfromtemplateinstantiation.cpp:128:7:128:30 | AnotherTemplateClass<T *> | | T | Declaration | |
|
||||
| isfromtemplateinstantiation.cpp:128:7:128:30 | AnotherTemplateClass<long *> | I | | Declaration | |
|
||||
| isfromtemplateinstantiation.cpp:129:6:129:6 | f | | T | Declaration | |
|
||||
| isfromtemplateinstantiation.cpp:134:29:134:29 | declaration of operator= | I | | DeclarationEntry | |
|
||||
| isfromtemplateinstantiation.cpp:134:29:134:29 | declaration of operator= | I | | DeclarationEntry | |
|
||||
| isfromtemplateinstantiation.cpp:134:29:134:29 | operator= | I | | Declaration | |
|
||||
| isfromtemplateinstantiation.cpp:134:29:134:29 | operator= | I | | Declaration | |
|
||||
| isfromtemplateinstantiation.cpp:134:29:134:33 | Outer<T> | | T | Declaration | |
|
||||
| isfromtemplateinstantiation.cpp:134:29:134:33 | Outer<int> | I | | Declaration | |
|
||||
| isfromtemplateinstantiation.cpp:135:31:135:31 | declaration of operator= | I | T | DeclarationEntry | |
|
||||
| isfromtemplateinstantiation.cpp:135:31:135:31 | declaration of operator= | I | T | DeclarationEntry | |
|
||||
| isfromtemplateinstantiation.cpp:135:31:135:31 | operator= | I | T | Declaration | |
|
||||
| isfromtemplateinstantiation.cpp:135:31:135:31 | operator= | I | T | Declaration | |
|
||||
| isfromtemplateinstantiation.cpp:135:31:135:35 | Inner<U> | | T | Declaration | |
|
||||
| isfromtemplateinstantiation.cpp:135:31:135:35 | Inner<U> | I | T | Declaration | |
|
||||
| isfromtemplateinstantiation.cpp:135:31:135:35 | Inner<long> | I | T | Declaration | |
|
||||
@@ -488,11 +455,6 @@ isFromUninstantiatedTemplate
|
||||
| load.cpp:6:13:6:21 | externInt | | | Expr | Not ref |
|
||||
| load.cpp:7:16:7:20 | (reference to) | | | Expr | |
|
||||
| load.cpp:7:16:7:20 | * ... | | | Expr | |
|
||||
| load.cpp:13:7:13:7 | basic_text_iprimitive | I | | Declaration | |
|
||||
| load.cpp:13:7:13:7 | basic_text_iprimitive | I | | Declaration | |
|
||||
| load.cpp:13:7:13:7 | declaration of basic_text_iprimitive | I | | DeclarationEntry | |
|
||||
| load.cpp:13:7:13:7 | declaration of basic_text_iprimitive | I | | DeclarationEntry | |
|
||||
| load.cpp:13:7:13:7 | operator= | I | | Declaration | |
|
||||
| load.cpp:13:7:13:27 | basic_text_iprimitive<IStream> | | T | Declaration | |
|
||||
| load.cpp:13:7:13:27 | basic_text_iprimitive<std_istream_mockup> | I | | Declaration | |
|
||||
| load.cpp:15:14:15:15 | definition of is | | T | Definition | |
|
||||
|
||||
@@ -4,44 +4,8 @@
|
||||
| 0 | file://:0:0:0:0 | a[10] | refersTo.cpp:2:7:2:7 | a | direct |
|
||||
| 0 | file://:0:0:0:0 | const a | refersTo.cpp:2:7:2:7 | a | direct |
|
||||
| 0 | file://:0:0:0:0 | const a & | refersTo.cpp:2:7:2:7 | a | |
|
||||
| 0 | file://:0:0:0:0 | const container<a> | refersTo.cpp:2:7:2:7 | a | |
|
||||
| 0 | file://:0:0:0:0 | const container<a> | refersTo.cpp:10:16:10:16 | T | |
|
||||
| 0 | file://:0:0:0:0 | const container<a> | refersTo.cpp:11:7:11:15 | container<T> | |
|
||||
| 0 | file://:0:0:0:0 | const container<a> | refersTo.cpp:11:7:11:15 | container<a> | direct |
|
||||
| 0 | file://:0:0:0:0 | const container<a> & | refersTo.cpp:2:7:2:7 | a | |
|
||||
| 0 | file://:0:0:0:0 | const container<a> & | refersTo.cpp:10:16:10:16 | T | |
|
||||
| 0 | file://:0:0:0:0 | const container<a> & | refersTo.cpp:11:7:11:15 | container<T> | |
|
||||
| 0 | file://:0:0:0:0 | const container<a> & | refersTo.cpp:11:7:11:15 | container<a> | |
|
||||
| 0 | file://:0:0:0:0 | const container<container<a>> | refersTo.cpp:2:7:2:7 | a | |
|
||||
| 0 | file://:0:0:0:0 | const container<container<a>> | refersTo.cpp:10:16:10:16 | T | |
|
||||
| 0 | file://:0:0:0:0 | const container<container<a>> | refersTo.cpp:11:7:11:15 | container<T> | |
|
||||
| 0 | file://:0:0:0:0 | const container<container<a>> | refersTo.cpp:11:7:11:15 | container<a> | |
|
||||
| 0 | file://:0:0:0:0 | const container<container<a>> | refersTo.cpp:11:7:11:15 | container<container<a>> | direct |
|
||||
| 0 | file://:0:0:0:0 | const container<container<a>> & | refersTo.cpp:2:7:2:7 | a | |
|
||||
| 0 | file://:0:0:0:0 | const container<container<a>> & | refersTo.cpp:10:16:10:16 | T | |
|
||||
| 0 | file://:0:0:0:0 | const container<container<a>> & | refersTo.cpp:11:7:11:15 | container<T> | |
|
||||
| 0 | file://:0:0:0:0 | const container<container<a>> & | refersTo.cpp:11:7:11:15 | container<a> | |
|
||||
| 0 | file://:0:0:0:0 | const container<container<a>> & | refersTo.cpp:11:7:11:15 | container<container<a>> | |
|
||||
| 0 | file://:0:0:0:0 | const strange | refersTo.cpp:17:7:17:13 | strange | direct |
|
||||
| 0 | file://:0:0:0:0 | const strange & | refersTo.cpp:17:7:17:13 | strange | |
|
||||
| 0 | file://:0:0:0:0 | container<a> & | refersTo.cpp:2:7:2:7 | a | |
|
||||
| 0 | file://:0:0:0:0 | container<a> & | refersTo.cpp:10:16:10:16 | T | |
|
||||
| 0 | file://:0:0:0:0 | container<a> & | refersTo.cpp:11:7:11:15 | container<T> | |
|
||||
| 0 | file://:0:0:0:0 | container<a> & | refersTo.cpp:11:7:11:15 | container<a> | direct |
|
||||
| 0 | file://:0:0:0:0 | container<a> && | refersTo.cpp:2:7:2:7 | a | |
|
||||
| 0 | file://:0:0:0:0 | container<a> && | refersTo.cpp:10:16:10:16 | T | |
|
||||
| 0 | file://:0:0:0:0 | container<a> && | refersTo.cpp:11:7:11:15 | container<T> | |
|
||||
| 0 | file://:0:0:0:0 | container<a> && | refersTo.cpp:11:7:11:15 | container<a> | direct |
|
||||
| 0 | file://:0:0:0:0 | container<container<a>> & | refersTo.cpp:2:7:2:7 | a | |
|
||||
| 0 | file://:0:0:0:0 | container<container<a>> & | refersTo.cpp:10:16:10:16 | T | |
|
||||
| 0 | file://:0:0:0:0 | container<container<a>> & | refersTo.cpp:11:7:11:15 | container<T> | |
|
||||
| 0 | file://:0:0:0:0 | container<container<a>> & | refersTo.cpp:11:7:11:15 | container<a> | |
|
||||
| 0 | file://:0:0:0:0 | container<container<a>> & | refersTo.cpp:11:7:11:15 | container<container<a>> | direct |
|
||||
| 0 | file://:0:0:0:0 | container<container<a>> && | refersTo.cpp:2:7:2:7 | a | |
|
||||
| 0 | file://:0:0:0:0 | container<container<a>> && | refersTo.cpp:10:16:10:16 | T | |
|
||||
| 0 | file://:0:0:0:0 | container<container<a>> && | refersTo.cpp:11:7:11:15 | container<T> | |
|
||||
| 0 | file://:0:0:0:0 | container<container<a>> && | refersTo.cpp:11:7:11:15 | container<a> | |
|
||||
| 0 | file://:0:0:0:0 | container<container<a>> && | refersTo.cpp:11:7:11:15 | container<container<a>> | direct |
|
||||
| 0 | file://:0:0:0:0 | strange & | refersTo.cpp:17:7:17:13 | strange | direct |
|
||||
| 0 | file://:0:0:0:0 | strange && | refersTo.cpp:17:7:17:13 | strange | direct |
|
||||
| 2 | refersTo.cpp:2:7:2:7 | a | refersTo.cpp:2:7:2:7 | a | |
|
||||
|
||||
@@ -468,7 +468,7 @@ test.cpp:
|
||||
# 56| valnum = r50_1, r55_3, r56_12, r56_19, r56_2, r59_1
|
||||
# 56| r56_3(char *) = Load[ptr] : &:r56_2, m56_1
|
||||
# 56| valnum = m56_1, r56_13, r56_20, r56_3, r59_2
|
||||
# 56| r56_4(char) = Load[?] : &:r56_3, ~m49_4
|
||||
# 56| r56_4(char) = Load[?] : &:r56_3, ~m49_12
|
||||
# 56| valnum = r56_14, r56_4, r59_3
|
||||
# 56| r56_5(int) = Convert : r56_4
|
||||
# 56| valnum = r56_15, r56_5, r59_4
|
||||
@@ -491,7 +491,7 @@ test.cpp:
|
||||
# 56| valnum = r50_1, r55_3, r56_12, r56_19, r56_2, r59_1
|
||||
# 56| r56_13(char *) = Load[ptr] : &:r56_12, m56_1
|
||||
# 56| valnum = m56_1, r56_13, r56_20, r56_3, r59_2
|
||||
# 56| r56_14(char) = Load[?] : &:r56_13, ~m49_4
|
||||
# 56| r56_14(char) = Load[?] : &:r56_13, ~m49_12
|
||||
# 56| valnum = r56_14, r56_4, r59_3
|
||||
# 56| r56_15(int) = Convert : r56_14
|
||||
# 56| valnum = r56_15, r56_5, r59_4
|
||||
@@ -521,7 +521,7 @@ test.cpp:
|
||||
# 59| valnum = r50_1, r55_3, r56_12, r56_19, r56_2, r59_1
|
||||
# 59| r59_2(char *) = Load[ptr] : &:r59_1, m56_1
|
||||
# 59| valnum = m56_1, r56_13, r56_20, r56_3, r59_2
|
||||
# 59| r59_3(char) = Load[?] : &:r59_2, ~m49_4
|
||||
# 59| r59_3(char) = Load[?] : &:r59_2, ~m49_12
|
||||
# 59| valnum = r56_14, r56_4, r59_3
|
||||
# 59| r59_4(int) = Convert : r59_3
|
||||
# 59| valnum = r56_15, r56_5, r59_4
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
| tests.cpp:18:15:18:22 | Hello | This argument should be of type 'char *' but is of type 'char16_t *'. |
|
||||
| tests.cpp:19:15:19:22 | Hello | This argument should be of type 'char *' but is of type 'wchar_t *'. |
|
||||
| tests.cpp:21:15:21:21 | Hello | This argument should be of type 'char16_t *' but is of type 'char *'. |
|
||||
| tests.cpp:21:15:21:21 | Hello | This argument should be of type 'wchar_t *' but is of type 'char *'. |
|
||||
| tests.cpp:26:17:26:24 | Hello | This argument should be of type 'char *' but is of type 'char16_t *'. |
|
||||
| tests.cpp:30:17:30:24 | Hello | This argument should be of type 'wchar_t *' but is of type 'char16_t *'. |
|
||||
| tests.cpp:35:36:35:43 | Hello | This argument should be of type 'char *' but is of type 'wchar_t *'. |
|
||||
| tests.cpp:39:36:39:43 | Hello | This argument should be of type 'char16_t *' but is of type 'wchar_t *'. |
|
||||
| tests.cpp:42:37:42:44 | Hello | This argument should be of type 'char *' but is of type 'char16_t *'. |
|
||||
| tests.cpp:43:37:43:44 | Hello | This argument should be of type 'char *' but is of type 'wchar_t *'. |
|
||||
| tests.cpp:45:37:45:43 | Hello | This argument should be of type 'char16_t *' but is of type 'char *'. |
|
||||
| tests.cpp:47:37:47:44 | Hello | This argument should be of type 'char16_t *' but is of type 'wchar_t *'. |
|
||||
| tests.cpp:18:15:18:22 | Hello | This format specifier for type 'char *' does not match the argument type 'char16_t *'. |
|
||||
| tests.cpp:19:15:19:22 | Hello | This format specifier for type 'char *' does not match the argument type 'wchar_t *'. |
|
||||
| tests.cpp:21:15:21:21 | Hello | This format specifier for type 'char16_t *' does not match the argument type 'char *'. |
|
||||
| tests.cpp:21:15:21:21 | Hello | This format specifier for type 'wchar_t *' does not match the argument type 'char *'. |
|
||||
| tests.cpp:26:17:26:24 | Hello | This format specifier for type 'char *' does not match the argument type 'char16_t *'. |
|
||||
| tests.cpp:30:17:30:24 | Hello | This format specifier for type 'wchar_t *' does not match the argument type 'char16_t *'. |
|
||||
| tests.cpp:35:36:35:43 | Hello | This format specifier for type 'char *' does not match the argument type 'wchar_t *'. |
|
||||
| tests.cpp:39:36:39:43 | Hello | This format specifier for type 'char16_t *' does not match the argument type 'wchar_t *'. |
|
||||
| tests.cpp:42:37:42:44 | Hello | This format specifier for type 'char *' does not match the argument type 'char16_t *'. |
|
||||
| tests.cpp:43:37:43:44 | Hello | This format specifier for type 'char *' does not match the argument type 'wchar_t *'. |
|
||||
| tests.cpp:45:37:45:43 | Hello | This format specifier for type 'char16_t *' does not match the argument type 'char *'. |
|
||||
| tests.cpp:47:37:47:44 | Hello | This format specifier for type 'char16_t *' does not match the argument type 'wchar_t *'. |
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
| tests_32.cpp:14:16:14:23 | void_ptr | This argument should be of type 'long' but is of type 'void *'. |
|
||||
| tests_32.cpp:15:15:15:15 | l | This argument should be of type 'void *' but is of type 'long'. |
|
||||
| tests_64.cpp:14:16:14:23 | void_ptr | This argument should be of type 'long' but is of type 'void *'. |
|
||||
| tests_64.cpp:15:15:15:15 | l | This argument should be of type 'void *' but is of type 'long'. |
|
||||
| tests_32.cpp:14:16:14:23 | void_ptr | This format specifier for type 'long' does not match the argument type 'void *'. |
|
||||
| tests_32.cpp:15:15:15:15 | l | This format specifier for type 'void *' does not match the argument type 'long'. |
|
||||
| tests_64.cpp:14:16:14:23 | void_ptr | This format specifier for type 'long' does not match the argument type 'void *'. |
|
||||
| tests_64.cpp:15:15:15:15 | l | This format specifier for type 'void *' does not match the argument type 'long'. |
|
||||
|
||||
@@ -1,62 +1,62 @@
|
||||
| format.h:16:59:16:61 | str | This argument should be of type 'int' but is of type 'char *'. |
|
||||
| format.h:16:64:16:64 | i | This argument should be of type 'double' but is of type 'int'. |
|
||||
| format.h:16:67:16:67 | d | This argument should be of type 'char *' but is of type 'double'. |
|
||||
| linux.cpp:15:24:15:41 | call to get_template_value | This argument should be of type 'int' but is of type 'long'. |
|
||||
| linux_c.c:11:15:11:18 | str3 | This argument should be of type 'char *' but is of type 'short *'. |
|
||||
| pri_macros.h:15:35:15:40 | my_u64 | This argument should be of type 'unsigned int' but is of type 'unsigned long long'. |
|
||||
| printf1.h:12:27:12:27 | i | This argument should be of type 'double' but is of type 'int'. |
|
||||
| printf1.h:18:18:18:18 | i | This argument should be of type 'void *' but is of type 'int'. |
|
||||
| printf1.h:25:22:25:22 | i | This argument should be of type 'char *' but is of type 'int'. |
|
||||
| printf1.h:27:19:27:20 | cs | This argument should be of type 'int' but is of type 'char *'. |
|
||||
| printf1.h:38:18:38:30 | MYONETHOUSAND | This argument should be of type 'char *' but is of type 'int'. |
|
||||
| printf1.h:44:18:44:20 | ull | This argument should be of type 'int' but is of type 'unsigned long long'. |
|
||||
| printf1.h:45:18:45:20 | ull | This argument should be of type 'unsigned int' but is of type 'unsigned long long'. |
|
||||
| printf1.h:46:18:46:20 | ull | This argument should be of type 'unsigned int' but is of type 'unsigned long long'. |
|
||||
| printf1.h:113:17:113:17 | d | This argument should be of type 'long double' but is of type 'double'. |
|
||||
| printf1.h:114:18:114:18 | d | This argument should be of type 'long double' but is of type 'double'. |
|
||||
| printf1.h:147:19:147:19 | i | This argument should be of type 'long long' but is of type 'int'. |
|
||||
| printf1.h:148:19:148:20 | ui | This argument should be of type 'unsigned long long' but is of type 'unsigned int'. |
|
||||
| printf1.h:160:18:160:18 | i | This argument should be of type 'char *' but is of type 'int'. |
|
||||
| printf1.h:161:21:161:21 | s | This argument should be of type 'int' but is of type 'char *'. |
|
||||
| printf1.h:167:17:167:17 | i | This argument should be of type 'char *' but is of type 'int'. |
|
||||
| printf1.h:168:18:168:18 | i | This argument should be of type 'char *' but is of type 'int'. |
|
||||
| printf1.h:169:19:169:19 | i | This argument should be of type 'char *' but is of type 'int'. |
|
||||
| printf1.h:174:17:174:17 | s | This argument should be of type 'int' but is of type 'char *'. |
|
||||
| printf1.h:175:18:175:18 | s | This argument should be of type 'int' but is of type 'char *'. |
|
||||
| printf1.h:176:19:176:19 | s | This argument should be of type 'int' but is of type 'char *'. |
|
||||
| printf1.h:180:17:180:17 | s | This argument should be of type 'int' but is of type 'char *'. |
|
||||
| printf1.h:181:20:181:20 | i | This argument should be of type 'char *' but is of type 'int'. |
|
||||
| printf1.h:183:18:183:18 | s | This argument should be of type 'int' but is of type 'char *'. |
|
||||
| printf1.h:184:21:184:21 | i | This argument should be of type 'char *' but is of type 'int'. |
|
||||
| printf1.h:186:19:186:19 | s | This argument should be of type 'int' but is of type 'char *'. |
|
||||
| printf1.h:187:22:187:22 | i | This argument should be of type 'char *' but is of type 'int'. |
|
||||
| printf1.h:189:19:189:19 | s | This argument should be of type 'int' but is of type 'char *'. |
|
||||
| printf1.h:190:22:190:22 | i | This argument should be of type 'char *' but is of type 'int'. |
|
||||
| printf1.h:192:19:192:19 | s | This argument should be of type 'int' but is of type 'char *'. |
|
||||
| printf1.h:193:22:193:22 | s | This argument should be of type 'int' but is of type 'char *'. |
|
||||
| printf1.h:194:25:194:25 | i | This argument should be of type 'char *' but is of type 'int'. |
|
||||
| printf1.h:198:24:198:24 | s | This argument should be of type 'int' but is of type 'char *'. |
|
||||
| printf1.h:199:21:199:21 | i | This argument should be of type 'char *' but is of type 'int'. |
|
||||
| printf1.h:202:26:202:26 | s | This argument should be of type 'int' but is of type 'char *'. |
|
||||
| printf1.h:203:23:203:23 | i | This argument should be of type 'char *' but is of type 'int'. |
|
||||
| printf1.h:206:25:206:25 | s | This argument should be of type 'int' but is of type 'char *'. |
|
||||
| printf1.h:207:22:207:22 | i | This argument should be of type 'char *' but is of type 'int'. |
|
||||
| printf1.h:210:26:210:26 | s | This argument should be of type 'int' but is of type 'char *'. |
|
||||
| printf1.h:211:23:211:23 | i | This argument should be of type 'char *' but is of type 'int'. |
|
||||
| printf1.h:214:28:214:28 | s | This argument should be of type 'int' but is of type 'char *'. |
|
||||
| printf1.h:215:28:215:28 | s | This argument should be of type 'int' but is of type 'char *'. |
|
||||
| printf1.h:216:25:216:25 | i | This argument should be of type 'char *' but is of type 'int'. |
|
||||
| printf1.h:221:18:221:18 | s | This argument should be of type 'int' but is of type 'char *'. |
|
||||
| printf1.h:222:20:222:20 | s | This argument should be of type 'int' but is of type 'char *'. |
|
||||
| printf1.h:225:23:225:23 | i | This argument should be of type 'char *' but is of type 'int'. |
|
||||
| printf1.h:228:24:228:24 | i | This argument should be of type 'char *' but is of type 'int'. |
|
||||
| printf1.h:231:25:231:25 | i | This argument should be of type 'char *' but is of type 'int'. |
|
||||
| printf1.h:234:25:234:25 | i | This argument should be of type 'char *' but is of type 'int'. |
|
||||
| printf1.h:235:22:235:22 | s | This argument should be of type 'int' but is of type 'char *'. |
|
||||
| printf1.h:276:32:276:32 | s | This argument should be of type 'int' but is of type 'char *'. |
|
||||
| printf1.h:278:17:278:17 | s | This argument should be of type 'int' but is of type 'char *'. |
|
||||
| real_world.h:61:21:61:22 | & ... | This argument should be of type 'int *' but is of type 'short *'. |
|
||||
| real_world.h:62:22:62:23 | & ... | This argument should be of type 'short *' but is of type 'int *'. |
|
||||
| real_world.h:63:22:63:24 | & ... | This argument should be of type 'short *' but is of type 'unsigned int *'. |
|
||||
| real_world.h:64:22:64:24 | & ... | This argument should be of type 'short *' but is of type 'signed int *'. |
|
||||
| wide_string.h:25:18:25:20 | c | This argument should be of type 'char' but is of type 'char *'. |
|
||||
| format.h:16:59:16:61 | str | This format specifier for type 'int' does not match the argument type 'char *'. |
|
||||
| format.h:16:64:16:64 | i | This format specifier for type 'double' does not match the argument type 'int'. |
|
||||
| format.h:16:67:16:67 | d | This format specifier for type 'char *' does not match the argument type 'double'. |
|
||||
| linux.cpp:15:24:15:41 | call to get_template_value | This format specifier for type 'int' does not match the argument type 'long'. |
|
||||
| linux_c.c:11:15:11:18 | str3 | This format specifier for type 'char *' does not match the argument type 'short *'. |
|
||||
| pri_macros.h:15:35:15:40 | my_u64 | This format specifier for type 'unsigned int' does not match the argument type 'unsigned long long'. |
|
||||
| printf1.h:12:27:12:27 | i | This format specifier for type 'double' does not match the argument type 'int'. |
|
||||
| printf1.h:18:18:18:18 | i | This format specifier for type 'void *' does not match the argument type 'int'. |
|
||||
| printf1.h:25:22:25:22 | i | This format specifier for type 'char *' does not match the argument type 'int'. |
|
||||
| printf1.h:27:19:27:20 | cs | This format specifier for type 'int' does not match the argument type 'char *'. |
|
||||
| printf1.h:38:18:38:30 | MYONETHOUSAND | This format specifier for type 'char *' does not match the argument type 'int'. |
|
||||
| printf1.h:44:18:44:20 | ull | This format specifier for type 'int' does not match the argument type 'unsigned long long'. |
|
||||
| printf1.h:45:18:45:20 | ull | This format specifier for type 'unsigned int' does not match the argument type 'unsigned long long'. |
|
||||
| printf1.h:46:18:46:20 | ull | This format specifier for type 'unsigned int' does not match the argument type 'unsigned long long'. |
|
||||
| printf1.h:113:17:113:17 | d | This format specifier for type 'long double' does not match the argument type 'double'. |
|
||||
| printf1.h:114:18:114:18 | d | This format specifier for type 'long double' does not match the argument type 'double'. |
|
||||
| printf1.h:147:19:147:19 | i | This format specifier for type 'long long' does not match the argument type 'int'. |
|
||||
| printf1.h:148:19:148:20 | ui | This format specifier for type 'unsigned long long' does not match the argument type 'unsigned int'. |
|
||||
| printf1.h:160:18:160:18 | i | This format specifier for type 'char *' does not match the argument type 'int'. |
|
||||
| printf1.h:161:21:161:21 | s | This format specifier for type 'int' does not match the argument type 'char *'. |
|
||||
| printf1.h:167:17:167:17 | i | This format specifier for type 'char *' does not match the argument type 'int'. |
|
||||
| printf1.h:168:18:168:18 | i | This format specifier for type 'char *' does not match the argument type 'int'. |
|
||||
| printf1.h:169:19:169:19 | i | This format specifier for type 'char *' does not match the argument type 'int'. |
|
||||
| printf1.h:174:17:174:17 | s | This format specifier for type 'int' does not match the argument type 'char *'. |
|
||||
| printf1.h:175:18:175:18 | s | This format specifier for type 'int' does not match the argument type 'char *'. |
|
||||
| printf1.h:176:19:176:19 | s | This format specifier for type 'int' does not match the argument type 'char *'. |
|
||||
| printf1.h:180:17:180:17 | s | This format specifier for type 'int' does not match the argument type 'char *'. |
|
||||
| printf1.h:181:20:181:20 | i | This format specifier for type 'char *' does not match the argument type 'int'. |
|
||||
| printf1.h:183:18:183:18 | s | This format specifier for type 'int' does not match the argument type 'char *'. |
|
||||
| printf1.h:184:21:184:21 | i | This format specifier for type 'char *' does not match the argument type 'int'. |
|
||||
| printf1.h:186:19:186:19 | s | This format specifier for type 'int' does not match the argument type 'char *'. |
|
||||
| printf1.h:187:22:187:22 | i | This format specifier for type 'char *' does not match the argument type 'int'. |
|
||||
| printf1.h:189:19:189:19 | s | This format specifier for type 'int' does not match the argument type 'char *'. |
|
||||
| printf1.h:190:22:190:22 | i | This format specifier for type 'char *' does not match the argument type 'int'. |
|
||||
| printf1.h:192:19:192:19 | s | This format specifier for type 'int' does not match the argument type 'char *'. |
|
||||
| printf1.h:193:22:193:22 | s | This format specifier for type 'int' does not match the argument type 'char *'. |
|
||||
| printf1.h:194:25:194:25 | i | This format specifier for type 'char *' does not match the argument type 'int'. |
|
||||
| printf1.h:198:24:198:24 | s | This format specifier for type 'int' does not match the argument type 'char *'. |
|
||||
| printf1.h:199:21:199:21 | i | This format specifier for type 'char *' does not match the argument type 'int'. |
|
||||
| printf1.h:202:26:202:26 | s | This format specifier for type 'int' does not match the argument type 'char *'. |
|
||||
| printf1.h:203:23:203:23 | i | This format specifier for type 'char *' does not match the argument type 'int'. |
|
||||
| printf1.h:206:25:206:25 | s | This format specifier for type 'int' does not match the argument type 'char *'. |
|
||||
| printf1.h:207:22:207:22 | i | This format specifier for type 'char *' does not match the argument type 'int'. |
|
||||
| printf1.h:210:26:210:26 | s | This format specifier for type 'int' does not match the argument type 'char *'. |
|
||||
| printf1.h:211:23:211:23 | i | This format specifier for type 'char *' does not match the argument type 'int'. |
|
||||
| printf1.h:214:28:214:28 | s | This format specifier for type 'int' does not match the argument type 'char *'. |
|
||||
| printf1.h:215:28:215:28 | s | This format specifier for type 'int' does not match the argument type 'char *'. |
|
||||
| printf1.h:216:25:216:25 | i | This format specifier for type 'char *' does not match the argument type 'int'. |
|
||||
| printf1.h:221:18:221:18 | s | This format specifier for type 'int' does not match the argument type 'char *'. |
|
||||
| printf1.h:222:20:222:20 | s | This format specifier for type 'int' does not match the argument type 'char *'. |
|
||||
| printf1.h:225:23:225:23 | i | This format specifier for type 'char *' does not match the argument type 'int'. |
|
||||
| printf1.h:228:24:228:24 | i | This format specifier for type 'char *' does not match the argument type 'int'. |
|
||||
| printf1.h:231:25:231:25 | i | This format specifier for type 'char *' does not match the argument type 'int'. |
|
||||
| printf1.h:234:25:234:25 | i | This format specifier for type 'char *' does not match the argument type 'int'. |
|
||||
| printf1.h:235:22:235:22 | s | This format specifier for type 'int' does not match the argument type 'char *'. |
|
||||
| printf1.h:276:32:276:32 | s | This format specifier for type 'int' does not match the argument type 'char *'. |
|
||||
| printf1.h:278:17:278:17 | s | This format specifier for type 'int' does not match the argument type 'char *'. |
|
||||
| real_world.h:61:21:61:22 | & ... | This format specifier for type 'int *' does not match the argument type 'short *'. |
|
||||
| real_world.h:62:22:62:23 | & ... | This format specifier for type 'short *' does not match the argument type 'int *'. |
|
||||
| real_world.h:63:22:63:24 | & ... | This format specifier for type 'short *' does not match the argument type 'unsigned int *'. |
|
||||
| real_world.h:64:22:64:24 | & ... | This format specifier for type 'short *' does not match the argument type 'signed int *'. |
|
||||
| wide_string.h:25:18:25:20 | c | This format specifier for type 'char' does not match the argument type 'char *'. |
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
| printf.cpp:43:29:43:35 | test | This argument should be of type 'char *' but is of type 'char16_t *'. |
|
||||
| printf.cpp:50:29:50:35 | test | This argument should be of type 'char16_t *' but is of type 'wchar_t *'. |
|
||||
| printf.cpp:43:29:43:35 | test | This format specifier for type 'char *' does not match the argument type 'char16_t *'. |
|
||||
| printf.cpp:50:29:50:35 | test | This format specifier for type 'char16_t *' does not match the argument type 'wchar_t *'. |
|
||||
|
||||
@@ -1,20 +1,20 @@
|
||||
| format.h:16:59:16:61 | str | This argument should be of type 'int' but is of type 'char *'. |
|
||||
| format.h:16:64:16:64 | i | This argument should be of type 'double' but is of type 'int'. |
|
||||
| format.h:16:67:16:67 | d | This argument should be of type 'char *' but is of type 'double'. |
|
||||
| pri_macros.h:15:35:15:40 | my_u64 | This argument should be of type 'unsigned int' but is of type 'unsigned long long'. |
|
||||
| printf1.h:12:27:12:27 | i | This argument should be of type 'double' but is of type 'int'. |
|
||||
| printf1.h:18:18:18:18 | i | This argument should be of type 'void *' but is of type 'int'. |
|
||||
| printf1.h:25:22:25:22 | i | This argument should be of type 'char *' but is of type 'int'. |
|
||||
| printf1.h:27:19:27:20 | cs | This argument should be of type 'int' but is of type 'char *'. |
|
||||
| printf1.h:38:18:38:30 | MYONETHOUSAND | This argument should be of type 'char *' but is of type 'int'. |
|
||||
| printf1.h:44:18:44:20 | ull | This argument should be of type 'int' but is of type 'unsigned long long'. |
|
||||
| printf1.h:45:18:45:20 | ull | This argument should be of type 'unsigned int' but is of type 'unsigned long long'. |
|
||||
| printf1.h:46:18:46:20 | ull | This argument should be of type 'unsigned int' but is of type 'unsigned long long'. |
|
||||
| printf1.h:130:18:130:18 | 0 | This argument should be of type 'void *' but is of type 'int'. |
|
||||
| printf1.h:168:19:168:19 | i | This argument should be of type 'long long' but is of type 'int'. |
|
||||
| printf1.h:169:19:169:20 | ui | This argument should be of type 'unsigned long long' but is of type 'unsigned int'. |
|
||||
| real_world.h:61:21:61:22 | & ... | This argument should be of type 'int *' but is of type 'short *'. |
|
||||
| real_world.h:62:22:62:23 | & ... | This argument should be of type 'short *' but is of type 'int *'. |
|
||||
| real_world.h:63:22:63:24 | & ... | This argument should be of type 'short *' but is of type 'unsigned int *'. |
|
||||
| real_world.h:64:22:64:24 | & ... | This argument should be of type 'short *' but is of type 'signed int *'. |
|
||||
| wide_string.h:25:18:25:20 | c | This argument should be of type 'char' but is of type 'char *'. |
|
||||
| format.h:16:59:16:61 | str | This format specifier for type 'int' does not match the argument type 'char *'. |
|
||||
| format.h:16:64:16:64 | i | This format specifier for type 'double' does not match the argument type 'int'. |
|
||||
| format.h:16:67:16:67 | d | This format specifier for type 'char *' does not match the argument type 'double'. |
|
||||
| pri_macros.h:15:35:15:40 | my_u64 | This format specifier for type 'unsigned int' does not match the argument type 'unsigned long long'. |
|
||||
| printf1.h:12:27:12:27 | i | This format specifier for type 'double' does not match the argument type 'int'. |
|
||||
| printf1.h:18:18:18:18 | i | This format specifier for type 'void *' does not match the argument type 'int'. |
|
||||
| printf1.h:25:22:25:22 | i | This format specifier for type 'char *' does not match the argument type 'int'. |
|
||||
| printf1.h:27:19:27:20 | cs | This format specifier for type 'int' does not match the argument type 'char *'. |
|
||||
| printf1.h:38:18:38:30 | MYONETHOUSAND | This format specifier for type 'char *' does not match the argument type 'int'. |
|
||||
| printf1.h:44:18:44:20 | ull | This format specifier for type 'int' does not match the argument type 'unsigned long long'. |
|
||||
| printf1.h:45:18:45:20 | ull | This format specifier for type 'unsigned int' does not match the argument type 'unsigned long long'. |
|
||||
| printf1.h:46:18:46:20 | ull | This format specifier for type 'unsigned int' does not match the argument type 'unsigned long long'. |
|
||||
| printf1.h:130:18:130:18 | 0 | This format specifier for type 'void *' does not match the argument type 'int'. |
|
||||
| printf1.h:168:19:168:19 | i | This format specifier for type 'long long' does not match the argument type 'int'. |
|
||||
| printf1.h:169:19:169:20 | ui | This format specifier for type 'unsigned long long' does not match the argument type 'unsigned int'. |
|
||||
| real_world.h:61:21:61:22 | & ... | This format specifier for type 'int *' does not match the argument type 'short *'. |
|
||||
| real_world.h:62:22:62:23 | & ... | This format specifier for type 'short *' does not match the argument type 'int *'. |
|
||||
| real_world.h:63:22:63:24 | & ... | This format specifier for type 'short *' does not match the argument type 'unsigned int *'. |
|
||||
| real_world.h:64:22:64:24 | & ... | This format specifier for type 'short *' does not match the argument type 'signed int *'. |
|
||||
| wide_string.h:25:18:25:20 | c | This format specifier for type 'char' does not match the argument type 'char *'. |
|
||||
|
||||
@@ -1,37 +1,37 @@
|
||||
| format.h:16:59:16:61 | str | This argument should be of type 'int' but is of type 'char *'. |
|
||||
| format.h:16:64:16:64 | i | This argument should be of type 'double' but is of type 'int'. |
|
||||
| format.h:16:67:16:67 | d | This argument should be of type 'char *' but is of type 'double'. |
|
||||
| pri_macros.h:15:35:15:40 | my_u64 | This argument should be of type 'unsigned int' but is of type 'unsigned long long'. |
|
||||
| printf1.h:12:27:12:27 | i | This argument should be of type 'double' but is of type 'int'. |
|
||||
| printf1.h:18:18:18:18 | i | This argument should be of type 'void *' but is of type 'int'. |
|
||||
| printf1.h:25:22:25:22 | i | This argument should be of type 'char *' but is of type 'int'. |
|
||||
| printf1.h:27:19:27:20 | cs | This argument should be of type 'int' but is of type 'char *'. |
|
||||
| printf1.h:38:18:38:30 | MYONETHOUSAND | This argument should be of type 'char *' but is of type 'int'. |
|
||||
| printf1.h:44:18:44:20 | ull | This argument should be of type 'int' but is of type 'unsigned long long'. |
|
||||
| printf1.h:45:18:45:20 | ull | This argument should be of type 'unsigned int' but is of type 'unsigned long long'. |
|
||||
| printf1.h:46:18:46:20 | ull | This argument should be of type 'unsigned int' but is of type 'unsigned long long'. |
|
||||
| printf1.h:71:19:71:20 | st | This argument should be of type 'ssize_t' but is of type 'unsigned long long'. |
|
||||
| printf1.h:72:19:72:20 | ST | This argument should be of type 'ssize_t' but is of type 'unsigned long long'. |
|
||||
| printf1.h:73:19:73:22 | c_st | This argument should be of type 'ssize_t' but is of type 'unsigned long long'. |
|
||||
| printf1.h:74:19:74:22 | C_ST | This argument should be of type 'ssize_t' but is of type 'unsigned long long'. |
|
||||
| printf1.h:75:19:75:28 | sizeof(<expr>) | This argument should be of type 'ssize_t' but is of type 'unsigned long long'. |
|
||||
| printf1.h:84:23:84:35 | ... - ... | This argument should be of type 'ssize_t' but is of type 'long long'. |
|
||||
| printf1.h:116:16:116:24 | myString3 | This argument should be of type '__wchar_t *' but is of type 'int *'. |
|
||||
| printf1.h:117:16:117:24 | myString4 | This argument should be of type '__wchar_t *' but is of type 'int *'. |
|
||||
| printf1.h:130:18:130:18 | 0 | This argument should be of type 'void *' but is of type 'int'. |
|
||||
| printf1.h:181:21:181:22 | ll | This argument should be of type 'int' but is of type 'long long'. |
|
||||
| printf1.h:182:21:182:23 | ull | This argument should be of type 'unsigned int' but is of type 'unsigned long long'. |
|
||||
| printf1.h:185:21:185:23 | i64 | This argument should be of type 'int' but is of type 'long long'. |
|
||||
| printf1.h:186:21:186:23 | u64 | This argument should be of type 'unsigned int' but is of type 'unsigned long long'. |
|
||||
| printf1.h:188:21:188:21 | i | This argument should be of type 'long long' but is of type 'int'. |
|
||||
| printf1.h:189:21:189:22 | ui | This argument should be of type 'unsigned long long' but is of type 'unsigned int'. |
|
||||
| printf1.h:190:21:190:21 | l | This argument should be of type 'long long' but is of type 'long'. |
|
||||
| printf1.h:191:21:191:22 | ul | This argument should be of type 'unsigned long long' but is of type 'unsigned long'. |
|
||||
| printf1.h:194:21:194:23 | i32 | This argument should be of type 'long long' but is of type 'int'. |
|
||||
| printf1.h:195:21:195:23 | u32 | This argument should be of type 'unsigned long long' but is of type 'unsigned int'. |
|
||||
| real_world.h:61:21:61:22 | & ... | This argument should be of type 'int *' but is of type 'short *'. |
|
||||
| real_world.h:62:22:62:23 | & ... | This argument should be of type 'short *' but is of type 'int *'. |
|
||||
| real_world.h:63:22:63:24 | & ... | This argument should be of type 'short *' but is of type 'unsigned int *'. |
|
||||
| real_world.h:64:22:64:24 | & ... | This argument should be of type 'short *' but is of type 'signed int *'. |
|
||||
| wide_string.h:25:18:25:20 | c | This argument should be of type 'char' but is of type 'char *'. |
|
||||
| wide_string.h:29:19:29:22 | c | This argument should be of type 'wchar_t' but is of type '__wchar_t *'. |
|
||||
| format.h:16:59:16:61 | str | This format specifier for type 'int' does not match the argument type 'char *'. |
|
||||
| format.h:16:64:16:64 | i | This format specifier for type 'double' does not match the argument type 'int'. |
|
||||
| format.h:16:67:16:67 | d | This format specifier for type 'char *' does not match the argument type 'double'. |
|
||||
| pri_macros.h:15:35:15:40 | my_u64 | This format specifier for type 'unsigned int' does not match the argument type 'unsigned long long'. |
|
||||
| printf1.h:12:27:12:27 | i | This format specifier for type 'double' does not match the argument type 'int'. |
|
||||
| printf1.h:18:18:18:18 | i | This format specifier for type 'void *' does not match the argument type 'int'. |
|
||||
| printf1.h:25:22:25:22 | i | This format specifier for type 'char *' does not match the argument type 'int'. |
|
||||
| printf1.h:27:19:27:20 | cs | This format specifier for type 'int' does not match the argument type 'char *'. |
|
||||
| printf1.h:38:18:38:30 | MYONETHOUSAND | This format specifier for type 'char *' does not match the argument type 'int'. |
|
||||
| printf1.h:44:18:44:20 | ull | This format specifier for type 'int' does not match the argument type 'unsigned long long'. |
|
||||
| printf1.h:45:18:45:20 | ull | This format specifier for type 'unsigned int' does not match the argument type 'unsigned long long'. |
|
||||
| printf1.h:46:18:46:20 | ull | This format specifier for type 'unsigned int' does not match the argument type 'unsigned long long'. |
|
||||
| printf1.h:71:19:71:20 | st | This format specifier for type 'ssize_t' does not match the argument type 'unsigned long long'. |
|
||||
| printf1.h:72:19:72:20 | ST | This format specifier for type 'ssize_t' does not match the argument type 'unsigned long long'. |
|
||||
| printf1.h:73:19:73:22 | c_st | This format specifier for type 'ssize_t' does not match the argument type 'unsigned long long'. |
|
||||
| printf1.h:74:19:74:22 | C_ST | This format specifier for type 'ssize_t' does not match the argument type 'unsigned long long'. |
|
||||
| printf1.h:75:19:75:28 | sizeof(<expr>) | This format specifier for type 'ssize_t' does not match the argument type 'unsigned long long'. |
|
||||
| printf1.h:84:23:84:35 | ... - ... | This format specifier for type 'ssize_t' does not match the argument type 'long long'. |
|
||||
| printf1.h:116:16:116:24 | myString3 | This format specifier for type '__wchar_t *' does not match the argument type 'int *'. |
|
||||
| printf1.h:117:16:117:24 | myString4 | This format specifier for type '__wchar_t *' does not match the argument type 'int *'. |
|
||||
| printf1.h:130:18:130:18 | 0 | This format specifier for type 'void *' does not match the argument type 'int'. |
|
||||
| printf1.h:181:21:181:22 | ll | This format specifier for type 'int' does not match the argument type 'long long'. |
|
||||
| printf1.h:182:21:182:23 | ull | This format specifier for type 'unsigned int' does not match the argument type 'unsigned long long'. |
|
||||
| printf1.h:185:21:185:23 | i64 | This format specifier for type 'int' does not match the argument type 'long long'. |
|
||||
| printf1.h:186:21:186:23 | u64 | This format specifier for type 'unsigned int' does not match the argument type 'unsigned long long'. |
|
||||
| printf1.h:188:21:188:21 | i | This format specifier for type 'long long' does not match the argument type 'int'. |
|
||||
| printf1.h:189:21:189:22 | ui | This format specifier for type 'unsigned long long' does not match the argument type 'unsigned int'. |
|
||||
| printf1.h:190:21:190:21 | l | This format specifier for type 'long long' does not match the argument type 'long'. |
|
||||
| printf1.h:191:21:191:22 | ul | This format specifier for type 'unsigned long long' does not match the argument type 'unsigned long'. |
|
||||
| printf1.h:194:21:194:23 | i32 | This format specifier for type 'long long' does not match the argument type 'int'. |
|
||||
| printf1.h:195:21:195:23 | u32 | This format specifier for type 'unsigned long long' does not match the argument type 'unsigned int'. |
|
||||
| real_world.h:61:21:61:22 | & ... | This format specifier for type 'int *' does not match the argument type 'short *'. |
|
||||
| real_world.h:62:22:62:23 | & ... | This format specifier for type 'short *' does not match the argument type 'int *'. |
|
||||
| real_world.h:63:22:63:24 | & ... | This format specifier for type 'short *' does not match the argument type 'unsigned int *'. |
|
||||
| real_world.h:64:22:64:24 | & ... | This format specifier for type 'short *' does not match the argument type 'signed int *'. |
|
||||
| wide_string.h:25:18:25:20 | c | This format specifier for type 'char' does not match the argument type 'char *'. |
|
||||
| wide_string.h:29:19:29:22 | c | This format specifier for type 'wchar_t' does not match the argument type '__wchar_t *'. |
|
||||
|
||||
@@ -1,35 +1,35 @@
|
||||
| format.h:16:59:16:61 | str | This argument should be of type 'int' but is of type 'char *'. |
|
||||
| format.h:16:64:16:64 | i | This argument should be of type 'double' but is of type 'int'. |
|
||||
| format.h:16:67:16:67 | d | This argument should be of type 'char *' but is of type 'double'. |
|
||||
| pri_macros.h:15:35:15:40 | my_u64 | This argument should be of type 'unsigned int' but is of type 'unsigned long long'. |
|
||||
| printf1.h:12:27:12:27 | i | This argument should be of type 'double' but is of type 'int'. |
|
||||
| printf1.h:18:18:18:18 | i | This argument should be of type 'void *' but is of type 'int'. |
|
||||
| printf1.h:25:22:25:22 | i | This argument should be of type 'char *' but is of type 'int'. |
|
||||
| printf1.h:27:19:27:20 | cs | This argument should be of type 'int' but is of type 'char *'. |
|
||||
| printf1.h:38:18:38:30 | MYONETHOUSAND | This argument should be of type 'char *' but is of type 'int'. |
|
||||
| printf1.h:44:18:44:20 | ull | This argument should be of type 'int' but is of type 'unsigned long long'. |
|
||||
| printf1.h:45:18:45:20 | ull | This argument should be of type 'unsigned int' but is of type 'unsigned long long'. |
|
||||
| printf1.h:46:18:46:20 | ull | This argument should be of type 'unsigned int' but is of type 'unsigned long long'. |
|
||||
| printf1.h:71:19:71:20 | st | This argument should be of type 'ssize_t' but is of type 'unsigned long long'. |
|
||||
| printf1.h:72:19:72:20 | ST | This argument should be of type 'ssize_t' but is of type 'unsigned long long'. |
|
||||
| printf1.h:73:19:73:22 | c_st | This argument should be of type 'ssize_t' but is of type 'unsigned long long'. |
|
||||
| printf1.h:74:19:74:22 | C_ST | This argument should be of type 'ssize_t' but is of type 'unsigned long long'. |
|
||||
| printf1.h:75:19:75:28 | sizeof(<expr>) | This argument should be of type 'ssize_t' but is of type 'unsigned long long'. |
|
||||
| printf1.h:84:23:84:35 | ... - ... | This argument should be of type 'ssize_t' but is of type 'long long'. |
|
||||
| printf1.h:130:18:130:18 | 0 | This argument should be of type 'void *' but is of type 'int'. |
|
||||
| printf1.h:155:21:155:22 | ll | This argument should be of type 'int' but is of type 'long long'. |
|
||||
| printf1.h:156:21:156:23 | ull | This argument should be of type 'unsigned int' but is of type 'unsigned long long'. |
|
||||
| printf1.h:159:21:159:23 | i64 | This argument should be of type 'int' but is of type 'long long'. |
|
||||
| printf1.h:160:21:160:23 | u64 | This argument should be of type 'unsigned int' but is of type 'unsigned long long'. |
|
||||
| printf1.h:162:21:162:21 | i | This argument should be of type 'long long' but is of type 'int'. |
|
||||
| printf1.h:163:21:163:22 | ui | This argument should be of type 'unsigned long long' but is of type 'unsigned int'. |
|
||||
| printf1.h:164:21:164:21 | l | This argument should be of type 'long long' but is of type 'long'. |
|
||||
| printf1.h:165:21:165:22 | ul | This argument should be of type 'unsigned long long' but is of type 'unsigned long'. |
|
||||
| printf1.h:168:21:168:23 | i32 | This argument should be of type 'long long' but is of type 'int'. |
|
||||
| printf1.h:169:21:169:23 | u32 | This argument should be of type 'unsigned long long' but is of type 'unsigned int'. |
|
||||
| real_world.h:61:21:61:22 | & ... | This argument should be of type 'int *' but is of type 'short *'. |
|
||||
| real_world.h:62:22:62:23 | & ... | This argument should be of type 'short *' but is of type 'int *'. |
|
||||
| real_world.h:63:22:63:24 | & ... | This argument should be of type 'short *' but is of type 'unsigned int *'. |
|
||||
| real_world.h:64:22:64:24 | & ... | This argument should be of type 'short *' but is of type 'signed int *'. |
|
||||
| wide_string.h:25:18:25:20 | c | This argument should be of type 'char' but is of type 'char *'. |
|
||||
| wide_string.h:29:19:29:22 | c | This argument should be of type 'wchar_t' but is of type 'unsigned short *'. |
|
||||
| format.h:16:59:16:61 | str | This format specifier for type 'int' does not match the argument type 'char *'. |
|
||||
| format.h:16:64:16:64 | i | This format specifier for type 'double' does not match the argument type 'int'. |
|
||||
| format.h:16:67:16:67 | d | This format specifier for type 'char *' does not match the argument type 'double'. |
|
||||
| pri_macros.h:15:35:15:40 | my_u64 | This format specifier for type 'unsigned int' does not match the argument type 'unsigned long long'. |
|
||||
| printf1.h:12:27:12:27 | i | This format specifier for type 'double' does not match the argument type 'int'. |
|
||||
| printf1.h:18:18:18:18 | i | This format specifier for type 'void *' does not match the argument type 'int'. |
|
||||
| printf1.h:25:22:25:22 | i | This format specifier for type 'char *' does not match the argument type 'int'. |
|
||||
| printf1.h:27:19:27:20 | cs | This format specifier for type 'int' does not match the argument type 'char *'. |
|
||||
| printf1.h:38:18:38:30 | MYONETHOUSAND | This format specifier for type 'char *' does not match the argument type 'int'. |
|
||||
| printf1.h:44:18:44:20 | ull | This format specifier for type 'int' does not match the argument type 'unsigned long long'. |
|
||||
| printf1.h:45:18:45:20 | ull | This format specifier for type 'unsigned int' does not match the argument type 'unsigned long long'. |
|
||||
| printf1.h:46:18:46:20 | ull | This format specifier for type 'unsigned int' does not match the argument type 'unsigned long long'. |
|
||||
| printf1.h:71:19:71:20 | st | This format specifier for type 'ssize_t' does not match the argument type 'unsigned long long'. |
|
||||
| printf1.h:72:19:72:20 | ST | This format specifier for type 'ssize_t' does not match the argument type 'unsigned long long'. |
|
||||
| printf1.h:73:19:73:22 | c_st | This format specifier for type 'ssize_t' does not match the argument type 'unsigned long long'. |
|
||||
| printf1.h:74:19:74:22 | C_ST | This format specifier for type 'ssize_t' does not match the argument type 'unsigned long long'. |
|
||||
| printf1.h:75:19:75:28 | sizeof(<expr>) | This format specifier for type 'ssize_t' does not match the argument type 'unsigned long long'. |
|
||||
| printf1.h:84:23:84:35 | ... - ... | This format specifier for type 'ssize_t' does not match the argument type 'long long'. |
|
||||
| printf1.h:130:18:130:18 | 0 | This format specifier for type 'void *' does not match the argument type 'int'. |
|
||||
| printf1.h:155:21:155:22 | ll | This format specifier for type 'int' does not match the argument type 'long long'. |
|
||||
| printf1.h:156:21:156:23 | ull | This format specifier for type 'unsigned int' does not match the argument type 'unsigned long long'. |
|
||||
| printf1.h:159:21:159:23 | i64 | This format specifier for type 'int' does not match the argument type 'long long'. |
|
||||
| printf1.h:160:21:160:23 | u64 | This format specifier for type 'unsigned int' does not match the argument type 'unsigned long long'. |
|
||||
| printf1.h:162:21:162:21 | i | This format specifier for type 'long long' does not match the argument type 'int'. |
|
||||
| printf1.h:163:21:163:22 | ui | This format specifier for type 'unsigned long long' does not match the argument type 'unsigned int'. |
|
||||
| printf1.h:164:21:164:21 | l | This format specifier for type 'long long' does not match the argument type 'long'. |
|
||||
| printf1.h:165:21:165:22 | ul | This format specifier for type 'unsigned long long' does not match the argument type 'unsigned long'. |
|
||||
| printf1.h:168:21:168:23 | i32 | This format specifier for type 'long long' does not match the argument type 'int'. |
|
||||
| printf1.h:169:21:169:23 | u32 | This format specifier for type 'unsigned long long' does not match the argument type 'unsigned int'. |
|
||||
| real_world.h:61:21:61:22 | & ... | This format specifier for type 'int *' does not match the argument type 'short *'. |
|
||||
| real_world.h:62:22:62:23 | & ... | This format specifier for type 'short *' does not match the argument type 'int *'. |
|
||||
| real_world.h:63:22:63:24 | & ... | This format specifier for type 'short *' does not match the argument type 'unsigned int *'. |
|
||||
| real_world.h:64:22:64:24 | & ... | This format specifier for type 'short *' does not match the argument type 'signed int *'. |
|
||||
| wide_string.h:25:18:25:20 | c | This format specifier for type 'char' does not match the argument type 'char *'. |
|
||||
| wide_string.h:29:19:29:22 | c | This format specifier for type 'wchar_t' does not match the argument type 'unsigned short *'. |
|
||||
|
||||
@@ -13,3 +13,5 @@
|
||||
| test.cpp:266:10:266:24 | ... > ... | Unsigned subtraction can never be negative. |
|
||||
| test.cpp:276:11:276:19 | ... > ... | Unsigned subtraction can never be negative. |
|
||||
| test.cpp:288:10:288:18 | ... > ... | Unsigned subtraction can never be negative. |
|
||||
| test.cpp:312:9:312:25 | ... > ... | Unsigned subtraction can never be negative. |
|
||||
| test.cpp:362:8:362:16 | ... > ... | Unsigned subtraction can never be negative. |
|
||||
|
||||
@@ -43,7 +43,7 @@ void test(unsigned x, unsigned y, bool unknown) {
|
||||
while(cond()) {
|
||||
if(unknown) { y--; }
|
||||
}
|
||||
|
||||
|
||||
if(x - y > 0) { } // GOOD
|
||||
|
||||
x = y;
|
||||
@@ -298,3 +298,80 @@ int test18() {
|
||||
|
||||
return (a - b > 0); // GOOD (as b = 0)
|
||||
}
|
||||
|
||||
typedef unsigned int uint32_t;
|
||||
typedef long long int64_t;
|
||||
uint32_t get_limit();
|
||||
uint32_t get_data();
|
||||
|
||||
void test19() {
|
||||
// from the doc:
|
||||
uint32_t limit = get_limit();
|
||||
uint32_t total = 0;
|
||||
|
||||
while (limit - total > 0) { // BAD: if `total` is greater than `limit` this will underflow and continue executing the loop.
|
||||
total += get_data();
|
||||
}
|
||||
|
||||
while (total < limit) { // GOOD: never underflows here because there is no arithmetic.
|
||||
total += get_data();
|
||||
}
|
||||
|
||||
while ((int64_t)limit - total > 0) { // GOOD: never underflows here because the result always fits in an `int64_t`.
|
||||
total += get_data();
|
||||
}
|
||||
}
|
||||
|
||||
void test20(int a, bool b, unsigned long c)
|
||||
{
|
||||
int x = 0;
|
||||
|
||||
if(b) {
|
||||
x = (a - c) / 2;
|
||||
} else {
|
||||
x = a - c;
|
||||
}
|
||||
|
||||
if (a - c - x > 0) // GOOD
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t get_uint32();
|
||||
int64_t get_int64();
|
||||
|
||||
void test21(unsigned long a)
|
||||
{
|
||||
{
|
||||
int b = a & get_int64();
|
||||
if (a - b > 0) { } // GOOD
|
||||
}
|
||||
|
||||
{
|
||||
int b = a - get_uint32();
|
||||
if(a - b > 0) { } // GOOD
|
||||
}
|
||||
|
||||
{
|
||||
int64_t c = get_int64();
|
||||
if(c <= 0) {
|
||||
int64_t b = (int64_t)a + c;
|
||||
if(a - b > 0) { } // GOOD
|
||||
}
|
||||
int64_t b = (int64_t)a + c;
|
||||
if(a - b > 0) { } // BAD
|
||||
}
|
||||
|
||||
{
|
||||
unsigned c = get_uint32();
|
||||
if(c >= 1) {
|
||||
int b = a / c;
|
||||
if(a - b > 0) { } // GOOD
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
int b = a >> get_uint32();
|
||||
if(a - b > 0) { } // GOOD
|
||||
}
|
||||
}
|
||||
@@ -13,7 +13,6 @@ nodes
|
||||
| test.cpp:458:6:458:6 | definition of x | semmle.label | definition of x |
|
||||
| test.cpp:464:6:464:6 | definition of x | semmle.label | definition of x |
|
||||
| test.cpp:471:6:471:6 | definition of x | semmle.label | definition of x |
|
||||
| test.cpp:557:15:557:15 | definition of r | semmle.label | definition of r |
|
||||
#select
|
||||
| test.cpp:12:6:12:8 | foo | test.cpp:11:6:11:8 | definition of foo | test.cpp:11:6:11:8 | definition of foo | The variable $@ may not be initialized at this access. | test.cpp:11:6:11:8 | foo | foo |
|
||||
| test.cpp:113:6:113:8 | foo | test.cpp:111:6:111:8 | definition of foo | test.cpp:111:6:111:8 | definition of foo | The variable $@ may not be initialized at this access. | test.cpp:111:6:111:8 | foo | foo |
|
||||
@@ -28,4 +27,3 @@ nodes
|
||||
| test.cpp:460:7:460:7 | x | test.cpp:458:6:458:6 | definition of x | test.cpp:458:6:458:6 | definition of x | The variable $@ may not be initialized at this access. | test.cpp:458:6:458:6 | x | x |
|
||||
| test.cpp:467:2:467:2 | x | test.cpp:464:6:464:6 | definition of x | test.cpp:464:6:464:6 | definition of x | The variable $@ may not be initialized at this access. | test.cpp:464:6:464:6 | x | x |
|
||||
| test.cpp:474:7:474:7 | x | test.cpp:471:6:471:6 | definition of x | test.cpp:471:6:471:6 | definition of x | The variable $@ may not be initialized at this access. | test.cpp:471:6:471:6 | x | x |
|
||||
| test.cpp:567:7:567:7 | r | test.cpp:557:15:557:15 | definition of r | test.cpp:557:15:557:15 | definition of r | The variable $@ may not be initialized at this access. | test.cpp:557:15:557:15 | r | r |
|
||||
|
||||
@@ -564,5 +564,5 @@ void test45() {
|
||||
}
|
||||
|
||||
*rP = NULL;
|
||||
use(r); // GOOD [FALSE POSITIVE]
|
||||
use(r); // GOOD
|
||||
}
|
||||
@@ -16,3 +16,4 @@
|
||||
| test.cpp:151:9:151:24 | new | This allocation cannot throw. $@ is unnecessary. | test.cpp:152:15:152:18 | { ... } | This catch block |
|
||||
| test.cpp:199:15:199:35 | new | This allocation cannot throw. $@ is unnecessary. | test.cpp:201:16:201:19 | { ... } | This catch block |
|
||||
| test.cpp:212:14:212:34 | new | This allocation cannot throw. $@ is unnecessary. | test.cpp:213:34:213:36 | { ... } | This catch block |
|
||||
| test.cpp:246:17:246:31 | new[] | This allocation cannot return null. $@ is unnecessary. | test.cpp:247:8:247:12 | ! ... | This check |
|
||||
|
||||
@@ -233,3 +233,54 @@ void test_operator_new_without_exception_spec() {
|
||||
int* p = new(42, std::nothrow) int; // GOOD
|
||||
if(p == nullptr) {}
|
||||
}
|
||||
|
||||
namespace std {
|
||||
void *memset(void *s, int c, size_t n);
|
||||
}
|
||||
|
||||
// from the qhelp:
|
||||
namespace qhelp {
|
||||
// BAD: the allocation will throw an unhandled exception
|
||||
// instead of returning a null pointer.
|
||||
void bad1(std::size_t length) noexcept {
|
||||
int* dest = new int[length];
|
||||
if(!dest) {
|
||||
return;
|
||||
}
|
||||
std::memset(dest, 0, length);
|
||||
// ...
|
||||
}
|
||||
|
||||
// BAD: the allocation won't throw an exception, but
|
||||
// instead return a null pointer. [NOT DETECTED]
|
||||
void bad2(std::size_t length) noexcept {
|
||||
try {
|
||||
int* dest = new(std::nothrow) int[length];
|
||||
std::memset(dest, 0, length);
|
||||
// ...
|
||||
} catch(std::bad_alloc&) {
|
||||
// ...
|
||||
}
|
||||
}
|
||||
|
||||
// GOOD: the allocation failure is handled appropriately.
|
||||
void good1(std::size_t length) noexcept {
|
||||
try {
|
||||
int* dest = new int[length];
|
||||
std::memset(dest, 0, length);
|
||||
// ...
|
||||
} catch(std::bad_alloc&) {
|
||||
// ...
|
||||
}
|
||||
}
|
||||
|
||||
// GOOD: the allocation failure is handled appropriately.
|
||||
void good2(std::size_t length) noexcept {
|
||||
int* dest = new(std::nothrow) int[length];
|
||||
if(!dest) {
|
||||
return;
|
||||
}
|
||||
std::memset(dest, 0, length);
|
||||
// ...
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,10 +16,6 @@
|
||||
| | forstmt02.cpp:3:6:3:14 | for_loop2 | 0 | 8 | file://:0:0:0:0 | file://:0:0:0:0 | file://:0:0:0:0 | initializer for (__range) | 4: declaration |
|
||||
| | forstmt02.cpp:3:6:3:14 | for_loop2 | 0 | 12 | file://:0:0:0:0 | file://:0:0:0:0 | file://:0:0:0:0 | initializer for (__begin) | 6: (__range) |
|
||||
| | forstmt02.cpp:3:6:3:14 | for_loop2 | 0 | 15 | file://:0:0:0:0 | file://:0:0:0:0 | file://:0:0:0:0 | initializer for (__end) | 6: (__end) |
|
||||
| forstmt | forstmt.h:2:8:2:8 | operator= | 2 | 1 | forstmt.h:2:8:2:8 | forstmt.h:2:8:2:8 | forstmt.h:2:8:2:8 | operator= | <none> |
|
||||
| forstmt | forstmt.h:2:8:2:8 | operator= | 2 | 1 | forstmt.h:2:8:2:8 | forstmt.h:2:8:2:8 | forstmt.h:2:8:2:8 | operator= | <none> |
|
||||
| forstmt | forstmt.h:3:12:3:12 | operator= | 3 | 1 | forstmt.h:3:12:3:12 | forstmt.h:3:12:3:12 | forstmt.h:3:12:3:12 | operator= | <none> |
|
||||
| forstmt | forstmt.h:3:12:3:12 | operator= | 3 | 1 | forstmt.h:3:12:3:12 | forstmt.h:3:12:3:12 | forstmt.h:3:12:3:12 | operator= | <none> |
|
||||
| forstmt | forstmt.h:4:19:4:28 | operator++ | 4 | 1 | forstmt.h:4:19:4:28 | forstmt.h:4:19:4:28 | forstmt.h:4:19:4:28 | operator++ | <none> |
|
||||
| forstmt | forstmt.h:4:19:4:28 | operator++ | 4 | 1 | forstmt.h:4:19:4:28 | forstmt.h:4:19:4:28 | forstmt.h:4:19:4:28 | operator++ | <none> |
|
||||
| forstmt | forstmt.h:5:12:5:20 | operator* | 5 | 1 | forstmt.h:5:12:5:20 | forstmt.h:5:12:5:20 | forstmt.h:5:12:5:20 | operator* | <none> |
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user