mirror of
https://github.com/github/codeql.git
synced 2025-12-16 08:43:11 +01:00
Merge branch 'main' into callderef
This commit is contained in:
@@ -2,7 +2,10 @@
|
||||
|
||||
## General improvements
|
||||
|
||||
* Angular-specific taint sources and sinks are now recognized by the security queries.
|
||||
|
||||
* Support for the following frameworks and libraries has been improved:
|
||||
- [@angular/*](https://www.npmjs.com/package/@angular/core)
|
||||
- [AWS Serverless](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/sam-resource-function.html)
|
||||
- [Alibaba Serverless](https://www.alibabacloud.com/help/doc-detail/156876.htm)
|
||||
- [bluebird](https://www.npmjs.com/package/bluebird)
|
||||
|
||||
@@ -21,7 +21,7 @@ class Include extends PreprocessorDirective, @ppd_include {
|
||||
|
||||
/**
|
||||
* Gets the token which occurs after `#include`, for example `"filename"`
|
||||
* or `<filename>`.
|
||||
* or `<filename>`.
|
||||
*/
|
||||
string getIncludeText() { result = getHead() }
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -2,6 +2,30 @@ private import DataFlowImplSpecific::Private
|
||||
private import DataFlowImplSpecific::Public
|
||||
import Cached
|
||||
|
||||
/**
|
||||
* The cost limits for the `AccessPathFront` to `AccessPathApprox` expansion.
|
||||
*
|
||||
* `apLimit` bounds the acceptable fan-out, and `tupleLimit` bounds the
|
||||
* estimated per-`AccessPathFront` tuple cost. Access paths exceeding both of
|
||||
* these limits are represented with lower precision during pruning.
|
||||
*/
|
||||
predicate accessPathApproxCostLimits(int apLimit, int tupleLimit) {
|
||||
apLimit = 10 and
|
||||
tupleLimit = 10000
|
||||
}
|
||||
|
||||
/**
|
||||
* The cost limits for the `AccessPathApprox` to `AccessPath` expansion.
|
||||
*
|
||||
* `apLimit` bounds the acceptable fan-out, and `tupleLimit` bounds the
|
||||
* estimated per-`AccessPathApprox` tuple cost. Access paths exceeding both of
|
||||
* these limits are represented with lower precision.
|
||||
*/
|
||||
predicate accessPathCostLimits(int apLimit, int tupleLimit) {
|
||||
apLimit = 5 and
|
||||
tupleLimit = 1000
|
||||
}
|
||||
|
||||
cached
|
||||
private module Cached {
|
||||
/**
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -2,6 +2,30 @@ private import DataFlowImplSpecific::Private
|
||||
private import DataFlowImplSpecific::Public
|
||||
import Cached
|
||||
|
||||
/**
|
||||
* The cost limits for the `AccessPathFront` to `AccessPathApprox` expansion.
|
||||
*
|
||||
* `apLimit` bounds the acceptable fan-out, and `tupleLimit` bounds the
|
||||
* estimated per-`AccessPathFront` tuple cost. Access paths exceeding both of
|
||||
* these limits are represented with lower precision during pruning.
|
||||
*/
|
||||
predicate accessPathApproxCostLimits(int apLimit, int tupleLimit) {
|
||||
apLimit = 10 and
|
||||
tupleLimit = 10000
|
||||
}
|
||||
|
||||
/**
|
||||
* The cost limits for the `AccessPathApprox` to `AccessPath` expansion.
|
||||
*
|
||||
* `apLimit` bounds the acceptable fan-out, and `tupleLimit` bounds the
|
||||
* estimated per-`AccessPathApprox` tuple cost. Access paths exceeding both of
|
||||
* these limits are represented with lower precision.
|
||||
*/
|
||||
predicate accessPathCostLimits(int apLimit, int tupleLimit) {
|
||||
apLimit = 5 and
|
||||
tupleLimit = 1000
|
||||
}
|
||||
|
||||
cached
|
||||
private module Cached {
|
||||
/**
|
||||
|
||||
@@ -0,0 +1,169 @@
|
||||
private import cpp
|
||||
// The `ValueNumbering` library has to be imported right after `cpp` to ensure
|
||||
// that the cached IR gets the same checksum here as it does in queries that use
|
||||
// `ValueNumbering` without `DataFlow`.
|
||||
private import semmle.code.cpp.ir.ValueNumbering
|
||||
private import semmle.code.cpp.ir.IR
|
||||
private import semmle.code.cpp.ir.dataflow.DataFlow
|
||||
private import semmle.code.cpp.ir.dataflow.internal.DataFlowUtil
|
||||
|
||||
/**
|
||||
* Gets a short ID for an IR dataflow node.
|
||||
* - For `Instruction`s, this is just the result ID of the instruction (e.g. `m128`).
|
||||
* - For `Operand`s, this is the label of the operand, prefixed with the result ID of the
|
||||
* instruction and a dot (e.g. `m128.left`).
|
||||
* - For `Variable`s, this is the qualified name of the variable.
|
||||
*/
|
||||
private string nodeId(DataFlow::Node node, int order1, int order2) {
|
||||
exists(Instruction instruction | instruction = node.asInstruction() |
|
||||
result = instruction.getResultId() and
|
||||
order1 = instruction.getBlock().getDisplayIndex() and
|
||||
order2 = instruction.getDisplayIndexInBlock()
|
||||
)
|
||||
or
|
||||
exists(Operand operand, Instruction instruction |
|
||||
operand = node.asOperand() and
|
||||
instruction = operand.getUse()
|
||||
|
|
||||
result = instruction.getResultId() + "." + operand.getDumpId() and
|
||||
order1 = instruction.getBlock().getDisplayIndex() and
|
||||
order2 = instruction.getDisplayIndexInBlock()
|
||||
)
|
||||
or
|
||||
result = "var(" + node.asVariable().getQualifiedName() + ")" and
|
||||
order1 = 1000000 and
|
||||
order2 = 0
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the local dataflow from other nodes in the same function to this node.
|
||||
*/
|
||||
private string getFromFlow(DataFlow::Node useNode, int order1, int order2) {
|
||||
exists(DataFlow::Node defNode, string prefix |
|
||||
(
|
||||
simpleLocalFlowStep(defNode, useNode) and prefix = ""
|
||||
or
|
||||
any(DataFlow::Configuration cfg).isAdditionalFlowStep(defNode, useNode) and
|
||||
defNode.getEnclosingCallable() = useNode.getEnclosingCallable() and
|
||||
prefix = "+"
|
||||
) and
|
||||
if defNode.asInstruction() = useNode.asOperand().getAnyDef()
|
||||
then
|
||||
// Shorthand for flow from the def of this operand.
|
||||
result = prefix + "def" and
|
||||
order1 = -1 and
|
||||
order2 = 0
|
||||
else
|
||||
if defNode.asOperand().getUse() = useNode.asInstruction()
|
||||
then
|
||||
// Shorthand for flow from an operand of this instruction
|
||||
result = prefix + defNode.asOperand().getDumpId() and
|
||||
order1 = -1 and
|
||||
order2 = defNode.asOperand().getDumpSortOrder()
|
||||
else result = prefix + nodeId(defNode, order1, order2)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the local dataflow from this node to other nodes in the same function.
|
||||
*/
|
||||
private string getToFlow(DataFlow::Node defNode, int order1, int order2) {
|
||||
exists(DataFlow::Node useNode, string prefix |
|
||||
(
|
||||
simpleLocalFlowStep(defNode, useNode) and prefix = ""
|
||||
or
|
||||
any(DataFlow::Configuration cfg).isAdditionalFlowStep(defNode, useNode) and
|
||||
defNode.getEnclosingCallable() = useNode.getEnclosingCallable() and
|
||||
prefix = "+"
|
||||
) and
|
||||
if useNode.asInstruction() = defNode.asOperand().getUse()
|
||||
then
|
||||
// Shorthand for flow to this operand's instruction.
|
||||
result = prefix + "result" and
|
||||
order1 = -1 and
|
||||
order2 = 0
|
||||
else result = prefix + nodeId(useNode, order1, order2)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the properties of the dataflow node `node`.
|
||||
*/
|
||||
private string getNodeProperty(DataFlow::Node node, string key) {
|
||||
// List dataflow into and out of this node. Flow into this node is printed as `src->@`, and flow
|
||||
// out of this node is printed as `@->dest`.
|
||||
key = "flow" and
|
||||
result =
|
||||
strictconcat(string flow, boolean to, int order1, int order2 |
|
||||
flow = getFromFlow(node, order1, order2) + "->@" and to = false
|
||||
or
|
||||
flow = "@->" + getToFlow(node, order1, order2) and to = true
|
||||
|
|
||||
flow, ", " order by to, order1, order2, flow
|
||||
)
|
||||
or
|
||||
// Is this node a dataflow sink?
|
||||
key = "sink" and
|
||||
any(DataFlow::Configuration cfg).isSink(node) and
|
||||
result = "true"
|
||||
or
|
||||
// Is this node a dataflow source?
|
||||
key = "source" and
|
||||
any(DataFlow::Configuration cfg).isSource(node) and
|
||||
result = "true"
|
||||
or
|
||||
// Is this node a dataflow barrier, and if so, what kind?
|
||||
key = "barrier" and
|
||||
result =
|
||||
strictconcat(string kind |
|
||||
any(DataFlow::Configuration cfg).isBarrier(node) and kind = "full"
|
||||
or
|
||||
any(DataFlow::Configuration cfg).isBarrierIn(node) and kind = "in"
|
||||
or
|
||||
any(DataFlow::Configuration cfg).isBarrierOut(node) and kind = "out"
|
||||
or
|
||||
exists(DataFlow::BarrierGuard guard |
|
||||
any(DataFlow::Configuration cfg).isBarrierGuard(guard) and
|
||||
node = guard.getAGuardedNode() and
|
||||
kind = "guard(" + guard.getResultId() + ")"
|
||||
)
|
||||
|
|
||||
kind, ", "
|
||||
)
|
||||
or
|
||||
// Is there partial flow from a source to this node?
|
||||
// This property will only be emitted if partial flow is enabled by overriding
|
||||
// `DataFlow::Configration::explorationLimit()`.
|
||||
key = "pflow" and
|
||||
result =
|
||||
strictconcat(DataFlow::PartialPathNode sourceNode, DataFlow::PartialPathNode destNode, int dist,
|
||||
int order1, int order2 |
|
||||
any(DataFlow::Configuration cfg).hasPartialFlow(sourceNode, destNode, dist) and
|
||||
destNode.getNode() = node and
|
||||
// Only print flow from a source in the same function.
|
||||
sourceNode.getNode().getEnclosingCallable() = node.getEnclosingCallable()
|
||||
|
|
||||
nodeId(sourceNode.getNode(), order1, order2) + "+" + dist.toString(), ", "
|
||||
order by
|
||||
order1, order2, dist desc
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Property provider for local IR dataflow.
|
||||
*/
|
||||
class LocalFlowPropertyProvider extends IRPropertyProvider {
|
||||
override string getOperandProperty(Operand operand, string key) {
|
||||
exists(DataFlow::Node node |
|
||||
operand = node.asOperand() and
|
||||
result = getNodeProperty(node, key)
|
||||
)
|
||||
}
|
||||
|
||||
override string getInstructionProperty(Instruction instruction, string key) {
|
||||
exists(DataFlow::Node node |
|
||||
instruction = node.asInstruction() and
|
||||
result = getNodeProperty(node, key)
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -72,4 +72,9 @@ class IRPropertyProvider extends TIRPropertyProvider {
|
||||
* Gets the value of the property named `key` for the specified block.
|
||||
*/
|
||||
string getBlockProperty(IRBlock block, string key) { none() }
|
||||
|
||||
/**
|
||||
* Gets the value of the property named `key` for the specified operand.
|
||||
*/
|
||||
string getOperandProperty(Operand operand, string key) { none() }
|
||||
}
|
||||
|
||||
@@ -1501,6 +1501,12 @@ class SwitchInstruction extends Instruction {
|
||||
class CallInstruction extends Instruction {
|
||||
CallInstruction() { getOpcode() instanceof Opcode::Call }
|
||||
|
||||
final override string getImmediateString() {
|
||||
result = getStaticCallTarget().toString()
|
||||
or
|
||||
not exists(getStaticCallTarget()) and result = "?"
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the operand the specifies the target function of the call.
|
||||
*/
|
||||
|
||||
@@ -151,6 +151,11 @@ class Operand extends TOperand {
|
||||
*/
|
||||
string getDumpLabel() { result = "" }
|
||||
|
||||
/**
|
||||
* Gets a string that uniquely identifies this operand on its use instruction.
|
||||
*/
|
||||
string getDumpId() { result = "" }
|
||||
|
||||
/**
|
||||
* Gets a string describing this operand, suitable for display in IR dumps. This consists of the
|
||||
* result ID of the instruction consumed by the operand, plus a label identifying the operand
|
||||
@@ -280,6 +285,8 @@ class NonPhiOperand extends Operand {
|
||||
|
||||
final override string getDumpLabel() { result = tag.getLabel() }
|
||||
|
||||
final override string getDumpId() { result = tag.getId() }
|
||||
|
||||
final override int getDumpSortOrder() { result = tag.getSortOrder() }
|
||||
|
||||
/**
|
||||
@@ -477,6 +484,8 @@ class PhiInputOperand extends MemoryOperand, PhiOperandBase {
|
||||
result = "from " + getPredecessorBlock().getDisplayIndex().toString() + ":"
|
||||
}
|
||||
|
||||
final override string getDumpId() { result = getPredecessorBlock().getDisplayIndex().toString() }
|
||||
|
||||
/**
|
||||
* Gets the predecessor block from which this value comes.
|
||||
*/
|
||||
|
||||
@@ -50,6 +50,37 @@ private string getAdditionalBlockProperty(IRBlock block, string key) {
|
||||
exists(IRPropertyProvider provider | result = provider.getBlockProperty(block, key))
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the properties of an operand from any active property providers.
|
||||
*/
|
||||
private string getAdditionalOperandProperty(Operand operand, string key) {
|
||||
exists(IRPropertyProvider provider | result = provider.getOperandProperty(operand, key))
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a string listing the properties of the operand and their corresponding values. If the
|
||||
* operand has no properties, this predicate has no result.
|
||||
*/
|
||||
private string getOperandPropertyListString(Operand operand) {
|
||||
result =
|
||||
strictconcat(string key, string value |
|
||||
value = getAdditionalOperandProperty(operand, key)
|
||||
|
|
||||
key + ":" + value, ", "
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a string listing the properties of the operand and their corresponding values. The list is
|
||||
* surrounded by curly braces. If the operand has no properties, this predicate returns an empty
|
||||
* string.
|
||||
*/
|
||||
private string getOperandPropertyString(Operand operand) {
|
||||
result = "{" + getOperandPropertyListString(operand) + "}"
|
||||
or
|
||||
not exists(getOperandPropertyListString(operand)) and result = ""
|
||||
}
|
||||
|
||||
private newtype TPrintableIRNode =
|
||||
TPrintableIRFunction(IRFunction irFunc) { shouldPrintFunction(irFunc.getFunction()) } or
|
||||
TPrintableIRBlock(IRBlock block) { shouldPrintFunction(block.getEnclosingFunction()) } or
|
||||
@@ -190,7 +221,7 @@ private class PrintableInstruction extends PrintableIRNode, TPrintableInstructio
|
||||
|
|
||||
resultString = instr.getResultString() and
|
||||
operationString = instr.getOperationString() and
|
||||
operandsString = instr.getOperandsString() and
|
||||
operandsString = getOperandsString() and
|
||||
columnWidths(block, resultWidth, operationWidth) and
|
||||
result =
|
||||
resultString + getPaddingString(resultWidth - resultString.length()) + " = " +
|
||||
@@ -210,6 +241,22 @@ private class PrintableInstruction extends PrintableIRNode, TPrintableInstructio
|
||||
result = PrintableIRNode.super.getProperty(key) or
|
||||
result = getAdditionalInstructionProperty(instr, key)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the string representation of the operand list. This is the same as
|
||||
* `Instruction::getOperandsString()`, except that each operand is annotated with any properties
|
||||
* provided by active `IRPropertyProvider` instances.
|
||||
*/
|
||||
private string getOperandsString() {
|
||||
result =
|
||||
concat(Operand operand |
|
||||
operand = instr.getAnOperand()
|
||||
|
|
||||
operand.getDumpString() + getOperandPropertyString(operand), ", "
|
||||
order by
|
||||
operand.getDumpSortOrder()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private predicate columnWidths(IRBlock block, int resultWidth, int operationWidth) {
|
||||
|
||||
@@ -40,7 +40,17 @@ abstract class OperandTag extends TOperandTag {
|
||||
/**
|
||||
* Gets a label that will appear before the operand when the IR is printed.
|
||||
*/
|
||||
string getLabel() { result = "" }
|
||||
final string getLabel() { if alwaysPrintLabel() then result = getId() + ":" else result = "" }
|
||||
|
||||
/**
|
||||
* Gets an identifier that uniquely identifies this operand within its instruction.
|
||||
*/
|
||||
abstract string getId();
|
||||
|
||||
/**
|
||||
* Holds if the operand should always be prefixed with its label in the dump of its instruction.
|
||||
*/
|
||||
predicate alwaysPrintLabel() { none() }
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -69,7 +79,9 @@ class AddressOperandTag extends RegisterOperandTag, TAddressOperand {
|
||||
|
||||
final override int getSortOrder() { result = 0 }
|
||||
|
||||
final override string getLabel() { result = "&:" }
|
||||
final override predicate alwaysPrintLabel() { any() }
|
||||
|
||||
final override string getId() { result = "&" }
|
||||
}
|
||||
|
||||
AddressOperandTag addressOperand() { result = TAddressOperand() }
|
||||
@@ -82,6 +94,8 @@ class BufferSizeOperandTag extends RegisterOperandTag, TBufferSizeOperand {
|
||||
final override string toString() { result = "BufferSize" }
|
||||
|
||||
final override int getSortOrder() { result = 1 }
|
||||
|
||||
final override string getId() { result = "size" }
|
||||
}
|
||||
|
||||
BufferSizeOperandTag bufferSizeOperand() { result = TBufferSizeOperand() }
|
||||
@@ -93,6 +107,8 @@ class SideEffectOperandTag extends TypedOperandTag, TSideEffectOperand {
|
||||
final override string toString() { result = "SideEffect" }
|
||||
|
||||
final override int getSortOrder() { result = 2 }
|
||||
|
||||
final override string getId() { result = "side_effect" }
|
||||
}
|
||||
|
||||
SideEffectOperandTag sideEffectOperand() { result = TSideEffectOperand() }
|
||||
@@ -105,6 +121,8 @@ class LoadOperandTag extends TypedOperandTag, TLoadOperand {
|
||||
final override string toString() { result = "Load" }
|
||||
|
||||
final override int getSortOrder() { result = 3 }
|
||||
|
||||
final override string getId() { result = "load" }
|
||||
}
|
||||
|
||||
LoadOperandTag loadOperand() { result = TLoadOperand() }
|
||||
@@ -116,6 +134,8 @@ class StoreValueOperandTag extends RegisterOperandTag, TStoreValueOperand {
|
||||
final override string toString() { result = "StoreValue" }
|
||||
|
||||
final override int getSortOrder() { result = 4 }
|
||||
|
||||
final override string getId() { result = "store" }
|
||||
}
|
||||
|
||||
StoreValueOperandTag storeValueOperand() { result = TStoreValueOperand() }
|
||||
@@ -127,6 +147,8 @@ class UnaryOperandTag extends RegisterOperandTag, TUnaryOperand {
|
||||
final override string toString() { result = "Unary" }
|
||||
|
||||
final override int getSortOrder() { result = 5 }
|
||||
|
||||
final override string getId() { result = "unary" }
|
||||
}
|
||||
|
||||
UnaryOperandTag unaryOperand() { result = TUnaryOperand() }
|
||||
@@ -138,6 +160,8 @@ class LeftOperandTag extends RegisterOperandTag, TLeftOperand {
|
||||
final override string toString() { result = "Left" }
|
||||
|
||||
final override int getSortOrder() { result = 6 }
|
||||
|
||||
final override string getId() { result = "left" }
|
||||
}
|
||||
|
||||
LeftOperandTag leftOperand() { result = TLeftOperand() }
|
||||
@@ -149,6 +173,8 @@ class RightOperandTag extends RegisterOperandTag, TRightOperand {
|
||||
final override string toString() { result = "Right" }
|
||||
|
||||
final override int getSortOrder() { result = 7 }
|
||||
|
||||
final override string getId() { result = "right" }
|
||||
}
|
||||
|
||||
RightOperandTag rightOperand() { result = TRightOperand() }
|
||||
@@ -160,6 +186,8 @@ class ConditionOperandTag extends RegisterOperandTag, TConditionOperand {
|
||||
final override string toString() { result = "Condition" }
|
||||
|
||||
final override int getSortOrder() { result = 8 }
|
||||
|
||||
final override string getId() { result = "cond" }
|
||||
}
|
||||
|
||||
ConditionOperandTag conditionOperand() { result = TConditionOperand() }
|
||||
@@ -172,7 +200,9 @@ class CallTargetOperandTag extends RegisterOperandTag, TCallTargetOperand {
|
||||
|
||||
final override int getSortOrder() { result = 10 }
|
||||
|
||||
final override string getLabel() { result = "func:" }
|
||||
final override predicate alwaysPrintLabel() { any() }
|
||||
|
||||
final override string getId() { result = "func" }
|
||||
}
|
||||
|
||||
CallTargetOperandTag callTargetOperand() { result = TCallTargetOperand() }
|
||||
@@ -195,7 +225,9 @@ class ThisArgumentOperandTag extends ArgumentOperandTag, TThisArgumentOperand {
|
||||
|
||||
final override int getSortOrder() { result = 11 }
|
||||
|
||||
final override string getLabel() { result = "this:" }
|
||||
final override predicate alwaysPrintLabel() { any() }
|
||||
|
||||
final override string getId() { result = "this" }
|
||||
}
|
||||
|
||||
ThisArgumentOperandTag thisArgumentOperand() { result = TThisArgumentOperand() }
|
||||
@@ -212,9 +244,11 @@ class PositionalArgumentOperandTag extends ArgumentOperandTag, TPositionalArgume
|
||||
|
||||
final override int getSortOrder() { result = 12 + argIndex }
|
||||
|
||||
final override string getLabel() { result = argIndex.toString() + ":" }
|
||||
final override predicate alwaysPrintLabel() { any() }
|
||||
|
||||
final int getArgIndex() { result = argIndex }
|
||||
|
||||
final override string getId() { result = argIndex.toString() }
|
||||
}
|
||||
|
||||
PositionalArgumentOperandTag positionalArgumentOperand(int argIndex) {
|
||||
@@ -228,7 +262,9 @@ class ChiTotalOperandTag extends ChiOperandTag, TChiTotalOperand {
|
||||
|
||||
final override int getSortOrder() { result = 13 }
|
||||
|
||||
final override string getLabel() { result = "total:" }
|
||||
final override predicate alwaysPrintLabel() { any() }
|
||||
|
||||
final override string getId() { result = "total" }
|
||||
}
|
||||
|
||||
ChiTotalOperandTag chiTotalOperand() { result = TChiTotalOperand() }
|
||||
@@ -238,7 +274,9 @@ class ChiPartialOperandTag extends ChiOperandTag, TChiPartialOperand {
|
||||
|
||||
final override int getSortOrder() { result = 14 }
|
||||
|
||||
final override string getLabel() { result = "partial:" }
|
||||
final override predicate alwaysPrintLabel() { any() }
|
||||
|
||||
final override string getId() { result = "partial" }
|
||||
}
|
||||
|
||||
ChiPartialOperandTag chiPartialOperand() { result = TChiPartialOperand() }
|
||||
@@ -252,7 +290,9 @@ class AsmOperandTag extends RegisterOperandTag, TAsmOperand {
|
||||
|
||||
final override int getSortOrder() { result = 15 + index }
|
||||
|
||||
final override string getLabel() { result = index.toString() + ":" }
|
||||
final override predicate alwaysPrintLabel() { any() }
|
||||
|
||||
final override string getId() { result = index.toString() }
|
||||
}
|
||||
|
||||
AsmOperandTag asmOperand(int index) { result = TAsmOperand(index) }
|
||||
|
||||
@@ -72,4 +72,9 @@ class IRPropertyProvider extends TIRPropertyProvider {
|
||||
* Gets the value of the property named `key` for the specified block.
|
||||
*/
|
||||
string getBlockProperty(IRBlock block, string key) { none() }
|
||||
|
||||
/**
|
||||
* Gets the value of the property named `key` for the specified operand.
|
||||
*/
|
||||
string getOperandProperty(Operand operand, string key) { none() }
|
||||
}
|
||||
|
||||
@@ -1501,6 +1501,12 @@ class SwitchInstruction extends Instruction {
|
||||
class CallInstruction extends Instruction {
|
||||
CallInstruction() { getOpcode() instanceof Opcode::Call }
|
||||
|
||||
final override string getImmediateString() {
|
||||
result = getStaticCallTarget().toString()
|
||||
or
|
||||
not exists(getStaticCallTarget()) and result = "?"
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the operand the specifies the target function of the call.
|
||||
*/
|
||||
|
||||
@@ -151,6 +151,11 @@ class Operand extends TOperand {
|
||||
*/
|
||||
string getDumpLabel() { result = "" }
|
||||
|
||||
/**
|
||||
* Gets a string that uniquely identifies this operand on its use instruction.
|
||||
*/
|
||||
string getDumpId() { result = "" }
|
||||
|
||||
/**
|
||||
* Gets a string describing this operand, suitable for display in IR dumps. This consists of the
|
||||
* result ID of the instruction consumed by the operand, plus a label identifying the operand
|
||||
@@ -280,6 +285,8 @@ class NonPhiOperand extends Operand {
|
||||
|
||||
final override string getDumpLabel() { result = tag.getLabel() }
|
||||
|
||||
final override string getDumpId() { result = tag.getId() }
|
||||
|
||||
final override int getDumpSortOrder() { result = tag.getSortOrder() }
|
||||
|
||||
/**
|
||||
@@ -477,6 +484,8 @@ class PhiInputOperand extends MemoryOperand, PhiOperandBase {
|
||||
result = "from " + getPredecessorBlock().getDisplayIndex().toString() + ":"
|
||||
}
|
||||
|
||||
final override string getDumpId() { result = getPredecessorBlock().getDisplayIndex().toString() }
|
||||
|
||||
/**
|
||||
* Gets the predecessor block from which this value comes.
|
||||
*/
|
||||
|
||||
@@ -50,6 +50,37 @@ private string getAdditionalBlockProperty(IRBlock block, string key) {
|
||||
exists(IRPropertyProvider provider | result = provider.getBlockProperty(block, key))
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the properties of an operand from any active property providers.
|
||||
*/
|
||||
private string getAdditionalOperandProperty(Operand operand, string key) {
|
||||
exists(IRPropertyProvider provider | result = provider.getOperandProperty(operand, key))
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a string listing the properties of the operand and their corresponding values. If the
|
||||
* operand has no properties, this predicate has no result.
|
||||
*/
|
||||
private string getOperandPropertyListString(Operand operand) {
|
||||
result =
|
||||
strictconcat(string key, string value |
|
||||
value = getAdditionalOperandProperty(operand, key)
|
||||
|
|
||||
key + ":" + value, ", "
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a string listing the properties of the operand and their corresponding values. The list is
|
||||
* surrounded by curly braces. If the operand has no properties, this predicate returns an empty
|
||||
* string.
|
||||
*/
|
||||
private string getOperandPropertyString(Operand operand) {
|
||||
result = "{" + getOperandPropertyListString(operand) + "}"
|
||||
or
|
||||
not exists(getOperandPropertyListString(operand)) and result = ""
|
||||
}
|
||||
|
||||
private newtype TPrintableIRNode =
|
||||
TPrintableIRFunction(IRFunction irFunc) { shouldPrintFunction(irFunc.getFunction()) } or
|
||||
TPrintableIRBlock(IRBlock block) { shouldPrintFunction(block.getEnclosingFunction()) } or
|
||||
@@ -190,7 +221,7 @@ private class PrintableInstruction extends PrintableIRNode, TPrintableInstructio
|
||||
|
|
||||
resultString = instr.getResultString() and
|
||||
operationString = instr.getOperationString() and
|
||||
operandsString = instr.getOperandsString() and
|
||||
operandsString = getOperandsString() and
|
||||
columnWidths(block, resultWidth, operationWidth) and
|
||||
result =
|
||||
resultString + getPaddingString(resultWidth - resultString.length()) + " = " +
|
||||
@@ -210,6 +241,22 @@ private class PrintableInstruction extends PrintableIRNode, TPrintableInstructio
|
||||
result = PrintableIRNode.super.getProperty(key) or
|
||||
result = getAdditionalInstructionProperty(instr, key)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the string representation of the operand list. This is the same as
|
||||
* `Instruction::getOperandsString()`, except that each operand is annotated with any properties
|
||||
* provided by active `IRPropertyProvider` instances.
|
||||
*/
|
||||
private string getOperandsString() {
|
||||
result =
|
||||
concat(Operand operand |
|
||||
operand = instr.getAnOperand()
|
||||
|
|
||||
operand.getDumpString() + getOperandPropertyString(operand), ", "
|
||||
order by
|
||||
operand.getDumpSortOrder()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private predicate columnWidths(IRBlock block, int resultWidth, int operationWidth) {
|
||||
|
||||
@@ -72,4 +72,9 @@ class IRPropertyProvider extends TIRPropertyProvider {
|
||||
* Gets the value of the property named `key` for the specified block.
|
||||
*/
|
||||
string getBlockProperty(IRBlock block, string key) { none() }
|
||||
|
||||
/**
|
||||
* Gets the value of the property named `key` for the specified operand.
|
||||
*/
|
||||
string getOperandProperty(Operand operand, string key) { none() }
|
||||
}
|
||||
|
||||
@@ -1501,6 +1501,12 @@ class SwitchInstruction extends Instruction {
|
||||
class CallInstruction extends Instruction {
|
||||
CallInstruction() { getOpcode() instanceof Opcode::Call }
|
||||
|
||||
final override string getImmediateString() {
|
||||
result = getStaticCallTarget().toString()
|
||||
or
|
||||
not exists(getStaticCallTarget()) and result = "?"
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the operand the specifies the target function of the call.
|
||||
*/
|
||||
|
||||
@@ -151,6 +151,11 @@ class Operand extends TOperand {
|
||||
*/
|
||||
string getDumpLabel() { result = "" }
|
||||
|
||||
/**
|
||||
* Gets a string that uniquely identifies this operand on its use instruction.
|
||||
*/
|
||||
string getDumpId() { result = "" }
|
||||
|
||||
/**
|
||||
* Gets a string describing this operand, suitable for display in IR dumps. This consists of the
|
||||
* result ID of the instruction consumed by the operand, plus a label identifying the operand
|
||||
@@ -280,6 +285,8 @@ class NonPhiOperand extends Operand {
|
||||
|
||||
final override string getDumpLabel() { result = tag.getLabel() }
|
||||
|
||||
final override string getDumpId() { result = tag.getId() }
|
||||
|
||||
final override int getDumpSortOrder() { result = tag.getSortOrder() }
|
||||
|
||||
/**
|
||||
@@ -477,6 +484,8 @@ class PhiInputOperand extends MemoryOperand, PhiOperandBase {
|
||||
result = "from " + getPredecessorBlock().getDisplayIndex().toString() + ":"
|
||||
}
|
||||
|
||||
final override string getDumpId() { result = getPredecessorBlock().getDisplayIndex().toString() }
|
||||
|
||||
/**
|
||||
* Gets the predecessor block from which this value comes.
|
||||
*/
|
||||
|
||||
@@ -50,6 +50,37 @@ private string getAdditionalBlockProperty(IRBlock block, string key) {
|
||||
exists(IRPropertyProvider provider | result = provider.getBlockProperty(block, key))
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the properties of an operand from any active property providers.
|
||||
*/
|
||||
private string getAdditionalOperandProperty(Operand operand, string key) {
|
||||
exists(IRPropertyProvider provider | result = provider.getOperandProperty(operand, key))
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a string listing the properties of the operand and their corresponding values. If the
|
||||
* operand has no properties, this predicate has no result.
|
||||
*/
|
||||
private string getOperandPropertyListString(Operand operand) {
|
||||
result =
|
||||
strictconcat(string key, string value |
|
||||
value = getAdditionalOperandProperty(operand, key)
|
||||
|
|
||||
key + ":" + value, ", "
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a string listing the properties of the operand and their corresponding values. The list is
|
||||
* surrounded by curly braces. If the operand has no properties, this predicate returns an empty
|
||||
* string.
|
||||
*/
|
||||
private string getOperandPropertyString(Operand operand) {
|
||||
result = "{" + getOperandPropertyListString(operand) + "}"
|
||||
or
|
||||
not exists(getOperandPropertyListString(operand)) and result = ""
|
||||
}
|
||||
|
||||
private newtype TPrintableIRNode =
|
||||
TPrintableIRFunction(IRFunction irFunc) { shouldPrintFunction(irFunc.getFunction()) } or
|
||||
TPrintableIRBlock(IRBlock block) { shouldPrintFunction(block.getEnclosingFunction()) } or
|
||||
@@ -190,7 +221,7 @@ private class PrintableInstruction extends PrintableIRNode, TPrintableInstructio
|
||||
|
|
||||
resultString = instr.getResultString() and
|
||||
operationString = instr.getOperationString() and
|
||||
operandsString = instr.getOperandsString() and
|
||||
operandsString = getOperandsString() and
|
||||
columnWidths(block, resultWidth, operationWidth) and
|
||||
result =
|
||||
resultString + getPaddingString(resultWidth - resultString.length()) + " = " +
|
||||
@@ -210,6 +241,22 @@ private class PrintableInstruction extends PrintableIRNode, TPrintableInstructio
|
||||
result = PrintableIRNode.super.getProperty(key) or
|
||||
result = getAdditionalInstructionProperty(instr, key)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the string representation of the operand list. This is the same as
|
||||
* `Instruction::getOperandsString()`, except that each operand is annotated with any properties
|
||||
* provided by active `IRPropertyProvider` instances.
|
||||
*/
|
||||
private string getOperandsString() {
|
||||
result =
|
||||
concat(Operand operand |
|
||||
operand = instr.getAnOperand()
|
||||
|
|
||||
operand.getDumpString() + getOperandPropertyString(operand), ", "
|
||||
order by
|
||||
operand.getDumpSortOrder()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private predicate columnWidths(IRBlock block, int resultWidth, int operationWidth) {
|
||||
|
||||
@@ -39,17 +39,8 @@ void sink(int x)
|
||||
|
||||
void bar(Outer &b)
|
||||
{
|
||||
// The library correctly finds that the four `user_input` sources can make it
|
||||
// to the `sink` calls, but it also finds some source/sink combinations that
|
||||
// are impossible. Those false positives here are a consequence of how the
|
||||
// shared data flow library overapproximates field flow. The library only
|
||||
// tracks the final two fields (`f` and `inner`) and the length (3) of the field
|
||||
// access path, and then it tracks that both `a_` and `b_` have followed `f.inner`
|
||||
// in _some_ access path somewhere in the search. That makes the library conclude
|
||||
// that there could be flow to `b.inner.f.a_` even when the flow was actually to
|
||||
// `b.inner.f.b_`.
|
||||
sink(b.inner.f.a()); // $ast=62:19 $f+:ast=63:19 $ast=64:19 $f+:ast=65:19 $ir=62:19 $f+:ir=63:19 $ir=64:19 $f+:ir=65:19
|
||||
sink(b.inner.f.b()); // $f+:ast=62:19 $ast=63:19 $f+:ast=64:19 $ast=65:19 $f+:ir=62:19 $ir=63:19 $f+:ir=64:19 $ir=65:19
|
||||
sink(b.inner.f.a()); // $ast=53:19 $ast=55:19 $ir=53:19 $ir=55:19
|
||||
sink(b.inner.f.b()); // $ast=54:19 $ast=56:19 $ir=54:19 $ir=56:19
|
||||
}
|
||||
|
||||
void foo()
|
||||
|
||||
@@ -34,10 +34,6 @@
|
||||
| by_reference.cpp:84:14:84:23 | call to user_input | by_reference.cpp:115:27:115:27 | a | AST only |
|
||||
| by_reference.cpp:88:13:88:22 | call to user_input | by_reference.cpp:131:25:131:25 | a | AST only |
|
||||
| by_reference.cpp:88:13:88:22 | call to user_input | by_reference.cpp:135:27:135:27 | a | AST only |
|
||||
| complex.cpp:62:19:62:28 | call to user_input | complex.cpp:52:18:52:18 | call to b | AST only |
|
||||
| complex.cpp:63:19:63:28 | call to user_input | complex.cpp:51:18:51:18 | call to a | AST only |
|
||||
| complex.cpp:64:19:64:28 | call to user_input | complex.cpp:52:18:52:18 | call to b | AST only |
|
||||
| complex.cpp:65:19:65:28 | call to user_input | complex.cpp:51:18:51:18 | call to a | AST only |
|
||||
| qualifiers.cpp:22:27:22:36 | call to user_input | qualifiers.cpp:23:23:23:23 | a | AST only |
|
||||
| qualifiers.cpp:27:28:27:37 | call to user_input | qualifiers.cpp:28:23:28:23 | a | AST only |
|
||||
| qualifiers.cpp:32:35:32:44 | call to user_input | qualifiers.cpp:33:23:33:23 | a | AST only |
|
||||
|
||||
@@ -1,4 +0,0 @@
|
||||
| complex.cpp:51:24:51:121 | // $ast=62:19 $f+:ast=63:19 $ast=64:19 $f+:ast=65:19 $ir=62:19 $f+:ir=63:19 $ir=64:19 $f+:ir=65:19 | Fixed false positive:ir=63:19 |
|
||||
| complex.cpp:51:24:51:121 | // $ast=62:19 $f+:ast=63:19 $ast=64:19 $f+:ast=65:19 $ir=62:19 $f+:ir=63:19 $ir=64:19 $f+:ir=65:19 | Fixed false positive:ir=65:19 |
|
||||
| complex.cpp:52:24:52:121 | // $f+:ast=62:19 $ast=63:19 $f+:ast=64:19 $ast=65:19 $f+:ir=62:19 $ir=63:19 $f+:ir=64:19 $ir=65:19 | Fixed false positive:ir=62:19 |
|
||||
| complex.cpp:52:24:52:121 | // $f+:ast=62:19 $ast=63:19 $f+:ast=64:19 $ast=65:19 $f+:ir=62:19 $ir=63:19 $f+:ir=64:19 $ir=65:19 | Fixed false positive:ir=64:19 |
|
||||
|
||||
@@ -140,20 +140,20 @@ edges
|
||||
| by_reference.cpp:128:15:128:23 | Chi | by_reference.cpp:128:15:128:23 | Chi [a] |
|
||||
| by_reference.cpp:128:15:128:23 | Chi [a] | by_reference.cpp:136:16:136:16 | a |
|
||||
| by_reference.cpp:128:15:128:23 | taint_a_ref output argument [array content] | by_reference.cpp:128:15:128:23 | Chi |
|
||||
| complex.cpp:40:17:40:17 | *b [a_] | complex.cpp:51:18:51:18 | call to a |
|
||||
| complex.cpp:40:17:40:17 | *b [b_] | complex.cpp:51:16:51:16 | a output argument [b_] |
|
||||
| complex.cpp:40:17:40:17 | *b [b_] | complex.cpp:52:18:52:18 | call to b |
|
||||
| complex.cpp:51:16:51:16 | a output argument [b_] | complex.cpp:52:18:52:18 | call to b |
|
||||
| complex.cpp:62:12:62:12 | setA output argument [a_] | complex.cpp:40:17:40:17 | *b [a_] |
|
||||
| complex.cpp:62:19:62:28 | call to user_input | complex.cpp:62:12:62:12 | setA output argument [a_] |
|
||||
| complex.cpp:63:12:63:12 | setB output argument [b_] | complex.cpp:40:17:40:17 | *b [b_] |
|
||||
| complex.cpp:63:19:63:28 | call to user_input | complex.cpp:63:12:63:12 | setB output argument [b_] |
|
||||
| complex.cpp:64:12:64:12 | setA output argument [a_] | complex.cpp:40:17:40:17 | *b [a_] |
|
||||
| complex.cpp:64:12:64:12 | setA output argument [a_] | complex.cpp:65:12:65:12 | setB output argument [a_] |
|
||||
| complex.cpp:64:19:64:28 | call to user_input | complex.cpp:64:12:64:12 | setA output argument [a_] |
|
||||
| complex.cpp:65:12:65:12 | setB output argument [a_] | complex.cpp:40:17:40:17 | *b [a_] |
|
||||
| complex.cpp:65:12:65:12 | setB output argument [b_] | complex.cpp:40:17:40:17 | *b [b_] |
|
||||
| complex.cpp:65:19:65:28 | call to user_input | complex.cpp:65:12:65:12 | setB output argument [b_] |
|
||||
| complex.cpp:40:17:40:17 | *b [a_] | complex.cpp:42:18:42:18 | call to a |
|
||||
| complex.cpp:40:17:40:17 | *b [b_] | complex.cpp:42:16:42:16 | a output argument [b_] |
|
||||
| complex.cpp:40:17:40:17 | *b [b_] | complex.cpp:43:18:43:18 | call to b |
|
||||
| complex.cpp:42:16:42:16 | a output argument [b_] | complex.cpp:43:18:43:18 | call to b |
|
||||
| complex.cpp:53:12:53:12 | setA output argument [a_] | complex.cpp:40:17:40:17 | *b [a_] |
|
||||
| complex.cpp:53:19:53:28 | call to user_input | complex.cpp:53:12:53:12 | setA output argument [a_] |
|
||||
| complex.cpp:54:12:54:12 | setB output argument [b_] | complex.cpp:40:17:40:17 | *b [b_] |
|
||||
| complex.cpp:54:19:54:28 | call to user_input | complex.cpp:54:12:54:12 | setB output argument [b_] |
|
||||
| complex.cpp:55:12:55:12 | setA output argument [a_] | complex.cpp:40:17:40:17 | *b [a_] |
|
||||
| complex.cpp:55:12:55:12 | setA output argument [a_] | complex.cpp:56:12:56:12 | setB output argument [a_] |
|
||||
| complex.cpp:55:19:55:28 | call to user_input | complex.cpp:55:12:55:12 | setA output argument [a_] |
|
||||
| complex.cpp:56:12:56:12 | setB output argument [a_] | complex.cpp:40:17:40:17 | *b [a_] |
|
||||
| complex.cpp:56:12:56:12 | setB output argument [b_] | complex.cpp:40:17:40:17 | *b [b_] |
|
||||
| complex.cpp:56:19:56:28 | call to user_input | complex.cpp:56:12:56:12 | setB output argument [b_] |
|
||||
| constructors.cpp:26:15:26:15 | *f [a_] | constructors.cpp:28:12:28:12 | call to a |
|
||||
| constructors.cpp:26:15:26:15 | *f [b_] | constructors.cpp:28:10:28:10 | a output argument [b_] |
|
||||
| constructors.cpp:26:15:26:15 | *f [b_] | constructors.cpp:29:12:29:12 | call to b |
|
||||
@@ -371,18 +371,18 @@ nodes
|
||||
| by_reference.cpp:136:16:136:16 | a | semmle.label | a |
|
||||
| complex.cpp:40:17:40:17 | *b [a_] | semmle.label | *b [a_] |
|
||||
| complex.cpp:40:17:40:17 | *b [b_] | semmle.label | *b [b_] |
|
||||
| complex.cpp:51:16:51:16 | a output argument [b_] | semmle.label | a output argument [b_] |
|
||||
| complex.cpp:51:18:51:18 | call to a | semmle.label | call to a |
|
||||
| complex.cpp:52:18:52:18 | call to b | semmle.label | call to b |
|
||||
| complex.cpp:62:12:62:12 | setA output argument [a_] | semmle.label | setA output argument [a_] |
|
||||
| complex.cpp:62:19:62:28 | call to user_input | semmle.label | call to user_input |
|
||||
| complex.cpp:63:12:63:12 | setB output argument [b_] | semmle.label | setB output argument [b_] |
|
||||
| complex.cpp:63:19:63:28 | call to user_input | semmle.label | call to user_input |
|
||||
| complex.cpp:64:12:64:12 | setA output argument [a_] | semmle.label | setA output argument [a_] |
|
||||
| complex.cpp:64:19:64:28 | call to user_input | semmle.label | call to user_input |
|
||||
| complex.cpp:65:12:65:12 | setB output argument [a_] | semmle.label | setB output argument [a_] |
|
||||
| complex.cpp:65:12:65:12 | setB output argument [b_] | semmle.label | setB output argument [b_] |
|
||||
| complex.cpp:65:19:65:28 | call to user_input | semmle.label | call to user_input |
|
||||
| complex.cpp:42:16:42:16 | a output argument [b_] | semmle.label | a output argument [b_] |
|
||||
| complex.cpp:42:18:42:18 | call to a | semmle.label | call to a |
|
||||
| complex.cpp:43:18:43:18 | call to b | semmle.label | call to b |
|
||||
| complex.cpp:53:12:53:12 | setA output argument [a_] | semmle.label | setA output argument [a_] |
|
||||
| complex.cpp:53:19:53:28 | call to user_input | semmle.label | call to user_input |
|
||||
| complex.cpp:54:12:54:12 | setB output argument [b_] | semmle.label | setB output argument [b_] |
|
||||
| complex.cpp:54:19:54:28 | call to user_input | semmle.label | call to user_input |
|
||||
| complex.cpp:55:12:55:12 | setA output argument [a_] | semmle.label | setA output argument [a_] |
|
||||
| complex.cpp:55:19:55:28 | call to user_input | semmle.label | call to user_input |
|
||||
| complex.cpp:56:12:56:12 | setB output argument [a_] | semmle.label | setB output argument [a_] |
|
||||
| complex.cpp:56:12:56:12 | setB output argument [b_] | semmle.label | setB output argument [b_] |
|
||||
| complex.cpp:56:19:56:28 | call to user_input | semmle.label | call to user_input |
|
||||
| constructors.cpp:26:15:26:15 | *f [a_] | semmle.label | *f [a_] |
|
||||
| constructors.cpp:26:15:26:15 | *f [b_] | semmle.label | *f [b_] |
|
||||
| constructors.cpp:28:10:28:10 | a output argument [b_] | semmle.label | a output argument [b_] |
|
||||
@@ -478,10 +478,10 @@ nodes
|
||||
| by_reference.cpp:132:14:132:14 | a | by_reference.cpp:96:8:96:17 | call to user_input | by_reference.cpp:132:14:132:14 | a | a flows from $@ | by_reference.cpp:96:8:96:17 | call to user_input | call to user_input |
|
||||
| by_reference.cpp:134:29:134:29 | a | by_reference.cpp:88:13:88:22 | call to user_input | by_reference.cpp:134:29:134:29 | a | a flows from $@ | by_reference.cpp:88:13:88:22 | call to user_input | call to user_input |
|
||||
| by_reference.cpp:136:16:136:16 | a | by_reference.cpp:96:8:96:17 | call to user_input | by_reference.cpp:136:16:136:16 | a | a flows from $@ | by_reference.cpp:96:8:96:17 | call to user_input | call to user_input |
|
||||
| complex.cpp:51:18:51:18 | call to a | complex.cpp:62:19:62:28 | call to user_input | complex.cpp:51:18:51:18 | call to a | call to a flows from $@ | complex.cpp:62:19:62:28 | call to user_input | call to user_input |
|
||||
| complex.cpp:51:18:51:18 | call to a | complex.cpp:64:19:64:28 | call to user_input | complex.cpp:51:18:51:18 | call to a | call to a flows from $@ | complex.cpp:64:19:64:28 | call to user_input | call to user_input |
|
||||
| complex.cpp:52:18:52:18 | call to b | complex.cpp:63:19:63:28 | call to user_input | complex.cpp:52:18:52:18 | call to b | call to b flows from $@ | complex.cpp:63:19:63:28 | call to user_input | call to user_input |
|
||||
| complex.cpp:52:18:52:18 | call to b | complex.cpp:65:19:65:28 | call to user_input | complex.cpp:52:18:52:18 | call to b | call to b flows from $@ | complex.cpp:65:19:65:28 | call to user_input | call to user_input |
|
||||
| complex.cpp:42:18:42:18 | call to a | complex.cpp:53:19:53:28 | call to user_input | complex.cpp:42:18:42:18 | call to a | call to a flows from $@ | complex.cpp:53:19:53:28 | call to user_input | call to user_input |
|
||||
| complex.cpp:42:18:42:18 | call to a | complex.cpp:55:19:55:28 | call to user_input | complex.cpp:42:18:42:18 | call to a | call to a flows from $@ | complex.cpp:55:19:55:28 | call to user_input | call to user_input |
|
||||
| complex.cpp:43:18:43:18 | call to b | complex.cpp:54:19:54:28 | call to user_input | complex.cpp:43:18:43:18 | call to b | call to b flows from $@ | complex.cpp:54:19:54:28 | call to user_input | call to user_input |
|
||||
| complex.cpp:43:18:43:18 | call to b | complex.cpp:56:19:56:28 | call to user_input | complex.cpp:43:18:43:18 | call to b | call to b flows from $@ | complex.cpp:56:19:56:28 | call to user_input | call to user_input |
|
||||
| constructors.cpp:28:12:28:12 | call to a | constructors.cpp:34:11:34:20 | call to user_input | constructors.cpp:28:12:28:12 | call to a | call to a flows from $@ | constructors.cpp:34:11:34:20 | call to user_input | call to user_input |
|
||||
| constructors.cpp:28:12:28:12 | call to a | constructors.cpp:36:11:36:20 | call to user_input | constructors.cpp:28:12:28:12 | call to a | call to a flows from $@ | constructors.cpp:36:11:36:20 | call to user_input | call to user_input |
|
||||
| constructors.cpp:29:12:29:12 | call to b | constructors.cpp:35:14:35:23 | call to user_input | constructors.cpp:29:12:29:12 | call to b | call to b flows from $@ | constructors.cpp:35:14:35:23 | call to user_input | call to user_input |
|
||||
|
||||
@@ -293,28 +293,28 @@
|
||||
| by_reference.cpp:136:16:136:16 | a | AST only |
|
||||
| complex.cpp:11:22:11:23 | a_ | AST only |
|
||||
| complex.cpp:12:22:12:23 | b_ | AST only |
|
||||
| complex.cpp:51:8:51:8 | b | AST only |
|
||||
| complex.cpp:51:10:51:14 | inner | AST only |
|
||||
| complex.cpp:51:16:51:16 | f | AST only |
|
||||
| complex.cpp:52:8:52:8 | b | AST only |
|
||||
| complex.cpp:52:10:52:14 | inner | AST only |
|
||||
| complex.cpp:52:16:52:16 | f | AST only |
|
||||
| complex.cpp:62:3:62:4 | b1 | AST only |
|
||||
| complex.cpp:62:6:62:10 | inner | AST only |
|
||||
| complex.cpp:62:12:62:12 | f | AST only |
|
||||
| complex.cpp:63:3:63:4 | b2 | AST only |
|
||||
| complex.cpp:63:6:63:10 | inner | AST only |
|
||||
| complex.cpp:63:12:63:12 | f | AST only |
|
||||
| complex.cpp:64:3:64:4 | b3 | AST only |
|
||||
| complex.cpp:64:6:64:10 | inner | AST only |
|
||||
| complex.cpp:64:12:64:12 | f | AST only |
|
||||
| complex.cpp:65:3:65:4 | b3 | AST only |
|
||||
| complex.cpp:65:6:65:10 | inner | AST only |
|
||||
| complex.cpp:65:12:65:12 | f | AST only |
|
||||
| complex.cpp:68:7:68:8 | b1 | AST only |
|
||||
| complex.cpp:71:7:71:8 | b2 | AST only |
|
||||
| complex.cpp:74:7:74:8 | b3 | AST only |
|
||||
| complex.cpp:77:7:77:8 | b4 | AST only |
|
||||
| complex.cpp:42:8:42:8 | b | AST only |
|
||||
| complex.cpp:42:10:42:14 | inner | AST only |
|
||||
| complex.cpp:42:16:42:16 | f | AST only |
|
||||
| complex.cpp:43:8:43:8 | b | AST only |
|
||||
| complex.cpp:43:10:43:14 | inner | AST only |
|
||||
| complex.cpp:43:16:43:16 | f | AST only |
|
||||
| complex.cpp:53:3:53:4 | b1 | AST only |
|
||||
| complex.cpp:53:6:53:10 | inner | AST only |
|
||||
| complex.cpp:53:12:53:12 | f | AST only |
|
||||
| complex.cpp:54:3:54:4 | b2 | AST only |
|
||||
| complex.cpp:54:6:54:10 | inner | AST only |
|
||||
| complex.cpp:54:12:54:12 | f | AST only |
|
||||
| complex.cpp:55:3:55:4 | b3 | AST only |
|
||||
| complex.cpp:55:6:55:10 | inner | AST only |
|
||||
| complex.cpp:55:12:55:12 | f | AST only |
|
||||
| complex.cpp:56:3:56:4 | b3 | AST only |
|
||||
| complex.cpp:56:6:56:10 | inner | AST only |
|
||||
| complex.cpp:56:12:56:12 | f | AST only |
|
||||
| complex.cpp:59:7:59:8 | b1 | AST only |
|
||||
| complex.cpp:62:7:62:8 | b2 | AST only |
|
||||
| complex.cpp:65:7:65:8 | b3 | AST only |
|
||||
| complex.cpp:68:7:68:8 | b4 | AST only |
|
||||
| constructors.cpp:20:24:20:25 | a_ | AST only |
|
||||
| constructors.cpp:21:24:21:25 | b_ | AST only |
|
||||
| constructors.cpp:28:10:28:10 | f | AST only |
|
||||
|
||||
@@ -344,28 +344,28 @@
|
||||
| complex.cpp:11:22:11:23 | this |
|
||||
| complex.cpp:12:22:12:23 | b_ |
|
||||
| complex.cpp:12:22:12:23 | this |
|
||||
| complex.cpp:51:8:51:8 | b |
|
||||
| complex.cpp:51:10:51:14 | inner |
|
||||
| complex.cpp:51:16:51:16 | f |
|
||||
| complex.cpp:52:8:52:8 | b |
|
||||
| complex.cpp:52:10:52:14 | inner |
|
||||
| complex.cpp:52:16:52:16 | f |
|
||||
| complex.cpp:62:3:62:4 | b1 |
|
||||
| complex.cpp:62:6:62:10 | inner |
|
||||
| complex.cpp:62:12:62:12 | f |
|
||||
| complex.cpp:63:3:63:4 | b2 |
|
||||
| complex.cpp:63:6:63:10 | inner |
|
||||
| complex.cpp:63:12:63:12 | f |
|
||||
| complex.cpp:64:3:64:4 | b3 |
|
||||
| complex.cpp:64:6:64:10 | inner |
|
||||
| complex.cpp:64:12:64:12 | f |
|
||||
| complex.cpp:65:3:65:4 | b3 |
|
||||
| complex.cpp:65:6:65:10 | inner |
|
||||
| complex.cpp:65:12:65:12 | f |
|
||||
| complex.cpp:68:7:68:8 | b1 |
|
||||
| complex.cpp:71:7:71:8 | b2 |
|
||||
| complex.cpp:74:7:74:8 | b3 |
|
||||
| complex.cpp:77:7:77:8 | b4 |
|
||||
| complex.cpp:42:8:42:8 | b |
|
||||
| complex.cpp:42:10:42:14 | inner |
|
||||
| complex.cpp:42:16:42:16 | f |
|
||||
| complex.cpp:43:8:43:8 | b |
|
||||
| complex.cpp:43:10:43:14 | inner |
|
||||
| complex.cpp:43:16:43:16 | f |
|
||||
| complex.cpp:53:3:53:4 | b1 |
|
||||
| complex.cpp:53:6:53:10 | inner |
|
||||
| complex.cpp:53:12:53:12 | f |
|
||||
| complex.cpp:54:3:54:4 | b2 |
|
||||
| complex.cpp:54:6:54:10 | inner |
|
||||
| complex.cpp:54:12:54:12 | f |
|
||||
| complex.cpp:55:3:55:4 | b3 |
|
||||
| complex.cpp:55:6:55:10 | inner |
|
||||
| complex.cpp:55:12:55:12 | f |
|
||||
| complex.cpp:56:3:56:4 | b3 |
|
||||
| complex.cpp:56:6:56:10 | inner |
|
||||
| complex.cpp:56:12:56:12 | f |
|
||||
| complex.cpp:59:7:59:8 | b1 |
|
||||
| complex.cpp:62:7:62:8 | b2 |
|
||||
| complex.cpp:65:7:65:8 | b3 |
|
||||
| complex.cpp:68:7:68:8 | b4 |
|
||||
| constructors.cpp:20:24:20:25 | a_ |
|
||||
| constructors.cpp:20:24:20:25 | this |
|
||||
| constructors.cpp:21:24:21:25 | b_ |
|
||||
|
||||
@@ -51,14 +51,14 @@ edges
|
||||
| A.cpp:160:29:160:29 | b | A.cpp:160:18:160:60 | call to MyList [head] |
|
||||
| A.cpp:161:18:161:40 | call to MyList [next, head] | A.cpp:162:38:162:39 | l2 [next, head] |
|
||||
| A.cpp:161:38:161:39 | l1 [head] | A.cpp:161:18:161:40 | call to MyList [next, head] |
|
||||
| A.cpp:162:18:162:40 | call to MyList [next, next, ... (3)] | A.cpp:165:10:165:11 | l3 [next, next, ... (3)] |
|
||||
| A.cpp:162:18:162:40 | call to MyList [next, next, ... (3)] | A.cpp:167:44:167:44 | l [next, next, ... (3)] |
|
||||
| A.cpp:162:38:162:39 | l2 [next, head] | A.cpp:162:18:162:40 | call to MyList [next, next, ... (3)] |
|
||||
| A.cpp:165:10:165:11 | l3 [next, next, ... (3)] | A.cpp:165:14:165:17 | next [next, head] |
|
||||
| A.cpp:162:18:162:40 | call to MyList [next, next, head] | A.cpp:165:10:165:11 | l3 [next, next, head] |
|
||||
| A.cpp:162:18:162:40 | call to MyList [next, next, head] | A.cpp:167:44:167:44 | l [next, next, head] |
|
||||
| A.cpp:162:38:162:39 | l2 [next, head] | A.cpp:162:18:162:40 | call to MyList [next, next, head] |
|
||||
| A.cpp:165:10:165:11 | l3 [next, next, head] | A.cpp:165:14:165:17 | next [next, head] |
|
||||
| A.cpp:165:14:165:17 | next [next, head] | A.cpp:165:20:165:23 | next [head] |
|
||||
| A.cpp:165:20:165:23 | next [head] | A.cpp:165:26:165:29 | head |
|
||||
| A.cpp:167:44:167:44 | l [next, head] | A.cpp:167:47:167:50 | next [head] |
|
||||
| A.cpp:167:44:167:44 | l [next, next, ... (3)] | A.cpp:167:47:167:50 | next [next, head] |
|
||||
| A.cpp:167:44:167:44 | l [next, next, head] | A.cpp:167:47:167:50 | next [next, head] |
|
||||
| A.cpp:167:47:167:50 | next [head] | A.cpp:169:12:169:12 | l [head] |
|
||||
| A.cpp:167:47:167:50 | next [next, head] | A.cpp:167:44:167:44 | l [next, head] |
|
||||
| A.cpp:169:12:169:12 | l [head] | A.cpp:169:15:169:18 | head |
|
||||
@@ -113,14 +113,14 @@ edges
|
||||
| D.cpp:51:27:51:27 | e | D.cpp:51:8:51:14 | ref arg call to getBox1 [elem] |
|
||||
| D.cpp:52:14:52:14 | b [box, elem] | D.cpp:21:30:21:31 | b2 [box, elem] |
|
||||
| D.cpp:56:15:56:24 | new | D.cpp:58:5:58:27 | ... = ... |
|
||||
| D.cpp:58:5:58:12 | boxfield [post update] [box, elem] | D.cpp:58:5:58:12 | this [post update] [boxfield, box, ... (3)] |
|
||||
| D.cpp:58:5:58:12 | this [post update] [boxfield, box, ... (3)] | D.cpp:59:5:59:7 | this [boxfield, box, ... (3)] |
|
||||
| D.cpp:58:5:58:12 | boxfield [post update] [box, elem] | D.cpp:58:5:58:12 | this [post update] [boxfield, box, elem] |
|
||||
| D.cpp:58:5:58:12 | this [post update] [boxfield, box, elem] | D.cpp:59:5:59:7 | this [boxfield, box, elem] |
|
||||
| D.cpp:58:5:58:27 | ... = ... | D.cpp:58:15:58:17 | box [post update] [elem] |
|
||||
| D.cpp:58:15:58:17 | box [post update] [elem] | D.cpp:58:5:58:12 | boxfield [post update] [box, elem] |
|
||||
| D.cpp:59:5:59:7 | this [boxfield, box, ... (3)] | D.cpp:63:8:63:10 | this [boxfield, box, ... (3)] |
|
||||
| D.cpp:63:8:63:10 | this [boxfield, box, ... (3)] | D.cpp:64:10:64:17 | this [boxfield, box, ... (3)] |
|
||||
| D.cpp:59:5:59:7 | this [boxfield, box, elem] | D.cpp:63:8:63:10 | this [boxfield, box, elem] |
|
||||
| D.cpp:63:8:63:10 | this [boxfield, box, elem] | D.cpp:64:10:64:17 | this [boxfield, box, elem] |
|
||||
| D.cpp:64:10:64:17 | boxfield [box, elem] | D.cpp:64:20:64:22 | box [elem] |
|
||||
| D.cpp:64:10:64:17 | this [boxfield, box, ... (3)] | D.cpp:64:10:64:17 | boxfield [box, elem] |
|
||||
| D.cpp:64:10:64:17 | this [boxfield, box, elem] | D.cpp:64:10:64:17 | boxfield [box, elem] |
|
||||
| D.cpp:64:20:64:22 | box [elem] | D.cpp:64:25:64:28 | elem |
|
||||
| E.cpp:19:27:19:27 | p [data, buffer] | E.cpp:21:10:21:10 | p [data, buffer] |
|
||||
| E.cpp:21:10:21:10 | p [data, buffer] | E.cpp:21:13:21:16 | data [buffer] |
|
||||
@@ -193,33 +193,33 @@ edges
|
||||
| arrays.cpp:6:12:6:21 | call to user_input | arrays.cpp:10:8:10:15 | * ... |
|
||||
| arrays.cpp:15:14:15:23 | call to user_input | arrays.cpp:16:8:16:13 | access to array |
|
||||
| arrays.cpp:15:14:15:23 | call to user_input | arrays.cpp:17:8:17:13 | access to array |
|
||||
| arrays.cpp:36:3:36:3 | o [post update] [nested, arr, ... (3)] | arrays.cpp:37:8:37:8 | o [nested, arr, ... (3)] |
|
||||
| arrays.cpp:36:3:36:3 | o [post update] [nested, arr, ... (3)] | arrays.cpp:38:8:38:8 | o [nested, arr, ... (3)] |
|
||||
| arrays.cpp:36:3:36:3 | o [post update] [nested, arr, data] | arrays.cpp:37:8:37:8 | o [nested, arr, data] |
|
||||
| arrays.cpp:36:3:36:3 | o [post update] [nested, arr, data] | arrays.cpp:38:8:38:8 | o [nested, arr, data] |
|
||||
| arrays.cpp:36:3:36:17 | access to array [post update] [data] | arrays.cpp:36:12:36:14 | arr [inner post update] [data] |
|
||||
| arrays.cpp:36:3:36:37 | ... = ... | arrays.cpp:36:3:36:17 | access to array [post update] [data] |
|
||||
| arrays.cpp:36:5:36:10 | nested [post update] [arr, data] | arrays.cpp:36:3:36:3 | o [post update] [nested, arr, ... (3)] |
|
||||
| arrays.cpp:36:5:36:10 | nested [post update] [arr, data] | arrays.cpp:36:3:36:3 | o [post update] [nested, arr, data] |
|
||||
| arrays.cpp:36:12:36:14 | arr [inner post update] [data] | arrays.cpp:36:5:36:10 | nested [post update] [arr, data] |
|
||||
| arrays.cpp:36:26:36:35 | call to user_input | arrays.cpp:36:3:36:37 | ... = ... |
|
||||
| arrays.cpp:37:8:37:8 | o [nested, arr, ... (3)] | arrays.cpp:37:10:37:15 | nested [arr, data] |
|
||||
| arrays.cpp:37:8:37:8 | o [nested, arr, data] | arrays.cpp:37:10:37:15 | nested [arr, data] |
|
||||
| arrays.cpp:37:8:37:22 | access to array [data] | arrays.cpp:37:24:37:27 | data |
|
||||
| arrays.cpp:37:10:37:15 | nested [arr, data] | arrays.cpp:37:17:37:19 | arr [data] |
|
||||
| arrays.cpp:37:17:37:19 | arr [data] | arrays.cpp:37:8:37:22 | access to array [data] |
|
||||
| arrays.cpp:38:8:38:8 | o [nested, arr, ... (3)] | arrays.cpp:38:10:38:15 | nested [arr, data] |
|
||||
| arrays.cpp:38:8:38:8 | o [nested, arr, data] | arrays.cpp:38:10:38:15 | nested [arr, data] |
|
||||
| arrays.cpp:38:8:38:22 | access to array [data] | arrays.cpp:38:24:38:27 | data |
|
||||
| arrays.cpp:38:10:38:15 | nested [arr, data] | arrays.cpp:38:17:38:19 | arr [data] |
|
||||
| arrays.cpp:38:17:38:19 | arr [data] | arrays.cpp:38:8:38:22 | access to array [data] |
|
||||
| arrays.cpp:42:3:42:3 | o [post update] [indirect, arr, ... (3)] | arrays.cpp:43:8:43:8 | o [indirect, arr, ... (3)] |
|
||||
| arrays.cpp:42:3:42:3 | o [post update] [indirect, arr, ... (3)] | arrays.cpp:44:8:44:8 | o [indirect, arr, ... (3)] |
|
||||
| arrays.cpp:42:3:42:3 | o [post update] [indirect, arr, data] | arrays.cpp:43:8:43:8 | o [indirect, arr, data] |
|
||||
| arrays.cpp:42:3:42:3 | o [post update] [indirect, arr, data] | arrays.cpp:44:8:44:8 | o [indirect, arr, data] |
|
||||
| arrays.cpp:42:3:42:20 | access to array [post update] [data] | arrays.cpp:42:15:42:17 | arr [inner post update] [data] |
|
||||
| arrays.cpp:42:3:42:40 | ... = ... | arrays.cpp:42:3:42:20 | access to array [post update] [data] |
|
||||
| arrays.cpp:42:5:42:12 | indirect [post update] [arr, data] | arrays.cpp:42:3:42:3 | o [post update] [indirect, arr, ... (3)] |
|
||||
| arrays.cpp:42:5:42:12 | indirect [post update] [arr, data] | arrays.cpp:42:3:42:3 | o [post update] [indirect, arr, data] |
|
||||
| arrays.cpp:42:15:42:17 | arr [inner post update] [data] | arrays.cpp:42:5:42:12 | indirect [post update] [arr, data] |
|
||||
| arrays.cpp:42:29:42:38 | call to user_input | arrays.cpp:42:3:42:40 | ... = ... |
|
||||
| arrays.cpp:43:8:43:8 | o [indirect, arr, ... (3)] | arrays.cpp:43:10:43:17 | indirect [arr, data] |
|
||||
| arrays.cpp:43:8:43:8 | o [indirect, arr, data] | arrays.cpp:43:10:43:17 | indirect [arr, data] |
|
||||
| arrays.cpp:43:8:43:25 | access to array [data] | arrays.cpp:43:27:43:30 | data |
|
||||
| arrays.cpp:43:10:43:17 | indirect [arr, data] | arrays.cpp:43:20:43:22 | arr [data] |
|
||||
| arrays.cpp:43:20:43:22 | arr [data] | arrays.cpp:43:8:43:25 | access to array [data] |
|
||||
| arrays.cpp:44:8:44:8 | o [indirect, arr, ... (3)] | arrays.cpp:44:10:44:17 | indirect [arr, data] |
|
||||
| arrays.cpp:44:8:44:8 | o [indirect, arr, data] | arrays.cpp:44:10:44:17 | indirect [arr, data] |
|
||||
| arrays.cpp:44:8:44:25 | access to array [data] | arrays.cpp:44:27:44:30 | data |
|
||||
| arrays.cpp:44:10:44:17 | indirect [arr, data] | arrays.cpp:44:20:44:22 | arr [data] |
|
||||
| arrays.cpp:44:20:44:22 | arr [data] | arrays.cpp:44:8:44:25 | access to array [data] |
|
||||
@@ -308,33 +308,34 @@ edges
|
||||
| by_reference.cpp:135:8:135:13 | pouter [inner_ptr, a] | by_reference.cpp:135:16:135:24 | inner_ptr [a] |
|
||||
| by_reference.cpp:135:16:135:24 | inner_ptr [a] | by_reference.cpp:135:27:135:27 | a |
|
||||
| by_reference.cpp:136:8:136:13 | pouter [a] | by_reference.cpp:136:16:136:16 | a |
|
||||
| complex.cpp:40:17:40:17 | b [inner, f, ... (3)] | complex.cpp:51:8:51:8 | b [inner, f, ... (3)] |
|
||||
| complex.cpp:40:17:40:17 | b [inner, f, ... (3)] | complex.cpp:52:8:52:8 | b [inner, f, ... (3)] |
|
||||
| complex.cpp:51:8:51:8 | b [inner, f, ... (3)] | complex.cpp:51:10:51:14 | inner [f, a_] |
|
||||
| complex.cpp:51:10:51:14 | inner [f, a_] | complex.cpp:51:16:51:16 | f [a_] |
|
||||
| complex.cpp:51:16:51:16 | f [a_] | complex.cpp:51:18:51:18 | call to a |
|
||||
| complex.cpp:52:8:52:8 | b [inner, f, ... (3)] | complex.cpp:52:10:52:14 | inner [f, b_] |
|
||||
| complex.cpp:52:10:52:14 | inner [f, b_] | complex.cpp:52:16:52:16 | f [b_] |
|
||||
| complex.cpp:52:16:52:16 | f [b_] | complex.cpp:52:18:52:18 | call to b |
|
||||
| complex.cpp:62:3:62:4 | b1 [post update] [inner, f, ... (3)] | complex.cpp:68:7:68:8 | b1 [inner, f, ... (3)] |
|
||||
| complex.cpp:62:6:62:10 | inner [post update] [f, a_] | complex.cpp:62:3:62:4 | b1 [post update] [inner, f, ... (3)] |
|
||||
| complex.cpp:62:12:62:12 | ref arg f [a_] | complex.cpp:62:6:62:10 | inner [post update] [f, a_] |
|
||||
| complex.cpp:62:19:62:28 | call to user_input | complex.cpp:62:12:62:12 | ref arg f [a_] |
|
||||
| complex.cpp:63:3:63:4 | b2 [post update] [inner, f, ... (3)] | complex.cpp:71:7:71:8 | b2 [inner, f, ... (3)] |
|
||||
| complex.cpp:63:6:63:10 | inner [post update] [f, b_] | complex.cpp:63:3:63:4 | b2 [post update] [inner, f, ... (3)] |
|
||||
| complex.cpp:63:12:63:12 | ref arg f [b_] | complex.cpp:63:6:63:10 | inner [post update] [f, b_] |
|
||||
| complex.cpp:63:19:63:28 | call to user_input | complex.cpp:63:12:63:12 | ref arg f [b_] |
|
||||
| complex.cpp:64:3:64:4 | b3 [post update] [inner, f, ... (3)] | complex.cpp:74:7:74:8 | b3 [inner, f, ... (3)] |
|
||||
| complex.cpp:64:6:64:10 | inner [post update] [f, a_] | complex.cpp:64:3:64:4 | b3 [post update] [inner, f, ... (3)] |
|
||||
| complex.cpp:64:12:64:12 | ref arg f [a_] | complex.cpp:64:6:64:10 | inner [post update] [f, a_] |
|
||||
| complex.cpp:64:19:64:28 | call to user_input | complex.cpp:64:12:64:12 | ref arg f [a_] |
|
||||
| complex.cpp:65:3:65:4 | b3 [post update] [inner, f, ... (3)] | complex.cpp:74:7:74:8 | b3 [inner, f, ... (3)] |
|
||||
| complex.cpp:65:6:65:10 | inner [post update] [f, b_] | complex.cpp:65:3:65:4 | b3 [post update] [inner, f, ... (3)] |
|
||||
| complex.cpp:65:12:65:12 | ref arg f [b_] | complex.cpp:65:6:65:10 | inner [post update] [f, b_] |
|
||||
| complex.cpp:65:19:65:28 | call to user_input | complex.cpp:65:12:65:12 | ref arg f [b_] |
|
||||
| complex.cpp:68:7:68:8 | b1 [inner, f, ... (3)] | complex.cpp:40:17:40:17 | b [inner, f, ... (3)] |
|
||||
| complex.cpp:71:7:71:8 | b2 [inner, f, ... (3)] | complex.cpp:40:17:40:17 | b [inner, f, ... (3)] |
|
||||
| complex.cpp:74:7:74:8 | b3 [inner, f, ... (3)] | complex.cpp:40:17:40:17 | b [inner, f, ... (3)] |
|
||||
| complex.cpp:40:17:40:17 | b [inner, f, a_] | complex.cpp:42:8:42:8 | b [inner, f, a_] |
|
||||
| complex.cpp:40:17:40:17 | b [inner, f, b_] | complex.cpp:43:8:43:8 | b [inner, f, b_] |
|
||||
| complex.cpp:42:8:42:8 | b [inner, f, a_] | complex.cpp:42:10:42:14 | inner [f, a_] |
|
||||
| complex.cpp:42:10:42:14 | inner [f, a_] | complex.cpp:42:16:42:16 | f [a_] |
|
||||
| complex.cpp:42:16:42:16 | f [a_] | complex.cpp:42:18:42:18 | call to a |
|
||||
| complex.cpp:43:8:43:8 | b [inner, f, b_] | complex.cpp:43:10:43:14 | inner [f, b_] |
|
||||
| complex.cpp:43:10:43:14 | inner [f, b_] | complex.cpp:43:16:43:16 | f [b_] |
|
||||
| complex.cpp:43:16:43:16 | f [b_] | complex.cpp:43:18:43:18 | call to b |
|
||||
| complex.cpp:53:3:53:4 | b1 [post update] [inner, f, a_] | complex.cpp:59:7:59:8 | b1 [inner, f, a_] |
|
||||
| complex.cpp:53:6:53:10 | inner [post update] [f, a_] | complex.cpp:53:3:53:4 | b1 [post update] [inner, f, a_] |
|
||||
| complex.cpp:53:12:53:12 | ref arg f [a_] | complex.cpp:53:6:53:10 | inner [post update] [f, a_] |
|
||||
| complex.cpp:53:19:53:28 | call to user_input | complex.cpp:53:12:53:12 | ref arg f [a_] |
|
||||
| complex.cpp:54:3:54:4 | b2 [post update] [inner, f, b_] | complex.cpp:62:7:62:8 | b2 [inner, f, b_] |
|
||||
| complex.cpp:54:6:54:10 | inner [post update] [f, b_] | complex.cpp:54:3:54:4 | b2 [post update] [inner, f, b_] |
|
||||
| complex.cpp:54:12:54:12 | ref arg f [b_] | complex.cpp:54:6:54:10 | inner [post update] [f, b_] |
|
||||
| complex.cpp:54:19:54:28 | call to user_input | complex.cpp:54:12:54:12 | ref arg f [b_] |
|
||||
| complex.cpp:55:3:55:4 | b3 [post update] [inner, f, a_] | complex.cpp:65:7:65:8 | b3 [inner, f, a_] |
|
||||
| complex.cpp:55:6:55:10 | inner [post update] [f, a_] | complex.cpp:55:3:55:4 | b3 [post update] [inner, f, a_] |
|
||||
| complex.cpp:55:12:55:12 | ref arg f [a_] | complex.cpp:55:6:55:10 | inner [post update] [f, a_] |
|
||||
| complex.cpp:55:19:55:28 | call to user_input | complex.cpp:55:12:55:12 | ref arg f [a_] |
|
||||
| complex.cpp:56:3:56:4 | b3 [post update] [inner, f, b_] | complex.cpp:65:7:65:8 | b3 [inner, f, b_] |
|
||||
| complex.cpp:56:6:56:10 | inner [post update] [f, b_] | complex.cpp:56:3:56:4 | b3 [post update] [inner, f, b_] |
|
||||
| complex.cpp:56:12:56:12 | ref arg f [b_] | complex.cpp:56:6:56:10 | inner [post update] [f, b_] |
|
||||
| complex.cpp:56:19:56:28 | call to user_input | complex.cpp:56:12:56:12 | ref arg f [b_] |
|
||||
| complex.cpp:59:7:59:8 | b1 [inner, f, a_] | complex.cpp:40:17:40:17 | b [inner, f, a_] |
|
||||
| complex.cpp:62:7:62:8 | b2 [inner, f, b_] | complex.cpp:40:17:40:17 | b [inner, f, b_] |
|
||||
| complex.cpp:65:7:65:8 | b3 [inner, f, a_] | complex.cpp:40:17:40:17 | b [inner, f, a_] |
|
||||
| complex.cpp:65:7:65:8 | b3 [inner, f, b_] | complex.cpp:40:17:40:17 | b [inner, f, b_] |
|
||||
| constructors.cpp:26:15:26:15 | f [a_] | constructors.cpp:28:10:28:10 | f [a_] |
|
||||
| constructors.cpp:26:15:26:15 | f [b_] | constructors.cpp:29:10:29:10 | f [b_] |
|
||||
| constructors.cpp:28:10:28:10 | f [a_] | constructors.cpp:28:12:28:12 | call to a |
|
||||
@@ -386,16 +387,16 @@ edges
|
||||
| qualifiers.cpp:47:31:47:40 | call to user_input | qualifiers.cpp:47:5:47:42 | ... = ... |
|
||||
| qualifiers.cpp:48:10:48:14 | outer [inner, a] | qualifiers.cpp:48:16:48:20 | inner [a] |
|
||||
| qualifiers.cpp:48:16:48:20 | inner [a] | qualifiers.cpp:48:23:48:23 | a |
|
||||
| realistic.cpp:53:9:53:11 | foo [post update] [bar, baz, ... (4)] | realistic.cpp:61:21:61:23 | foo [bar, baz, ... (4)] |
|
||||
| realistic.cpp:53:9:53:18 | access to array [post update] [baz, userInput, ... (3)] | realistic.cpp:53:13:53:15 | bar [inner post update] [baz, userInput, ... (3)] |
|
||||
| realistic.cpp:53:9:53:11 | foo [post update] [bar, baz, userInput, bufferLen] | realistic.cpp:61:21:61:23 | foo [bar, baz, userInput, bufferLen] |
|
||||
| realistic.cpp:53:9:53:18 | access to array [post update] [baz, userInput, bufferLen] | realistic.cpp:53:13:53:15 | bar [inner post update] [baz, userInput, bufferLen] |
|
||||
| realistic.cpp:53:9:53:66 | ... = ... | realistic.cpp:53:25:53:33 | userInput [post update] [bufferLen] |
|
||||
| realistic.cpp:53:13:53:15 | bar [inner post update] [baz, userInput, ... (3)] | realistic.cpp:53:9:53:11 | foo [post update] [bar, baz, ... (4)] |
|
||||
| realistic.cpp:53:20:53:22 | baz [post update] [userInput, bufferLen] | realistic.cpp:53:9:53:18 | access to array [post update] [baz, userInput, ... (3)] |
|
||||
| realistic.cpp:53:13:53:15 | bar [inner post update] [baz, userInput, bufferLen] | realistic.cpp:53:9:53:11 | foo [post update] [bar, baz, userInput, bufferLen] |
|
||||
| realistic.cpp:53:20:53:22 | baz [post update] [userInput, bufferLen] | realistic.cpp:53:9:53:18 | access to array [post update] [baz, userInput, bufferLen] |
|
||||
| realistic.cpp:53:25:53:33 | userInput [post update] [bufferLen] | realistic.cpp:53:20:53:22 | baz [post update] [userInput, bufferLen] |
|
||||
| realistic.cpp:53:55:53:64 | call to user_input | realistic.cpp:53:9:53:66 | ... = ... |
|
||||
| realistic.cpp:61:21:61:23 | foo [bar, baz, ... (4)] | realistic.cpp:61:25:61:27 | bar [baz, userInput, ... (3)] |
|
||||
| realistic.cpp:61:21:61:30 | access to array [baz, userInput, ... (3)] | realistic.cpp:61:32:61:34 | baz [userInput, bufferLen] |
|
||||
| realistic.cpp:61:25:61:27 | bar [baz, userInput, ... (3)] | realistic.cpp:61:21:61:30 | access to array [baz, userInput, ... (3)] |
|
||||
| realistic.cpp:61:21:61:23 | foo [bar, baz, userInput, bufferLen] | realistic.cpp:61:25:61:27 | bar [baz, userInput, bufferLen] |
|
||||
| realistic.cpp:61:21:61:30 | access to array [baz, userInput, bufferLen] | realistic.cpp:61:32:61:34 | baz [userInput, bufferLen] |
|
||||
| realistic.cpp:61:25:61:27 | bar [baz, userInput, bufferLen] | realistic.cpp:61:21:61:30 | access to array [baz, userInput, bufferLen] |
|
||||
| realistic.cpp:61:32:61:34 | baz [userInput, bufferLen] | realistic.cpp:61:37:61:45 | userInput [bufferLen] |
|
||||
| realistic.cpp:61:37:61:45 | userInput [bufferLen] | realistic.cpp:61:47:61:55 | bufferLen |
|
||||
| simple.cpp:26:15:26:15 | f [a_] | simple.cpp:28:10:28:10 | f [a_] |
|
||||
@@ -517,14 +518,14 @@ nodes
|
||||
| A.cpp:160:29:160:29 | b | semmle.label | b |
|
||||
| A.cpp:161:18:161:40 | call to MyList [next, head] | semmle.label | call to MyList [next, head] |
|
||||
| A.cpp:161:38:161:39 | l1 [head] | semmle.label | l1 [head] |
|
||||
| A.cpp:162:18:162:40 | call to MyList [next, next, ... (3)] | semmle.label | call to MyList [next, next, ... (3)] |
|
||||
| A.cpp:162:18:162:40 | call to MyList [next, next, head] | semmle.label | call to MyList [next, next, head] |
|
||||
| A.cpp:162:38:162:39 | l2 [next, head] | semmle.label | l2 [next, head] |
|
||||
| A.cpp:165:10:165:11 | l3 [next, next, ... (3)] | semmle.label | l3 [next, next, ... (3)] |
|
||||
| A.cpp:165:10:165:11 | l3 [next, next, head] | semmle.label | l3 [next, next, head] |
|
||||
| A.cpp:165:14:165:17 | next [next, head] | semmle.label | next [next, head] |
|
||||
| A.cpp:165:20:165:23 | next [head] | semmle.label | next [head] |
|
||||
| A.cpp:165:26:165:29 | head | semmle.label | head |
|
||||
| A.cpp:167:44:167:44 | l [next, head] | semmle.label | l [next, head] |
|
||||
| A.cpp:167:44:167:44 | l [next, next, ... (3)] | semmle.label | l [next, next, ... (3)] |
|
||||
| A.cpp:167:44:167:44 | l [next, next, head] | semmle.label | l [next, next, head] |
|
||||
| A.cpp:167:47:167:50 | next [head] | semmle.label | next [head] |
|
||||
| A.cpp:167:47:167:50 | next [next, head] | semmle.label | next [next, head] |
|
||||
| A.cpp:169:12:169:12 | l [head] | semmle.label | l [head] |
|
||||
@@ -586,13 +587,13 @@ nodes
|
||||
| D.cpp:52:14:52:14 | b [box, elem] | semmle.label | b [box, elem] |
|
||||
| D.cpp:56:15:56:24 | new | semmle.label | new |
|
||||
| D.cpp:58:5:58:12 | boxfield [post update] [box, elem] | semmle.label | boxfield [post update] [box, elem] |
|
||||
| D.cpp:58:5:58:12 | this [post update] [boxfield, box, ... (3)] | semmle.label | this [post update] [boxfield, box, ... (3)] |
|
||||
| D.cpp:58:5:58:12 | this [post update] [boxfield, box, elem] | semmle.label | this [post update] [boxfield, box, elem] |
|
||||
| D.cpp:58:5:58:27 | ... = ... | semmle.label | ... = ... |
|
||||
| D.cpp:58:15:58:17 | box [post update] [elem] | semmle.label | box [post update] [elem] |
|
||||
| D.cpp:59:5:59:7 | this [boxfield, box, ... (3)] | semmle.label | this [boxfield, box, ... (3)] |
|
||||
| D.cpp:63:8:63:10 | this [boxfield, box, ... (3)] | semmle.label | this [boxfield, box, ... (3)] |
|
||||
| D.cpp:59:5:59:7 | this [boxfield, box, elem] | semmle.label | this [boxfield, box, elem] |
|
||||
| D.cpp:63:8:63:10 | this [boxfield, box, elem] | semmle.label | this [boxfield, box, elem] |
|
||||
| D.cpp:64:10:64:17 | boxfield [box, elem] | semmle.label | boxfield [box, elem] |
|
||||
| D.cpp:64:10:64:17 | this [boxfield, box, ... (3)] | semmle.label | this [boxfield, box, ... (3)] |
|
||||
| D.cpp:64:10:64:17 | this [boxfield, box, elem] | semmle.label | this [boxfield, box, elem] |
|
||||
| D.cpp:64:20:64:22 | box [elem] | semmle.label | box [elem] |
|
||||
| D.cpp:64:25:64:28 | elem | semmle.label | elem |
|
||||
| E.cpp:19:27:19:27 | p [data, buffer] | semmle.label | p [data, buffer] |
|
||||
@@ -675,34 +676,34 @@ nodes
|
||||
| arrays.cpp:15:14:15:23 | call to user_input | semmle.label | call to user_input |
|
||||
| arrays.cpp:16:8:16:13 | access to array | semmle.label | access to array |
|
||||
| arrays.cpp:17:8:17:13 | access to array | semmle.label | access to array |
|
||||
| arrays.cpp:36:3:36:3 | o [post update] [nested, arr, ... (3)] | semmle.label | o [post update] [nested, arr, ... (3)] |
|
||||
| arrays.cpp:36:3:36:3 | o [post update] [nested, arr, data] | semmle.label | o [post update] [nested, arr, data] |
|
||||
| arrays.cpp:36:3:36:17 | access to array [post update] [data] | semmle.label | access to array [post update] [data] |
|
||||
| arrays.cpp:36:3:36:37 | ... = ... | semmle.label | ... = ... |
|
||||
| arrays.cpp:36:5:36:10 | nested [post update] [arr, data] | semmle.label | nested [post update] [arr, data] |
|
||||
| arrays.cpp:36:12:36:14 | arr [inner post update] [data] | semmle.label | arr [inner post update] [data] |
|
||||
| arrays.cpp:36:26:36:35 | call to user_input | semmle.label | call to user_input |
|
||||
| arrays.cpp:37:8:37:8 | o [nested, arr, ... (3)] | semmle.label | o [nested, arr, ... (3)] |
|
||||
| arrays.cpp:37:8:37:8 | o [nested, arr, data] | semmle.label | o [nested, arr, data] |
|
||||
| arrays.cpp:37:8:37:22 | access to array [data] | semmle.label | access to array [data] |
|
||||
| arrays.cpp:37:10:37:15 | nested [arr, data] | semmle.label | nested [arr, data] |
|
||||
| arrays.cpp:37:17:37:19 | arr [data] | semmle.label | arr [data] |
|
||||
| arrays.cpp:37:24:37:27 | data | semmle.label | data |
|
||||
| arrays.cpp:38:8:38:8 | o [nested, arr, ... (3)] | semmle.label | o [nested, arr, ... (3)] |
|
||||
| arrays.cpp:38:8:38:8 | o [nested, arr, data] | semmle.label | o [nested, arr, data] |
|
||||
| arrays.cpp:38:8:38:22 | access to array [data] | semmle.label | access to array [data] |
|
||||
| arrays.cpp:38:10:38:15 | nested [arr, data] | semmle.label | nested [arr, data] |
|
||||
| arrays.cpp:38:17:38:19 | arr [data] | semmle.label | arr [data] |
|
||||
| arrays.cpp:38:24:38:27 | data | semmle.label | data |
|
||||
| arrays.cpp:42:3:42:3 | o [post update] [indirect, arr, ... (3)] | semmle.label | o [post update] [indirect, arr, ... (3)] |
|
||||
| arrays.cpp:42:3:42:3 | o [post update] [indirect, arr, data] | semmle.label | o [post update] [indirect, arr, data] |
|
||||
| arrays.cpp:42:3:42:20 | access to array [post update] [data] | semmle.label | access to array [post update] [data] |
|
||||
| arrays.cpp:42:3:42:40 | ... = ... | semmle.label | ... = ... |
|
||||
| arrays.cpp:42:5:42:12 | indirect [post update] [arr, data] | semmle.label | indirect [post update] [arr, data] |
|
||||
| arrays.cpp:42:15:42:17 | arr [inner post update] [data] | semmle.label | arr [inner post update] [data] |
|
||||
| arrays.cpp:42:29:42:38 | call to user_input | semmle.label | call to user_input |
|
||||
| arrays.cpp:43:8:43:8 | o [indirect, arr, ... (3)] | semmle.label | o [indirect, arr, ... (3)] |
|
||||
| arrays.cpp:43:8:43:8 | o [indirect, arr, data] | semmle.label | o [indirect, arr, data] |
|
||||
| arrays.cpp:43:8:43:25 | access to array [data] | semmle.label | access to array [data] |
|
||||
| arrays.cpp:43:10:43:17 | indirect [arr, data] | semmle.label | indirect [arr, data] |
|
||||
| arrays.cpp:43:20:43:22 | arr [data] | semmle.label | arr [data] |
|
||||
| arrays.cpp:43:27:43:30 | data | semmle.label | data |
|
||||
| arrays.cpp:44:8:44:8 | o [indirect, arr, ... (3)] | semmle.label | o [indirect, arr, ... (3)] |
|
||||
| arrays.cpp:44:8:44:8 | o [indirect, arr, data] | semmle.label | o [indirect, arr, data] |
|
||||
| arrays.cpp:44:8:44:25 | access to array [data] | semmle.label | access to array [data] |
|
||||
| arrays.cpp:44:10:44:17 | indirect [arr, data] | semmle.label | indirect [arr, data] |
|
||||
| arrays.cpp:44:20:44:22 | arr [data] | semmle.label | arr [data] |
|
||||
@@ -796,34 +797,36 @@ nodes
|
||||
| by_reference.cpp:135:27:135:27 | a | semmle.label | a |
|
||||
| by_reference.cpp:136:8:136:13 | pouter [a] | semmle.label | pouter [a] |
|
||||
| by_reference.cpp:136:16:136:16 | a | semmle.label | a |
|
||||
| complex.cpp:40:17:40:17 | b [inner, f, ... (3)] | semmle.label | b [inner, f, ... (3)] |
|
||||
| complex.cpp:51:8:51:8 | b [inner, f, ... (3)] | semmle.label | b [inner, f, ... (3)] |
|
||||
| complex.cpp:51:10:51:14 | inner [f, a_] | semmle.label | inner [f, a_] |
|
||||
| complex.cpp:51:16:51:16 | f [a_] | semmle.label | f [a_] |
|
||||
| complex.cpp:51:18:51:18 | call to a | semmle.label | call to a |
|
||||
| complex.cpp:52:8:52:8 | b [inner, f, ... (3)] | semmle.label | b [inner, f, ... (3)] |
|
||||
| complex.cpp:52:10:52:14 | inner [f, b_] | semmle.label | inner [f, b_] |
|
||||
| complex.cpp:52:16:52:16 | f [b_] | semmle.label | f [b_] |
|
||||
| complex.cpp:52:18:52:18 | call to b | semmle.label | call to b |
|
||||
| complex.cpp:62:3:62:4 | b1 [post update] [inner, f, ... (3)] | semmle.label | b1 [post update] [inner, f, ... (3)] |
|
||||
| complex.cpp:62:6:62:10 | inner [post update] [f, a_] | semmle.label | inner [post update] [f, a_] |
|
||||
| complex.cpp:62:12:62:12 | ref arg f [a_] | semmle.label | ref arg f [a_] |
|
||||
| complex.cpp:62:19:62:28 | call to user_input | semmle.label | call to user_input |
|
||||
| complex.cpp:63:3:63:4 | b2 [post update] [inner, f, ... (3)] | semmle.label | b2 [post update] [inner, f, ... (3)] |
|
||||
| complex.cpp:63:6:63:10 | inner [post update] [f, b_] | semmle.label | inner [post update] [f, b_] |
|
||||
| complex.cpp:63:12:63:12 | ref arg f [b_] | semmle.label | ref arg f [b_] |
|
||||
| complex.cpp:63:19:63:28 | call to user_input | semmle.label | call to user_input |
|
||||
| complex.cpp:64:3:64:4 | b3 [post update] [inner, f, ... (3)] | semmle.label | b3 [post update] [inner, f, ... (3)] |
|
||||
| complex.cpp:64:6:64:10 | inner [post update] [f, a_] | semmle.label | inner [post update] [f, a_] |
|
||||
| complex.cpp:64:12:64:12 | ref arg f [a_] | semmle.label | ref arg f [a_] |
|
||||
| complex.cpp:64:19:64:28 | call to user_input | semmle.label | call to user_input |
|
||||
| complex.cpp:65:3:65:4 | b3 [post update] [inner, f, ... (3)] | semmle.label | b3 [post update] [inner, f, ... (3)] |
|
||||
| complex.cpp:65:6:65:10 | inner [post update] [f, b_] | semmle.label | inner [post update] [f, b_] |
|
||||
| complex.cpp:65:12:65:12 | ref arg f [b_] | semmle.label | ref arg f [b_] |
|
||||
| complex.cpp:65:19:65:28 | call to user_input | semmle.label | call to user_input |
|
||||
| complex.cpp:68:7:68:8 | b1 [inner, f, ... (3)] | semmle.label | b1 [inner, f, ... (3)] |
|
||||
| complex.cpp:71:7:71:8 | b2 [inner, f, ... (3)] | semmle.label | b2 [inner, f, ... (3)] |
|
||||
| complex.cpp:74:7:74:8 | b3 [inner, f, ... (3)] | semmle.label | b3 [inner, f, ... (3)] |
|
||||
| complex.cpp:40:17:40:17 | b [inner, f, a_] | semmle.label | b [inner, f, a_] |
|
||||
| complex.cpp:40:17:40:17 | b [inner, f, b_] | semmle.label | b [inner, f, b_] |
|
||||
| complex.cpp:42:8:42:8 | b [inner, f, a_] | semmle.label | b [inner, f, a_] |
|
||||
| complex.cpp:42:10:42:14 | inner [f, a_] | semmle.label | inner [f, a_] |
|
||||
| complex.cpp:42:16:42:16 | f [a_] | semmle.label | f [a_] |
|
||||
| complex.cpp:42:18:42:18 | call to a | semmle.label | call to a |
|
||||
| complex.cpp:43:8:43:8 | b [inner, f, b_] | semmle.label | b [inner, f, b_] |
|
||||
| complex.cpp:43:10:43:14 | inner [f, b_] | semmle.label | inner [f, b_] |
|
||||
| complex.cpp:43:16:43:16 | f [b_] | semmle.label | f [b_] |
|
||||
| complex.cpp:43:18:43:18 | call to b | semmle.label | call to b |
|
||||
| complex.cpp:53:3:53:4 | b1 [post update] [inner, f, a_] | semmle.label | b1 [post update] [inner, f, a_] |
|
||||
| complex.cpp:53:6:53:10 | inner [post update] [f, a_] | semmle.label | inner [post update] [f, a_] |
|
||||
| complex.cpp:53:12:53:12 | ref arg f [a_] | semmle.label | ref arg f [a_] |
|
||||
| complex.cpp:53:19:53:28 | call to user_input | semmle.label | call to user_input |
|
||||
| complex.cpp:54:3:54:4 | b2 [post update] [inner, f, b_] | semmle.label | b2 [post update] [inner, f, b_] |
|
||||
| complex.cpp:54:6:54:10 | inner [post update] [f, b_] | semmle.label | inner [post update] [f, b_] |
|
||||
| complex.cpp:54:12:54:12 | ref arg f [b_] | semmle.label | ref arg f [b_] |
|
||||
| complex.cpp:54:19:54:28 | call to user_input | semmle.label | call to user_input |
|
||||
| complex.cpp:55:3:55:4 | b3 [post update] [inner, f, a_] | semmle.label | b3 [post update] [inner, f, a_] |
|
||||
| complex.cpp:55:6:55:10 | inner [post update] [f, a_] | semmle.label | inner [post update] [f, a_] |
|
||||
| complex.cpp:55:12:55:12 | ref arg f [a_] | semmle.label | ref arg f [a_] |
|
||||
| complex.cpp:55:19:55:28 | call to user_input | semmle.label | call to user_input |
|
||||
| complex.cpp:56:3:56:4 | b3 [post update] [inner, f, b_] | semmle.label | b3 [post update] [inner, f, b_] |
|
||||
| complex.cpp:56:6:56:10 | inner [post update] [f, b_] | semmle.label | inner [post update] [f, b_] |
|
||||
| complex.cpp:56:12:56:12 | ref arg f [b_] | semmle.label | ref arg f [b_] |
|
||||
| complex.cpp:56:19:56:28 | call to user_input | semmle.label | call to user_input |
|
||||
| complex.cpp:59:7:59:8 | b1 [inner, f, a_] | semmle.label | b1 [inner, f, a_] |
|
||||
| complex.cpp:62:7:62:8 | b2 [inner, f, b_] | semmle.label | b2 [inner, f, b_] |
|
||||
| complex.cpp:65:7:65:8 | b3 [inner, f, a_] | semmle.label | b3 [inner, f, a_] |
|
||||
| complex.cpp:65:7:65:8 | b3 [inner, f, b_] | semmle.label | b3 [inner, f, b_] |
|
||||
| constructors.cpp:26:15:26:15 | f [a_] | semmle.label | f [a_] |
|
||||
| constructors.cpp:26:15:26:15 | f [b_] | semmle.label | f [b_] |
|
||||
| constructors.cpp:28:10:28:10 | f [a_] | semmle.label | f [a_] |
|
||||
@@ -883,16 +886,16 @@ nodes
|
||||
| qualifiers.cpp:48:10:48:14 | outer [inner, a] | semmle.label | outer [inner, a] |
|
||||
| qualifiers.cpp:48:16:48:20 | inner [a] | semmle.label | inner [a] |
|
||||
| qualifiers.cpp:48:23:48:23 | a | semmle.label | a |
|
||||
| realistic.cpp:53:9:53:11 | foo [post update] [bar, baz, ... (4)] | semmle.label | foo [post update] [bar, baz, ... (4)] |
|
||||
| realistic.cpp:53:9:53:18 | access to array [post update] [baz, userInput, ... (3)] | semmle.label | access to array [post update] [baz, userInput, ... (3)] |
|
||||
| realistic.cpp:53:9:53:11 | foo [post update] [bar, baz, userInput, bufferLen] | semmle.label | foo [post update] [bar, baz, userInput, bufferLen] |
|
||||
| realistic.cpp:53:9:53:18 | access to array [post update] [baz, userInput, bufferLen] | semmle.label | access to array [post update] [baz, userInput, bufferLen] |
|
||||
| realistic.cpp:53:9:53:66 | ... = ... | semmle.label | ... = ... |
|
||||
| realistic.cpp:53:13:53:15 | bar [inner post update] [baz, userInput, ... (3)] | semmle.label | bar [inner post update] [baz, userInput, ... (3)] |
|
||||
| realistic.cpp:53:13:53:15 | bar [inner post update] [baz, userInput, bufferLen] | semmle.label | bar [inner post update] [baz, userInput, bufferLen] |
|
||||
| realistic.cpp:53:20:53:22 | baz [post update] [userInput, bufferLen] | semmle.label | baz [post update] [userInput, bufferLen] |
|
||||
| realistic.cpp:53:25:53:33 | userInput [post update] [bufferLen] | semmle.label | userInput [post update] [bufferLen] |
|
||||
| realistic.cpp:53:55:53:64 | call to user_input | semmle.label | call to user_input |
|
||||
| realistic.cpp:61:21:61:23 | foo [bar, baz, ... (4)] | semmle.label | foo [bar, baz, ... (4)] |
|
||||
| realistic.cpp:61:21:61:30 | access to array [baz, userInput, ... (3)] | semmle.label | access to array [baz, userInput, ... (3)] |
|
||||
| realistic.cpp:61:25:61:27 | bar [baz, userInput, ... (3)] | semmle.label | bar [baz, userInput, ... (3)] |
|
||||
| realistic.cpp:61:21:61:23 | foo [bar, baz, userInput, bufferLen] | semmle.label | foo [bar, baz, userInput, bufferLen] |
|
||||
| realistic.cpp:61:21:61:30 | access to array [baz, userInput, bufferLen] | semmle.label | access to array [baz, userInput, bufferLen] |
|
||||
| realistic.cpp:61:25:61:27 | bar [baz, userInput, bufferLen] | semmle.label | bar [baz, userInput, bufferLen] |
|
||||
| realistic.cpp:61:32:61:34 | baz [userInput, bufferLen] | semmle.label | baz [userInput, bufferLen] |
|
||||
| realistic.cpp:61:37:61:45 | userInput [bufferLen] | semmle.label | userInput [bufferLen] |
|
||||
| realistic.cpp:61:47:61:55 | bufferLen | semmle.label | bufferLen |
|
||||
@@ -1021,14 +1024,10 @@ nodes
|
||||
| by_reference.cpp:134:29:134:29 | a | by_reference.cpp:88:13:88:22 | call to user_input | by_reference.cpp:134:29:134:29 | a | a flows from $@ | by_reference.cpp:88:13:88:22 | call to user_input | call to user_input |
|
||||
| by_reference.cpp:135:27:135:27 | a | by_reference.cpp:88:13:88:22 | call to user_input | by_reference.cpp:135:27:135:27 | a | a flows from $@ | by_reference.cpp:88:13:88:22 | call to user_input | call to user_input |
|
||||
| by_reference.cpp:136:16:136:16 | a | by_reference.cpp:96:8:96:17 | call to user_input | by_reference.cpp:136:16:136:16 | a | a flows from $@ | by_reference.cpp:96:8:96:17 | call to user_input | call to user_input |
|
||||
| complex.cpp:51:18:51:18 | call to a | complex.cpp:62:19:62:28 | call to user_input | complex.cpp:51:18:51:18 | call to a | call to a flows from $@ | complex.cpp:62:19:62:28 | call to user_input | call to user_input |
|
||||
| complex.cpp:51:18:51:18 | call to a | complex.cpp:63:19:63:28 | call to user_input | complex.cpp:51:18:51:18 | call to a | call to a flows from $@ | complex.cpp:63:19:63:28 | call to user_input | call to user_input |
|
||||
| complex.cpp:51:18:51:18 | call to a | complex.cpp:64:19:64:28 | call to user_input | complex.cpp:51:18:51:18 | call to a | call to a flows from $@ | complex.cpp:64:19:64:28 | call to user_input | call to user_input |
|
||||
| complex.cpp:51:18:51:18 | call to a | complex.cpp:65:19:65:28 | call to user_input | complex.cpp:51:18:51:18 | call to a | call to a flows from $@ | complex.cpp:65:19:65:28 | call to user_input | call to user_input |
|
||||
| complex.cpp:52:18:52:18 | call to b | complex.cpp:62:19:62:28 | call to user_input | complex.cpp:52:18:52:18 | call to b | call to b flows from $@ | complex.cpp:62:19:62:28 | call to user_input | call to user_input |
|
||||
| complex.cpp:52:18:52:18 | call to b | complex.cpp:63:19:63:28 | call to user_input | complex.cpp:52:18:52:18 | call to b | call to b flows from $@ | complex.cpp:63:19:63:28 | call to user_input | call to user_input |
|
||||
| complex.cpp:52:18:52:18 | call to b | complex.cpp:64:19:64:28 | call to user_input | complex.cpp:52:18:52:18 | call to b | call to b flows from $@ | complex.cpp:64:19:64:28 | call to user_input | call to user_input |
|
||||
| complex.cpp:52:18:52:18 | call to b | complex.cpp:65:19:65:28 | call to user_input | complex.cpp:52:18:52:18 | call to b | call to b flows from $@ | complex.cpp:65:19:65:28 | call to user_input | call to user_input |
|
||||
| complex.cpp:42:18:42:18 | call to a | complex.cpp:53:19:53:28 | call to user_input | complex.cpp:42:18:42:18 | call to a | call to a flows from $@ | complex.cpp:53:19:53:28 | call to user_input | call to user_input |
|
||||
| complex.cpp:42:18:42:18 | call to a | complex.cpp:55:19:55:28 | call to user_input | complex.cpp:42:18:42:18 | call to a | call to a flows from $@ | complex.cpp:55:19:55:28 | call to user_input | call to user_input |
|
||||
| complex.cpp:43:18:43:18 | call to b | complex.cpp:54:19:54:28 | call to user_input | complex.cpp:43:18:43:18 | call to b | call to b flows from $@ | complex.cpp:54:19:54:28 | call to user_input | call to user_input |
|
||||
| complex.cpp:43:18:43:18 | call to b | complex.cpp:56:19:56:28 | call to user_input | complex.cpp:43:18:43:18 | call to b | call to b flows from $@ | complex.cpp:56:19:56:28 | call to user_input | call to user_input |
|
||||
| constructors.cpp:28:12:28:12 | call to a | constructors.cpp:34:11:34:20 | call to user_input | constructors.cpp:28:12:28:12 | call to a | call to a flows from $@ | constructors.cpp:34:11:34:20 | call to user_input | call to user_input |
|
||||
| constructors.cpp:28:12:28:12 | call to a | constructors.cpp:36:11:36:20 | call to user_input | constructors.cpp:28:12:28:12 | call to a | call to a flows from $@ | constructors.cpp:36:11:36:20 | call to user_input | call to user_input |
|
||||
| constructors.cpp:29:12:29:12 | call to b | constructors.cpp:35:14:35:23 | call to user_input | constructors.cpp:29:12:29:12 | call to b | call to b flows from $@ | constructors.cpp:35:14:35:23 | call to user_input | call to user_input |
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -346,7 +346,7 @@ ssa.cpp:
|
||||
# 97| r97_2(glval<Point>) = VariableAddress[a] :
|
||||
# 97| r97_3(Point *) = CopyValue : r97_2
|
||||
# 97| r97_4(void *) = Convert : r97_3
|
||||
# 97| v97_5(void) = Call : func:r97_1, 0:r97_4
|
||||
# 97| v97_5(void) = Call[Escape] : func:r97_1, 0:r97_4
|
||||
# 97| m97_6(unknown) = ^CallSideEffect : ~m95_7
|
||||
# 97| m97_7(unknown) = Chi : total:m95_7, partial:m97_6
|
||||
# 97| v97_8(void) = ^BufferReadSideEffect[0] : &:r97_4, ~m97_7
|
||||
@@ -403,7 +403,7 @@ ssa.cpp:
|
||||
# 108| r108_2(glval<Point>) = VariableAddress[a] :
|
||||
# 108| r108_3(Point *) = CopyValue : r108_2
|
||||
# 108| r108_4(void *) = Convert : r108_3
|
||||
# 108| v108_5(void) = Call : func:r108_1, 0:r108_4
|
||||
# 108| v108_5(void) = Call[Escape] : func:r108_1, 0:r108_4
|
||||
# 108| m108_6(unknown) = ^CallSideEffect : ~m105_7
|
||||
# 108| m108_7(unknown) = Chi : total:m105_7, partial:m108_6
|
||||
# 108| v108_8(void) = ^BufferReadSideEffect[0] : &:r108_4, ~m108_7
|
||||
@@ -476,7 +476,7 @@ ssa.cpp:
|
||||
# 119| r119_2(glval<Point>) = VariableAddress[a] :
|
||||
# 119| r119_3(Point *) = CopyValue : r119_2
|
||||
# 119| r119_4(void *) = Convert : r119_3
|
||||
# 119| v119_5(void) = Call : func:r119_1, 0:r119_4
|
||||
# 119| v119_5(void) = Call[Escape] : func:r119_1, 0:r119_4
|
||||
# 119| m119_6(unknown) = ^CallSideEffect : ~m117_13
|
||||
# 119| m119_7(unknown) = Chi : total:m117_13, partial:m119_6
|
||||
# 119| v119_8(void) = ^BufferReadSideEffect[0] : &:r119_4, ~m119_7
|
||||
@@ -848,7 +848,7 @@ ssa.cpp:
|
||||
# 199| r199_6(glval<char *>) = VariableAddress[str2] :
|
||||
# 199| r199_7(char *) = Load : &:r199_6, m198_10
|
||||
# 199| r199_8(char *) = Convert : r199_7
|
||||
# 199| r199_9(int) = Call : func:r199_2, 0:r199_5, 1:r199_8
|
||||
# 199| r199_9(int) = Call[strcmp] : func:r199_2, 0:r199_5, 1:r199_8
|
||||
# 199| v199_10(void) = ^BufferReadSideEffect[0] : &:r199_5, ~m198_8
|
||||
# 199| v199_11(void) = ^BufferReadSideEffect[1] : &:r199_8, ~m198_12
|
||||
# 199| m199_12(int) = Store : &:r199_1, r199_9
|
||||
@@ -856,7 +856,7 @@ ssa.cpp:
|
||||
# 200| r200_2(glval<char *>) = VariableAddress[str1] :
|
||||
# 200| r200_3(char *) = Load : &:r200_2, m198_6
|
||||
# 200| r200_4(char *) = Convert : r200_3
|
||||
# 200| r200_5(int) = Call : func:r200_1, 0:r200_4
|
||||
# 200| r200_5(int) = Call[strlen] : func:r200_1, 0:r200_4
|
||||
# 200| v200_6(void) = ^BufferReadSideEffect[0] : &:r200_4, ~m198_8
|
||||
# 200| r200_7(glval<int>) = VariableAddress[ret] :
|
||||
# 200| r200_8(int) = Load : &:r200_7, m199_12
|
||||
@@ -865,7 +865,7 @@ ssa.cpp:
|
||||
# 201| r201_1(glval<unknown>) = FunctionAddress[abs] :
|
||||
# 201| r201_2(glval<int>) = VariableAddress[x] :
|
||||
# 201| r201_3(int) = Load : &:r201_2, m198_14
|
||||
# 201| r201_4(int) = Call : func:r201_1, 0:r201_3
|
||||
# 201| r201_4(int) = Call[abs] : func:r201_1, 0:r201_3
|
||||
# 201| r201_5(glval<int>) = VariableAddress[ret] :
|
||||
# 201| r201_6(int) = Load : &:r201_5, m200_10
|
||||
# 201| r201_7(int) = Add : r201_6, r201_4
|
||||
@@ -901,7 +901,7 @@ ssa.cpp:
|
||||
# 209| r209_6(int *) = CopyValue : r209_5
|
||||
# 209| r209_7(void *) = Convert : r209_6
|
||||
# 209| r209_8(int) = Constant[4] :
|
||||
# 209| r209_9(void *) = Call : func:r209_1, 0:r209_4, 1:r209_7, 2:r209_8
|
||||
# 209| r209_9(void *) = Call[memcpy] : func:r209_1, 0:r209_4, 1:r209_7, 2:r209_8
|
||||
# 209| v209_10(void) = ^SizedBufferReadSideEffect[1] : &:r209_7, r209_8, ~m207_6
|
||||
# 209| m209_11(unknown) = ^SizedBufferMustWriteSideEffect[0] : &:r209_4, r209_8
|
||||
# 209| m209_12(unknown) = Chi : total:m208_3, partial:m209_11
|
||||
@@ -988,7 +988,7 @@ ssa.cpp:
|
||||
# 226| m226_3(unknown) = InitializeNonLocal :
|
||||
# 226| m226_4(unknown) = Chi : total:m226_2, partial:m226_3
|
||||
# 227| r227_1(glval<unknown>) = FunctionAddress[ExternalFunc] :
|
||||
# 227| v227_2(void) = Call : func:r227_1
|
||||
# 227| v227_2(void) = Call[ExternalFunc] : func:r227_1
|
||||
# 227| m227_3(unknown) = ^CallSideEffect : ~m226_4
|
||||
# 227| m227_4(unknown) = Chi : total:m226_4, partial:m227_3
|
||||
# 229| r229_1(glval<char *>) = VariableAddress[s] :
|
||||
@@ -1051,14 +1051,14 @@ ssa.cpp:
|
||||
# 240| m240_2(Constructible) = Uninitialized[c] : &:r240_1
|
||||
# 240| r240_3(glval<unknown>) = FunctionAddress[Constructible] :
|
||||
# 240| r240_4(int) = Constant[1] :
|
||||
# 240| v240_5(void) = Call : func:r240_3, this:r240_1, 0:r240_4
|
||||
# 240| v240_5(void) = Call[Constructible] : func:r240_3, this:r240_1, 0:r240_4
|
||||
# 240| m240_6(unknown) = ^CallSideEffect : ~m239_4
|
||||
# 240| m240_7(unknown) = Chi : total:m239_4, partial:m240_6
|
||||
# 240| m240_8(Constructible) = ^IndirectMayWriteSideEffect[-1] : &:r240_1
|
||||
# 240| m240_9(Constructible) = Chi : total:m240_2, partial:m240_8
|
||||
# 241| r241_1(glval<Constructible>) = VariableAddress[c] :
|
||||
# 241| r241_2(glval<unknown>) = FunctionAddress[g] :
|
||||
# 241| v241_3(void) = Call : func:r241_2, this:r241_1
|
||||
# 241| v241_3(void) = Call[g] : func:r241_2, this:r241_1
|
||||
# 241| m241_4(unknown) = ^CallSideEffect : ~m240_7
|
||||
# 241| m241_5(unknown) = Chi : total:m240_7, partial:m241_4
|
||||
# 241| v241_6(void) = ^BufferReadSideEffect[-1] : &:r241_1, ~m240_9
|
||||
@@ -1066,7 +1066,7 @@ ssa.cpp:
|
||||
# 241| m241_8(Constructible) = Chi : total:m240_9, partial:m241_7
|
||||
# 242| r242_1(glval<Constructible>) = VariableAddress[c] :
|
||||
# 242| r242_2(glval<unknown>) = FunctionAddress[g] :
|
||||
# 242| v242_3(void) = Call : func:r242_2, this:r242_1
|
||||
# 242| v242_3(void) = Call[g] : func:r242_2, this:r242_1
|
||||
# 242| m242_4(unknown) = ^CallSideEffect : ~m241_5
|
||||
# 242| m242_5(unknown) = Chi : total:m241_5, partial:m242_4
|
||||
# 242| v242_6(void) = ^BufferReadSideEffect[-1] : &:r242_1, ~m241_8
|
||||
@@ -1076,14 +1076,14 @@ ssa.cpp:
|
||||
# 243| m243_2(Constructible) = Uninitialized[c2] : &:r243_1
|
||||
# 243| r243_3(glval<unknown>) = FunctionAddress[Constructible] :
|
||||
# 243| r243_4(int) = Constant[2] :
|
||||
# 243| v243_5(void) = Call : func:r243_3, this:r243_1, 0:r243_4
|
||||
# 243| v243_5(void) = Call[Constructible] : func:r243_3, this:r243_1, 0:r243_4
|
||||
# 243| m243_6(unknown) = ^CallSideEffect : ~m242_5
|
||||
# 243| m243_7(unknown) = Chi : total:m242_5, partial:m243_6
|
||||
# 243| m243_8(Constructible) = ^IndirectMayWriteSideEffect[-1] : &:r243_1
|
||||
# 243| m243_9(Constructible) = Chi : total:m243_2, partial:m243_8
|
||||
# 244| r244_1(glval<Constructible>) = VariableAddress[c2] :
|
||||
# 244| r244_2(glval<unknown>) = FunctionAddress[g] :
|
||||
# 244| v244_3(void) = Call : func:r244_2, this:r244_1
|
||||
# 244| v244_3(void) = Call[g] : func:r244_2, this:r244_1
|
||||
# 244| m244_4(unknown) = ^CallSideEffect : ~m243_7
|
||||
# 244| m244_5(unknown) = Chi : total:m243_7, partial:m244_4
|
||||
# 244| v244_6(void) = ^BufferReadSideEffect[-1] : &:r244_1, ~m243_9
|
||||
@@ -1114,7 +1114,7 @@ ssa.cpp:
|
||||
# 248| r248_5(unsigned long) = Convert : r248_4
|
||||
# 248| r248_6(unsigned long) = Constant[1] :
|
||||
# 248| r248_7(unsigned long) = Mul : r248_5, r248_6
|
||||
# 248| r248_8(void *) = Call : func:r248_2, 0:r248_7
|
||||
# 248| r248_8(void *) = Call[operator new[]] : func:r248_2, 0:r248_7
|
||||
# 248| m248_9(unknown) = ^CallSideEffect : ~m247_9
|
||||
# 248| m248_10(unknown) = Chi : total:m247_9, partial:m248_9
|
||||
# 248| m248_11(unknown) = ^InitializeDynamicAllocation : &:r248_8
|
||||
@@ -1136,7 +1136,7 @@ ssa.cpp:
|
||||
# 250| r250_7(void *) = Convert : r250_6
|
||||
# 250| r250_8(glval<int>) = VariableAddress[size] :
|
||||
# 250| r250_9(int) = Load : &:r250_8, m247_11
|
||||
# 250| r250_10(void *) = Call : func:r250_1, 0:r250_4, 1:r250_7, 2:r250_9
|
||||
# 250| r250_10(void *) = Call[memcpy] : func:r250_1, 0:r250_4, 1:r250_7, 2:r250_9
|
||||
# 250| v250_11(void) = ^SizedBufferReadSideEffect[1] : &:r250_7, r250_9, ~m249_6
|
||||
# 250| m250_12(unknown) = ^SizedBufferMustWriteSideEffect[0] : &:r250_4, r250_9
|
||||
# 250| m250_13(unknown) = Chi : total:m249_6, partial:m250_12
|
||||
@@ -1166,14 +1166,14 @@ ssa.cpp:
|
||||
|
||||
# 256| Block 1
|
||||
# 256| r256_1(glval<unknown>) = FunctionAddress[ExternalFunc] :
|
||||
# 256| v256_2(void) = Call : func:r256_1
|
||||
# 256| v256_2(void) = Call[ExternalFunc] : func:r256_1
|
||||
# 256| m256_3(unknown) = ^CallSideEffect : ~m254_4
|
||||
# 256| m256_4(unknown) = Chi : total:m254_4, partial:m256_3
|
||||
#-----| Goto -> Block 3
|
||||
|
||||
# 259| Block 2
|
||||
# 259| r259_1(glval<unknown>) = FunctionAddress[ExternalFunc] :
|
||||
# 259| v259_2(void) = Call : func:r259_1
|
||||
# 259| v259_2(void) = Call[ExternalFunc] : func:r259_1
|
||||
# 259| m259_3(unknown) = ^CallSideEffect : ~m254_4
|
||||
# 259| m259_4(unknown) = Chi : total:m254_4, partial:m259_3
|
||||
#-----| Goto -> Block 3
|
||||
@@ -1213,7 +1213,7 @@ ssa.cpp:
|
||||
# 269| r269_2(glval<unknown>) = FunctionAddress[malloc] :
|
||||
# 269| r269_3(glval<int>) = VariableAddress[size] :
|
||||
# 269| r269_4(int) = Load : &:r269_3, m268_11
|
||||
# 269| r269_5(void *) = Call : func:r269_2, 0:r269_4
|
||||
# 269| r269_5(void *) = Call[malloc] : func:r269_2, 0:r269_4
|
||||
# 269| m269_6(unknown) = ^CallSideEffect : ~m268_9
|
||||
# 269| m269_7(unknown) = Chi : total:m268_9, partial:m269_6
|
||||
# 269| m269_8(unknown) = ^InitializeDynamicAllocation : &:r269_5
|
||||
@@ -1226,7 +1226,7 @@ ssa.cpp:
|
||||
# 270| r270_5(void *) = Load : &:r270_4, m268_6
|
||||
# 270| r270_6(glval<int>) = VariableAddress[size] :
|
||||
# 270| r270_7(int) = Load : &:r270_6, m268_11
|
||||
# 270| r270_8(void *) = Call : func:r270_1, 0:r270_3, 1:r270_5, 2:r270_7
|
||||
# 270| r270_8(void *) = Call[memcpy] : func:r270_1, 0:r270_3, 1:r270_5, 2:r270_7
|
||||
# 270| v270_9(void) = ^SizedBufferReadSideEffect[1] : &:r270_5, r270_7, ~m269_7
|
||||
# 270| m270_10(unknown) = ^SizedBufferMustWriteSideEffect[0] : &:r270_3, r270_7
|
||||
# 270| m270_11(unknown) = Chi : total:m269_9, partial:m270_10
|
||||
@@ -1362,7 +1362,7 @@ ssa.cpp:
|
||||
# 292| r292_1(glval<Point *>) = VariableAddress[p] :
|
||||
# 292| r292_2(glval<unknown>) = FunctionAddress[operator new] :
|
||||
# 292| r292_3(unsigned long) = Constant[8] :
|
||||
# 292| r292_4(void *) = Call : func:r292_2, 0:r292_3
|
||||
# 292| r292_4(void *) = Call[operator new] : func:r292_2, 0:r292_3
|
||||
# 292| m292_5(unknown) = ^CallSideEffect : ~m291_4
|
||||
# 292| m292_6(unknown) = Chi : total:m291_4, partial:m292_5
|
||||
# 292| m292_7(unknown) = ^InitializeDynamicAllocation : &:r292_4
|
||||
@@ -1371,7 +1371,7 @@ ssa.cpp:
|
||||
# 293| r293_1(glval<Point *>) = VariableAddress[q] :
|
||||
# 293| r293_2(glval<unknown>) = FunctionAddress[operator new] :
|
||||
# 293| r293_3(unsigned long) = Constant[8] :
|
||||
# 293| r293_4(void *) = Call : func:r293_2, 0:r293_3
|
||||
# 293| r293_4(void *) = Call[operator new] : func:r293_2, 0:r293_3
|
||||
# 293| m293_5(unknown) = ^CallSideEffect : ~m292_6
|
||||
# 293| m293_6(unknown) = Chi : total:m292_6, partial:m293_5
|
||||
# 293| m293_7(unknown) = ^InitializeDynamicAllocation : &:r293_4
|
||||
@@ -1380,7 +1380,7 @@ ssa.cpp:
|
||||
# 294| r294_1(glval<int>) = VariableAddress[j] :
|
||||
# 294| r294_2(glval<unknown>) = FunctionAddress[operator new] :
|
||||
# 294| r294_3(unsigned long) = Constant[4] :
|
||||
# 294| r294_4(void *) = Call : func:r294_2, 0:r294_3
|
||||
# 294| r294_4(void *) = Call[operator new] : func:r294_2, 0:r294_3
|
||||
# 294| m294_5(unknown) = ^CallSideEffect : ~m293_6
|
||||
# 294| m294_6(unknown) = Chi : total:m293_6, partial:m294_5
|
||||
# 294| m294_7(unknown) = ^InitializeDynamicAllocation : &:r294_4
|
||||
@@ -1388,7 +1388,7 @@ ssa.cpp:
|
||||
# 294| r294_9(glval<unknown>) = FunctionAddress[A] :
|
||||
# 294| r294_10(glval<unknown>) = FunctionAddress[operator new] :
|
||||
# 294| r294_11(unsigned long) = Constant[4] :
|
||||
# 294| r294_12(void *) = Call : func:r294_10, 0:r294_11
|
||||
# 294| r294_12(void *) = Call[operator new] : func:r294_10, 0:r294_11
|
||||
# 294| m294_13(unknown) = ^CallSideEffect : ~m294_6
|
||||
# 294| m294_14(unknown) = Chi : total:m294_6, partial:m294_13
|
||||
# 294| m294_15(unknown) = ^InitializeDynamicAllocation : &:r294_12
|
||||
@@ -1396,12 +1396,12 @@ ssa.cpp:
|
||||
# 294| r294_17(glval<unknown>) = FunctionAddress[A] :
|
||||
# 294| r294_18(glval<int>) = VariableAddress[x] :
|
||||
# 294| r294_19(int) = Load : &:r294_18, m291_6
|
||||
# 294| v294_20(void) = Call : func:r294_17, this:r294_16, 0:r294_19
|
||||
# 294| v294_20(void) = Call[A] : func:r294_17, this:r294_16, 0:r294_19
|
||||
# 294| m294_21(unknown) = ^CallSideEffect : ~m294_14
|
||||
# 294| m294_22(unknown) = Chi : total:m294_14, partial:m294_21
|
||||
# 294| m294_23(A) = ^IndirectMayWriteSideEffect[-1] : &:r294_16
|
||||
# 294| m294_24(unknown) = Chi : total:m294_15, partial:m294_23
|
||||
# 294| v294_25(void) = Call : func:r294_9, this:r294_8, 0:r294_16
|
||||
# 294| v294_25(void) = Call[A] : func:r294_9, this:r294_8, 0:r294_16
|
||||
# 294| m294_26(unknown) = ^CallSideEffect : ~m294_22
|
||||
# 294| m294_27(unknown) = Chi : total:m294_22, partial:m294_26
|
||||
# 294| m294_28(A) = ^IndirectMayWriteSideEffect[-1] : &:r294_8
|
||||
@@ -1415,13 +1415,13 @@ ssa.cpp:
|
||||
# 295| r295_1(glval<A *>) = VariableAddress[a] :
|
||||
# 295| r295_2(glval<unknown>) = FunctionAddress[operator new] :
|
||||
# 295| r295_3(unsigned long) = Constant[4] :
|
||||
# 295| r295_4(void *) = Call : func:r295_2, 0:r295_3
|
||||
# 295| r295_4(void *) = Call[operator new] : func:r295_2, 0:r295_3
|
||||
# 295| m295_5(unknown) = ^CallSideEffect : ~m294_27
|
||||
# 295| m295_6(unknown) = Chi : total:m294_27, partial:m295_5
|
||||
# 295| m295_7(unknown) = ^InitializeDynamicAllocation : &:r295_4
|
||||
# 295| r295_8(A *) = Convert : r295_4
|
||||
# 295| r295_9(glval<unknown>) = FunctionAddress[A] :
|
||||
# 295| v295_10(void) = Call : func:r295_9, this:r295_8
|
||||
# 295| v295_10(void) = Call[A] : func:r295_9, this:r295_8
|
||||
# 295| m295_11(unknown) = ^CallSideEffect : ~m295_6
|
||||
# 295| m295_12(unknown) = Chi : total:m295_6, partial:m295_11
|
||||
# 295| m295_13(A) = ^IndirectMayWriteSideEffect[-1] : &:r295_8
|
||||
@@ -1454,7 +1454,7 @@ ssa.cpp:
|
||||
# 302| r302_3(int) = Load : &:r302_2, m301_6
|
||||
# 302| r302_4(glval<char **>) = VariableAddress[argv] :
|
||||
# 302| r302_5(char **) = Load : &:r302_4, m301_8
|
||||
# 302| v302_6(void) = Call : func:r302_1, 0:r302_3, 1:r302_5
|
||||
# 302| v302_6(void) = Call[unknownFunction] : func:r302_1, 0:r302_3, 1:r302_5
|
||||
# 302| m302_7(unknown) = ^CallSideEffect : ~m301_11
|
||||
# 302| m302_8(unknown) = Chi : total:m301_11, partial:m302_7
|
||||
# 302| v302_9(void) = ^BufferReadSideEffect[1] : &:r302_5, ~m302_8
|
||||
@@ -1465,7 +1465,7 @@ ssa.cpp:
|
||||
# 303| r303_3(int) = Load : &:r303_2, m301_6
|
||||
# 303| r303_4(glval<char **>) = VariableAddress[argv] :
|
||||
# 303| r303_5(char **) = Load : &:r303_4, m301_8
|
||||
# 303| v303_6(void) = Call : func:r303_1, 0:r303_3, 1:r303_5
|
||||
# 303| v303_6(void) = Call[unknownFunction] : func:r303_1, 0:r303_3, 1:r303_5
|
||||
# 303| m303_7(unknown) = ^CallSideEffect : ~m302_11
|
||||
# 303| m303_8(unknown) = Chi : total:m302_11, partial:m303_7
|
||||
# 303| v303_9(void) = ^BufferReadSideEffect[1] : &:r303_5, ~m303_8
|
||||
|
||||
@@ -345,7 +345,7 @@ ssa.cpp:
|
||||
# 97| r97_2(glval<Point>) = VariableAddress[a] :
|
||||
# 97| r97_3(Point *) = CopyValue : r97_2
|
||||
# 97| r97_4(void *) = Convert : r97_3
|
||||
# 97| v97_5(void) = Call : func:r97_1, 0:r97_4
|
||||
# 97| v97_5(void) = Call[Escape] : func:r97_1, 0:r97_4
|
||||
# 97| m97_6(unknown) = ^CallSideEffect : ~m95_4
|
||||
# 97| m97_7(unknown) = Chi : total:m95_4, partial:m97_6
|
||||
# 97| v97_8(void) = ^BufferReadSideEffect[0] : &:r97_4, ~m95_6
|
||||
@@ -401,7 +401,7 @@ ssa.cpp:
|
||||
# 108| r108_2(glval<Point>) = VariableAddress[a] :
|
||||
# 108| r108_3(Point *) = CopyValue : r108_2
|
||||
# 108| r108_4(void *) = Convert : r108_3
|
||||
# 108| v108_5(void) = Call : func:r108_1, 0:r108_4
|
||||
# 108| v108_5(void) = Call[Escape] : func:r108_1, 0:r108_4
|
||||
# 108| m108_6(unknown) = ^CallSideEffect : ~m105_4
|
||||
# 108| m108_7(unknown) = Chi : total:m105_4, partial:m108_6
|
||||
# 108| v108_8(void) = ^BufferReadSideEffect[0] : &:r108_4, ~m105_6
|
||||
@@ -473,7 +473,7 @@ ssa.cpp:
|
||||
# 119| r119_2(glval<Point>) = VariableAddress[a] :
|
||||
# 119| r119_3(Point *) = CopyValue : r119_2
|
||||
# 119| r119_4(void *) = Convert : r119_3
|
||||
# 119| v119_5(void) = Call : func:r119_1, 0:r119_4
|
||||
# 119| v119_5(void) = Call[Escape] : func:r119_1, 0:r119_4
|
||||
# 119| m119_6(unknown) = ^CallSideEffect : ~m116_4
|
||||
# 119| m119_7(unknown) = Chi : total:m116_4, partial:m119_6
|
||||
# 119| v119_8(void) = ^BufferReadSideEffect[0] : &:r119_4, ~m117_12
|
||||
@@ -843,7 +843,7 @@ ssa.cpp:
|
||||
# 199| r199_6(glval<char *>) = VariableAddress[str2] :
|
||||
# 199| r199_7(char *) = Load : &:r199_6, m198_10
|
||||
# 199| r199_8(char *) = Convert : r199_7
|
||||
# 199| r199_9(int) = Call : func:r199_2, 0:r199_5, 1:r199_8
|
||||
# 199| r199_9(int) = Call[strcmp] : func:r199_2, 0:r199_5, 1:r199_8
|
||||
# 199| v199_10(void) = ^BufferReadSideEffect[0] : &:r199_5, ~m198_8
|
||||
# 199| v199_11(void) = ^BufferReadSideEffect[1] : &:r199_8, ~m198_12
|
||||
# 199| m199_12(int) = Store : &:r199_1, r199_9
|
||||
@@ -851,7 +851,7 @@ ssa.cpp:
|
||||
# 200| r200_2(glval<char *>) = VariableAddress[str1] :
|
||||
# 200| r200_3(char *) = Load : &:r200_2, m198_6
|
||||
# 200| r200_4(char *) = Convert : r200_3
|
||||
# 200| r200_5(int) = Call : func:r200_1, 0:r200_4
|
||||
# 200| r200_5(int) = Call[strlen] : func:r200_1, 0:r200_4
|
||||
# 200| v200_6(void) = ^BufferReadSideEffect[0] : &:r200_4, ~m198_8
|
||||
# 200| r200_7(glval<int>) = VariableAddress[ret] :
|
||||
# 200| r200_8(int) = Load : &:r200_7, m199_12
|
||||
@@ -860,7 +860,7 @@ ssa.cpp:
|
||||
# 201| r201_1(glval<unknown>) = FunctionAddress[abs] :
|
||||
# 201| r201_2(glval<int>) = VariableAddress[x] :
|
||||
# 201| r201_3(int) = Load : &:r201_2, m198_14
|
||||
# 201| r201_4(int) = Call : func:r201_1, 0:r201_3
|
||||
# 201| r201_4(int) = Call[abs] : func:r201_1, 0:r201_3
|
||||
# 201| r201_5(glval<int>) = VariableAddress[ret] :
|
||||
# 201| r201_6(int) = Load : &:r201_5, m200_10
|
||||
# 201| r201_7(int) = Add : r201_6, r201_4
|
||||
@@ -894,7 +894,7 @@ ssa.cpp:
|
||||
# 209| r209_6(int *) = CopyValue : r209_5
|
||||
# 209| r209_7(void *) = Convert : r209_6
|
||||
# 209| r209_8(int) = Constant[4] :
|
||||
# 209| r209_9(void *) = Call : func:r209_1, 0:r209_4, 1:r209_7, 2:r209_8
|
||||
# 209| r209_9(void *) = Call[memcpy] : func:r209_1, 0:r209_4, 1:r209_7, 2:r209_8
|
||||
# 209| v209_10(void) = ^SizedBufferReadSideEffect[1] : &:r209_7, r209_8, ~m207_6
|
||||
# 209| m209_11(unknown) = ^SizedBufferMustWriteSideEffect[0] : &:r209_4, r209_8
|
||||
# 209| m209_12(int) = Chi : total:m208_2, partial:m209_11
|
||||
@@ -981,7 +981,7 @@ ssa.cpp:
|
||||
# 226| m226_3(unknown) = InitializeNonLocal :
|
||||
# 226| m226_4(unknown) = Chi : total:m226_2, partial:m226_3
|
||||
# 227| r227_1(glval<unknown>) = FunctionAddress[ExternalFunc] :
|
||||
# 227| v227_2(void) = Call : func:r227_1
|
||||
# 227| v227_2(void) = Call[ExternalFunc] : func:r227_1
|
||||
# 227| m227_3(unknown) = ^CallSideEffect : ~m226_4
|
||||
# 227| m227_4(unknown) = Chi : total:m226_4, partial:m227_3
|
||||
# 229| r229_1(glval<char *>) = VariableAddress[s] :
|
||||
@@ -1044,14 +1044,14 @@ ssa.cpp:
|
||||
# 240| m240_2(Constructible) = Uninitialized[c] : &:r240_1
|
||||
# 240| r240_3(glval<unknown>) = FunctionAddress[Constructible] :
|
||||
# 240| r240_4(int) = Constant[1] :
|
||||
# 240| v240_5(void) = Call : func:r240_3, this:r240_1, 0:r240_4
|
||||
# 240| v240_5(void) = Call[Constructible] : func:r240_3, this:r240_1, 0:r240_4
|
||||
# 240| m240_6(unknown) = ^CallSideEffect : ~m239_4
|
||||
# 240| m240_7(unknown) = Chi : total:m239_4, partial:m240_6
|
||||
# 240| m240_8(Constructible) = ^IndirectMayWriteSideEffect[-1] : &:r240_1
|
||||
# 240| m240_9(Constructible) = Chi : total:m240_2, partial:m240_8
|
||||
# 241| r241_1(glval<Constructible>) = VariableAddress[c] :
|
||||
# 241| r241_2(glval<unknown>) = FunctionAddress[g] :
|
||||
# 241| v241_3(void) = Call : func:r241_2, this:r241_1
|
||||
# 241| v241_3(void) = Call[g] : func:r241_2, this:r241_1
|
||||
# 241| m241_4(unknown) = ^CallSideEffect : ~m240_7
|
||||
# 241| m241_5(unknown) = Chi : total:m240_7, partial:m241_4
|
||||
# 241| v241_6(void) = ^BufferReadSideEffect[-1] : &:r241_1, ~m240_9
|
||||
@@ -1059,7 +1059,7 @@ ssa.cpp:
|
||||
# 241| m241_8(Constructible) = Chi : total:m240_9, partial:m241_7
|
||||
# 242| r242_1(glval<Constructible>) = VariableAddress[c] :
|
||||
# 242| r242_2(glval<unknown>) = FunctionAddress[g] :
|
||||
# 242| v242_3(void) = Call : func:r242_2, this:r242_1
|
||||
# 242| v242_3(void) = Call[g] : func:r242_2, this:r242_1
|
||||
# 242| m242_4(unknown) = ^CallSideEffect : ~m241_5
|
||||
# 242| m242_5(unknown) = Chi : total:m241_5, partial:m242_4
|
||||
# 242| v242_6(void) = ^BufferReadSideEffect[-1] : &:r242_1, ~m241_8
|
||||
@@ -1069,14 +1069,14 @@ ssa.cpp:
|
||||
# 243| m243_2(Constructible) = Uninitialized[c2] : &:r243_1
|
||||
# 243| r243_3(glval<unknown>) = FunctionAddress[Constructible] :
|
||||
# 243| r243_4(int) = Constant[2] :
|
||||
# 243| v243_5(void) = Call : func:r243_3, this:r243_1, 0:r243_4
|
||||
# 243| v243_5(void) = Call[Constructible] : func:r243_3, this:r243_1, 0:r243_4
|
||||
# 243| m243_6(unknown) = ^CallSideEffect : ~m242_5
|
||||
# 243| m243_7(unknown) = Chi : total:m242_5, partial:m243_6
|
||||
# 243| m243_8(Constructible) = ^IndirectMayWriteSideEffect[-1] : &:r243_1
|
||||
# 243| m243_9(Constructible) = Chi : total:m243_2, partial:m243_8
|
||||
# 244| r244_1(glval<Constructible>) = VariableAddress[c2] :
|
||||
# 244| r244_2(glval<unknown>) = FunctionAddress[g] :
|
||||
# 244| v244_3(void) = Call : func:r244_2, this:r244_1
|
||||
# 244| v244_3(void) = Call[g] : func:r244_2, this:r244_1
|
||||
# 244| m244_4(unknown) = ^CallSideEffect : ~m243_7
|
||||
# 244| m244_5(unknown) = Chi : total:m243_7, partial:m244_4
|
||||
# 244| v244_6(void) = ^BufferReadSideEffect[-1] : &:r244_1, ~m243_9
|
||||
@@ -1106,7 +1106,7 @@ ssa.cpp:
|
||||
# 248| r248_5(unsigned long) = Convert : r248_4
|
||||
# 248| r248_6(unsigned long) = Constant[1] :
|
||||
# 248| r248_7(unsigned long) = Mul : r248_5, r248_6
|
||||
# 248| r248_8(void *) = Call : func:r248_2, 0:r248_7
|
||||
# 248| r248_8(void *) = Call[operator new[]] : func:r248_2, 0:r248_7
|
||||
# 248| m248_9(unknown) = ^CallSideEffect : ~m247_4
|
||||
# 248| m248_10(unknown) = Chi : total:m247_4, partial:m248_9
|
||||
# 248| m248_11(unknown) = ^InitializeDynamicAllocation : &:r248_8
|
||||
@@ -1127,7 +1127,7 @@ ssa.cpp:
|
||||
# 250| r250_7(void *) = Convert : r250_6
|
||||
# 250| r250_8(glval<int>) = VariableAddress[size] :
|
||||
# 250| r250_9(int) = Load : &:r250_8, m247_10
|
||||
# 250| r250_10(void *) = Call : func:r250_1, 0:r250_4, 1:r250_7, 2:r250_9
|
||||
# 250| r250_10(void *) = Call[memcpy] : func:r250_1, 0:r250_4, 1:r250_7, 2:r250_9
|
||||
# 250| v250_11(void) = ^SizedBufferReadSideEffect[1] : &:r250_7, r250_9, ~m249_6
|
||||
# 250| m250_12(unknown) = ^SizedBufferMustWriteSideEffect[0] : &:r250_4, r250_9
|
||||
# 250| m250_13(unknown) = Chi : total:m248_11, partial:m250_12
|
||||
@@ -1157,14 +1157,14 @@ ssa.cpp:
|
||||
|
||||
# 256| Block 1
|
||||
# 256| r256_1(glval<unknown>) = FunctionAddress[ExternalFunc] :
|
||||
# 256| v256_2(void) = Call : func:r256_1
|
||||
# 256| v256_2(void) = Call[ExternalFunc] : func:r256_1
|
||||
# 256| m256_3(unknown) = ^CallSideEffect : ~m254_4
|
||||
# 256| m256_4(unknown) = Chi : total:m254_4, partial:m256_3
|
||||
#-----| Goto -> Block 3
|
||||
|
||||
# 259| Block 2
|
||||
# 259| r259_1(glval<unknown>) = FunctionAddress[ExternalFunc] :
|
||||
# 259| v259_2(void) = Call : func:r259_1
|
||||
# 259| v259_2(void) = Call[ExternalFunc] : func:r259_1
|
||||
# 259| m259_3(unknown) = ^CallSideEffect : ~m254_4
|
||||
# 259| m259_4(unknown) = Chi : total:m254_4, partial:m259_3
|
||||
#-----| Goto -> Block 3
|
||||
@@ -1203,7 +1203,7 @@ ssa.cpp:
|
||||
# 269| r269_2(glval<unknown>) = FunctionAddress[malloc] :
|
||||
# 269| r269_3(glval<int>) = VariableAddress[size] :
|
||||
# 269| r269_4(int) = Load : &:r269_3, m268_10
|
||||
# 269| r269_5(void *) = Call : func:r269_2, 0:r269_4
|
||||
# 269| r269_5(void *) = Call[malloc] : func:r269_2, 0:r269_4
|
||||
# 269| m269_6(unknown) = ^CallSideEffect : ~m268_4
|
||||
# 269| m269_7(unknown) = Chi : total:m268_4, partial:m269_6
|
||||
# 269| m269_8(unknown) = ^InitializeDynamicAllocation : &:r269_5
|
||||
@@ -1215,7 +1215,7 @@ ssa.cpp:
|
||||
# 270| r270_5(void *) = Load : &:r270_4, m268_6
|
||||
# 270| r270_6(glval<int>) = VariableAddress[size] :
|
||||
# 270| r270_7(int) = Load : &:r270_6, m268_10
|
||||
# 270| r270_8(void *) = Call : func:r270_1, 0:r270_3, 1:r270_5, 2:r270_7
|
||||
# 270| r270_8(void *) = Call[memcpy] : func:r270_1, 0:r270_3, 1:r270_5, 2:r270_7
|
||||
# 270| v270_9(void) = ^SizedBufferReadSideEffect[1] : &:r270_5, r270_7, ~m268_8
|
||||
# 270| m270_10(unknown) = ^SizedBufferMustWriteSideEffect[0] : &:r270_3, r270_7
|
||||
# 270| m270_11(unknown) = Chi : total:m269_8, partial:m270_10
|
||||
@@ -1350,7 +1350,7 @@ ssa.cpp:
|
||||
# 292| r292_1(glval<Point *>) = VariableAddress[p] :
|
||||
# 292| r292_2(glval<unknown>) = FunctionAddress[operator new] :
|
||||
# 292| r292_3(unsigned long) = Constant[8] :
|
||||
# 292| r292_4(void *) = Call : func:r292_2, 0:r292_3
|
||||
# 292| r292_4(void *) = Call[operator new] : func:r292_2, 0:r292_3
|
||||
# 292| m292_5(unknown) = ^CallSideEffect : ~m291_4
|
||||
# 292| m292_6(unknown) = Chi : total:m291_4, partial:m292_5
|
||||
# 292| m292_7(unknown) = ^InitializeDynamicAllocation : &:r292_4
|
||||
@@ -1359,7 +1359,7 @@ ssa.cpp:
|
||||
# 293| r293_1(glval<Point *>) = VariableAddress[q] :
|
||||
# 293| r293_2(glval<unknown>) = FunctionAddress[operator new] :
|
||||
# 293| r293_3(unsigned long) = Constant[8] :
|
||||
# 293| r293_4(void *) = Call : func:r293_2, 0:r293_3
|
||||
# 293| r293_4(void *) = Call[operator new] : func:r293_2, 0:r293_3
|
||||
# 293| m293_5(unknown) = ^CallSideEffect : ~m292_6
|
||||
# 293| m293_6(unknown) = Chi : total:m292_6, partial:m293_5
|
||||
# 293| m293_7(unknown) = ^InitializeDynamicAllocation : &:r293_4
|
||||
@@ -1368,7 +1368,7 @@ ssa.cpp:
|
||||
# 294| r294_1(glval<int>) = VariableAddress[j] :
|
||||
# 294| r294_2(glval<unknown>) = FunctionAddress[operator new] :
|
||||
# 294| r294_3(unsigned long) = Constant[4] :
|
||||
# 294| r294_4(void *) = Call : func:r294_2, 0:r294_3
|
||||
# 294| r294_4(void *) = Call[operator new] : func:r294_2, 0:r294_3
|
||||
# 294| m294_5(unknown) = ^CallSideEffect : ~m293_6
|
||||
# 294| m294_6(unknown) = Chi : total:m293_6, partial:m294_5
|
||||
# 294| m294_7(unknown) = ^InitializeDynamicAllocation : &:r294_4
|
||||
@@ -1376,7 +1376,7 @@ ssa.cpp:
|
||||
# 294| r294_9(glval<unknown>) = FunctionAddress[A] :
|
||||
# 294| r294_10(glval<unknown>) = FunctionAddress[operator new] :
|
||||
# 294| r294_11(unsigned long) = Constant[4] :
|
||||
# 294| r294_12(void *) = Call : func:r294_10, 0:r294_11
|
||||
# 294| r294_12(void *) = Call[operator new] : func:r294_10, 0:r294_11
|
||||
# 294| m294_13(unknown) = ^CallSideEffect : ~m294_6
|
||||
# 294| m294_14(unknown) = Chi : total:m294_6, partial:m294_13
|
||||
# 294| m294_15(unknown) = ^InitializeDynamicAllocation : &:r294_12
|
||||
@@ -1384,12 +1384,12 @@ ssa.cpp:
|
||||
# 294| r294_17(glval<unknown>) = FunctionAddress[A] :
|
||||
# 294| r294_18(glval<int>) = VariableAddress[x] :
|
||||
# 294| r294_19(int) = Load : &:r294_18, m291_6
|
||||
# 294| v294_20(void) = Call : func:r294_17, this:r294_16, 0:r294_19
|
||||
# 294| v294_20(void) = Call[A] : func:r294_17, this:r294_16, 0:r294_19
|
||||
# 294| m294_21(unknown) = ^CallSideEffect : ~m294_14
|
||||
# 294| m294_22(unknown) = Chi : total:m294_14, partial:m294_21
|
||||
# 294| m294_23(A) = ^IndirectMayWriteSideEffect[-1] : &:r294_16
|
||||
# 294| m294_24(unknown) = Chi : total:m294_15, partial:m294_23
|
||||
# 294| v294_25(void) = Call : func:r294_9, this:r294_8, 0:r294_16
|
||||
# 294| v294_25(void) = Call[A] : func:r294_9, this:r294_8, 0:r294_16
|
||||
# 294| m294_26(unknown) = ^CallSideEffect : ~m294_22
|
||||
# 294| m294_27(unknown) = Chi : total:m294_22, partial:m294_26
|
||||
# 294| m294_28(A) = ^IndirectMayWriteSideEffect[-1] : &:r294_8
|
||||
@@ -1403,13 +1403,13 @@ ssa.cpp:
|
||||
# 295| r295_1(glval<A *>) = VariableAddress[a] :
|
||||
# 295| r295_2(glval<unknown>) = FunctionAddress[operator new] :
|
||||
# 295| r295_3(unsigned long) = Constant[4] :
|
||||
# 295| r295_4(void *) = Call : func:r295_2, 0:r295_3
|
||||
# 295| r295_4(void *) = Call[operator new] : func:r295_2, 0:r295_3
|
||||
# 295| m295_5(unknown) = ^CallSideEffect : ~m294_27
|
||||
# 295| m295_6(unknown) = Chi : total:m294_27, partial:m295_5
|
||||
# 295| m295_7(unknown) = ^InitializeDynamicAllocation : &:r295_4
|
||||
# 295| r295_8(A *) = Convert : r295_4
|
||||
# 295| r295_9(glval<unknown>) = FunctionAddress[A] :
|
||||
# 295| v295_10(void) = Call : func:r295_9, this:r295_8
|
||||
# 295| v295_10(void) = Call[A] : func:r295_9, this:r295_8
|
||||
# 295| m295_11(unknown) = ^CallSideEffect : ~m295_6
|
||||
# 295| m295_12(unknown) = Chi : total:m295_6, partial:m295_11
|
||||
# 295| m295_13(A) = ^IndirectMayWriteSideEffect[-1] : &:r295_8
|
||||
@@ -1441,7 +1441,7 @@ ssa.cpp:
|
||||
# 302| r302_3(int) = Load : &:r302_2, m301_6
|
||||
# 302| r302_4(glval<char **>) = VariableAddress[argv] :
|
||||
# 302| r302_5(char **) = Load : &:r302_4, m301_8
|
||||
# 302| v302_6(void) = Call : func:r302_1, 0:r302_3, 1:r302_5
|
||||
# 302| v302_6(void) = Call[unknownFunction] : func:r302_1, 0:r302_3, 1:r302_5
|
||||
# 302| m302_7(unknown) = ^CallSideEffect : ~m301_4
|
||||
# 302| m302_8(unknown) = Chi : total:m301_4, partial:m302_7
|
||||
# 302| v302_9(void) = ^BufferReadSideEffect[1] : &:r302_5, ~m301_10
|
||||
@@ -1452,7 +1452,7 @@ ssa.cpp:
|
||||
# 303| r303_3(int) = Load : &:r303_2, m301_6
|
||||
# 303| r303_4(glval<char **>) = VariableAddress[argv] :
|
||||
# 303| r303_5(char **) = Load : &:r303_4, m301_8
|
||||
# 303| v303_6(void) = Call : func:r303_1, 0:r303_3, 1:r303_5
|
||||
# 303| v303_6(void) = Call[unknownFunction] : func:r303_1, 0:r303_3, 1:r303_5
|
||||
# 303| m303_7(unknown) = ^CallSideEffect : ~m302_8
|
||||
# 303| m303_8(unknown) = Chi : total:m302_8, partial:m303_7
|
||||
# 303| v303_9(void) = ^BufferReadSideEffect[1] : &:r303_5, ~m302_11
|
||||
|
||||
@@ -334,7 +334,7 @@ ssa.cpp:
|
||||
# 97| r97_2(glval<Point>) = VariableAddress[a] :
|
||||
# 97| r97_3(Point *) = CopyValue : r97_2
|
||||
# 97| r97_4(void *) = Convert : r97_3
|
||||
# 97| v97_5(void) = Call : func:r97_1, 0:r97_4
|
||||
# 97| v97_5(void) = Call[Escape] : func:r97_1, 0:r97_4
|
||||
# 97| mu97_6(unknown) = ^CallSideEffect : ~m?
|
||||
# 97| v97_7(void) = ^BufferReadSideEffect[0] : &:r97_4, ~m?
|
||||
# 97| mu97_8(unknown) = ^BufferMayWriteSideEffect[0] : &:r97_4
|
||||
@@ -386,7 +386,7 @@ ssa.cpp:
|
||||
# 108| r108_2(glval<Point>) = VariableAddress[a] :
|
||||
# 108| r108_3(Point *) = CopyValue : r108_2
|
||||
# 108| r108_4(void *) = Convert : r108_3
|
||||
# 108| v108_5(void) = Call : func:r108_1, 0:r108_4
|
||||
# 108| v108_5(void) = Call[Escape] : func:r108_1, 0:r108_4
|
||||
# 108| mu108_6(unknown) = ^CallSideEffect : ~m?
|
||||
# 108| v108_7(void) = ^BufferReadSideEffect[0] : &:r108_4, ~m?
|
||||
# 108| mu108_8(unknown) = ^BufferMayWriteSideEffect[0] : &:r108_4
|
||||
@@ -450,7 +450,7 @@ ssa.cpp:
|
||||
# 119| r119_2(glval<Point>) = VariableAddress[a] :
|
||||
# 119| r119_3(Point *) = CopyValue : r119_2
|
||||
# 119| r119_4(void *) = Convert : r119_3
|
||||
# 119| v119_5(void) = Call : func:r119_1, 0:r119_4
|
||||
# 119| v119_5(void) = Call[Escape] : func:r119_1, 0:r119_4
|
||||
# 119| mu119_6(unknown) = ^CallSideEffect : ~m?
|
||||
# 119| v119_7(void) = ^BufferReadSideEffect[0] : &:r119_4, ~m?
|
||||
# 119| mu119_8(unknown) = ^BufferMayWriteSideEffect[0] : &:r119_4
|
||||
@@ -789,7 +789,7 @@ ssa.cpp:
|
||||
# 199| r199_6(glval<char *>) = VariableAddress[str2] :
|
||||
# 199| r199_7(char *) = Load : &:r199_6, m198_9
|
||||
# 199| r199_8(char *) = Convert : r199_7
|
||||
# 199| r199_9(int) = Call : func:r199_2, 0:r199_5, 1:r199_8
|
||||
# 199| r199_9(int) = Call[strcmp] : func:r199_2, 0:r199_5, 1:r199_8
|
||||
# 199| v199_10(void) = ^BufferReadSideEffect[0] : &:r199_5, ~m?
|
||||
# 199| v199_11(void) = ^BufferReadSideEffect[1] : &:r199_8, ~m?
|
||||
# 199| m199_12(int) = Store : &:r199_1, r199_9
|
||||
@@ -797,7 +797,7 @@ ssa.cpp:
|
||||
# 200| r200_2(glval<char *>) = VariableAddress[str1] :
|
||||
# 200| r200_3(char *) = Load : &:r200_2, m198_5
|
||||
# 200| r200_4(char *) = Convert : r200_3
|
||||
# 200| r200_5(int) = Call : func:r200_1, 0:r200_4
|
||||
# 200| r200_5(int) = Call[strlen] : func:r200_1, 0:r200_4
|
||||
# 200| v200_6(void) = ^BufferReadSideEffect[0] : &:r200_4, ~m?
|
||||
# 200| r200_7(glval<int>) = VariableAddress[ret] :
|
||||
# 200| r200_8(int) = Load : &:r200_7, m199_12
|
||||
@@ -806,7 +806,7 @@ ssa.cpp:
|
||||
# 201| r201_1(glval<unknown>) = FunctionAddress[abs] :
|
||||
# 201| r201_2(glval<int>) = VariableAddress[x] :
|
||||
# 201| r201_3(int) = Load : &:r201_2, m198_13
|
||||
# 201| r201_4(int) = Call : func:r201_1, 0:r201_3
|
||||
# 201| r201_4(int) = Call[abs] : func:r201_1, 0:r201_3
|
||||
# 201| r201_5(glval<int>) = VariableAddress[ret] :
|
||||
# 201| r201_6(int) = Load : &:r201_5, m200_10
|
||||
# 201| r201_7(int) = Add : r201_6, r201_4
|
||||
@@ -839,7 +839,7 @@ ssa.cpp:
|
||||
# 209| r209_6(int *) = CopyValue : r209_5
|
||||
# 209| r209_7(void *) = Convert : r209_6
|
||||
# 209| r209_8(int) = Constant[4] :
|
||||
# 209| r209_9(void *) = Call : func:r209_1, 0:r209_4, 1:r209_7, 2:r209_8
|
||||
# 209| r209_9(void *) = Call[memcpy] : func:r209_1, 0:r209_4, 1:r209_7, 2:r209_8
|
||||
# 209| v209_10(void) = ^SizedBufferReadSideEffect[1] : &:r209_7, r209_8, ~m?
|
||||
# 209| mu209_11(unknown) = ^SizedBufferMustWriteSideEffect[0] : &:r209_4, r209_8
|
||||
# 210| r210_1(glval<int>) = VariableAddress[#return] :
|
||||
@@ -917,7 +917,7 @@ ssa.cpp:
|
||||
# 226| mu226_2(unknown) = AliasedDefinition :
|
||||
# 226| mu226_3(unknown) = InitializeNonLocal :
|
||||
# 227| r227_1(glval<unknown>) = FunctionAddress[ExternalFunc] :
|
||||
# 227| v227_2(void) = Call : func:r227_1
|
||||
# 227| v227_2(void) = Call[ExternalFunc] : func:r227_1
|
||||
# 227| mu227_3(unknown) = ^CallSideEffect : ~m?
|
||||
# 229| r229_1(glval<char *>) = VariableAddress[s] :
|
||||
# 229| r229_2(glval<char[8]>) = StringConstant["Literal"] :
|
||||
@@ -976,18 +976,18 @@ ssa.cpp:
|
||||
# 240| mu240_2(Constructible) = Uninitialized[c] : &:r240_1
|
||||
# 240| r240_3(glval<unknown>) = FunctionAddress[Constructible] :
|
||||
# 240| r240_4(int) = Constant[1] :
|
||||
# 240| v240_5(void) = Call : func:r240_3, this:r240_1, 0:r240_4
|
||||
# 240| v240_5(void) = Call[Constructible] : func:r240_3, this:r240_1, 0:r240_4
|
||||
# 240| mu240_6(unknown) = ^CallSideEffect : ~m?
|
||||
# 240| mu240_7(Constructible) = ^IndirectMayWriteSideEffect[-1] : &:r240_1
|
||||
# 241| r241_1(glval<Constructible>) = VariableAddress[c] :
|
||||
# 241| r241_2(glval<unknown>) = FunctionAddress[g] :
|
||||
# 241| v241_3(void) = Call : func:r241_2, this:r241_1
|
||||
# 241| v241_3(void) = Call[g] : func:r241_2, this:r241_1
|
||||
# 241| mu241_4(unknown) = ^CallSideEffect : ~m?
|
||||
# 241| v241_5(void) = ^BufferReadSideEffect[-1] : &:r241_1, ~m?
|
||||
# 241| mu241_6(Constructible) = ^IndirectMayWriteSideEffect[-1] : &:r241_1
|
||||
# 242| r242_1(glval<Constructible>) = VariableAddress[c] :
|
||||
# 242| r242_2(glval<unknown>) = FunctionAddress[g] :
|
||||
# 242| v242_3(void) = Call : func:r242_2, this:r242_1
|
||||
# 242| v242_3(void) = Call[g] : func:r242_2, this:r242_1
|
||||
# 242| mu242_4(unknown) = ^CallSideEffect : ~m?
|
||||
# 242| v242_5(void) = ^BufferReadSideEffect[-1] : &:r242_1, ~m?
|
||||
# 242| mu242_6(Constructible) = ^IndirectMayWriteSideEffect[-1] : &:r242_1
|
||||
@@ -995,12 +995,12 @@ ssa.cpp:
|
||||
# 243| mu243_2(Constructible) = Uninitialized[c2] : &:r243_1
|
||||
# 243| r243_3(glval<unknown>) = FunctionAddress[Constructible] :
|
||||
# 243| r243_4(int) = Constant[2] :
|
||||
# 243| v243_5(void) = Call : func:r243_3, this:r243_1, 0:r243_4
|
||||
# 243| v243_5(void) = Call[Constructible] : func:r243_3, this:r243_1, 0:r243_4
|
||||
# 243| mu243_6(unknown) = ^CallSideEffect : ~m?
|
||||
# 243| mu243_7(Constructible) = ^IndirectMayWriteSideEffect[-1] : &:r243_1
|
||||
# 244| r244_1(glval<Constructible>) = VariableAddress[c2] :
|
||||
# 244| r244_2(glval<unknown>) = FunctionAddress[g] :
|
||||
# 244| v244_3(void) = Call : func:r244_2, this:r244_1
|
||||
# 244| v244_3(void) = Call[g] : func:r244_2, this:r244_1
|
||||
# 244| mu244_4(unknown) = ^CallSideEffect : ~m?
|
||||
# 244| v244_5(void) = ^BufferReadSideEffect[-1] : &:r244_1, ~m?
|
||||
# 244| mu244_6(Constructible) = ^IndirectMayWriteSideEffect[-1] : &:r244_1
|
||||
@@ -1027,7 +1027,7 @@ ssa.cpp:
|
||||
# 248| r248_5(unsigned long) = Convert : r248_4
|
||||
# 248| r248_6(unsigned long) = Constant[1] :
|
||||
# 248| r248_7(unsigned long) = Mul : r248_5, r248_6
|
||||
# 248| r248_8(void *) = Call : func:r248_2, 0:r248_7
|
||||
# 248| r248_8(void *) = Call[operator new[]] : func:r248_2, 0:r248_7
|
||||
# 248| mu248_9(unknown) = ^CallSideEffect : ~m?
|
||||
# 248| mu248_10(unknown) = ^InitializeDynamicAllocation : &:r248_8
|
||||
# 248| r248_11(char *) = Convert : r248_8
|
||||
@@ -1046,7 +1046,7 @@ ssa.cpp:
|
||||
# 250| r250_7(void *) = Convert : r250_6
|
||||
# 250| r250_8(glval<int>) = VariableAddress[size] :
|
||||
# 250| r250_9(int) = Load : &:r250_8, m247_9
|
||||
# 250| r250_10(void *) = Call : func:r250_1, 0:r250_4, 1:r250_7, 2:r250_9
|
||||
# 250| r250_10(void *) = Call[memcpy] : func:r250_1, 0:r250_4, 1:r250_7, 2:r250_9
|
||||
# 250| v250_11(void) = ^SizedBufferReadSideEffect[1] : &:r250_7, r250_9, ~m?
|
||||
# 250| mu250_12(unknown) = ^SizedBufferMustWriteSideEffect[0] : &:r250_4, r250_9
|
||||
# 251| r251_1(glval<char *>) = VariableAddress[#return] :
|
||||
@@ -1074,13 +1074,13 @@ ssa.cpp:
|
||||
|
||||
# 256| Block 1
|
||||
# 256| r256_1(glval<unknown>) = FunctionAddress[ExternalFunc] :
|
||||
# 256| v256_2(void) = Call : func:r256_1
|
||||
# 256| v256_2(void) = Call[ExternalFunc] : func:r256_1
|
||||
# 256| mu256_3(unknown) = ^CallSideEffect : ~m?
|
||||
#-----| Goto -> Block 3
|
||||
|
||||
# 259| Block 2
|
||||
# 259| r259_1(glval<unknown>) = FunctionAddress[ExternalFunc] :
|
||||
# 259| v259_2(void) = Call : func:r259_1
|
||||
# 259| v259_2(void) = Call[ExternalFunc] : func:r259_1
|
||||
# 259| mu259_3(unknown) = ^CallSideEffect : ~m?
|
||||
#-----| Goto -> Block 3
|
||||
|
||||
@@ -1116,7 +1116,7 @@ ssa.cpp:
|
||||
# 269| r269_2(glval<unknown>) = FunctionAddress[malloc] :
|
||||
# 269| r269_3(glval<int>) = VariableAddress[size] :
|
||||
# 269| r269_4(int) = Load : &:r269_3, m268_9
|
||||
# 269| r269_5(void *) = Call : func:r269_2, 0:r269_4
|
||||
# 269| r269_5(void *) = Call[malloc] : func:r269_2, 0:r269_4
|
||||
# 269| mu269_6(unknown) = ^CallSideEffect : ~m?
|
||||
# 269| mu269_7(unknown) = ^InitializeDynamicAllocation : &:r269_5
|
||||
# 269| m269_8(void *) = Store : &:r269_1, r269_5
|
||||
@@ -1127,7 +1127,7 @@ ssa.cpp:
|
||||
# 270| r270_5(void *) = Load : &:r270_4, m268_5
|
||||
# 270| r270_6(glval<int>) = VariableAddress[size] :
|
||||
# 270| r270_7(int) = Load : &:r270_6, m268_9
|
||||
# 270| r270_8(void *) = Call : func:r270_1, 0:r270_3, 1:r270_5, 2:r270_7
|
||||
# 270| r270_8(void *) = Call[memcpy] : func:r270_1, 0:r270_3, 1:r270_5, 2:r270_7
|
||||
# 270| v270_9(void) = ^SizedBufferReadSideEffect[1] : &:r270_5, r270_7, ~m?
|
||||
# 270| mu270_10(unknown) = ^SizedBufferMustWriteSideEffect[0] : &:r270_3, r270_7
|
||||
# 271| r271_1(glval<void *>) = VariableAddress[#return] :
|
||||
@@ -1250,7 +1250,7 @@ ssa.cpp:
|
||||
# 292| r292_1(glval<Point *>) = VariableAddress[p] :
|
||||
# 292| r292_2(glval<unknown>) = FunctionAddress[operator new] :
|
||||
# 292| r292_3(unsigned long) = Constant[8] :
|
||||
# 292| r292_4(void *) = Call : func:r292_2, 0:r292_3
|
||||
# 292| r292_4(void *) = Call[operator new] : func:r292_2, 0:r292_3
|
||||
# 292| mu292_5(unknown) = ^CallSideEffect : ~m?
|
||||
# 292| mu292_6(unknown) = ^InitializeDynamicAllocation : &:r292_4
|
||||
# 292| r292_7(Point *) = Convert : r292_4
|
||||
@@ -1258,7 +1258,7 @@ ssa.cpp:
|
||||
# 293| r293_1(glval<Point *>) = VariableAddress[q] :
|
||||
# 293| r293_2(glval<unknown>) = FunctionAddress[operator new] :
|
||||
# 293| r293_3(unsigned long) = Constant[8] :
|
||||
# 293| r293_4(void *) = Call : func:r293_2, 0:r293_3
|
||||
# 293| r293_4(void *) = Call[operator new] : func:r293_2, 0:r293_3
|
||||
# 293| mu293_5(unknown) = ^CallSideEffect : ~m?
|
||||
# 293| mu293_6(unknown) = ^InitializeDynamicAllocation : &:r293_4
|
||||
# 293| r293_7(Point *) = Convert : r293_4
|
||||
@@ -1266,24 +1266,24 @@ ssa.cpp:
|
||||
# 294| r294_1(glval<int>) = VariableAddress[j] :
|
||||
# 294| r294_2(glval<unknown>) = FunctionAddress[operator new] :
|
||||
# 294| r294_3(unsigned long) = Constant[4] :
|
||||
# 294| r294_4(void *) = Call : func:r294_2, 0:r294_3
|
||||
# 294| r294_4(void *) = Call[operator new] : func:r294_2, 0:r294_3
|
||||
# 294| mu294_5(unknown) = ^CallSideEffect : ~m?
|
||||
# 294| mu294_6(unknown) = ^InitializeDynamicAllocation : &:r294_4
|
||||
# 294| r294_7(A *) = Convert : r294_4
|
||||
# 294| r294_8(glval<unknown>) = FunctionAddress[A] :
|
||||
# 294| r294_9(glval<unknown>) = FunctionAddress[operator new] :
|
||||
# 294| r294_10(unsigned long) = Constant[4] :
|
||||
# 294| r294_11(void *) = Call : func:r294_9, 0:r294_10
|
||||
# 294| r294_11(void *) = Call[operator new] : func:r294_9, 0:r294_10
|
||||
# 294| mu294_12(unknown) = ^CallSideEffect : ~m?
|
||||
# 294| mu294_13(unknown) = ^InitializeDynamicAllocation : &:r294_11
|
||||
# 294| r294_14(A *) = Convert : r294_11
|
||||
# 294| r294_15(glval<unknown>) = FunctionAddress[A] :
|
||||
# 294| r294_16(glval<int>) = VariableAddress[x] :
|
||||
# 294| r294_17(int) = Load : &:r294_16, m291_5
|
||||
# 294| v294_18(void) = Call : func:r294_15, this:r294_14, 0:r294_17
|
||||
# 294| v294_18(void) = Call[A] : func:r294_15, this:r294_14, 0:r294_17
|
||||
# 294| mu294_19(unknown) = ^CallSideEffect : ~m?
|
||||
# 294| mu294_20(A) = ^IndirectMayWriteSideEffect[-1] : &:r294_14
|
||||
# 294| v294_21(void) = Call : func:r294_8, this:r294_7, 0:r294_14
|
||||
# 294| v294_21(void) = Call[A] : func:r294_8, this:r294_7, 0:r294_14
|
||||
# 294| mu294_22(unknown) = ^CallSideEffect : ~m?
|
||||
# 294| mu294_23(A) = ^IndirectMayWriteSideEffect[-1] : &:r294_7
|
||||
# 294| v294_24(void) = ^BufferReadSideEffect[0] : &:r294_14, ~m?
|
||||
@@ -1294,12 +1294,12 @@ ssa.cpp:
|
||||
# 295| r295_1(glval<A *>) = VariableAddress[a] :
|
||||
# 295| r295_2(glval<unknown>) = FunctionAddress[operator new] :
|
||||
# 295| r295_3(unsigned long) = Constant[4] :
|
||||
# 295| r295_4(void *) = Call : func:r295_2, 0:r295_3
|
||||
# 295| r295_4(void *) = Call[operator new] : func:r295_2, 0:r295_3
|
||||
# 295| mu295_5(unknown) = ^CallSideEffect : ~m?
|
||||
# 295| mu295_6(unknown) = ^InitializeDynamicAllocation : &:r295_4
|
||||
# 295| r295_7(A *) = Convert : r295_4
|
||||
# 295| r295_8(glval<unknown>) = FunctionAddress[A] :
|
||||
# 295| v295_9(void) = Call : func:r295_8, this:r295_7
|
||||
# 295| v295_9(void) = Call[A] : func:r295_8, this:r295_7
|
||||
# 295| mu295_10(unknown) = ^CallSideEffect : ~m?
|
||||
# 295| mu295_11(A) = ^IndirectMayWriteSideEffect[-1] : &:r295_7
|
||||
# 295| m295_12(A *) = Store : &:r295_1, r295_7
|
||||
@@ -1328,7 +1328,7 @@ ssa.cpp:
|
||||
# 302| r302_3(int) = Load : &:r302_2, m301_5
|
||||
# 302| r302_4(glval<char **>) = VariableAddress[argv] :
|
||||
# 302| r302_5(char **) = Load : &:r302_4, m301_7
|
||||
# 302| v302_6(void) = Call : func:r302_1, 0:r302_3, 1:r302_5
|
||||
# 302| v302_6(void) = Call[unknownFunction] : func:r302_1, 0:r302_3, 1:r302_5
|
||||
# 302| mu302_7(unknown) = ^CallSideEffect : ~m?
|
||||
# 302| v302_8(void) = ^BufferReadSideEffect[1] : &:r302_5, ~m?
|
||||
# 302| mu302_9(unknown) = ^BufferMayWriteSideEffect[1] : &:r302_5
|
||||
@@ -1337,7 +1337,7 @@ ssa.cpp:
|
||||
# 303| r303_3(int) = Load : &:r303_2, m301_5
|
||||
# 303| r303_4(glval<char **>) = VariableAddress[argv] :
|
||||
# 303| r303_5(char **) = Load : &:r303_4, m301_7
|
||||
# 303| v303_6(void) = Call : func:r303_1, 0:r303_3, 1:r303_5
|
||||
# 303| v303_6(void) = Call[unknownFunction] : func:r303_1, 0:r303_3, 1:r303_5
|
||||
# 303| mu303_7(unknown) = ^CallSideEffect : ~m?
|
||||
# 303| v303_8(void) = ^BufferReadSideEffect[1] : &:r303_5, ~m?
|
||||
# 303| mu303_9(unknown) = ^BufferMayWriteSideEffect[1] : &:r303_5
|
||||
|
||||
@@ -334,7 +334,7 @@ ssa.cpp:
|
||||
# 97| r97_2(glval<Point>) = VariableAddress[a] :
|
||||
# 97| r97_3(Point *) = CopyValue : r97_2
|
||||
# 97| r97_4(void *) = Convert : r97_3
|
||||
# 97| v97_5(void) = Call : func:r97_1, 0:r97_4
|
||||
# 97| v97_5(void) = Call[Escape] : func:r97_1, 0:r97_4
|
||||
# 97| mu97_6(unknown) = ^CallSideEffect : ~m?
|
||||
# 97| v97_7(void) = ^BufferReadSideEffect[0] : &:r97_4, ~m?
|
||||
# 97| mu97_8(unknown) = ^BufferMayWriteSideEffect[0] : &:r97_4
|
||||
@@ -386,7 +386,7 @@ ssa.cpp:
|
||||
# 108| r108_2(glval<Point>) = VariableAddress[a] :
|
||||
# 108| r108_3(Point *) = CopyValue : r108_2
|
||||
# 108| r108_4(void *) = Convert : r108_3
|
||||
# 108| v108_5(void) = Call : func:r108_1, 0:r108_4
|
||||
# 108| v108_5(void) = Call[Escape] : func:r108_1, 0:r108_4
|
||||
# 108| mu108_6(unknown) = ^CallSideEffect : ~m?
|
||||
# 108| v108_7(void) = ^BufferReadSideEffect[0] : &:r108_4, ~m?
|
||||
# 108| mu108_8(unknown) = ^BufferMayWriteSideEffect[0] : &:r108_4
|
||||
@@ -450,7 +450,7 @@ ssa.cpp:
|
||||
# 119| r119_2(glval<Point>) = VariableAddress[a] :
|
||||
# 119| r119_3(Point *) = CopyValue : r119_2
|
||||
# 119| r119_4(void *) = Convert : r119_3
|
||||
# 119| v119_5(void) = Call : func:r119_1, 0:r119_4
|
||||
# 119| v119_5(void) = Call[Escape] : func:r119_1, 0:r119_4
|
||||
# 119| mu119_6(unknown) = ^CallSideEffect : ~m?
|
||||
# 119| v119_7(void) = ^BufferReadSideEffect[0] : &:r119_4, ~m?
|
||||
# 119| mu119_8(unknown) = ^BufferMayWriteSideEffect[0] : &:r119_4
|
||||
@@ -789,7 +789,7 @@ ssa.cpp:
|
||||
# 199| r199_6(glval<char *>) = VariableAddress[str2] :
|
||||
# 199| r199_7(char *) = Load : &:r199_6, m198_9
|
||||
# 199| r199_8(char *) = Convert : r199_7
|
||||
# 199| r199_9(int) = Call : func:r199_2, 0:r199_5, 1:r199_8
|
||||
# 199| r199_9(int) = Call[strcmp] : func:r199_2, 0:r199_5, 1:r199_8
|
||||
# 199| v199_10(void) = ^BufferReadSideEffect[0] : &:r199_5, ~m?
|
||||
# 199| v199_11(void) = ^BufferReadSideEffect[1] : &:r199_8, ~m?
|
||||
# 199| m199_12(int) = Store : &:r199_1, r199_9
|
||||
@@ -797,7 +797,7 @@ ssa.cpp:
|
||||
# 200| r200_2(glval<char *>) = VariableAddress[str1] :
|
||||
# 200| r200_3(char *) = Load : &:r200_2, m198_5
|
||||
# 200| r200_4(char *) = Convert : r200_3
|
||||
# 200| r200_5(int) = Call : func:r200_1, 0:r200_4
|
||||
# 200| r200_5(int) = Call[strlen] : func:r200_1, 0:r200_4
|
||||
# 200| v200_6(void) = ^BufferReadSideEffect[0] : &:r200_4, ~m?
|
||||
# 200| r200_7(glval<int>) = VariableAddress[ret] :
|
||||
# 200| r200_8(int) = Load : &:r200_7, m199_12
|
||||
@@ -806,7 +806,7 @@ ssa.cpp:
|
||||
# 201| r201_1(glval<unknown>) = FunctionAddress[abs] :
|
||||
# 201| r201_2(glval<int>) = VariableAddress[x] :
|
||||
# 201| r201_3(int) = Load : &:r201_2, m198_13
|
||||
# 201| r201_4(int) = Call : func:r201_1, 0:r201_3
|
||||
# 201| r201_4(int) = Call[abs] : func:r201_1, 0:r201_3
|
||||
# 201| r201_5(glval<int>) = VariableAddress[ret] :
|
||||
# 201| r201_6(int) = Load : &:r201_5, m200_10
|
||||
# 201| r201_7(int) = Add : r201_6, r201_4
|
||||
@@ -839,7 +839,7 @@ ssa.cpp:
|
||||
# 209| r209_6(int *) = CopyValue : r209_5
|
||||
# 209| r209_7(void *) = Convert : r209_6
|
||||
# 209| r209_8(int) = Constant[4] :
|
||||
# 209| r209_9(void *) = Call : func:r209_1, 0:r209_4, 1:r209_7, 2:r209_8
|
||||
# 209| r209_9(void *) = Call[memcpy] : func:r209_1, 0:r209_4, 1:r209_7, 2:r209_8
|
||||
# 209| v209_10(void) = ^SizedBufferReadSideEffect[1] : &:r209_7, r209_8, ~m?
|
||||
# 209| mu209_11(unknown) = ^SizedBufferMustWriteSideEffect[0] : &:r209_4, r209_8
|
||||
# 210| r210_1(glval<int>) = VariableAddress[#return] :
|
||||
@@ -917,7 +917,7 @@ ssa.cpp:
|
||||
# 226| mu226_2(unknown) = AliasedDefinition :
|
||||
# 226| mu226_3(unknown) = InitializeNonLocal :
|
||||
# 227| r227_1(glval<unknown>) = FunctionAddress[ExternalFunc] :
|
||||
# 227| v227_2(void) = Call : func:r227_1
|
||||
# 227| v227_2(void) = Call[ExternalFunc] : func:r227_1
|
||||
# 227| mu227_3(unknown) = ^CallSideEffect : ~m?
|
||||
# 229| r229_1(glval<char *>) = VariableAddress[s] :
|
||||
# 229| r229_2(glval<char[8]>) = StringConstant["Literal"] :
|
||||
@@ -976,18 +976,18 @@ ssa.cpp:
|
||||
# 240| mu240_2(Constructible) = Uninitialized[c] : &:r240_1
|
||||
# 240| r240_3(glval<unknown>) = FunctionAddress[Constructible] :
|
||||
# 240| r240_4(int) = Constant[1] :
|
||||
# 240| v240_5(void) = Call : func:r240_3, this:r240_1, 0:r240_4
|
||||
# 240| v240_5(void) = Call[Constructible] : func:r240_3, this:r240_1, 0:r240_4
|
||||
# 240| mu240_6(unknown) = ^CallSideEffect : ~m?
|
||||
# 240| mu240_7(Constructible) = ^IndirectMayWriteSideEffect[-1] : &:r240_1
|
||||
# 241| r241_1(glval<Constructible>) = VariableAddress[c] :
|
||||
# 241| r241_2(glval<unknown>) = FunctionAddress[g] :
|
||||
# 241| v241_3(void) = Call : func:r241_2, this:r241_1
|
||||
# 241| v241_3(void) = Call[g] : func:r241_2, this:r241_1
|
||||
# 241| mu241_4(unknown) = ^CallSideEffect : ~m?
|
||||
# 241| v241_5(void) = ^BufferReadSideEffect[-1] : &:r241_1, ~m?
|
||||
# 241| mu241_6(Constructible) = ^IndirectMayWriteSideEffect[-1] : &:r241_1
|
||||
# 242| r242_1(glval<Constructible>) = VariableAddress[c] :
|
||||
# 242| r242_2(glval<unknown>) = FunctionAddress[g] :
|
||||
# 242| v242_3(void) = Call : func:r242_2, this:r242_1
|
||||
# 242| v242_3(void) = Call[g] : func:r242_2, this:r242_1
|
||||
# 242| mu242_4(unknown) = ^CallSideEffect : ~m?
|
||||
# 242| v242_5(void) = ^BufferReadSideEffect[-1] : &:r242_1, ~m?
|
||||
# 242| mu242_6(Constructible) = ^IndirectMayWriteSideEffect[-1] : &:r242_1
|
||||
@@ -995,12 +995,12 @@ ssa.cpp:
|
||||
# 243| mu243_2(Constructible) = Uninitialized[c2] : &:r243_1
|
||||
# 243| r243_3(glval<unknown>) = FunctionAddress[Constructible] :
|
||||
# 243| r243_4(int) = Constant[2] :
|
||||
# 243| v243_5(void) = Call : func:r243_3, this:r243_1, 0:r243_4
|
||||
# 243| v243_5(void) = Call[Constructible] : func:r243_3, this:r243_1, 0:r243_4
|
||||
# 243| mu243_6(unknown) = ^CallSideEffect : ~m?
|
||||
# 243| mu243_7(Constructible) = ^IndirectMayWriteSideEffect[-1] : &:r243_1
|
||||
# 244| r244_1(glval<Constructible>) = VariableAddress[c2] :
|
||||
# 244| r244_2(glval<unknown>) = FunctionAddress[g] :
|
||||
# 244| v244_3(void) = Call : func:r244_2, this:r244_1
|
||||
# 244| v244_3(void) = Call[g] : func:r244_2, this:r244_1
|
||||
# 244| mu244_4(unknown) = ^CallSideEffect : ~m?
|
||||
# 244| v244_5(void) = ^BufferReadSideEffect[-1] : &:r244_1, ~m?
|
||||
# 244| mu244_6(Constructible) = ^IndirectMayWriteSideEffect[-1] : &:r244_1
|
||||
@@ -1027,7 +1027,7 @@ ssa.cpp:
|
||||
# 248| r248_5(unsigned long) = Convert : r248_4
|
||||
# 248| r248_6(unsigned long) = Constant[1] :
|
||||
# 248| r248_7(unsigned long) = Mul : r248_5, r248_6
|
||||
# 248| r248_8(void *) = Call : func:r248_2, 0:r248_7
|
||||
# 248| r248_8(void *) = Call[operator new[]] : func:r248_2, 0:r248_7
|
||||
# 248| mu248_9(unknown) = ^CallSideEffect : ~m?
|
||||
# 248| mu248_10(unknown) = ^InitializeDynamicAllocation : &:r248_8
|
||||
# 248| r248_11(char *) = Convert : r248_8
|
||||
@@ -1046,7 +1046,7 @@ ssa.cpp:
|
||||
# 250| r250_7(void *) = Convert : r250_6
|
||||
# 250| r250_8(glval<int>) = VariableAddress[size] :
|
||||
# 250| r250_9(int) = Load : &:r250_8, m247_9
|
||||
# 250| r250_10(void *) = Call : func:r250_1, 0:r250_4, 1:r250_7, 2:r250_9
|
||||
# 250| r250_10(void *) = Call[memcpy] : func:r250_1, 0:r250_4, 1:r250_7, 2:r250_9
|
||||
# 250| v250_11(void) = ^SizedBufferReadSideEffect[1] : &:r250_7, r250_9, ~m?
|
||||
# 250| mu250_12(unknown) = ^SizedBufferMustWriteSideEffect[0] : &:r250_4, r250_9
|
||||
# 251| r251_1(glval<char *>) = VariableAddress[#return] :
|
||||
@@ -1074,13 +1074,13 @@ ssa.cpp:
|
||||
|
||||
# 256| Block 1
|
||||
# 256| r256_1(glval<unknown>) = FunctionAddress[ExternalFunc] :
|
||||
# 256| v256_2(void) = Call : func:r256_1
|
||||
# 256| v256_2(void) = Call[ExternalFunc] : func:r256_1
|
||||
# 256| mu256_3(unknown) = ^CallSideEffect : ~m?
|
||||
#-----| Goto -> Block 3
|
||||
|
||||
# 259| Block 2
|
||||
# 259| r259_1(glval<unknown>) = FunctionAddress[ExternalFunc] :
|
||||
# 259| v259_2(void) = Call : func:r259_1
|
||||
# 259| v259_2(void) = Call[ExternalFunc] : func:r259_1
|
||||
# 259| mu259_3(unknown) = ^CallSideEffect : ~m?
|
||||
#-----| Goto -> Block 3
|
||||
|
||||
@@ -1116,7 +1116,7 @@ ssa.cpp:
|
||||
# 269| r269_2(glval<unknown>) = FunctionAddress[malloc] :
|
||||
# 269| r269_3(glval<int>) = VariableAddress[size] :
|
||||
# 269| r269_4(int) = Load : &:r269_3, m268_9
|
||||
# 269| r269_5(void *) = Call : func:r269_2, 0:r269_4
|
||||
# 269| r269_5(void *) = Call[malloc] : func:r269_2, 0:r269_4
|
||||
# 269| mu269_6(unknown) = ^CallSideEffect : ~m?
|
||||
# 269| mu269_7(unknown) = ^InitializeDynamicAllocation : &:r269_5
|
||||
# 269| m269_8(void *) = Store : &:r269_1, r269_5
|
||||
@@ -1127,7 +1127,7 @@ ssa.cpp:
|
||||
# 270| r270_5(void *) = Load : &:r270_4, m268_5
|
||||
# 270| r270_6(glval<int>) = VariableAddress[size] :
|
||||
# 270| r270_7(int) = Load : &:r270_6, m268_9
|
||||
# 270| r270_8(void *) = Call : func:r270_1, 0:r270_3, 1:r270_5, 2:r270_7
|
||||
# 270| r270_8(void *) = Call[memcpy] : func:r270_1, 0:r270_3, 1:r270_5, 2:r270_7
|
||||
# 270| v270_9(void) = ^SizedBufferReadSideEffect[1] : &:r270_5, r270_7, ~m?
|
||||
# 270| mu270_10(unknown) = ^SizedBufferMustWriteSideEffect[0] : &:r270_3, r270_7
|
||||
# 271| r271_1(glval<void *>) = VariableAddress[#return] :
|
||||
@@ -1250,7 +1250,7 @@ ssa.cpp:
|
||||
# 292| r292_1(glval<Point *>) = VariableAddress[p] :
|
||||
# 292| r292_2(glval<unknown>) = FunctionAddress[operator new] :
|
||||
# 292| r292_3(unsigned long) = Constant[8] :
|
||||
# 292| r292_4(void *) = Call : func:r292_2, 0:r292_3
|
||||
# 292| r292_4(void *) = Call[operator new] : func:r292_2, 0:r292_3
|
||||
# 292| mu292_5(unknown) = ^CallSideEffect : ~m?
|
||||
# 292| mu292_6(unknown) = ^InitializeDynamicAllocation : &:r292_4
|
||||
# 292| r292_7(Point *) = Convert : r292_4
|
||||
@@ -1258,7 +1258,7 @@ ssa.cpp:
|
||||
# 293| r293_1(glval<Point *>) = VariableAddress[q] :
|
||||
# 293| r293_2(glval<unknown>) = FunctionAddress[operator new] :
|
||||
# 293| r293_3(unsigned long) = Constant[8] :
|
||||
# 293| r293_4(void *) = Call : func:r293_2, 0:r293_3
|
||||
# 293| r293_4(void *) = Call[operator new] : func:r293_2, 0:r293_3
|
||||
# 293| mu293_5(unknown) = ^CallSideEffect : ~m?
|
||||
# 293| mu293_6(unknown) = ^InitializeDynamicAllocation : &:r293_4
|
||||
# 293| r293_7(Point *) = Convert : r293_4
|
||||
@@ -1266,24 +1266,24 @@ ssa.cpp:
|
||||
# 294| r294_1(glval<int>) = VariableAddress[j] :
|
||||
# 294| r294_2(glval<unknown>) = FunctionAddress[operator new] :
|
||||
# 294| r294_3(unsigned long) = Constant[4] :
|
||||
# 294| r294_4(void *) = Call : func:r294_2, 0:r294_3
|
||||
# 294| r294_4(void *) = Call[operator new] : func:r294_2, 0:r294_3
|
||||
# 294| mu294_5(unknown) = ^CallSideEffect : ~m?
|
||||
# 294| mu294_6(unknown) = ^InitializeDynamicAllocation : &:r294_4
|
||||
# 294| r294_7(A *) = Convert : r294_4
|
||||
# 294| r294_8(glval<unknown>) = FunctionAddress[A] :
|
||||
# 294| r294_9(glval<unknown>) = FunctionAddress[operator new] :
|
||||
# 294| r294_10(unsigned long) = Constant[4] :
|
||||
# 294| r294_11(void *) = Call : func:r294_9, 0:r294_10
|
||||
# 294| r294_11(void *) = Call[operator new] : func:r294_9, 0:r294_10
|
||||
# 294| mu294_12(unknown) = ^CallSideEffect : ~m?
|
||||
# 294| mu294_13(unknown) = ^InitializeDynamicAllocation : &:r294_11
|
||||
# 294| r294_14(A *) = Convert : r294_11
|
||||
# 294| r294_15(glval<unknown>) = FunctionAddress[A] :
|
||||
# 294| r294_16(glval<int>) = VariableAddress[x] :
|
||||
# 294| r294_17(int) = Load : &:r294_16, m291_5
|
||||
# 294| v294_18(void) = Call : func:r294_15, this:r294_14, 0:r294_17
|
||||
# 294| v294_18(void) = Call[A] : func:r294_15, this:r294_14, 0:r294_17
|
||||
# 294| mu294_19(unknown) = ^CallSideEffect : ~m?
|
||||
# 294| mu294_20(A) = ^IndirectMayWriteSideEffect[-1] : &:r294_14
|
||||
# 294| v294_21(void) = Call : func:r294_8, this:r294_7, 0:r294_14
|
||||
# 294| v294_21(void) = Call[A] : func:r294_8, this:r294_7, 0:r294_14
|
||||
# 294| mu294_22(unknown) = ^CallSideEffect : ~m?
|
||||
# 294| mu294_23(A) = ^IndirectMayWriteSideEffect[-1] : &:r294_7
|
||||
# 294| v294_24(void) = ^BufferReadSideEffect[0] : &:r294_14, ~m?
|
||||
@@ -1294,12 +1294,12 @@ ssa.cpp:
|
||||
# 295| r295_1(glval<A *>) = VariableAddress[a] :
|
||||
# 295| r295_2(glval<unknown>) = FunctionAddress[operator new] :
|
||||
# 295| r295_3(unsigned long) = Constant[4] :
|
||||
# 295| r295_4(void *) = Call : func:r295_2, 0:r295_3
|
||||
# 295| r295_4(void *) = Call[operator new] : func:r295_2, 0:r295_3
|
||||
# 295| mu295_5(unknown) = ^CallSideEffect : ~m?
|
||||
# 295| mu295_6(unknown) = ^InitializeDynamicAllocation : &:r295_4
|
||||
# 295| r295_7(A *) = Convert : r295_4
|
||||
# 295| r295_8(glval<unknown>) = FunctionAddress[A] :
|
||||
# 295| v295_9(void) = Call : func:r295_8, this:r295_7
|
||||
# 295| v295_9(void) = Call[A] : func:r295_8, this:r295_7
|
||||
# 295| mu295_10(unknown) = ^CallSideEffect : ~m?
|
||||
# 295| mu295_11(A) = ^IndirectMayWriteSideEffect[-1] : &:r295_7
|
||||
# 295| m295_12(A *) = Store : &:r295_1, r295_7
|
||||
@@ -1328,7 +1328,7 @@ ssa.cpp:
|
||||
# 302| r302_3(int) = Load : &:r302_2, m301_5
|
||||
# 302| r302_4(glval<char **>) = VariableAddress[argv] :
|
||||
# 302| r302_5(char **) = Load : &:r302_4, m301_7
|
||||
# 302| v302_6(void) = Call : func:r302_1, 0:r302_3, 1:r302_5
|
||||
# 302| v302_6(void) = Call[unknownFunction] : func:r302_1, 0:r302_3, 1:r302_5
|
||||
# 302| mu302_7(unknown) = ^CallSideEffect : ~m?
|
||||
# 302| v302_8(void) = ^BufferReadSideEffect[1] : &:r302_5, ~m?
|
||||
# 302| mu302_9(unknown) = ^BufferMayWriteSideEffect[1] : &:r302_5
|
||||
@@ -1337,7 +1337,7 @@ ssa.cpp:
|
||||
# 303| r303_3(int) = Load : &:r303_2, m301_5
|
||||
# 303| r303_4(glval<char **>) = VariableAddress[argv] :
|
||||
# 303| r303_5(char **) = Load : &:r303_4, m301_7
|
||||
# 303| v303_6(void) = Call : func:r303_1, 0:r303_3, 1:r303_5
|
||||
# 303| v303_6(void) = Call[unknownFunction] : func:r303_1, 0:r303_3, 1:r303_5
|
||||
# 303| mu303_7(unknown) = ^CallSideEffect : ~m?
|
||||
# 303| v303_8(void) = ^BufferReadSideEffect[1] : &:r303_5, ~m?
|
||||
# 303| mu303_9(unknown) = ^BufferMayWriteSideEffect[1] : &:r303_5
|
||||
|
||||
@@ -202,7 +202,7 @@ test.cpp:
|
||||
# 29| valnum = m29_10, r29_8
|
||||
# 30| r30_1(glval<unknown>) = FunctionAddress[change_global02] :
|
||||
# 30| valnum = unique
|
||||
# 30| v30_2(void) = Call : func:r30_1
|
||||
# 30| v30_2(void) = Call[change_global02] : func:r30_1
|
||||
# 30| m30_3(unknown) = ^CallSideEffect : ~m25_4
|
||||
# 30| valnum = unique
|
||||
# 30| m30_4(unknown) = Chi : total:m25_4, partial:m30_3
|
||||
@@ -538,7 +538,7 @@ test.cpp:
|
||||
# 77| valnum = r77_1, r79_1, r80_6
|
||||
# 77| r77_2(glval<unknown>) = FunctionAddress[getAValue] :
|
||||
# 77| valnum = unique
|
||||
# 77| r77_3(int) = Call : func:r77_2
|
||||
# 77| r77_3(int) = Call[getAValue] : func:r77_2
|
||||
# 77| valnum = unique
|
||||
# 77| m77_4(unknown) = ^CallSideEffect : ~m75_4
|
||||
# 77| valnum = unique
|
||||
@@ -585,7 +585,7 @@ test.cpp:
|
||||
# 80| Block 1
|
||||
# 80| r80_1(glval<unknown>) = FunctionAddress[getAValue] :
|
||||
# 80| valnum = unique
|
||||
# 80| r80_2(int) = Call : func:r80_1
|
||||
# 80| r80_2(int) = Call[getAValue] : func:r80_1
|
||||
# 80| valnum = unique
|
||||
# 80| m80_3(unknown) = ^CallSideEffect : ~m77_5
|
||||
# 80| valnum = unique
|
||||
|
||||
@@ -20,15 +20,15 @@ namespace Semmle.Autobuild.CSharp.Tests
|
||||
/// <summary>
|
||||
/// List of strings passed to FileDelete.
|
||||
/// </summary>
|
||||
public readonly IList<string> FileDeleteIn = new List<string>();
|
||||
public IList<string> FileDeleteIn { get; } = new List<string>();
|
||||
|
||||
void IBuildActions.FileDelete(string file)
|
||||
{
|
||||
FileDeleteIn.Add(file);
|
||||
}
|
||||
|
||||
public readonly IList<string> FileExistsIn = new List<string>();
|
||||
public readonly IDictionary<string, bool> FileExists = new Dictionary<string, bool>();
|
||||
public IList<string> FileExistsIn { get; } = new List<string>();
|
||||
public IDictionary<string, bool> FileExists { get; } = new Dictionary<string, bool>();
|
||||
|
||||
bool IBuildActions.FileExists(string file)
|
||||
{
|
||||
@@ -42,12 +42,12 @@ namespace Semmle.Autobuild.CSharp.Tests
|
||||
throw new ArgumentException("Missing FileExists " + file);
|
||||
}
|
||||
|
||||
public readonly IList<string> RunProcessIn = new List<string>();
|
||||
public readonly IDictionary<string, int> RunProcess = new Dictionary<string, int>();
|
||||
public readonly IDictionary<string, string> RunProcessOut = new Dictionary<string, string>();
|
||||
public readonly IDictionary<string, string> RunProcessWorkingDirectory = new Dictionary<string, string>();
|
||||
public readonly HashSet<string> CreateDirectories = new HashSet<string>();
|
||||
public readonly HashSet<(string, string)> DownloadFiles = new HashSet<(string, string)>();
|
||||
public IList<string> RunProcessIn { get; } = new List<string>();
|
||||
public IDictionary<string, int> RunProcess { get; } = new Dictionary<string, int>();
|
||||
public IDictionary<string, string> RunProcessOut { get; } = new Dictionary<string, string>();
|
||||
public IDictionary<string, string> RunProcessWorkingDirectory { get; } = new Dictionary<string, string>();
|
||||
public HashSet<string> CreateDirectories { get; } = new HashSet<string>();
|
||||
public HashSet<(string, string)> DownloadFiles { get; } = new HashSet<(string, string)>();
|
||||
|
||||
int IBuildActions.RunProcess(string cmd, string args, string? workingDirectory, IDictionary<string, string>? env, out IList<string> stdOut)
|
||||
{
|
||||
@@ -85,14 +85,14 @@ namespace Semmle.Autobuild.CSharp.Tests
|
||||
return ret;
|
||||
}
|
||||
|
||||
public readonly IList<string> DirectoryDeleteIn = new List<string>();
|
||||
public IList<string> DirectoryDeleteIn { get; } = new List<string>();
|
||||
|
||||
void IBuildActions.DirectoryDelete(string dir, bool recursive)
|
||||
{
|
||||
DirectoryDeleteIn.Add(dir);
|
||||
}
|
||||
|
||||
public readonly IDictionary<string, bool> DirectoryExists = new Dictionary<string, bool>();
|
||||
public IDictionary<string, bool> DirectoryExists { get; } = new Dictionary<string, bool>();
|
||||
|
||||
bool IBuildActions.DirectoryExists(string dir)
|
||||
{
|
||||
@@ -102,7 +102,7 @@ namespace Semmle.Autobuild.CSharp.Tests
|
||||
return ret;
|
||||
}
|
||||
|
||||
public readonly IDictionary<string, string?> GetEnvironmentVariable = new Dictionary<string, string?>();
|
||||
public IDictionary<string, string?> GetEnvironmentVariable { get; } = new Dictionary<string, string?>();
|
||||
|
||||
string? IBuildActions.GetEnvironmentVariable(string name)
|
||||
{
|
||||
@@ -112,14 +112,14 @@ namespace Semmle.Autobuild.CSharp.Tests
|
||||
return ret;
|
||||
}
|
||||
|
||||
public string GetCurrentDirectory = "";
|
||||
public string GetCurrentDirectory { get; set; } = "";
|
||||
|
||||
string IBuildActions.GetCurrentDirectory()
|
||||
{
|
||||
return GetCurrentDirectory;
|
||||
}
|
||||
|
||||
public readonly IDictionary<string, string> EnumerateFiles = new Dictionary<string, string>();
|
||||
public IDictionary<string, string> EnumerateFiles { get; } = new Dictionary<string, string>();
|
||||
|
||||
IEnumerable<string> IBuildActions.EnumerateFiles(string dir)
|
||||
{
|
||||
@@ -129,7 +129,7 @@ namespace Semmle.Autobuild.CSharp.Tests
|
||||
return str.Split("\n").Select(p => PathCombine(dir, p));
|
||||
}
|
||||
|
||||
public readonly IDictionary<string, string> EnumerateDirectories = new Dictionary<string, string>();
|
||||
public IDictionary<string, string> EnumerateDirectories { get; } = new Dictionary<string, string>();
|
||||
|
||||
IEnumerable<string> IBuildActions.EnumerateDirectories(string dir)
|
||||
{
|
||||
@@ -141,7 +141,7 @@ namespace Semmle.Autobuild.CSharp.Tests
|
||||
: str.Split("\n").Select(p => PathCombine(dir, p));
|
||||
}
|
||||
|
||||
public bool IsWindows;
|
||||
public bool IsWindows { get; set; }
|
||||
|
||||
bool IBuildActions.IsWindows() => IsWindows;
|
||||
|
||||
@@ -164,7 +164,7 @@ namespace Semmle.Autobuild.CSharp.Tests
|
||||
{
|
||||
}
|
||||
|
||||
public readonly IDictionary<string, XmlDocument> LoadXml = new Dictionary<string, XmlDocument>();
|
||||
public IDictionary<string, XmlDocument> LoadXml { get; } = new Dictionary<string, XmlDocument>();
|
||||
|
||||
XmlDocument IBuildActions.LoadXml(string filename)
|
||||
{
|
||||
|
||||
@@ -227,6 +227,6 @@ namespace Semmle.Autobuild.Shared
|
||||
public void DownloadFile(string address, string fileName) =>
|
||||
DownloadFileAsync(address, fileName).Wait();
|
||||
|
||||
public static readonly IBuildActions Instance = new SystemBuildActions();
|
||||
public static IBuildActions Instance { get; } = new SystemBuildActions();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -232,13 +232,13 @@ namespace Semmle.Autobuild.Shared
|
||||
/// <summary>
|
||||
/// The empty build script that always returns exit code 0.
|
||||
/// </summary>
|
||||
public static readonly BuildScript Success = Create(actions => successCode);
|
||||
public static BuildScript Success { get; } = Create(actions => successCode);
|
||||
|
||||
private const int failureCode = 1;
|
||||
/// <summary>
|
||||
/// The empty build script that always returns exit code 1.
|
||||
/// </summary>
|
||||
public static readonly BuildScript Failure = Create(actions => failureCode);
|
||||
public static BuildScript Failure { get; } = Create(actions => failureCode);
|
||||
|
||||
private static bool Succeeded(int i) => i == successCode;
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@ namespace Semmle.Extraction.CIL.Driver
|
||||
/// </summary>
|
||||
internal class AssemblyInfo
|
||||
{
|
||||
public override string ToString() => filename;
|
||||
public override string ToString() => Filename;
|
||||
|
||||
private static AssemblyName CreateAssemblyName(MetadataReader mdReader, StringHandle name, System.Version version, StringHandle culture)
|
||||
{
|
||||
@@ -59,7 +59,7 @@ namespace Semmle.Extraction.CIL.Driver
|
||||
/// </exception>
|
||||
public AssemblyInfo(string path)
|
||||
{
|
||||
filename = path;
|
||||
Filename = path;
|
||||
|
||||
// Attempt to open the file and see if it's a valid assembly.
|
||||
using var stream = File.OpenRead(path);
|
||||
@@ -75,9 +75,9 @@ namespace Semmle.Extraction.CIL.Driver
|
||||
throw new InvalidAssemblyException();
|
||||
|
||||
// Get our own assembly name
|
||||
name = CreateAssemblyName(mdReader, mdReader.GetAssemblyDefinition());
|
||||
Name = CreateAssemblyName(mdReader, mdReader.GetAssemblyDefinition());
|
||||
|
||||
references = mdReader.AssemblyReferences
|
||||
References = mdReader.AssemblyReferences
|
||||
.Select(r => mdReader.GetAssemblyReference(r))
|
||||
.Select(ar => CreateAssemblyName(mdReader, ar))
|
||||
.ToArray();
|
||||
@@ -91,10 +91,10 @@ namespace Semmle.Extraction.CIL.Driver
|
||||
}
|
||||
}
|
||||
|
||||
public readonly AssemblyName name;
|
||||
public readonly string filename;
|
||||
public bool extract;
|
||||
public readonly AssemblyName[] references;
|
||||
public AssemblyName Name { get; }
|
||||
public string Filename { get; }
|
||||
public bool Extract { get; set; }
|
||||
public AssemblyName[] References { get; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -125,19 +125,19 @@ namespace Semmle.Extraction.CIL.Driver
|
||||
{
|
||||
var info = new AssemblyInfo(assemblyPath)
|
||||
{
|
||||
extract = extractAll
|
||||
Extract = extractAll
|
||||
};
|
||||
if (!assembliesRead.ContainsKey(info.name))
|
||||
assembliesRead.Add(info.name, info);
|
||||
if (!assembliesRead.ContainsKey(info.Name))
|
||||
assembliesRead.Add(info.Name, info);
|
||||
}
|
||||
catch (InvalidAssemblyException)
|
||||
{ }
|
||||
}
|
||||
}
|
||||
|
||||
public IEnumerable<AssemblyInfo> AssembliesToExtract => assembliesRead.Values.Where(info => info.extract);
|
||||
public IEnumerable<AssemblyInfo> AssembliesToExtract => assembliesRead.Values.Where(info => info.Extract);
|
||||
|
||||
private IEnumerable<AssemblyName> AssembliesToReference => AssembliesToExtract.SelectMany(info => info.references);
|
||||
private IEnumerable<AssemblyName> AssembliesToReference => AssembliesToExtract.SelectMany(info => info.References);
|
||||
|
||||
public void ResolveReferences()
|
||||
{
|
||||
@@ -148,22 +148,22 @@ namespace Semmle.Extraction.CIL.Driver
|
||||
var item = assembliesToReference.Pop();
|
||||
if (assembliesRead.TryGetValue(item, out var info))
|
||||
{
|
||||
if (!info.extract)
|
||||
if (!info.Extract)
|
||||
{
|
||||
info.extract = true;
|
||||
foreach (var reference in info.references)
|
||||
info.Extract = true;
|
||||
foreach (var reference in info.References)
|
||||
assembliesToReference.Push(reference);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
missingReferences.Add(item);
|
||||
MissingReferences.Add(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private readonly HashSet<string> filesAnalyzed = new HashSet<string>();
|
||||
public readonly HashSet<AssemblyName> missingReferences = new HashSet<AssemblyName>();
|
||||
public HashSet<AssemblyName> MissingReferences {get;} = new HashSet<AssemblyName>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -235,7 +235,7 @@ namespace Semmle.Extraction.CIL.Driver
|
||||
/// extracted. This is not an error, it just means that the database is not
|
||||
/// as complete as it could be.
|
||||
/// </summary>
|
||||
public IEnumerable<AssemblyName> MissingReferences => assemblyList.missingReferences;
|
||||
public IEnumerable<AssemblyName> MissingReferences => assemblyList.MissingReferences;
|
||||
|
||||
private void ParseArgs(string[] args)
|
||||
{
|
||||
|
||||
@@ -42,7 +42,7 @@ namespace Semmle.Extraction.CIL.Driver
|
||||
using var logger = new ConsoleLogger(options.Verbosity);
|
||||
|
||||
var actions = options.AssembliesToExtract
|
||||
.Select(asm => asm.filename)
|
||||
.Select(asm => asm.Filename)
|
||||
.Select<string, Action>(filename =>
|
||||
() => ExtractAssembly(layout, filename, logger, options.NoCache, options.PDB, options.TrapCompression))
|
||||
.ToArray();
|
||||
|
||||
@@ -38,7 +38,7 @@ namespace Semmle.Extraction.CIL.Entities
|
||||
/// <summary>
|
||||
/// For each Payload, how many additional bytes in the bytestream need to be read.
|
||||
/// </summary>
|
||||
internal static readonly int[] payloadSizes = {
|
||||
private static readonly int[] payloadSizes = {
|
||||
0, 4, 4, 1, 4,
|
||||
4, 1, 1, 4, 1,
|
||||
2, 4, 8, 4, 8,
|
||||
@@ -46,7 +46,7 @@ namespace Semmle.Extraction.CIL.Entities
|
||||
4, 2, 1, 4, 2, 4 };
|
||||
|
||||
// Maps opcodes to payloads for each instruction.
|
||||
public static readonly Dictionary<ILOpCode, Payload> opPayload = new Dictionary<ILOpCode, Payload>()
|
||||
private static readonly Dictionary<ILOpCode, Payload> opPayload = new Dictionary<ILOpCode, Payload>()
|
||||
{
|
||||
{ ILOpCode.Nop, Payload.None },
|
||||
{ ILOpCode.Break, Payload.None },
|
||||
@@ -268,10 +268,10 @@ namespace Semmle.Extraction.CIL.Entities
|
||||
{ ILOpCode.Readonly, Payload.None }
|
||||
};
|
||||
|
||||
public readonly DefinitionMethod Method;
|
||||
public readonly ILOpCode OpCode;
|
||||
public readonly int Offset;
|
||||
public readonly int Index;
|
||||
public DefinitionMethod Method { get; }
|
||||
public ILOpCode OpCode { get; }
|
||||
public int Offset { get; }
|
||||
public int Index { get; }
|
||||
private readonly int payloadValue;
|
||||
private readonly uint unsignedPayloadValue;
|
||||
|
||||
|
||||
@@ -12,11 +12,11 @@ namespace Semmle.Extraction.CSharp.Standalone
|
||||
{
|
||||
public Extraction(string directory)
|
||||
{
|
||||
this.directory = directory;
|
||||
Directory = directory;
|
||||
}
|
||||
|
||||
public readonly string directory;
|
||||
public readonly List<string> Sources = new List<string>();
|
||||
public string Directory { get; }
|
||||
public List<string> Sources { get; } = new List<string>();
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -83,7 +83,7 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
|
||||
private class AccessorFactory : ICachedEntityFactory<IMethodSymbol, Accessor>
|
||||
{
|
||||
public static readonly AccessorFactory Instance = new AccessorFactory();
|
||||
public static AccessorFactory Instance { get; } = new AccessorFactory();
|
||||
|
||||
public Accessor Create(Context cx, IMethodSymbol init) => new Accessor(cx, init);
|
||||
}
|
||||
|
||||
@@ -39,7 +39,7 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
|
||||
private class CommentBlockFactory : ICachedEntityFactory<ICommentBlock, CommentBlock>
|
||||
{
|
||||
public static readonly CommentBlockFactory Instance = new CommentBlockFactory();
|
||||
public static CommentBlockFactory Instance { get; } = new CommentBlockFactory();
|
||||
|
||||
public CommentBlock Create(Context cx, ICommentBlock init) => new CommentBlock(cx, init);
|
||||
}
|
||||
|
||||
@@ -139,7 +139,7 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
|
||||
private class CommentLineFactory : ICachedEntityFactory<(Microsoft.CodeAnalysis.Location, CommentLineType, string, string), CommentLine>
|
||||
{
|
||||
public static readonly CommentLineFactory Instance = new CommentLineFactory();
|
||||
public static CommentLineFactory Instance { get; } = new CommentLineFactory();
|
||||
|
||||
public CommentLine Create(Context cx, (Microsoft.CodeAnalysis.Location, CommentLineType, string, string) init) =>
|
||||
new CommentLine(cx, init.Item1, init.Item2, init.Item3, init.Item4);
|
||||
|
||||
@@ -147,7 +147,7 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
|
||||
private class ConstructorFactory : ICachedEntityFactory<IMethodSymbol, Constructor>
|
||||
{
|
||||
public static readonly ConstructorFactory Instance = new ConstructorFactory();
|
||||
public static ConstructorFactory Instance { get; } = new ConstructorFactory();
|
||||
|
||||
public Constructor Create(Context cx, IMethodSymbol init) => new Constructor(cx, init);
|
||||
}
|
||||
|
||||
@@ -28,7 +28,7 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
|
||||
private class ConversionFactory : ICachedEntityFactory<IMethodSymbol, Conversion>
|
||||
{
|
||||
public static readonly ConversionFactory Instance = new ConversionFactory();
|
||||
public static ConversionFactory Instance { get; } = new ConversionFactory();
|
||||
|
||||
public Conversion Create(Context cx, IMethodSymbol init) => new Conversion(cx, init);
|
||||
}
|
||||
|
||||
@@ -28,7 +28,7 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
|
||||
private class DestructorFactory : ICachedEntityFactory<IMethodSymbol, Destructor>
|
||||
{
|
||||
public static readonly DestructorFactory Instance = new DestructorFactory();
|
||||
public static DestructorFactory Instance { get; } = new DestructorFactory();
|
||||
|
||||
public Destructor Create(Context cx, IMethodSymbol init) => new Destructor(cx, init);
|
||||
}
|
||||
|
||||
@@ -67,7 +67,7 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
|
||||
private class EventFactory : ICachedEntityFactory<IEventSymbol, Event>
|
||||
{
|
||||
public static readonly EventFactory Instance = new EventFactory();
|
||||
public static EventFactory Instance { get; } = new EventFactory();
|
||||
|
||||
public Event Create(Context cx, IEventSymbol init) => new Event(cx, init);
|
||||
}
|
||||
|
||||
@@ -57,7 +57,7 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
|
||||
private class EventAccessorFactory : ICachedEntityFactory<IMethodSymbol, EventAccessor>
|
||||
{
|
||||
public static readonly EventAccessorFactory Instance = new EventAccessorFactory();
|
||||
public static EventAccessorFactory Instance { get; } = new EventAccessorFactory();
|
||||
|
||||
public EventAccessor Create(Context cx, IMethodSymbol init) => new EventAccessor(cx, init);
|
||||
}
|
||||
|
||||
@@ -20,9 +20,9 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
internal class Expression : FreshEntity, IExpressionParentEntity
|
||||
{
|
||||
private readonly IExpressionInfo info;
|
||||
public readonly AnnotatedType Type;
|
||||
public readonly Extraction.Entities.Location Location;
|
||||
public readonly ExprKind Kind;
|
||||
public AnnotatedType Type { get; }
|
||||
public Extraction.Entities.Location Location { get; }
|
||||
public ExprKind Kind { get; }
|
||||
|
||||
internal Expression(IExpressionInfo info)
|
||||
: base(info.Context)
|
||||
@@ -294,7 +294,7 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
internal abstract class Expression<TExpressionSyntax> : Expression
|
||||
where TExpressionSyntax : ExpressionSyntax
|
||||
{
|
||||
public readonly TExpressionSyntax Syntax;
|
||||
public TExpressionSyntax Syntax { get; }
|
||||
|
||||
protected Expression(ExpressionNodeInfo info)
|
||||
: base(info)
|
||||
|
||||
@@ -131,7 +131,7 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
|
||||
private class FieldFactory : ICachedEntityFactory<IFieldSymbol, Field>
|
||||
{
|
||||
public static readonly FieldFactory Instance = new FieldFactory();
|
||||
public static FieldFactory Instance { get; } = new FieldFactory();
|
||||
|
||||
public Field Create(Context cx, IFieldSymbol init) => new Field(cx, init);
|
||||
}
|
||||
|
||||
@@ -100,7 +100,7 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
|
||||
private class IndexerFactory : ICachedEntityFactory<IPropertySymbol, Indexer>
|
||||
{
|
||||
public static readonly IndexerFactory Instance = new IndexerFactory();
|
||||
public static IndexerFactory Instance { get; } = new IndexerFactory();
|
||||
|
||||
public Indexer Create(Context cx, IPropertySymbol init) => new Indexer(cx, init);
|
||||
}
|
||||
|
||||
@@ -26,7 +26,7 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
|
||||
private class LocalFunctionFactory : ICachedEntityFactory<IMethodSymbol, LocalFunction>
|
||||
{
|
||||
public static readonly LocalFunctionFactory Instance = new LocalFunctionFactory();
|
||||
public static LocalFunctionFactory Instance { get; } = new LocalFunctionFactory();
|
||||
|
||||
public LocalFunction Create(Context cx, IMethodSymbol init) => new LocalFunction(cx, init);
|
||||
}
|
||||
|
||||
@@ -55,7 +55,7 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
|
||||
private class LocalVariableFactory : ICachedEntityFactory<ISymbol, LocalVariable>
|
||||
{
|
||||
public static readonly LocalVariableFactory Instance = new LocalVariableFactory();
|
||||
public static LocalVariableFactory Instance { get; } = new LocalVariableFactory();
|
||||
|
||||
public LocalVariable Create(Context cx, ISymbol init) => new LocalVariable(cx, init);
|
||||
}
|
||||
|
||||
@@ -142,7 +142,7 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
|
||||
private class ModifierFactory : ICachedEntityFactory<string, Modifier>
|
||||
{
|
||||
public static readonly ModifierFactory Instance = new ModifierFactory();
|
||||
public static ModifierFactory Instance { get; } = new ModifierFactory();
|
||||
|
||||
public Modifier Create(Context cx, string init) => new Modifier(cx, init);
|
||||
}
|
||||
|
||||
@@ -38,7 +38,7 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
|
||||
private class NamespaceFactory : ICachedEntityFactory<INamespaceSymbol, Namespace>
|
||||
{
|
||||
public static readonly NamespaceFactory Instance = new NamespaceFactory();
|
||||
public static NamespaceFactory Instance { get; } = new NamespaceFactory();
|
||||
|
||||
public Namespace Create(Context cx, INamespaceSymbol init) => new Namespace(cx, init);
|
||||
}
|
||||
|
||||
@@ -57,7 +57,7 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
|
||||
private class OrdinaryMethodFactory : ICachedEntityFactory<IMethodSymbol, OrdinaryMethod>
|
||||
{
|
||||
public static readonly OrdinaryMethodFactory Instance = new OrdinaryMethodFactory();
|
||||
public static OrdinaryMethodFactory Instance { get; } = new OrdinaryMethodFactory();
|
||||
|
||||
public OrdinaryMethod Create(Context cx, IMethodSymbol init) => new OrdinaryMethod(cx, init);
|
||||
}
|
||||
|
||||
@@ -171,7 +171,7 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
|
||||
private class ParameterFactory : ICachedEntityFactory<(IParameterSymbol, IEntity, Parameter), Parameter>
|
||||
{
|
||||
public static readonly ParameterFactory Instance = new ParameterFactory();
|
||||
public static ParameterFactory Instance { get; } = new ParameterFactory();
|
||||
|
||||
public Parameter Create(Context cx, (IParameterSymbol, IEntity, Parameter) init) => new Parameter(cx, init.Item1, init.Item2, init.Item3);
|
||||
}
|
||||
@@ -212,7 +212,7 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
|
||||
private class VarargsTypeFactory : ICachedEntityFactory<string, VarargsType>
|
||||
{
|
||||
public static readonly VarargsTypeFactory Instance = new VarargsTypeFactory();
|
||||
public static VarargsTypeFactory Instance { get; } = new VarargsTypeFactory();
|
||||
|
||||
public VarargsType Create(Context cx, string init) => new VarargsType(cx);
|
||||
}
|
||||
@@ -247,7 +247,7 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
|
||||
private class VarargsParamFactory : ICachedEntityFactory<Method, VarargsParam>
|
||||
{
|
||||
public static readonly VarargsParamFactory Instance = new VarargsParamFactory();
|
||||
public static VarargsParamFactory Instance { get; } = new VarargsParamFactory();
|
||||
|
||||
public VarargsParam Create(Context cx, Method init) => new VarargsParam(cx, init);
|
||||
}
|
||||
@@ -275,7 +275,7 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
|
||||
private class ExtensionParamFactory : ICachedEntityFactory<(Method, Parameter), ConstructedExtensionParameter>
|
||||
{
|
||||
public static readonly ExtensionParamFactory Instance = new ExtensionParamFactory();
|
||||
public static ExtensionParamFactory Instance { get; } = new ExtensionParamFactory();
|
||||
|
||||
public ConstructedExtensionParameter Create(Context cx, (Method, Parameter) init) =>
|
||||
new ConstructedExtensionParameter(cx, init.Item1, init.Item2);
|
||||
|
||||
@@ -126,7 +126,7 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
|
||||
private class PropertyFactory : ICachedEntityFactory<IPropertySymbol, Property>
|
||||
{
|
||||
public static readonly PropertyFactory Instance = new PropertyFactory();
|
||||
public static PropertyFactory Instance { get; } = new PropertyFactory();
|
||||
|
||||
public Property Create(Context cx, IPropertySymbol init) => new Property(cx, init);
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@ namespace Semmle.Extraction.CSharp.Entities.Statements
|
||||
internal class Switch : Statement<SwitchStatementSyntax>
|
||||
{
|
||||
private static readonly object nullLabel = new object();
|
||||
public static readonly object DefaultLabel = new object();
|
||||
public static object DefaultLabel { get; } = new object();
|
||||
|
||||
// Sometimes, the literal "null" is used as a label.
|
||||
// This is inconveniently represented by the "null" object.
|
||||
|
||||
@@ -40,7 +40,7 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
|
||||
private class ArrayTypeFactory : ICachedEntityFactory<IArrayTypeSymbol, ArrayType>
|
||||
{
|
||||
public static readonly ArrayTypeFactory Instance = new ArrayTypeFactory();
|
||||
public static ArrayTypeFactory Instance { get; } = new ArrayTypeFactory();
|
||||
|
||||
public ArrayType Create(Context cx, IArrayTypeSymbol init) => new ArrayType(cx, init);
|
||||
}
|
||||
|
||||
@@ -29,7 +29,7 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
|
||||
private class DynamicTypeFactory : ICachedEntityFactory<IDynamicTypeSymbol, DynamicType>
|
||||
{
|
||||
public static readonly DynamicTypeFactory Instance = new DynamicTypeFactory();
|
||||
public static DynamicTypeFactory Instance { get; } = new DynamicTypeFactory();
|
||||
|
||||
public DynamicType Create(Context cx, IDynamicTypeSymbol init) => new DynamicType(cx, init);
|
||||
}
|
||||
|
||||
@@ -176,14 +176,14 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
|
||||
private class NamedTypeFactory : ICachedEntityFactory<INamedTypeSymbol, NamedType>
|
||||
{
|
||||
public static readonly NamedTypeFactory Instance = new NamedTypeFactory();
|
||||
public static NamedTypeFactory Instance { get; } = new NamedTypeFactory();
|
||||
|
||||
public NamedType Create(Context cx, INamedTypeSymbol init) => new NamedType(cx, init, false);
|
||||
}
|
||||
|
||||
private class UnderlyingTupleTypeFactory : ICachedEntityFactory<INamedTypeSymbol, NamedType>
|
||||
{
|
||||
public static readonly UnderlyingTupleTypeFactory Instance = new UnderlyingTupleTypeFactory();
|
||||
public static UnderlyingTupleTypeFactory Instance { get; } = new UnderlyingTupleTypeFactory();
|
||||
|
||||
public NamedType Create(Context cx, INamedTypeSymbol init) => new NamedType(cx, init, true);
|
||||
}
|
||||
@@ -213,7 +213,7 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
|
||||
private class NamedTypeRefFactory : ICachedEntityFactory<INamedTypeSymbol, NamedTypeRef>
|
||||
{
|
||||
public static readonly NamedTypeRefFactory Instance = new NamedTypeRefFactory();
|
||||
public static NamedTypeRefFactory Instance { get; } = new NamedTypeRefFactory();
|
||||
|
||||
public NamedTypeRef Create(Context cx, INamedTypeSymbol init) => new NamedTypeRef(cx, init);
|
||||
}
|
||||
|
||||
@@ -31,7 +31,7 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
|
||||
private class NullTypeFactory : ICachedEntityFactory<ITypeSymbol, NullType>
|
||||
{
|
||||
public static readonly NullTypeFactory Instance = new NullTypeFactory();
|
||||
public static NullTypeFactory Instance { get; } = new NullTypeFactory();
|
||||
|
||||
public NullType Create(Context cx, ITypeSymbol init) => new NullType(cx);
|
||||
}
|
||||
|
||||
@@ -129,7 +129,7 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
|
||||
private class NullabilityFactory : ICachedEntityFactory<Nullability, NullabilityEntity>
|
||||
{
|
||||
public static readonly NullabilityFactory Instance = new NullabilityFactory();
|
||||
public static NullabilityFactory Instance { get; } = new NullabilityFactory();
|
||||
|
||||
public NullabilityEntity Create(Context cx, Nullability init) => new NullabilityEntity(cx, init);
|
||||
}
|
||||
|
||||
@@ -33,7 +33,7 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
|
||||
private class PointerTypeFactory : ICachedEntityFactory<IPointerTypeSymbol, PointerType>
|
||||
{
|
||||
public static readonly PointerTypeFactory Instance = new PointerTypeFactory();
|
||||
public static PointerTypeFactory Instance { get; } = new PointerTypeFactory();
|
||||
|
||||
public PointerType Create(Context cx, IPointerTypeSymbol init) => new PointerType(cx, init);
|
||||
}
|
||||
|
||||
@@ -17,7 +17,7 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
|
||||
private class TupleTypeFactory : ICachedEntityFactory<INamedTypeSymbol, TupleType>
|
||||
{
|
||||
public static readonly TupleTypeFactory Instance = new TupleTypeFactory();
|
||||
public static TupleTypeFactory Instance { get; } = new TupleTypeFactory();
|
||||
|
||||
public TupleType Create(Context cx, INamedTypeSymbol init) => new TupleType(cx, init);
|
||||
}
|
||||
|
||||
@@ -305,7 +305,7 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
|
||||
private class DelegateTypeParameterFactory : ICachedEntityFactory<(IParameterSymbol, IEntity, Parameter), DelegateTypeParameter>
|
||||
{
|
||||
public static readonly DelegateTypeParameterFactory Instance = new DelegateTypeParameterFactory();
|
||||
public static DelegateTypeParameterFactory Instance { get; } = new DelegateTypeParameterFactory();
|
||||
|
||||
public DelegateTypeParameter Create(Context cx, (IParameterSymbol, IEntity, Parameter) init) =>
|
||||
new DelegateTypeParameter(cx, init.Item1, init.Item2, init.Item3);
|
||||
|
||||
@@ -129,7 +129,7 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
|
||||
private class TypeParameterFactory : ICachedEntityFactory<ITypeParameterSymbol, TypeParameter>
|
||||
{
|
||||
public static readonly TypeParameterFactory Instance = new TypeParameterFactory();
|
||||
public static TypeParameterFactory Instance { get; } = new TypeParameterFactory();
|
||||
|
||||
public TypeParameter Create(Context cx, ITypeParameterSymbol init) => new TypeParameter(cx, init);
|
||||
}
|
||||
|
||||
@@ -187,7 +187,7 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
|
||||
private class UserOperatorFactory : ICachedEntityFactory<IMethodSymbol, UserOperator>
|
||||
{
|
||||
public static readonly UserOperatorFactory Instance = new UserOperatorFactory();
|
||||
public static UserOperatorFactory Instance { get; } = new UserOperatorFactory();
|
||||
|
||||
public UserOperator Create(Context cx, IMethodSymbol init) => new UserOperator(cx, init);
|
||||
}
|
||||
|
||||
@@ -53,7 +53,7 @@ namespace Semmle.Extraction.Entities
|
||||
|
||||
private class AssemblyConstructorFactory : ICachedEntityFactory<Microsoft.CodeAnalysis.Location?, Assembly>
|
||||
{
|
||||
public static readonly AssemblyConstructorFactory Instance = new AssemblyConstructorFactory();
|
||||
public static AssemblyConstructorFactory Instance { get; } = new AssemblyConstructorFactory();
|
||||
|
||||
public Assembly Create(Context cx, Microsoft.CodeAnalysis.Location? init) => new Assembly(cx, init);
|
||||
}
|
||||
|
||||
@@ -78,7 +78,7 @@ namespace Semmle.Extraction.Entities
|
||||
|
||||
private class GeneratedFileFactory : ICachedEntityFactory<string?, GeneratedFile>
|
||||
{
|
||||
public static readonly GeneratedFileFactory Instance = new GeneratedFileFactory();
|
||||
public static GeneratedFileFactory Instance { get; } = new GeneratedFileFactory();
|
||||
|
||||
public GeneratedFile Create(Context cx, string? init) => new GeneratedFile(cx);
|
||||
}
|
||||
@@ -88,7 +88,7 @@ namespace Semmle.Extraction.Entities
|
||||
|
||||
private class FileFactory : ICachedEntityFactory<string, File>
|
||||
{
|
||||
public static readonly FileFactory Instance = new FileFactory();
|
||||
public static FileFactory Instance { get; } = new FileFactory();
|
||||
|
||||
public File Create(Context cx, string init) => new File(cx, init);
|
||||
}
|
||||
|
||||
@@ -28,7 +28,7 @@ namespace Semmle.Extraction.Entities
|
||||
|
||||
private class FolderFactory : ICachedEntityFactory<PathTransformer.ITransformedPath, Folder>
|
||||
{
|
||||
public static readonly FolderFactory Instance = new FolderFactory();
|
||||
public static FolderFactory Instance { get; } = new FolderFactory();
|
||||
|
||||
public Folder Create(Context cx, PathTransformer.ITransformedPath init) => new Folder(cx, init);
|
||||
}
|
||||
|
||||
@@ -32,7 +32,7 @@ namespace Semmle.Extraction.Entities
|
||||
|
||||
private class GeneratedLocationFactory : ICachedEntityFactory<string?, GeneratedLocation>
|
||||
{
|
||||
public static readonly GeneratedLocationFactory Instance = new GeneratedLocationFactory();
|
||||
public static GeneratedLocationFactory Instance { get; } = new GeneratedLocationFactory();
|
||||
|
||||
public GeneratedLocation Create(Context cx, string? init) => new GeneratedLocation(cx);
|
||||
}
|
||||
|
||||
@@ -58,7 +58,7 @@ namespace Semmle.Extraction.Entities
|
||||
|
||||
private class SourceLocationFactory : ICachedEntityFactory<Microsoft.CodeAnalysis.Location, SourceLocation>
|
||||
{
|
||||
public static readonly SourceLocationFactory Instance = new SourceLocationFactory();
|
||||
public static SourceLocationFactory Instance { get; } = new SourceLocationFactory();
|
||||
|
||||
public SourceLocation Create(Context cx, Microsoft.CodeAnalysis.Location init) => new NonGeneratedSourceLocation(cx, init);
|
||||
}
|
||||
|
||||
@@ -101,11 +101,6 @@ namespace Semmle.Extraction
|
||||
/// </summary>
|
||||
public class Extractor : IExtractor
|
||||
{
|
||||
/// <summary>
|
||||
/// The default number of threads to use for extraction.
|
||||
/// </summary>
|
||||
public static readonly int DefaultNumberOfThreads = Environment.ProcessorCount;
|
||||
|
||||
public bool Standalone
|
||||
{
|
||||
get; private set;
|
||||
|
||||
@@ -116,7 +116,7 @@ namespace Semmle.Extraction
|
||||
|
||||
public int Value { get; private set; }
|
||||
|
||||
public static readonly Label InvalidLabel = new Label(0);
|
||||
public static Label InvalidLabel { get; } = new Label(0);
|
||||
|
||||
public bool Valid => Value > 0;
|
||||
|
||||
|
||||
@@ -171,7 +171,7 @@ namespace Semmle.Extraction
|
||||
{
|
||||
private readonly List<FilePattern> filePatterns = new List<FilePattern>();
|
||||
|
||||
public readonly Layout.SubProject Directories;
|
||||
public Layout.SubProject Directories { get; }
|
||||
|
||||
private static string? ReadVariable(string name, string line)
|
||||
{
|
||||
|
||||
@@ -12,7 +12,7 @@ namespace Semmle.Extraction
|
||||
/// <summary>
|
||||
/// The specified number of threads, or the default if unspecified.
|
||||
/// </summary>
|
||||
public int Threads { get; private set; } = Extractor.DefaultNumberOfThreads;
|
||||
public int Threads { get; private set; } = System.Environment.ProcessorCount;
|
||||
|
||||
/// <summary>
|
||||
/// The verbosity used in output and logging.
|
||||
|
||||
@@ -40,7 +40,17 @@ abstract class OperandTag extends TOperandTag {
|
||||
/**
|
||||
* Gets a label that will appear before the operand when the IR is printed.
|
||||
*/
|
||||
string getLabel() { result = "" }
|
||||
final string getLabel() { if alwaysPrintLabel() then result = getId() + ":" else result = "" }
|
||||
|
||||
/**
|
||||
* Gets an identifier that uniquely identifies this operand within its instruction.
|
||||
*/
|
||||
abstract string getId();
|
||||
|
||||
/**
|
||||
* Holds if the operand should always be prefixed with its label in the dump of its instruction.
|
||||
*/
|
||||
predicate alwaysPrintLabel() { none() }
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -69,7 +79,9 @@ class AddressOperandTag extends RegisterOperandTag, TAddressOperand {
|
||||
|
||||
final override int getSortOrder() { result = 0 }
|
||||
|
||||
final override string getLabel() { result = "&:" }
|
||||
final override predicate alwaysPrintLabel() { any() }
|
||||
|
||||
final override string getId() { result = "&" }
|
||||
}
|
||||
|
||||
AddressOperandTag addressOperand() { result = TAddressOperand() }
|
||||
@@ -82,6 +94,8 @@ class BufferSizeOperandTag extends RegisterOperandTag, TBufferSizeOperand {
|
||||
final override string toString() { result = "BufferSize" }
|
||||
|
||||
final override int getSortOrder() { result = 1 }
|
||||
|
||||
final override string getId() { result = "size" }
|
||||
}
|
||||
|
||||
BufferSizeOperandTag bufferSizeOperand() { result = TBufferSizeOperand() }
|
||||
@@ -93,6 +107,8 @@ class SideEffectOperandTag extends TypedOperandTag, TSideEffectOperand {
|
||||
final override string toString() { result = "SideEffect" }
|
||||
|
||||
final override int getSortOrder() { result = 2 }
|
||||
|
||||
final override string getId() { result = "side_effect" }
|
||||
}
|
||||
|
||||
SideEffectOperandTag sideEffectOperand() { result = TSideEffectOperand() }
|
||||
@@ -105,6 +121,8 @@ class LoadOperandTag extends TypedOperandTag, TLoadOperand {
|
||||
final override string toString() { result = "Load" }
|
||||
|
||||
final override int getSortOrder() { result = 3 }
|
||||
|
||||
final override string getId() { result = "load" }
|
||||
}
|
||||
|
||||
LoadOperandTag loadOperand() { result = TLoadOperand() }
|
||||
@@ -116,6 +134,8 @@ class StoreValueOperandTag extends RegisterOperandTag, TStoreValueOperand {
|
||||
final override string toString() { result = "StoreValue" }
|
||||
|
||||
final override int getSortOrder() { result = 4 }
|
||||
|
||||
final override string getId() { result = "store" }
|
||||
}
|
||||
|
||||
StoreValueOperandTag storeValueOperand() { result = TStoreValueOperand() }
|
||||
@@ -127,6 +147,8 @@ class UnaryOperandTag extends RegisterOperandTag, TUnaryOperand {
|
||||
final override string toString() { result = "Unary" }
|
||||
|
||||
final override int getSortOrder() { result = 5 }
|
||||
|
||||
final override string getId() { result = "unary" }
|
||||
}
|
||||
|
||||
UnaryOperandTag unaryOperand() { result = TUnaryOperand() }
|
||||
@@ -138,6 +160,8 @@ class LeftOperandTag extends RegisterOperandTag, TLeftOperand {
|
||||
final override string toString() { result = "Left" }
|
||||
|
||||
final override int getSortOrder() { result = 6 }
|
||||
|
||||
final override string getId() { result = "left" }
|
||||
}
|
||||
|
||||
LeftOperandTag leftOperand() { result = TLeftOperand() }
|
||||
@@ -149,6 +173,8 @@ class RightOperandTag extends RegisterOperandTag, TRightOperand {
|
||||
final override string toString() { result = "Right" }
|
||||
|
||||
final override int getSortOrder() { result = 7 }
|
||||
|
||||
final override string getId() { result = "right" }
|
||||
}
|
||||
|
||||
RightOperandTag rightOperand() { result = TRightOperand() }
|
||||
@@ -160,6 +186,8 @@ class ConditionOperandTag extends RegisterOperandTag, TConditionOperand {
|
||||
final override string toString() { result = "Condition" }
|
||||
|
||||
final override int getSortOrder() { result = 8 }
|
||||
|
||||
final override string getId() { result = "cond" }
|
||||
}
|
||||
|
||||
ConditionOperandTag conditionOperand() { result = TConditionOperand() }
|
||||
@@ -172,7 +200,9 @@ class CallTargetOperandTag extends RegisterOperandTag, TCallTargetOperand {
|
||||
|
||||
final override int getSortOrder() { result = 10 }
|
||||
|
||||
final override string getLabel() { result = "func:" }
|
||||
final override predicate alwaysPrintLabel() { any() }
|
||||
|
||||
final override string getId() { result = "func" }
|
||||
}
|
||||
|
||||
CallTargetOperandTag callTargetOperand() { result = TCallTargetOperand() }
|
||||
@@ -195,7 +225,9 @@ class ThisArgumentOperandTag extends ArgumentOperandTag, TThisArgumentOperand {
|
||||
|
||||
final override int getSortOrder() { result = 11 }
|
||||
|
||||
final override string getLabel() { result = "this:" }
|
||||
final override predicate alwaysPrintLabel() { any() }
|
||||
|
||||
final override string getId() { result = "this" }
|
||||
}
|
||||
|
||||
ThisArgumentOperandTag thisArgumentOperand() { result = TThisArgumentOperand() }
|
||||
@@ -212,9 +244,11 @@ class PositionalArgumentOperandTag extends ArgumentOperandTag, TPositionalArgume
|
||||
|
||||
final override int getSortOrder() { result = 12 + argIndex }
|
||||
|
||||
final override string getLabel() { result = argIndex.toString() + ":" }
|
||||
final override predicate alwaysPrintLabel() { any() }
|
||||
|
||||
final int getArgIndex() { result = argIndex }
|
||||
|
||||
final override string getId() { result = argIndex.toString() }
|
||||
}
|
||||
|
||||
PositionalArgumentOperandTag positionalArgumentOperand(int argIndex) {
|
||||
@@ -228,7 +262,9 @@ class ChiTotalOperandTag extends ChiOperandTag, TChiTotalOperand {
|
||||
|
||||
final override int getSortOrder() { result = 13 }
|
||||
|
||||
final override string getLabel() { result = "total:" }
|
||||
final override predicate alwaysPrintLabel() { any() }
|
||||
|
||||
final override string getId() { result = "total" }
|
||||
}
|
||||
|
||||
ChiTotalOperandTag chiTotalOperand() { result = TChiTotalOperand() }
|
||||
@@ -238,7 +274,9 @@ class ChiPartialOperandTag extends ChiOperandTag, TChiPartialOperand {
|
||||
|
||||
final override int getSortOrder() { result = 14 }
|
||||
|
||||
final override string getLabel() { result = "partial:" }
|
||||
final override predicate alwaysPrintLabel() { any() }
|
||||
|
||||
final override string getId() { result = "partial" }
|
||||
}
|
||||
|
||||
ChiPartialOperandTag chiPartialOperand() { result = TChiPartialOperand() }
|
||||
@@ -252,7 +290,9 @@ class AsmOperandTag extends RegisterOperandTag, TAsmOperand {
|
||||
|
||||
final override int getSortOrder() { result = 15 + index }
|
||||
|
||||
final override string getLabel() { result = index.toString() + ":" }
|
||||
final override predicate alwaysPrintLabel() { any() }
|
||||
|
||||
final override string getId() { result = index.toString() }
|
||||
}
|
||||
|
||||
AsmOperandTag asmOperand(int index) { result = TAsmOperand(index) }
|
||||
|
||||
@@ -72,4 +72,9 @@ class IRPropertyProvider extends TIRPropertyProvider {
|
||||
* Gets the value of the property named `key` for the specified block.
|
||||
*/
|
||||
string getBlockProperty(IRBlock block, string key) { none() }
|
||||
|
||||
/**
|
||||
* Gets the value of the property named `key` for the specified operand.
|
||||
*/
|
||||
string getOperandProperty(Operand operand, string key) { none() }
|
||||
}
|
||||
|
||||
@@ -1501,6 +1501,12 @@ class SwitchInstruction extends Instruction {
|
||||
class CallInstruction extends Instruction {
|
||||
CallInstruction() { getOpcode() instanceof Opcode::Call }
|
||||
|
||||
final override string getImmediateString() {
|
||||
result = getStaticCallTarget().toString()
|
||||
or
|
||||
not exists(getStaticCallTarget()) and result = "?"
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the operand the specifies the target function of the call.
|
||||
*/
|
||||
|
||||
@@ -151,6 +151,11 @@ class Operand extends TOperand {
|
||||
*/
|
||||
string getDumpLabel() { result = "" }
|
||||
|
||||
/**
|
||||
* Gets a string that uniquely identifies this operand on its use instruction.
|
||||
*/
|
||||
string getDumpId() { result = "" }
|
||||
|
||||
/**
|
||||
* Gets a string describing this operand, suitable for display in IR dumps. This consists of the
|
||||
* result ID of the instruction consumed by the operand, plus a label identifying the operand
|
||||
@@ -280,6 +285,8 @@ class NonPhiOperand extends Operand {
|
||||
|
||||
final override string getDumpLabel() { result = tag.getLabel() }
|
||||
|
||||
final override string getDumpId() { result = tag.getId() }
|
||||
|
||||
final override int getDumpSortOrder() { result = tag.getSortOrder() }
|
||||
|
||||
/**
|
||||
@@ -477,6 +484,8 @@ class PhiInputOperand extends MemoryOperand, PhiOperandBase {
|
||||
result = "from " + getPredecessorBlock().getDisplayIndex().toString() + ":"
|
||||
}
|
||||
|
||||
final override string getDumpId() { result = getPredecessorBlock().getDisplayIndex().toString() }
|
||||
|
||||
/**
|
||||
* Gets the predecessor block from which this value comes.
|
||||
*/
|
||||
|
||||
@@ -50,6 +50,37 @@ private string getAdditionalBlockProperty(IRBlock block, string key) {
|
||||
exists(IRPropertyProvider provider | result = provider.getBlockProperty(block, key))
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the properties of an operand from any active property providers.
|
||||
*/
|
||||
private string getAdditionalOperandProperty(Operand operand, string key) {
|
||||
exists(IRPropertyProvider provider | result = provider.getOperandProperty(operand, key))
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a string listing the properties of the operand and their corresponding values. If the
|
||||
* operand has no properties, this predicate has no result.
|
||||
*/
|
||||
private string getOperandPropertyListString(Operand operand) {
|
||||
result =
|
||||
strictconcat(string key, string value |
|
||||
value = getAdditionalOperandProperty(operand, key)
|
||||
|
|
||||
key + ":" + value, ", "
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a string listing the properties of the operand and their corresponding values. The list is
|
||||
* surrounded by curly braces. If the operand has no properties, this predicate returns an empty
|
||||
* string.
|
||||
*/
|
||||
private string getOperandPropertyString(Operand operand) {
|
||||
result = "{" + getOperandPropertyListString(operand) + "}"
|
||||
or
|
||||
not exists(getOperandPropertyListString(operand)) and result = ""
|
||||
}
|
||||
|
||||
private newtype TPrintableIRNode =
|
||||
TPrintableIRFunction(IRFunction irFunc) { shouldPrintFunction(irFunc.getFunction()) } or
|
||||
TPrintableIRBlock(IRBlock block) { shouldPrintFunction(block.getEnclosingFunction()) } or
|
||||
@@ -190,7 +221,7 @@ private class PrintableInstruction extends PrintableIRNode, TPrintableInstructio
|
||||
|
|
||||
resultString = instr.getResultString() and
|
||||
operationString = instr.getOperationString() and
|
||||
operandsString = instr.getOperandsString() and
|
||||
operandsString = getOperandsString() and
|
||||
columnWidths(block, resultWidth, operationWidth) and
|
||||
result =
|
||||
resultString + getPaddingString(resultWidth - resultString.length()) + " = " +
|
||||
@@ -210,6 +241,22 @@ private class PrintableInstruction extends PrintableIRNode, TPrintableInstructio
|
||||
result = PrintableIRNode.super.getProperty(key) or
|
||||
result = getAdditionalInstructionProperty(instr, key)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the string representation of the operand list. This is the same as
|
||||
* `Instruction::getOperandsString()`, except that each operand is annotated with any properties
|
||||
* provided by active `IRPropertyProvider` instances.
|
||||
*/
|
||||
private string getOperandsString() {
|
||||
result =
|
||||
concat(Operand operand |
|
||||
operand = instr.getAnOperand()
|
||||
|
|
||||
operand.getDumpString() + getOperandPropertyString(operand), ", "
|
||||
order by
|
||||
operand.getDumpSortOrder()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private predicate columnWidths(IRBlock block, int resultWidth, int operationWidth) {
|
||||
|
||||
@@ -72,4 +72,9 @@ class IRPropertyProvider extends TIRPropertyProvider {
|
||||
* Gets the value of the property named `key` for the specified block.
|
||||
*/
|
||||
string getBlockProperty(IRBlock block, string key) { none() }
|
||||
|
||||
/**
|
||||
* Gets the value of the property named `key` for the specified operand.
|
||||
*/
|
||||
string getOperandProperty(Operand operand, string key) { none() }
|
||||
}
|
||||
|
||||
@@ -1501,6 +1501,12 @@ class SwitchInstruction extends Instruction {
|
||||
class CallInstruction extends Instruction {
|
||||
CallInstruction() { getOpcode() instanceof Opcode::Call }
|
||||
|
||||
final override string getImmediateString() {
|
||||
result = getStaticCallTarget().toString()
|
||||
or
|
||||
not exists(getStaticCallTarget()) and result = "?"
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the operand the specifies the target function of the call.
|
||||
*/
|
||||
|
||||
@@ -151,6 +151,11 @@ class Operand extends TOperand {
|
||||
*/
|
||||
string getDumpLabel() { result = "" }
|
||||
|
||||
/**
|
||||
* Gets a string that uniquely identifies this operand on its use instruction.
|
||||
*/
|
||||
string getDumpId() { result = "" }
|
||||
|
||||
/**
|
||||
* Gets a string describing this operand, suitable for display in IR dumps. This consists of the
|
||||
* result ID of the instruction consumed by the operand, plus a label identifying the operand
|
||||
@@ -280,6 +285,8 @@ class NonPhiOperand extends Operand {
|
||||
|
||||
final override string getDumpLabel() { result = tag.getLabel() }
|
||||
|
||||
final override string getDumpId() { result = tag.getId() }
|
||||
|
||||
final override int getDumpSortOrder() { result = tag.getSortOrder() }
|
||||
|
||||
/**
|
||||
@@ -477,6 +484,8 @@ class PhiInputOperand extends MemoryOperand, PhiOperandBase {
|
||||
result = "from " + getPredecessorBlock().getDisplayIndex().toString() + ":"
|
||||
}
|
||||
|
||||
final override string getDumpId() { result = getPredecessorBlock().getDisplayIndex().toString() }
|
||||
|
||||
/**
|
||||
* Gets the predecessor block from which this value comes.
|
||||
*/
|
||||
|
||||
@@ -50,6 +50,37 @@ private string getAdditionalBlockProperty(IRBlock block, string key) {
|
||||
exists(IRPropertyProvider provider | result = provider.getBlockProperty(block, key))
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the properties of an operand from any active property providers.
|
||||
*/
|
||||
private string getAdditionalOperandProperty(Operand operand, string key) {
|
||||
exists(IRPropertyProvider provider | result = provider.getOperandProperty(operand, key))
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a string listing the properties of the operand and their corresponding values. If the
|
||||
* operand has no properties, this predicate has no result.
|
||||
*/
|
||||
private string getOperandPropertyListString(Operand operand) {
|
||||
result =
|
||||
strictconcat(string key, string value |
|
||||
value = getAdditionalOperandProperty(operand, key)
|
||||
|
|
||||
key + ":" + value, ", "
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a string listing the properties of the operand and their corresponding values. The list is
|
||||
* surrounded by curly braces. If the operand has no properties, this predicate returns an empty
|
||||
* string.
|
||||
*/
|
||||
private string getOperandPropertyString(Operand operand) {
|
||||
result = "{" + getOperandPropertyListString(operand) + "}"
|
||||
or
|
||||
not exists(getOperandPropertyListString(operand)) and result = ""
|
||||
}
|
||||
|
||||
private newtype TPrintableIRNode =
|
||||
TPrintableIRFunction(IRFunction irFunc) { shouldPrintFunction(irFunc.getFunction()) } or
|
||||
TPrintableIRBlock(IRBlock block) { shouldPrintFunction(block.getEnclosingFunction()) } or
|
||||
@@ -190,7 +221,7 @@ private class PrintableInstruction extends PrintableIRNode, TPrintableInstructio
|
||||
|
|
||||
resultString = instr.getResultString() and
|
||||
operationString = instr.getOperationString() and
|
||||
operandsString = instr.getOperandsString() and
|
||||
operandsString = getOperandsString() and
|
||||
columnWidths(block, resultWidth, operationWidth) and
|
||||
result =
|
||||
resultString + getPaddingString(resultWidth - resultString.length()) + " = " +
|
||||
@@ -210,6 +241,22 @@ private class PrintableInstruction extends PrintableIRNode, TPrintableInstructio
|
||||
result = PrintableIRNode.super.getProperty(key) or
|
||||
result = getAdditionalInstructionProperty(instr, key)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the string representation of the operand list. This is the same as
|
||||
* `Instruction::getOperandsString()`, except that each operand is annotated with any properties
|
||||
* provided by active `IRPropertyProvider` instances.
|
||||
*/
|
||||
private string getOperandsString() {
|
||||
result =
|
||||
concat(Operand operand |
|
||||
operand = instr.getAnOperand()
|
||||
|
|
||||
operand.getDumpString() + getOperandPropertyString(operand), ", "
|
||||
order by
|
||||
operand.getDumpSortOrder()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private predicate columnWidths(IRBlock block, int resultWidth, int operationWidth) {
|
||||
|
||||
@@ -11,10 +11,7 @@ cached
|
||||
private newtype TCallContext =
|
||||
TEmptyCallContext() or
|
||||
TArgNonDelegateCallContext(Expr arg) { exists(DispatchCall dc | arg = dc.getArgument(_)) } or
|
||||
TArgDelegateCallContext(DelegateCall dc, int i) { exists(dc.getArgument(i)) } or
|
||||
TDelegateToLibraryCallableArgCallContext(DelegateArgumentToLibraryCallable arg, int i) {
|
||||
exists(arg.getDelegateType().getParameter(i))
|
||||
}
|
||||
TArgDelegateCallContext(DelegateCall dc, int i) { exists(dc.getArgument(i)) }
|
||||
|
||||
/**
|
||||
* A call context.
|
||||
@@ -79,31 +76,3 @@ class DelegateCallArgumentCallContext extends ArgumentCallContext, TArgDelegateC
|
||||
|
||||
override Location getLocation() { result = dc.getArgument(arg).getLocation() }
|
||||
}
|
||||
|
||||
/**
|
||||
* An argument of a call to a delegate supplied to a library callable,
|
||||
* identified by the delegate argument itself.
|
||||
*
|
||||
* For example, in `x.Select(y => y)` the call to the supplied delegate
|
||||
* that happens inside the library callable `Select` is not available
|
||||
* in the database, so the delegate argument `y => y` is used to
|
||||
* represent the call.
|
||||
*/
|
||||
class DelegateArgumentToLibraryCallableArgumentContext extends ArgumentCallContext,
|
||||
TDelegateToLibraryCallableArgCallContext {
|
||||
Expr delegate;
|
||||
int arg;
|
||||
|
||||
DelegateArgumentToLibraryCallableArgumentContext() {
|
||||
this = TDelegateToLibraryCallableArgCallContext(delegate, arg)
|
||||
}
|
||||
|
||||
override predicate isArgument(Expr call, int i) {
|
||||
call = delegate and
|
||||
i = arg
|
||||
}
|
||||
|
||||
override string toString() { result = "argument " + arg + " of " + delegate.toString() }
|
||||
|
||||
override Location getLocation() { result = delegate.getLocation() }
|
||||
}
|
||||
|
||||
@@ -199,27 +199,13 @@ class CallableFlowSink extends TCallableFlowSink {
|
||||
|
||||
/** Gets the sink of flow for call `c`, if any. */
|
||||
Expr getSink(Call c) { none() }
|
||||
|
||||
/**
|
||||
* Gets the type of the sink for call `c`. Unlike `getSink()`, this is defined
|
||||
* for all flow sink specifications.
|
||||
*/
|
||||
Type getSinkType(Call c) { result = this.getSink(c).getType() }
|
||||
}
|
||||
|
||||
/** A flow sink specification: (method call) qualifier. */
|
||||
class CallableFlowSinkQualifier extends CallableFlowSink, TCallableFlowSinkQualifier {
|
||||
override string toString() { result = "qualifier" }
|
||||
|
||||
override Expr getSink(Call c) {
|
||||
result = c.getChild(-1)
|
||||
or
|
||||
// E.g. `new Dictionary<int, string>{ {0, "a"}, {1, "b"} }`
|
||||
result.(CollectionInitializer).getAnElementInitializer() = c
|
||||
or
|
||||
// E.g. `new Dictionary<int, string>() { [0] = "a", [1] = "b" }`
|
||||
result.(ObjectInitializer).getAMemberInitializer().getLValue() = c
|
||||
}
|
||||
override Expr getSink(Call c) { result = c.getChild(-1) }
|
||||
}
|
||||
|
||||
/** A flow sink specification: return value. */
|
||||
@@ -253,8 +239,6 @@ class CallableFlowSinkArg extends CallableFlowSink, TCallableFlowSinkArg {
|
||||
// The uses of the `i`th argument are the actual sinks
|
||||
none()
|
||||
}
|
||||
|
||||
override Type getSinkType(Call c) { result = this.getArgument(c).getType() }
|
||||
}
|
||||
|
||||
private predicate isCollectionType(ValueOrRefType t) {
|
||||
@@ -312,16 +296,6 @@ class CallableFlowSinkDelegateArg extends CallableFlowSink, TCallableFlowSinkDel
|
||||
// The uses of the `j`th parameter are the actual sinks
|
||||
none()
|
||||
}
|
||||
|
||||
override Type getSinkType(Call c) {
|
||||
result =
|
||||
c
|
||||
.getArgument(delegateIndex)
|
||||
.(DelegateArgumentToLibraryCallable)
|
||||
.getDelegateType()
|
||||
.getParameter(parameterIndex)
|
||||
.getType()
|
||||
}
|
||||
}
|
||||
|
||||
/** A specification of data flow for a library (non-source code) type. */
|
||||
|
||||
@@ -1018,7 +1018,7 @@ module Ssa {
|
||||
private predicate intraInstanceCallEdge(Callable c1, InstanceCallable c2) {
|
||||
exists(Call c |
|
||||
c.getEnclosingCallable() = c1 and
|
||||
c2 = getARuntimeTarget(c) and
|
||||
c2 = getARuntimeTarget(c, _) and
|
||||
c.(QualifiableExpr).targetIsLocalInstance()
|
||||
)
|
||||
}
|
||||
@@ -1034,15 +1034,28 @@ module Ssa {
|
||||
* the SSA library and `Call.getARuntimeTarget()` mutually recursive), and
|
||||
*
|
||||
* (3) indirect calls to delegates via calls to library callables are included.
|
||||
*
|
||||
* The Boolean `libraryDelegateCall` indicates whether `c` is a call to a library
|
||||
* method and the result is a delegate passed to `c`. For example, in
|
||||
*
|
||||
* ```csharp
|
||||
* Lazy<int> M1()
|
||||
* {
|
||||
* return new Lazy<int>(M2);
|
||||
* }
|
||||
* ```
|
||||
*
|
||||
* the constructor call `new Lazy<int>(M2)` includes `M2` as a target.
|
||||
*/
|
||||
Callable getARuntimeTarget(Call c) {
|
||||
Callable getARuntimeTarget(Call c, boolean libraryDelegateCall) {
|
||||
// Non-delegate call: use dispatch library
|
||||
exists(DispatchCall dc | dc.getCall() = c |
|
||||
result = dc.getADynamicTarget().getSourceDeclaration()
|
||||
result = dc.getADynamicTarget().getSourceDeclaration() and
|
||||
libraryDelegateCall = false
|
||||
)
|
||||
or
|
||||
// Delegate call: use simple analysis
|
||||
result = SimpleDelegateAnalysis::getARuntimeDelegateTarget(c)
|
||||
result = SimpleDelegateAnalysis::getARuntimeDelegateTarget(c, libraryDelegateCall)
|
||||
}
|
||||
|
||||
private module SimpleDelegateAnalysis {
|
||||
@@ -1055,12 +1068,14 @@ module Ssa {
|
||||
* Either `c` is a delegate call and `e` is the qualifier, or `c` is a call to
|
||||
* a library callable and `e` is a delegate argument.
|
||||
*/
|
||||
private predicate delegateCall(Call c, Expr e) {
|
||||
c = any(DelegateCall dc | e = dc.getDelegateExpr())
|
||||
private predicate delegateCall(Call c, Expr e, boolean libraryDelegateCall) {
|
||||
c = any(DelegateCall dc | e = dc.getDelegateExpr()) and
|
||||
libraryDelegateCall = false
|
||||
or
|
||||
c.getTarget().fromLibrary() and
|
||||
e = c.getAnArgument() and
|
||||
e.getType() instanceof SystemLinqExpressions::DelegateExtType
|
||||
e.getType() instanceof SystemLinqExpressions::DelegateExtType and
|
||||
libraryDelegateCall = true
|
||||
}
|
||||
|
||||
/** Holds if expression `e` is a delegate creation for callable `c` of type `t`. */
|
||||
@@ -1090,7 +1105,7 @@ module Ssa {
|
||||
callable = call.getTarget() or
|
||||
callable = call.getTarget().(Method).getAnOverrider+() or
|
||||
callable = call.getTarget().(Method).getAnUltimateImplementor() or
|
||||
callable = getARuntimeDelegateTarget(call)
|
||||
callable = getARuntimeDelegateTarget(call, false)
|
||||
)
|
||||
or
|
||||
pred = succ.(DelegateCreation).getArgument()
|
||||
@@ -1110,7 +1125,7 @@ module Ssa {
|
||||
}
|
||||
|
||||
private predicate reachesDelegateCall(Expr e) {
|
||||
delegateCall(_, e)
|
||||
delegateCall(_, e, _)
|
||||
or
|
||||
exists(Expr mid | reachesDelegateCall(mid) | delegateFlowStep(e, mid))
|
||||
}
|
||||
@@ -1128,12 +1143,14 @@ module Ssa {
|
||||
}
|
||||
|
||||
/** Gets a run-time target for the delegate call `c`. */
|
||||
Callable getARuntimeDelegateTarget(Call c) { delegateCall(c, delegateCallSource(result)) }
|
||||
Callable getARuntimeDelegateTarget(Call c, boolean libraryDelegateCall) {
|
||||
delegateCall(c, delegateCallSource(result), libraryDelegateCall)
|
||||
}
|
||||
}
|
||||
|
||||
/** Holds if `(c1,c2)` is an edge in the call graph. */
|
||||
predicate callEdge(Callable c1, Callable c2) {
|
||||
exists(Call c | c.getEnclosingCallable() = c1 | getARuntimeTarget(c) = c2)
|
||||
exists(Call c | c.getEnclosingCallable() = c1 and c2 = getARuntimeTarget(c, _))
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1179,7 +1196,7 @@ module Ssa {
|
||||
pragma[noinline]
|
||||
predicate callAt(BasicBlock bb, int i, Call call) {
|
||||
bb.getNode(i) = call.getAControlFlowNode() and
|
||||
getARuntimeTarget(call).hasBody()
|
||||
getARuntimeTarget(call, _).hasBody()
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1201,7 +1218,7 @@ module Ssa {
|
||||
private predicate pruneFromLeft(Callable c) {
|
||||
exists(Call call, TrackedFieldOrProp f |
|
||||
updateCandidate(_, _, f, call) and
|
||||
c = getARuntimeTarget(call) and
|
||||
c = getARuntimeTarget(call, _) and
|
||||
generalSetter(_, f.getAssignable(), _)
|
||||
)
|
||||
or
|
||||
@@ -1238,7 +1255,7 @@ module Ssa {
|
||||
updateCandidate(_, _, tfp, call) and
|
||||
fp = tfp.getAssignable() and
|
||||
generalSetter(_, fp, _) and
|
||||
c1 = getARuntimeTarget(call)
|
||||
c1 = getARuntimeTarget(call, _)
|
||||
}
|
||||
|
||||
pragma[noinline]
|
||||
@@ -1279,7 +1296,7 @@ module Ssa {
|
||||
Call call, TrackedFieldOrProp tfp, Callable setter
|
||||
) {
|
||||
updateCandidate(_, _, tfp, call) and
|
||||
setsOwnFieldOrPropTransitive(getARuntimeTarget(call), tfp.getAssignable(), setter)
|
||||
setsOwnFieldOrPropTransitive(getARuntimeTarget(call, _), tfp.getAssignable(), setter)
|
||||
}
|
||||
|
||||
private predicate updatesNamedFieldOrPropPossiblyLive(
|
||||
@@ -1447,7 +1464,7 @@ module Ssa {
|
||||
private predicate pruneFromLeft(Callable c) {
|
||||
exists(Call call, CapturedWrittenLocalScopeSourceVariable v |
|
||||
updateCandidate(_, _, v, call) and
|
||||
c = getARuntimeTarget(call) and
|
||||
c = getARuntimeTarget(call, _) and
|
||||
relevantDefinition(_, v.getAssignable(), _)
|
||||
)
|
||||
or
|
||||
@@ -1485,12 +1502,12 @@ module Ssa {
|
||||
pragma[noinline]
|
||||
private predicate updatesCapturedVariablePrefix(
|
||||
Call call, CapturedWrittenLocalScopeSourceVariable v, PrunedCallable c,
|
||||
CapturedWrittenLocalScopeVariable captured
|
||||
CapturedWrittenLocalScopeVariable captured, boolean libraryDelegateCall
|
||||
) {
|
||||
updateCandidate(_, _, v, call) and
|
||||
captured = v.getAssignable() and
|
||||
relevantDefinitionProj(_, captured) and
|
||||
c = getARuntimeTarget(call)
|
||||
c = getARuntimeTarget(call, libraryDelegateCall)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1505,11 +1522,13 @@ module Ssa {
|
||||
Call call, CapturedWrittenLocalScopeSourceVariable v, PrunedCallable writer,
|
||||
boolean additionalCalls
|
||||
) {
|
||||
exists(PrunedCallable c, CapturedWrittenLocalScopeVariable captured |
|
||||
updatesCapturedVariablePrefix(call, v, c, captured) and
|
||||
exists(
|
||||
PrunedCallable c, CapturedWrittenLocalScopeVariable captured, boolean libraryDelegateCall
|
||||
|
|
||||
updatesCapturedVariablePrefix(call, v, c, captured, libraryDelegateCall) and
|
||||
relevantDefinitionProj(writer, captured) and
|
||||
(
|
||||
c = writer and additionalCalls = false
|
||||
c = writer and additionalCalls = libraryDelegateCall
|
||||
or
|
||||
callEdgePrunedPlus(c, writer) and additionalCalls = true
|
||||
)
|
||||
@@ -1667,7 +1686,7 @@ module Ssa {
|
||||
private predicate pruneFromLeft(Callable c) {
|
||||
exists(Call call, CapturedReadLocalScopeSourceVariable v |
|
||||
implicitReadCandidate(_, _, call.getAControlFlowNode(), v) and
|
||||
c = getARuntimeTarget(call)
|
||||
c = getARuntimeTarget(call, _)
|
||||
)
|
||||
or
|
||||
exists(Callable mid | pruneFromLeft(mid) | callEdge(mid, c))
|
||||
@@ -1702,12 +1721,12 @@ module Ssa {
|
||||
pragma[noinline]
|
||||
private predicate readsCapturedVariablePrefix(
|
||||
ControlFlow::Node call, CapturedReadLocalScopeSourceVariable v, PrunedCallable c,
|
||||
CapturedReadLocalScopeVariable captured
|
||||
CapturedReadLocalScopeVariable captured, boolean libraryDelegateCall
|
||||
) {
|
||||
implicitReadCandidate(_, _, call, v) and
|
||||
captured = v.getAssignable() and
|
||||
capturerReads(_, captured) and
|
||||
c = getARuntimeTarget(call.getElement())
|
||||
c = getARuntimeTarget(call.getElement(), libraryDelegateCall)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1722,11 +1741,13 @@ module Ssa {
|
||||
ControlFlow::Nodes::ElementNode call, CapturedReadLocalScopeSourceVariable v, Callable reader,
|
||||
boolean additionalCalls
|
||||
) {
|
||||
exists(PrunedCallable c, CapturedReadLocalScopeVariable captured |
|
||||
readsCapturedVariablePrefix(call, v, c, captured) and
|
||||
exists(
|
||||
PrunedCallable c, CapturedReadLocalScopeVariable captured, boolean libraryDelegateCall
|
||||
|
|
||||
readsCapturedVariablePrefix(call, v, c, captured, libraryDelegateCall) and
|
||||
capturerReads(reader, captured) and
|
||||
(
|
||||
c = reader and additionalCalls = false
|
||||
c = reader and additionalCalls = libraryDelegateCall
|
||||
or
|
||||
callEdgePrunedPlus(c, reader) and additionalCalls = true
|
||||
)
|
||||
@@ -1765,7 +1786,6 @@ module Ssa {
|
||||
def.getSourceVariable().getAssignable() = lsv
|
||||
|
|
||||
lsv = v.getAssignable() and
|
||||
adef = def.getAPossibleDefinition() and
|
||||
bb.getNode(i) = adef.getAControlFlowNode() and
|
||||
updatesCapturedVariable(def.getCall(), _, adef, additionalCalls)
|
||||
)
|
||||
|
||||
@@ -3,18 +3,24 @@ private import cil
|
||||
private import dotnet
|
||||
private import DataFlowPrivate
|
||||
private import DelegateDataFlow
|
||||
private import semmle.code.csharp.dataflow.LibraryTypeDataFlow
|
||||
private import semmle.code.csharp.dispatch.Dispatch
|
||||
private import semmle.code.csharp.frameworks.system.Collections
|
||||
private import semmle.code.csharp.frameworks.system.collections.Generic
|
||||
|
||||
/**
|
||||
* Gets a source declaration of callable `c` that has a body.
|
||||
* Gets a source declaration of callable `c` that has a body or has
|
||||
* a flow summary.
|
||||
*
|
||||
* If the callable has both CIL and source code, return only the source
|
||||
* code version.
|
||||
*/
|
||||
DotNet::Callable getCallableForDataFlow(DotNet::Callable c) {
|
||||
result.hasBody() and
|
||||
exists(DotNet::Callable sourceDecl | sourceDecl = c.getSourceDeclaration() |
|
||||
result = sourceDecl and
|
||||
Summaries::summary(result, _, _, _, _, _)
|
||||
or
|
||||
result.hasBody() and
|
||||
if sourceDecl.getFile().fromSource()
|
||||
then
|
||||
// C# callable with C# implementation in the database
|
||||
@@ -83,7 +89,8 @@ private module Cached {
|
||||
exists(Ssa::ExplicitDefinition def | def.isCapturedVariableDefinitionFlowOut(_, _) |
|
||||
v = def.getSourceVariable().getAssignable()
|
||||
)
|
||||
}
|
||||
} or
|
||||
TQualifierReturnKind()
|
||||
|
||||
cached
|
||||
newtype TDataFlowCall =
|
||||
@@ -93,15 +100,23 @@ private module Cached {
|
||||
TExplicitDelegateCall(ControlFlow::Nodes::ElementNode cfn, DelegateCall dc) {
|
||||
cfn.getElement() = dc
|
||||
} or
|
||||
TImplicitDelegateCall(ControlFlow::Nodes::ElementNode cfn, DelegateArgumentToLibraryCallable arg) {
|
||||
cfn.getElement() = arg
|
||||
} or
|
||||
TTransitiveCapturedCall(ControlFlow::Nodes::ElementNode cfn, Callable target) {
|
||||
transitiveCapturedCallTarget(cfn, target)
|
||||
} or
|
||||
TCilCall(CIL::Call call) {
|
||||
// No need to include calls that are compiled from source
|
||||
not call.getImplementation().getMethod().compiledFromSource()
|
||||
} or
|
||||
TSummaryDelegateCall(SourceDeclarationCallable c, int pos) {
|
||||
exists(CallableFlowSourceDelegateArg source |
|
||||
Summaries::summary(c, source, _, _, _, _) and
|
||||
pos = source.getArgumentIndex()
|
||||
)
|
||||
or
|
||||
exists(CallableFlowSinkDelegateArg sink |
|
||||
Summaries::summary(c, _, _, sink, _, _) and
|
||||
pos = sink.getDelegateIndex()
|
||||
)
|
||||
}
|
||||
|
||||
/** Gets a viable run-time target for the call `call`. */
|
||||
@@ -118,7 +133,7 @@ private module DispatchImpl {
|
||||
* Gets a viable run-time target for the delegate call `call`, requiring
|
||||
* call context `cc`.
|
||||
*/
|
||||
private DotNet::Callable viableDelegateCallable(DataFlowCall call, CallContext cc) {
|
||||
private DataFlowCallable viableDelegateCallable(DataFlowCall call, CallContext cc) {
|
||||
result = call.(DelegateDataFlowCall).getARuntimeTarget(cc)
|
||||
}
|
||||
|
||||
@@ -143,7 +158,7 @@ private module DispatchImpl {
|
||||
* Gets a viable dispatch target of `call` in the context `ctx`. This is
|
||||
* restricted to those `call`s for which a context might make a difference.
|
||||
*/
|
||||
DotNet::Callable viableImplInCallContext(DataFlowCall call, DataFlowCall ctx) {
|
||||
DataFlowCallable viableImplInCallContext(DataFlowCall call, DataFlowCall ctx) {
|
||||
exists(ArgumentCallContext cc | result = viableDelegateCallable(call, cc) |
|
||||
cc.isArgument(ctx.getExpr(), _)
|
||||
)
|
||||
@@ -153,6 +168,7 @@ private module DispatchImpl {
|
||||
.(NonDelegateDataFlowCall)
|
||||
.getDispatchCall()
|
||||
.getADynamicTargetInCallContext(ctx.(NonDelegateDataFlowCall).getDispatchCall())
|
||||
.getSourceDeclaration()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -218,6 +234,11 @@ class ImplicitCapturedReturnKind extends ReturnKind, TImplicitCapturedReturnKind
|
||||
override string toString() { result = "captured " + v }
|
||||
}
|
||||
|
||||
/** A value returned through the qualifier of a call. */
|
||||
class QualifierReturnKind extends ReturnKind, TQualifierReturnKind {
|
||||
override string toString() { result = "qualifier" }
|
||||
}
|
||||
|
||||
class DataFlowCallable = DotNet::Callable;
|
||||
|
||||
/** A call relevant for data flow. */
|
||||
@@ -261,7 +282,7 @@ class NonDelegateDataFlowCall extends DataFlowCall, TNonDelegateCall {
|
||||
/** Gets the underlying call. */
|
||||
DispatchCall getDispatchCall() { result = dc }
|
||||
|
||||
override DotNet::Callable getARuntimeTarget() {
|
||||
override DataFlowCallable getARuntimeTarget() {
|
||||
result = getCallableForDataFlow(dc.getADynamicTarget())
|
||||
}
|
||||
|
||||
@@ -279,9 +300,9 @@ class NonDelegateDataFlowCall extends DataFlowCall, TNonDelegateCall {
|
||||
/** A delegate call relevant for data flow. */
|
||||
abstract class DelegateDataFlowCall extends DataFlowCall {
|
||||
/** Gets a viable run-time target of this call requiring call context `cc`. */
|
||||
abstract DotNet::Callable getARuntimeTarget(CallContext::CallContext cc);
|
||||
abstract DataFlowCallable getARuntimeTarget(CallContext::CallContext cc);
|
||||
|
||||
override DotNet::Callable getARuntimeTarget() { result = this.getARuntimeTarget(_) }
|
||||
override DataFlowCallable getARuntimeTarget() { result = this.getARuntimeTarget(_) }
|
||||
}
|
||||
|
||||
/** An explicit delegate call relevant for data flow. */
|
||||
@@ -291,8 +312,8 @@ class ExplicitDelegateDataFlowCall extends DelegateDataFlowCall, TExplicitDelega
|
||||
|
||||
ExplicitDelegateDataFlowCall() { this = TExplicitDelegateCall(cfn, dc) }
|
||||
|
||||
override DotNet::Callable getARuntimeTarget(CallContext::CallContext cc) {
|
||||
result = dc.getARuntimeTarget(cc)
|
||||
override DataFlowCallable getARuntimeTarget(CallContext::CallContext cc) {
|
||||
result = getCallableForDataFlow(dc.getARuntimeTarget(cc))
|
||||
}
|
||||
|
||||
override ControlFlow::Nodes::ElementNode getControlFlowNode() { result = cfn }
|
||||
@@ -306,50 +327,6 @@ class ExplicitDelegateDataFlowCall extends DelegateDataFlowCall, TExplicitDelega
|
||||
override Location getLocation() { result = cfn.getLocation() }
|
||||
}
|
||||
|
||||
/**
|
||||
* An implicit delegate call in a call to a library method. For example, we add
|
||||
* an implicit call to `M` in `new Lazy<int>(M)` (although, technically, the delegate
|
||||
* would first be called when accessing the `Value` property).
|
||||
*/
|
||||
class ImplicitDelegateDataFlowCall extends DelegateDataFlowCall, TImplicitDelegateCall {
|
||||
private ControlFlow::Nodes::ElementNode cfn;
|
||||
private DelegateArgumentToLibraryCallable arg;
|
||||
|
||||
ImplicitDelegateDataFlowCall() { this = TImplicitDelegateCall(cfn, arg) }
|
||||
|
||||
/**
|
||||
* Holds if the underlying delegate argument is the `i`th argument of the
|
||||
* call `c` targeting a library callable. For example, `M` is the `0`th
|
||||
* argument of `new Lazy<int>(M)`.
|
||||
*/
|
||||
predicate isArgumentOf(NonDelegateDataFlowCall c, int i) {
|
||||
exists(ImplicitDelegateOutNode out | out.getControlFlowNode() = cfn | out.isArgumentOf(c, i))
|
||||
}
|
||||
|
||||
/** Gets the number of parameters of the supplied delegate. */
|
||||
int getNumberOfDelegateParameters() { result = arg.getDelegateType().getNumberOfParameters() }
|
||||
|
||||
/** Gets the type of the `i`th parameter of the supplied delegate. */
|
||||
Type getDelegateParameterType(int i) { result = arg.getDelegateType().getParameter(i).getType() }
|
||||
|
||||
/** Gets the return type of the supplied delegate. */
|
||||
Type getDelegateReturnType() { result = arg.getDelegateType().getReturnType() }
|
||||
|
||||
override DotNet::Callable getARuntimeTarget(CallContext::CallContext cc) {
|
||||
result = arg.getARuntimeTarget(cc)
|
||||
}
|
||||
|
||||
override ControlFlow::Nodes::ElementNode getControlFlowNode() { result = cfn }
|
||||
|
||||
override ImplicitDelegateOutNode getNode() { result.getControlFlowNode() = cfn }
|
||||
|
||||
override Callable getEnclosingCallable() { result = cfn.getEnclosingCallable() }
|
||||
|
||||
override string toString() { result = "[implicit call] " + cfn.toString() }
|
||||
|
||||
override Location getLocation() { result = cfn.getLocation() }
|
||||
}
|
||||
|
||||
/**
|
||||
* A call that can reach a callable, using one or more additional calls, which
|
||||
* reads or updates a captured variable. We model such a chain of calls as just
|
||||
@@ -380,7 +357,7 @@ class CilDataFlowCall extends DataFlowCall, TCilCall {
|
||||
|
||||
CilDataFlowCall() { this = TCilCall(call) }
|
||||
|
||||
override DotNet::Callable getARuntimeTarget() {
|
||||
override DataFlowCallable getARuntimeTarget() {
|
||||
// There is no dispatch library for CIL, so do not consider overrides for now
|
||||
result = getCallableForDataFlow(call.getTarget())
|
||||
}
|
||||
@@ -395,3 +372,34 @@ class CilDataFlowCall extends DataFlowCall, TCilCall {
|
||||
|
||||
override Location getLocation() { result = call.getLocation() }
|
||||
}
|
||||
|
||||
/**
|
||||
* A delegate call inside a callable with a flow summary.
|
||||
*
|
||||
* For example, in `ints.Select(i => i + 1)` there is a call to the delegate at
|
||||
* parameter position `1` (counting the qualifier as the `0`th argument) inside
|
||||
* the method `Select`.
|
||||
*/
|
||||
class SummaryDelegateCall extends DelegateDataFlowCall, TSummaryDelegateCall {
|
||||
private SourceDeclarationCallable c;
|
||||
private int pos;
|
||||
|
||||
SummaryDelegateCall() { this = TSummaryDelegateCall(c, pos) }
|
||||
|
||||
override DataFlowCallable getARuntimeTarget(CallContext::CallContext cc) {
|
||||
exists(SummaryDelegateParameterSink p |
|
||||
p = TSummaryParameterNode(c, pos) and
|
||||
result = p.getARuntimeTarget(cc)
|
||||
)
|
||||
}
|
||||
|
||||
override ControlFlow::Nodes::ElementNode getControlFlowNode() { none() }
|
||||
|
||||
override DataFlow::Node getNode() { none() }
|
||||
|
||||
override Callable getEnclosingCallable() { result = c }
|
||||
|
||||
override string toString() { result = "[summary] delegate call, parameter " + pos + " of " + c }
|
||||
|
||||
override Location getLocation() { result = c.getLocation() }
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user