Merge branch 'main' into callderef

This commit is contained in:
Geoffrey White
2020-10-19 17:15:33 +01:00
365 changed files with 36948 additions and 7783 deletions

View File

@@ -2,7 +2,10 @@
## General improvements ## 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: * 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) - [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) - [Alibaba Serverless](https://www.alibabacloud.com/help/doc-detail/156876.htm)
- [bluebird](https://www.npmjs.com/package/bluebird) - [bluebird](https://www.npmjs.com/package/bluebird)

View File

@@ -21,7 +21,7 @@ class Include extends PreprocessorDirective, @ppd_include {
/** /**
* Gets the token which occurs after `#include`, for example `"filename"` * Gets the token which occurs after `#include`, for example `"filename"`
* or `&lt;filename>`. * or `<filename>`.
*/ */
string getIncludeText() { result = getHead() } string getIncludeText() { result = getHead() }

File diff suppressed because it is too large Load Diff

View File

@@ -2,6 +2,30 @@ private import DataFlowImplSpecific::Private
private import DataFlowImplSpecific::Public private import DataFlowImplSpecific::Public
import Cached 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 cached
private module Cached { private module Cached {
/** /**

View File

@@ -2,6 +2,30 @@ private import DataFlowImplSpecific::Private
private import DataFlowImplSpecific::Public private import DataFlowImplSpecific::Public
import Cached 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 cached
private module Cached { private module Cached {
/** /**

View File

@@ -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)
)
}
}

View File

@@ -72,4 +72,9 @@ class IRPropertyProvider extends TIRPropertyProvider {
* Gets the value of the property named `key` for the specified block. * Gets the value of the property named `key` for the specified block.
*/ */
string getBlockProperty(IRBlock block, string key) { none() } 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() }
} }

View File

@@ -1501,6 +1501,12 @@ class SwitchInstruction extends Instruction {
class CallInstruction extends Instruction { class CallInstruction extends Instruction {
CallInstruction() { getOpcode() instanceof Opcode::Call } 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. * Gets the operand the specifies the target function of the call.
*/ */

View File

@@ -151,6 +151,11 @@ class Operand extends TOperand {
*/ */
string getDumpLabel() { result = "" } 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 * 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 * 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 getDumpLabel() { result = tag.getLabel() }
final override string getDumpId() { result = tag.getId() }
final override int getDumpSortOrder() { result = tag.getSortOrder() } final override int getDumpSortOrder() { result = tag.getSortOrder() }
/** /**
@@ -477,6 +484,8 @@ class PhiInputOperand extends MemoryOperand, PhiOperandBase {
result = "from " + getPredecessorBlock().getDisplayIndex().toString() + ":" result = "from " + getPredecessorBlock().getDisplayIndex().toString() + ":"
} }
final override string getDumpId() { result = getPredecessorBlock().getDisplayIndex().toString() }
/** /**
* Gets the predecessor block from which this value comes. * Gets the predecessor block from which this value comes.
*/ */

View File

@@ -50,6 +50,37 @@ private string getAdditionalBlockProperty(IRBlock block, string key) {
exists(IRPropertyProvider provider | result = provider.getBlockProperty(block, 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 = private newtype TPrintableIRNode =
TPrintableIRFunction(IRFunction irFunc) { shouldPrintFunction(irFunc.getFunction()) } or TPrintableIRFunction(IRFunction irFunc) { shouldPrintFunction(irFunc.getFunction()) } or
TPrintableIRBlock(IRBlock block) { shouldPrintFunction(block.getEnclosingFunction()) } or TPrintableIRBlock(IRBlock block) { shouldPrintFunction(block.getEnclosingFunction()) } or
@@ -190,7 +221,7 @@ private class PrintableInstruction extends PrintableIRNode, TPrintableInstructio
| |
resultString = instr.getResultString() and resultString = instr.getResultString() and
operationString = instr.getOperationString() and operationString = instr.getOperationString() and
operandsString = instr.getOperandsString() and operandsString = getOperandsString() and
columnWidths(block, resultWidth, operationWidth) and columnWidths(block, resultWidth, operationWidth) and
result = result =
resultString + getPaddingString(resultWidth - resultString.length()) + " = " + resultString + getPaddingString(resultWidth - resultString.length()) + " = " +
@@ -210,6 +241,22 @@ private class PrintableInstruction extends PrintableIRNode, TPrintableInstructio
result = PrintableIRNode.super.getProperty(key) or result = PrintableIRNode.super.getProperty(key) or
result = getAdditionalInstructionProperty(instr, key) 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) { private predicate columnWidths(IRBlock block, int resultWidth, int operationWidth) {

View File

@@ -40,7 +40,17 @@ abstract class OperandTag extends TOperandTag {
/** /**
* Gets a label that will appear before the operand when the IR is printed. * 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 int getSortOrder() { result = 0 }
final override string getLabel() { result = "&:" } final override predicate alwaysPrintLabel() { any() }
final override string getId() { result = "&" }
} }
AddressOperandTag addressOperand() { result = TAddressOperand() } AddressOperandTag addressOperand() { result = TAddressOperand() }
@@ -82,6 +94,8 @@ class BufferSizeOperandTag extends RegisterOperandTag, TBufferSizeOperand {
final override string toString() { result = "BufferSize" } final override string toString() { result = "BufferSize" }
final override int getSortOrder() { result = 1 } final override int getSortOrder() { result = 1 }
final override string getId() { result = "size" }
} }
BufferSizeOperandTag bufferSizeOperand() { result = TBufferSizeOperand() } BufferSizeOperandTag bufferSizeOperand() { result = TBufferSizeOperand() }
@@ -93,6 +107,8 @@ class SideEffectOperandTag extends TypedOperandTag, TSideEffectOperand {
final override string toString() { result = "SideEffect" } final override string toString() { result = "SideEffect" }
final override int getSortOrder() { result = 2 } final override int getSortOrder() { result = 2 }
final override string getId() { result = "side_effect" }
} }
SideEffectOperandTag sideEffectOperand() { result = TSideEffectOperand() } SideEffectOperandTag sideEffectOperand() { result = TSideEffectOperand() }
@@ -105,6 +121,8 @@ class LoadOperandTag extends TypedOperandTag, TLoadOperand {
final override string toString() { result = "Load" } final override string toString() { result = "Load" }
final override int getSortOrder() { result = 3 } final override int getSortOrder() { result = 3 }
final override string getId() { result = "load" }
} }
LoadOperandTag loadOperand() { result = TLoadOperand() } LoadOperandTag loadOperand() { result = TLoadOperand() }
@@ -116,6 +134,8 @@ class StoreValueOperandTag extends RegisterOperandTag, TStoreValueOperand {
final override string toString() { result = "StoreValue" } final override string toString() { result = "StoreValue" }
final override int getSortOrder() { result = 4 } final override int getSortOrder() { result = 4 }
final override string getId() { result = "store" }
} }
StoreValueOperandTag storeValueOperand() { result = TStoreValueOperand() } StoreValueOperandTag storeValueOperand() { result = TStoreValueOperand() }
@@ -127,6 +147,8 @@ class UnaryOperandTag extends RegisterOperandTag, TUnaryOperand {
final override string toString() { result = "Unary" } final override string toString() { result = "Unary" }
final override int getSortOrder() { result = 5 } final override int getSortOrder() { result = 5 }
final override string getId() { result = "unary" }
} }
UnaryOperandTag unaryOperand() { result = TUnaryOperand() } UnaryOperandTag unaryOperand() { result = TUnaryOperand() }
@@ -138,6 +160,8 @@ class LeftOperandTag extends RegisterOperandTag, TLeftOperand {
final override string toString() { result = "Left" } final override string toString() { result = "Left" }
final override int getSortOrder() { result = 6 } final override int getSortOrder() { result = 6 }
final override string getId() { result = "left" }
} }
LeftOperandTag leftOperand() { result = TLeftOperand() } LeftOperandTag leftOperand() { result = TLeftOperand() }
@@ -149,6 +173,8 @@ class RightOperandTag extends RegisterOperandTag, TRightOperand {
final override string toString() { result = "Right" } final override string toString() { result = "Right" }
final override int getSortOrder() { result = 7 } final override int getSortOrder() { result = 7 }
final override string getId() { result = "right" }
} }
RightOperandTag rightOperand() { result = TRightOperand() } RightOperandTag rightOperand() { result = TRightOperand() }
@@ -160,6 +186,8 @@ class ConditionOperandTag extends RegisterOperandTag, TConditionOperand {
final override string toString() { result = "Condition" } final override string toString() { result = "Condition" }
final override int getSortOrder() { result = 8 } final override int getSortOrder() { result = 8 }
final override string getId() { result = "cond" }
} }
ConditionOperandTag conditionOperand() { result = TConditionOperand() } ConditionOperandTag conditionOperand() { result = TConditionOperand() }
@@ -172,7 +200,9 @@ class CallTargetOperandTag extends RegisterOperandTag, TCallTargetOperand {
final override int getSortOrder() { result = 10 } 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() } CallTargetOperandTag callTargetOperand() { result = TCallTargetOperand() }
@@ -195,7 +225,9 @@ class ThisArgumentOperandTag extends ArgumentOperandTag, TThisArgumentOperand {
final override int getSortOrder() { result = 11 } 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() } ThisArgumentOperandTag thisArgumentOperand() { result = TThisArgumentOperand() }
@@ -212,9 +244,11 @@ class PositionalArgumentOperandTag extends ArgumentOperandTag, TPositionalArgume
final override int getSortOrder() { result = 12 + argIndex } 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 int getArgIndex() { result = argIndex }
final override string getId() { result = argIndex.toString() }
} }
PositionalArgumentOperandTag positionalArgumentOperand(int argIndex) { PositionalArgumentOperandTag positionalArgumentOperand(int argIndex) {
@@ -228,7 +262,9 @@ class ChiTotalOperandTag extends ChiOperandTag, TChiTotalOperand {
final override int getSortOrder() { result = 13 } 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() } ChiTotalOperandTag chiTotalOperand() { result = TChiTotalOperand() }
@@ -238,7 +274,9 @@ class ChiPartialOperandTag extends ChiOperandTag, TChiPartialOperand {
final override int getSortOrder() { result = 14 } 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() } ChiPartialOperandTag chiPartialOperand() { result = TChiPartialOperand() }
@@ -252,7 +290,9 @@ class AsmOperandTag extends RegisterOperandTag, TAsmOperand {
final override int getSortOrder() { result = 15 + index } 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) } AsmOperandTag asmOperand(int index) { result = TAsmOperand(index) }

View File

@@ -72,4 +72,9 @@ class IRPropertyProvider extends TIRPropertyProvider {
* Gets the value of the property named `key` for the specified block. * Gets the value of the property named `key` for the specified block.
*/ */
string getBlockProperty(IRBlock block, string key) { none() } 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() }
} }

View File

@@ -1501,6 +1501,12 @@ class SwitchInstruction extends Instruction {
class CallInstruction extends Instruction { class CallInstruction extends Instruction {
CallInstruction() { getOpcode() instanceof Opcode::Call } 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. * Gets the operand the specifies the target function of the call.
*/ */

View File

@@ -151,6 +151,11 @@ class Operand extends TOperand {
*/ */
string getDumpLabel() { result = "" } 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 * 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 * 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 getDumpLabel() { result = tag.getLabel() }
final override string getDumpId() { result = tag.getId() }
final override int getDumpSortOrder() { result = tag.getSortOrder() } final override int getDumpSortOrder() { result = tag.getSortOrder() }
/** /**
@@ -477,6 +484,8 @@ class PhiInputOperand extends MemoryOperand, PhiOperandBase {
result = "from " + getPredecessorBlock().getDisplayIndex().toString() + ":" result = "from " + getPredecessorBlock().getDisplayIndex().toString() + ":"
} }
final override string getDumpId() { result = getPredecessorBlock().getDisplayIndex().toString() }
/** /**
* Gets the predecessor block from which this value comes. * Gets the predecessor block from which this value comes.
*/ */

View File

@@ -50,6 +50,37 @@ private string getAdditionalBlockProperty(IRBlock block, string key) {
exists(IRPropertyProvider provider | result = provider.getBlockProperty(block, 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 = private newtype TPrintableIRNode =
TPrintableIRFunction(IRFunction irFunc) { shouldPrintFunction(irFunc.getFunction()) } or TPrintableIRFunction(IRFunction irFunc) { shouldPrintFunction(irFunc.getFunction()) } or
TPrintableIRBlock(IRBlock block) { shouldPrintFunction(block.getEnclosingFunction()) } or TPrintableIRBlock(IRBlock block) { shouldPrintFunction(block.getEnclosingFunction()) } or
@@ -190,7 +221,7 @@ private class PrintableInstruction extends PrintableIRNode, TPrintableInstructio
| |
resultString = instr.getResultString() and resultString = instr.getResultString() and
operationString = instr.getOperationString() and operationString = instr.getOperationString() and
operandsString = instr.getOperandsString() and operandsString = getOperandsString() and
columnWidths(block, resultWidth, operationWidth) and columnWidths(block, resultWidth, operationWidth) and
result = result =
resultString + getPaddingString(resultWidth - resultString.length()) + " = " + resultString + getPaddingString(resultWidth - resultString.length()) + " = " +
@@ -210,6 +241,22 @@ private class PrintableInstruction extends PrintableIRNode, TPrintableInstructio
result = PrintableIRNode.super.getProperty(key) or result = PrintableIRNode.super.getProperty(key) or
result = getAdditionalInstructionProperty(instr, key) 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) { private predicate columnWidths(IRBlock block, int resultWidth, int operationWidth) {

View File

@@ -72,4 +72,9 @@ class IRPropertyProvider extends TIRPropertyProvider {
* Gets the value of the property named `key` for the specified block. * Gets the value of the property named `key` for the specified block.
*/ */
string getBlockProperty(IRBlock block, string key) { none() } 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() }
} }

View File

@@ -1501,6 +1501,12 @@ class SwitchInstruction extends Instruction {
class CallInstruction extends Instruction { class CallInstruction extends Instruction {
CallInstruction() { getOpcode() instanceof Opcode::Call } 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. * Gets the operand the specifies the target function of the call.
*/ */

View File

@@ -151,6 +151,11 @@ class Operand extends TOperand {
*/ */
string getDumpLabel() { result = "" } 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 * 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 * 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 getDumpLabel() { result = tag.getLabel() }
final override string getDumpId() { result = tag.getId() }
final override int getDumpSortOrder() { result = tag.getSortOrder() } final override int getDumpSortOrder() { result = tag.getSortOrder() }
/** /**
@@ -477,6 +484,8 @@ class PhiInputOperand extends MemoryOperand, PhiOperandBase {
result = "from " + getPredecessorBlock().getDisplayIndex().toString() + ":" result = "from " + getPredecessorBlock().getDisplayIndex().toString() + ":"
} }
final override string getDumpId() { result = getPredecessorBlock().getDisplayIndex().toString() }
/** /**
* Gets the predecessor block from which this value comes. * Gets the predecessor block from which this value comes.
*/ */

View File

@@ -50,6 +50,37 @@ private string getAdditionalBlockProperty(IRBlock block, string key) {
exists(IRPropertyProvider provider | result = provider.getBlockProperty(block, 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 = private newtype TPrintableIRNode =
TPrintableIRFunction(IRFunction irFunc) { shouldPrintFunction(irFunc.getFunction()) } or TPrintableIRFunction(IRFunction irFunc) { shouldPrintFunction(irFunc.getFunction()) } or
TPrintableIRBlock(IRBlock block) { shouldPrintFunction(block.getEnclosingFunction()) } or TPrintableIRBlock(IRBlock block) { shouldPrintFunction(block.getEnclosingFunction()) } or
@@ -190,7 +221,7 @@ private class PrintableInstruction extends PrintableIRNode, TPrintableInstructio
| |
resultString = instr.getResultString() and resultString = instr.getResultString() and
operationString = instr.getOperationString() and operationString = instr.getOperationString() and
operandsString = instr.getOperandsString() and operandsString = getOperandsString() and
columnWidths(block, resultWidth, operationWidth) and columnWidths(block, resultWidth, operationWidth) and
result = result =
resultString + getPaddingString(resultWidth - resultString.length()) + " = " + resultString + getPaddingString(resultWidth - resultString.length()) + " = " +
@@ -210,6 +241,22 @@ private class PrintableInstruction extends PrintableIRNode, TPrintableInstructio
result = PrintableIRNode.super.getProperty(key) or result = PrintableIRNode.super.getProperty(key) or
result = getAdditionalInstructionProperty(instr, key) 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) { private predicate columnWidths(IRBlock block, int resultWidth, int operationWidth) {

View File

@@ -39,17 +39,8 @@ void sink(int x)
void bar(Outer &b) void bar(Outer &b)
{ {
// The library correctly finds that the four `user_input` sources can make it sink(b.inner.f.a()); // $ast=53:19 $ast=55:19 $ir=53:19 $ir=55:19
// to the `sink` calls, but it also finds some source/sink combinations that sink(b.inner.f.b()); // $ast=54:19 $ast=56:19 $ir=54:19 $ir=56:19
// 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
} }
void foo() void foo()

View File

@@ -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: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: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 | | 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: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: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 | | qualifiers.cpp:32:35:32:44 | call to user_input | qualifiers.cpp:33:23:33:23 | a | AST only |

View File

@@ -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 |

View File

@@ -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 | 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 | 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 | | 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 [a_] | complex.cpp:42:18:42: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:42:16:42:16 | a output argument [b_] |
| complex.cpp:40:17:40:17 | *b [b_] | complex.cpp:52:18:52:18 | call to b | | complex.cpp:40:17:40:17 | *b [b_] | complex.cpp:43:18:43: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:42:16:42:16 | a output argument [b_] | complex.cpp:43:18:43:18 | call to b |
| complex.cpp:62:12:62:12 | setA output argument [a_] | complex.cpp:40:17:40:17 | *b [a_] | | complex.cpp:53:12:53: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:53:19:53:28 | call to user_input | complex.cpp:53:12:53: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:54:12:54: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:54:19:54:28 | call to user_input | complex.cpp:54:12:54: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:55:12:55: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:55:12:55:12 | setA output argument [a_] | complex.cpp:56:12:56: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:55:19:55:28 | call to user_input | complex.cpp:55:12:55: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:56:12:56: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:56:12:56: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: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 [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: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 | | 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 | | 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 [a_] | semmle.label | *b [a_] |
| complex.cpp:40:17:40:17 | *b [b_] | semmle.label | *b [b_] | | 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:42:16:42: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:42:18:42: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:43:18:43: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:53:12:53: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:53:19:53: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:54:12:54: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:54:19:54: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:55:12:55: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:55:19:55: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:56:12:56: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:56:12:56: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: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 [a_] | semmle.label | *f [a_] |
| constructors.cpp:26:15:26:15 | *f [b_] | semmle.label | *f [b_] | | 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_] | | 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: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: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 | | 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: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: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: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: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: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: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: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: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: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 | | 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 |

View File

@@ -293,28 +293,28 @@
| by_reference.cpp:136:16:136:16 | a | AST only | | by_reference.cpp:136:16:136:16 | a | AST only |
| complex.cpp:11:22:11:23 | a_ | AST only | | complex.cpp:11:22:11:23 | a_ | AST only |
| complex.cpp:12:22:12:23 | b_ | AST only | | complex.cpp:12:22:12:23 | b_ | AST only |
| complex.cpp:51:8:51:8 | b | AST only | | complex.cpp:42:8:42:8 | b | AST only |
| complex.cpp:51:10:51:14 | inner | AST only | | complex.cpp:42:10:42:14 | inner | AST only |
| complex.cpp:51:16:51:16 | f | AST only | | complex.cpp:42:16:42:16 | f | AST only |
| complex.cpp:52:8:52:8 | b | AST only | | complex.cpp:43:8:43:8 | b | AST only |
| complex.cpp:52:10:52:14 | inner | AST only | | complex.cpp:43:10:43:14 | inner | AST only |
| complex.cpp:52:16:52:16 | f | AST only | | complex.cpp:43:16:43:16 | f | AST only |
| complex.cpp:62:3:62:4 | b1 | AST only | | complex.cpp:53:3:53:4 | b1 | AST only |
| complex.cpp:62:6:62:10 | inner | AST only | | complex.cpp:53:6:53:10 | inner | AST only |
| complex.cpp:62:12:62:12 | f | AST only | | complex.cpp:53:12:53:12 | f | AST only |
| complex.cpp:63:3:63:4 | b2 | AST only | | complex.cpp:54:3:54:4 | b2 | AST only |
| complex.cpp:63:6:63:10 | inner | AST only | | complex.cpp:54:6:54:10 | inner | AST only |
| complex.cpp:63:12:63:12 | f | AST only | | complex.cpp:54:12:54:12 | f | AST only |
| complex.cpp:64:3:64:4 | b3 | AST only | | complex.cpp:55:3:55:4 | b3 | AST only |
| complex.cpp:64:6:64:10 | inner | AST only | | complex.cpp:55:6:55:10 | inner | AST only |
| complex.cpp:64:12:64:12 | f | AST only | | complex.cpp:55:12:55:12 | f | AST only |
| complex.cpp:65:3:65:4 | b3 | AST only | | complex.cpp:56:3:56:4 | b3 | AST only |
| complex.cpp:65:6:65:10 | inner | AST only | | complex.cpp:56:6:56:10 | inner | AST only |
| complex.cpp:65:12:65:12 | f | AST only | | complex.cpp:56:12:56:12 | f | AST only |
| complex.cpp:68:7:68:8 | b1 | AST only | | complex.cpp:59:7:59:8 | b1 | AST only |
| complex.cpp:71:7:71:8 | b2 | AST only | | complex.cpp:62:7:62:8 | b2 | AST only |
| complex.cpp:74:7:74:8 | b3 | AST only | | complex.cpp:65:7:65:8 | b3 | AST only |
| complex.cpp:77:7:77:8 | b4 | AST only | | complex.cpp:68:7:68:8 | b4 | AST only |
| constructors.cpp:20:24:20:25 | a_ | AST only | | constructors.cpp:20:24:20:25 | a_ | AST only |
| constructors.cpp:21:24:21:25 | b_ | AST only | | constructors.cpp:21:24:21:25 | b_ | AST only |
| constructors.cpp:28:10:28:10 | f | AST only | | constructors.cpp:28:10:28:10 | f | AST only |

View File

@@ -344,28 +344,28 @@
| complex.cpp:11:22:11:23 | this | | complex.cpp:11:22:11:23 | this |
| complex.cpp:12:22:12:23 | b_ | | complex.cpp:12:22:12:23 | b_ |
| complex.cpp:12:22:12:23 | this | | complex.cpp:12:22:12:23 | this |
| complex.cpp:51:8:51:8 | b | | complex.cpp:42:8:42:8 | b |
| complex.cpp:51:10:51:14 | inner | | complex.cpp:42:10:42:14 | inner |
| complex.cpp:51:16:51:16 | f | | complex.cpp:42:16:42:16 | f |
| complex.cpp:52:8:52:8 | b | | complex.cpp:43:8:43:8 | b |
| complex.cpp:52:10:52:14 | inner | | complex.cpp:43:10:43:14 | inner |
| complex.cpp:52:16:52:16 | f | | complex.cpp:43:16:43:16 | f |
| complex.cpp:62:3:62:4 | b1 | | complex.cpp:53:3:53:4 | b1 |
| complex.cpp:62:6:62:10 | inner | | complex.cpp:53:6:53:10 | inner |
| complex.cpp:62:12:62:12 | f | | complex.cpp:53:12:53:12 | f |
| complex.cpp:63:3:63:4 | b2 | | complex.cpp:54:3:54:4 | b2 |
| complex.cpp:63:6:63:10 | inner | | complex.cpp:54:6:54:10 | inner |
| complex.cpp:63:12:63:12 | f | | complex.cpp:54:12:54:12 | f |
| complex.cpp:64:3:64:4 | b3 | | complex.cpp:55:3:55:4 | b3 |
| complex.cpp:64:6:64:10 | inner | | complex.cpp:55:6:55:10 | inner |
| complex.cpp:64:12:64:12 | f | | complex.cpp:55:12:55:12 | f |
| complex.cpp:65:3:65:4 | b3 | | complex.cpp:56:3:56:4 | b3 |
| complex.cpp:65:6:65:10 | inner | | complex.cpp:56:6:56:10 | inner |
| complex.cpp:65:12:65:12 | f | | complex.cpp:56:12:56:12 | f |
| complex.cpp:68:7:68:8 | b1 | | complex.cpp:59:7:59:8 | b1 |
| complex.cpp:71:7:71:8 | b2 | | complex.cpp:62:7:62:8 | b2 |
| complex.cpp:74:7:74:8 | b3 | | complex.cpp:65:7:65:8 | b3 |
| complex.cpp:77:7:77:8 | b4 | | complex.cpp:68:7:68:8 | b4 |
| constructors.cpp:20:24:20:25 | a_ | | constructors.cpp:20:24:20:25 | a_ |
| constructors.cpp:20:24:20:25 | this | | constructors.cpp:20:24:20:25 | this |
| constructors.cpp:21:24:21:25 | b_ | | constructors.cpp:21:24:21:25 | b_ |

View File

@@ -51,14 +51,14 @@ edges
| A.cpp:160:29:160:29 | b | A.cpp:160:18:160:60 | call to MyList [head] | | 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: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: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, head] | A.cpp:165:10:165:11 | l3 [next, next, head] |
| 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: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, ... (3)] | | 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, ... (3)] | A.cpp:165:14:165:17 | 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: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: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, 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 [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: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 | | 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: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: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: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 | 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, ... (3)] | D.cpp:59:5:59:7 | this [boxfield, box, ... (3)] | | 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: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: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: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, ... (3)] | D.cpp:64:10:64:17 | this [boxfield, box, ... (3)] | | 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 | 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 | | 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: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] | | 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: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: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: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, data] | arrays.cpp:37:8:37:8 | o [nested, arr, data] |
| 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: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: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: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: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: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: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: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: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: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: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: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, data] | arrays.cpp:43:8:43:8 | o [indirect, arr, data] |
| 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: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: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: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: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: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: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: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: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: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: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] | | 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: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: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 | | 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, a_] | complex.cpp:42:8:42:8 | b [inner, f, a_] |
| complex.cpp:40:17:40:17 | b [inner, f, ... (3)] | complex.cpp:52:8:52:8 | b [inner, f, ... (3)] | | complex.cpp:40:17:40:17 | b [inner, f, b_] | complex.cpp:43:8:43:8 | b [inner, f, b_] |
| complex.cpp:51:8:51:8 | b [inner, f, ... (3)] | complex.cpp:51:10:51:14 | inner [f, a_] | | complex.cpp:42:8:42:8 | b [inner, f, a_] | complex.cpp:42:10:42:14 | inner [f, a_] |
| complex.cpp:51:10:51:14 | inner [f, a_] | complex.cpp:51:16:51:16 | f [a_] | | complex.cpp:42:10:42:14 | inner [f, a_] | complex.cpp:42:16:42:16 | f [a_] |
| complex.cpp:51:16:51:16 | f [a_] | complex.cpp:51:18:51:18 | call to a | | complex.cpp:42:16:42:16 | f [a_] | complex.cpp:42:18:42: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:43:8:43:8 | b [inner, f, b_] | complex.cpp:43:10:43:14 | inner [f, b_] |
| complex.cpp:52:10:52:14 | inner [f, b_] | complex.cpp:52:16:52:16 | f [b_] | | complex.cpp:43:10:43:14 | inner [f, b_] | complex.cpp:43:16:43:16 | f [b_] |
| complex.cpp:52:16:52:16 | f [b_] | complex.cpp:52:18:52:18 | call to b | | complex.cpp:43:16:43:16 | f [b_] | complex.cpp:43:18:43: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:53:3:53:4 | b1 [post update] [inner, f, a_] | complex.cpp:59:7:59:8 | b1 [inner, f, a_] |
| 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:53:6:53:10 | inner [post update] [f, a_] | complex.cpp:53:3:53:4 | b1 [post update] [inner, f, a_] |
| complex.cpp:62:12:62:12 | ref arg f [a_] | complex.cpp:62:6:62:10 | inner [post update] [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:62:19:62:28 | call to user_input | complex.cpp:62:12:62:12 | ref arg f [a_] | | complex.cpp:53:19:53:28 | call to user_input | complex.cpp:53:12:53: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:54:3:54:4 | b2 [post update] [inner, f, b_] | complex.cpp:62:7:62:8 | b2 [inner, f, b_] |
| 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:54:6:54:10 | inner [post update] [f, b_] | complex.cpp:54:3:54:4 | b2 [post update] [inner, f, b_] |
| complex.cpp:63:12:63:12 | ref arg f [b_] | complex.cpp:63:6:63:10 | inner [post update] [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:63:19:63:28 | call to user_input | complex.cpp:63:12:63:12 | ref arg f [b_] | | complex.cpp:54:19:54:28 | call to user_input | complex.cpp:54:12:54: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:55:3:55:4 | b3 [post update] [inner, f, a_] | complex.cpp:65:7:65:8 | b3 [inner, f, a_] |
| 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:55:6:55:10 | inner [post update] [f, a_] | complex.cpp:55:3:55:4 | b3 [post update] [inner, f, a_] |
| complex.cpp:64:12:64:12 | ref arg f [a_] | complex.cpp:64:6:64:10 | inner [post update] [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:64:19:64:28 | call to user_input | complex.cpp:64:12:64:12 | ref arg f [a_] | | complex.cpp:55:19:55:28 | call to user_input | complex.cpp:55:12:55: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:56:3:56:4 | b3 [post update] [inner, f, b_] | complex.cpp:65:7:65:8 | b3 [inner, f, b_] |
| 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:56:6:56:10 | inner [post update] [f, b_] | complex.cpp:56:3:56:4 | b3 [post update] [inner, f, b_] |
| complex.cpp:65:12:65:12 | ref arg f [b_] | complex.cpp:65:6:65:10 | inner [post update] [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:65:19:65:28 | call to user_input | complex.cpp:65:12:65:12 | ref arg f [b_] | | complex.cpp:56:19:56:28 | call to user_input | complex.cpp:56:12:56: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:59:7:59:8 | b1 [inner, f, a_] | complex.cpp:40:17:40:17 | b [inner, f, a_] |
| complex.cpp:71:7:71:8 | b2 [inner, f, ... (3)] | complex.cpp:40:17:40:17 | b [inner, f, ... (3)] | | complex.cpp:62:7:62:8 | b2 [inner, f, b_] | complex.cpp:40:17:40:17 | b [inner, f, b_] |
| complex.cpp:74:7:74:8 | b3 [inner, f, ... (3)] | complex.cpp:40:17:40:17 | b [inner, f, ... (3)] | | 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 [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: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 | | 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: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: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 | | 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: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, ... (3)] | realistic.cpp:53:13:53:15 | bar [inner post update] [baz, userInput, ... (3)] | | 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: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: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, ... (3)] | | 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: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: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: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, ... (3)] | realistic.cpp:61:32:61:34 | 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, ... (3)] | realistic.cpp:61:21:61:30 | access to array [baz, userInput, ... (3)] | | 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: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 | | 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_] | | 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: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: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: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: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: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:20:165:23 | next [head] | semmle.label | next [head] |
| A.cpp:165:26:165:29 | head | semmle.label | 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, 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 [head] | semmle.label | next [head] |
| A.cpp:167:47:167:50 | next [next, head] | semmle.label | next [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] | | 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:52:14:52:14 | b [box, elem] | semmle.label | b [box, elem] |
| D.cpp:56:15:56:24 | new | semmle.label | new | | 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 | 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:5:58:27 | ... = ... | semmle.label | ... = ... |
| D.cpp:58:15:58:17 | box [post update] [elem] | semmle.label | box [post update] [elem] | | 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:59:5:59:7 | this [boxfield, box, elem] | semmle.label | this [boxfield, box, elem] |
| D.cpp:63:8:63:10 | this [boxfield, box, ... (3)] | semmle.label | this [boxfield, box, ... (3)] | | 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 | 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:20:64:22 | box [elem] | semmle.label | box [elem] |
| D.cpp:64:25:64:28 | elem | semmle.label | 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] | | 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: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: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: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: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: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: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: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: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: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: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:17:37:19 | arr [data] | semmle.label | arr [data] |
| arrays.cpp:37:24:37:27 | data | semmle.label | 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: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: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:17:38:19 | arr [data] | semmle.label | arr [data] |
| arrays.cpp:38:24:38:27 | data | semmle.label | 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: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: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: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: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: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: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: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:20:43:22 | arr [data] | semmle.label | arr [data] |
| arrays.cpp:43:27:43:30 | data | semmle.label | 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: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:10:44:17 | indirect [arr, data] | semmle.label | indirect [arr, data] |
| arrays.cpp:44:20:44:22 | arr [data] | semmle.label | 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: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:8:136:13 | pouter [a] | semmle.label | pouter [a] |
| by_reference.cpp:136:16:136:16 | a | semmle.label | 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:40:17:40:17 | b [inner, f, a_] | semmle.label | b [inner, f, a_] |
| complex.cpp:51:8:51:8 | b [inner, f, ... (3)] | semmle.label | b [inner, f, ... (3)] | | complex.cpp:40:17:40:17 | b [inner, f, b_] | semmle.label | b [inner, f, b_] |
| complex.cpp:51:10:51:14 | inner [f, a_] | semmle.label | inner [f, a_] | | complex.cpp:42:8:42:8 | b [inner, f, a_] | semmle.label | b [inner, f, a_] |
| complex.cpp:51:16:51:16 | f [a_] | semmle.label | f [a_] | | complex.cpp:42:10:42:14 | inner [f, a_] | semmle.label | inner [f, a_] |
| complex.cpp:51:18:51:18 | call to a | semmle.label | call to a | | complex.cpp:42:16:42:16 | f [a_] | semmle.label | f [a_] |
| complex.cpp:52:8:52:8 | b [inner, f, ... (3)] | semmle.label | b [inner, f, ... (3)] | | complex.cpp:42:18:42:18 | call to a | semmle.label | call to a |
| complex.cpp:52:10:52:14 | inner [f, b_] | semmle.label | inner [f, b_] | | complex.cpp:43:8:43:8 | b [inner, f, b_] | semmle.label | b [inner, f, b_] |
| complex.cpp:52:16:52:16 | f [b_] | semmle.label | f [b_] | | complex.cpp:43:10:43:14 | inner [f, b_] | semmle.label | inner [f, b_] |
| complex.cpp:52:18:52:18 | call to b | semmle.label | call to b | | complex.cpp:43:16:43:16 | f [b_] | semmle.label | f [b_] |
| complex.cpp:62:3:62:4 | b1 [post update] [inner, f, ... (3)] | semmle.label | b1 [post update] [inner, f, ... (3)] | | complex.cpp:43:18:43:18 | call to b | semmle.label | call to b |
| complex.cpp:62:6:62:10 | inner [post update] [f, a_] | semmle.label | inner [post update] [f, a_] | | complex.cpp:53:3:53:4 | b1 [post update] [inner, f, a_] | semmle.label | b1 [post update] [inner, f, a_] |
| complex.cpp:62:12:62:12 | ref arg f [a_] | semmle.label | ref arg f [a_] | | complex.cpp:53:6:53:10 | inner [post update] [f, a_] | semmle.label | inner [post update] [f, a_] |
| complex.cpp:62:19:62:28 | call to user_input | semmle.label | call to user_input | | complex.cpp:53:12:53:12 | ref arg f [a_] | semmle.label | ref arg f [a_] |
| complex.cpp:63:3:63:4 | b2 [post update] [inner, f, ... (3)] | semmle.label | b2 [post update] [inner, f, ... (3)] | | complex.cpp:53:19:53:28 | call to user_input | semmle.label | call to user_input |
| complex.cpp:63:6:63:10 | inner [post update] [f, b_] | semmle.label | inner [post update] [f, b_] | | complex.cpp:54:3:54:4 | b2 [post update] [inner, f, b_] | semmle.label | b2 [post update] [inner, f, b_] |
| complex.cpp:63:12:63:12 | ref arg f [b_] | semmle.label | ref arg f [b_] | | complex.cpp:54:6:54:10 | inner [post update] [f, b_] | semmle.label | inner [post update] [f, b_] |
| complex.cpp:63:19:63:28 | call to user_input | semmle.label | call to user_input | | complex.cpp:54:12:54:12 | ref arg f [b_] | semmle.label | ref arg f [b_] |
| complex.cpp:64:3:64:4 | b3 [post update] [inner, f, ... (3)] | semmle.label | b3 [post update] [inner, f, ... (3)] | | complex.cpp:54:19:54:28 | call to user_input | semmle.label | call to user_input |
| complex.cpp:64:6:64:10 | inner [post update] [f, a_] | semmle.label | inner [post update] [f, a_] | | complex.cpp:55:3:55:4 | b3 [post update] [inner, f, a_] | semmle.label | b3 [post update] [inner, f, a_] |
| complex.cpp:64:12:64:12 | ref arg f [a_] | semmle.label | ref arg f [a_] | | complex.cpp:55:6:55:10 | inner [post update] [f, a_] | semmle.label | inner [post update] [f, a_] |
| complex.cpp:64:19:64:28 | call to user_input | semmle.label | call to user_input | | complex.cpp:55:12:55:12 | ref arg f [a_] | semmle.label | ref arg f [a_] |
| complex.cpp:65:3:65:4 | b3 [post update] [inner, f, ... (3)] | semmle.label | b3 [post update] [inner, f, ... (3)] | | complex.cpp:55:19:55:28 | call to user_input | semmle.label | call to user_input |
| complex.cpp:65:6:65:10 | inner [post update] [f, b_] | semmle.label | inner [post update] [f, b_] | | complex.cpp:56:3:56:4 | b3 [post update] [inner, f, b_] | semmle.label | b3 [post update] [inner, f, b_] |
| complex.cpp:65:12:65:12 | ref arg f [b_] | semmle.label | ref arg f [b_] | | complex.cpp:56:6:56:10 | inner [post update] [f, b_] | semmle.label | inner [post update] [f, b_] |
| complex.cpp:65:19:65:28 | call to user_input | semmle.label | call to user_input | | complex.cpp:56:12:56:12 | ref arg f [b_] | semmle.label | ref arg f [b_] |
| complex.cpp:68:7:68:8 | b1 [inner, f, ... (3)] | semmle.label | b1 [inner, f, ... (3)] | | complex.cpp:56:19:56:28 | call to user_input | semmle.label | call to user_input |
| complex.cpp:71:7:71:8 | b2 [inner, f, ... (3)] | semmle.label | b2 [inner, f, ... (3)] | | complex.cpp:59:7:59:8 | b1 [inner, f, a_] | semmle.label | b1 [inner, f, a_] |
| complex.cpp:74:7:74:8 | b3 [inner, f, ... (3)] | semmle.label | b3 [inner, f, ... (3)] | | 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 [a_] | semmle.label | f [a_] |
| constructors.cpp:26:15:26:15 | f [b_] | semmle.label | f [b_] | | constructors.cpp:26:15:26:15 | f [b_] | semmle.label | f [b_] |
| constructors.cpp:28:10:28:10 | f [a_] | semmle.label | f [a_] | | 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: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:16:48:20 | inner [a] | semmle.label | inner [a] |
| qualifiers.cpp:48:23:48:23 | a | semmle.label | 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: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, ... (3)] | semmle.label | access to array [post update] [baz, userInput, ... (3)] | | 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: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: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: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: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:23 | foo [bar, baz, userInput, bufferLen] | semmle.label | foo [bar, baz, userInput, bufferLen] |
| realistic.cpp:61:21:61:30 | access to array [baz, userInput, ... (3)] | semmle.label | access to array [baz, userInput, ... (3)] | | 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, ... (3)] | semmle.label | bar [baz, userInput, ... (3)] | | 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: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:37:61:45 | userInput [bufferLen] | semmle.label | userInput [bufferLen] |
| realistic.cpp:61:47:61:55 | bufferLen | semmle.label | 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: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: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 | | 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: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: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: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: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: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: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: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 |
| 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 |
| 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: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: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 | | 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

View File

@@ -346,7 +346,7 @@ ssa.cpp:
# 97| r97_2(glval<Point>) = VariableAddress[a] : # 97| r97_2(glval<Point>) = VariableAddress[a] :
# 97| r97_3(Point *) = CopyValue : r97_2 # 97| r97_3(Point *) = CopyValue : r97_2
# 97| r97_4(void *) = Convert : r97_3 # 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_6(unknown) = ^CallSideEffect : ~m95_7
# 97| m97_7(unknown) = Chi : total:m95_7, partial:m97_6 # 97| m97_7(unknown) = Chi : total:m95_7, partial:m97_6
# 97| v97_8(void) = ^BufferReadSideEffect[0] : &:r97_4, ~m97_7 # 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_2(glval<Point>) = VariableAddress[a] :
# 108| r108_3(Point *) = CopyValue : r108_2 # 108| r108_3(Point *) = CopyValue : r108_2
# 108| r108_4(void *) = Convert : r108_3 # 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_6(unknown) = ^CallSideEffect : ~m105_7
# 108| m108_7(unknown) = Chi : total:m105_7, partial:m108_6 # 108| m108_7(unknown) = Chi : total:m105_7, partial:m108_6
# 108| v108_8(void) = ^BufferReadSideEffect[0] : &:r108_4, ~m108_7 # 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_2(glval<Point>) = VariableAddress[a] :
# 119| r119_3(Point *) = CopyValue : r119_2 # 119| r119_3(Point *) = CopyValue : r119_2
# 119| r119_4(void *) = Convert : r119_3 # 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_6(unknown) = ^CallSideEffect : ~m117_13
# 119| m119_7(unknown) = Chi : total:m117_13, partial:m119_6 # 119| m119_7(unknown) = Chi : total:m117_13, partial:m119_6
# 119| v119_8(void) = ^BufferReadSideEffect[0] : &:r119_4, ~m119_7 # 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_6(glval<char *>) = VariableAddress[str2] :
# 199| r199_7(char *) = Load : &:r199_6, m198_10 # 199| r199_7(char *) = Load : &:r199_6, m198_10
# 199| r199_8(char *) = Convert : r199_7 # 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_10(void) = ^BufferReadSideEffect[0] : &:r199_5, ~m198_8
# 199| v199_11(void) = ^BufferReadSideEffect[1] : &:r199_8, ~m198_12 # 199| v199_11(void) = ^BufferReadSideEffect[1] : &:r199_8, ~m198_12
# 199| m199_12(int) = Store : &:r199_1, r199_9 # 199| m199_12(int) = Store : &:r199_1, r199_9
@@ -856,7 +856,7 @@ ssa.cpp:
# 200| r200_2(glval<char *>) = VariableAddress[str1] : # 200| r200_2(glval<char *>) = VariableAddress[str1] :
# 200| r200_3(char *) = Load : &:r200_2, m198_6 # 200| r200_3(char *) = Load : &:r200_2, m198_6
# 200| r200_4(char *) = Convert : r200_3 # 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| v200_6(void) = ^BufferReadSideEffect[0] : &:r200_4, ~m198_8
# 200| r200_7(glval<int>) = VariableAddress[ret] : # 200| r200_7(glval<int>) = VariableAddress[ret] :
# 200| r200_8(int) = Load : &:r200_7, m199_12 # 200| r200_8(int) = Load : &:r200_7, m199_12
@@ -865,7 +865,7 @@ ssa.cpp:
# 201| r201_1(glval<unknown>) = FunctionAddress[abs] : # 201| r201_1(glval<unknown>) = FunctionAddress[abs] :
# 201| r201_2(glval<int>) = VariableAddress[x] : # 201| r201_2(glval<int>) = VariableAddress[x] :
# 201| r201_3(int) = Load : &:r201_2, m198_14 # 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_5(glval<int>) = VariableAddress[ret] :
# 201| r201_6(int) = Load : &:r201_5, m200_10 # 201| r201_6(int) = Load : &:r201_5, m200_10
# 201| r201_7(int) = Add : r201_6, r201_4 # 201| r201_7(int) = Add : r201_6, r201_4
@@ -901,7 +901,7 @@ ssa.cpp:
# 209| r209_6(int *) = CopyValue : r209_5 # 209| r209_6(int *) = CopyValue : r209_5
# 209| r209_7(void *) = Convert : r209_6 # 209| r209_7(void *) = Convert : r209_6
# 209| r209_8(int) = Constant[4] : # 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| v209_10(void) = ^SizedBufferReadSideEffect[1] : &:r209_7, r209_8, ~m207_6
# 209| m209_11(unknown) = ^SizedBufferMustWriteSideEffect[0] : &:r209_4, r209_8 # 209| m209_11(unknown) = ^SizedBufferMustWriteSideEffect[0] : &:r209_4, r209_8
# 209| m209_12(unknown) = Chi : total:m208_3, partial:m209_11 # 209| m209_12(unknown) = Chi : total:m208_3, partial:m209_11
@@ -988,7 +988,7 @@ ssa.cpp:
# 226| m226_3(unknown) = InitializeNonLocal : # 226| m226_3(unknown) = InitializeNonLocal :
# 226| m226_4(unknown) = Chi : total:m226_2, partial:m226_3 # 226| m226_4(unknown) = Chi : total:m226_2, partial:m226_3
# 227| r227_1(glval<unknown>) = FunctionAddress[ExternalFunc] : # 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_3(unknown) = ^CallSideEffect : ~m226_4
# 227| m227_4(unknown) = Chi : total:m226_4, partial:m227_3 # 227| m227_4(unknown) = Chi : total:m226_4, partial:m227_3
# 229| r229_1(glval<char *>) = VariableAddress[s] : # 229| r229_1(glval<char *>) = VariableAddress[s] :
@@ -1051,14 +1051,14 @@ ssa.cpp:
# 240| m240_2(Constructible) = Uninitialized[c] : &:r240_1 # 240| m240_2(Constructible) = Uninitialized[c] : &:r240_1
# 240| r240_3(glval<unknown>) = FunctionAddress[Constructible] : # 240| r240_3(glval<unknown>) = FunctionAddress[Constructible] :
# 240| r240_4(int) = Constant[1] : # 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_6(unknown) = ^CallSideEffect : ~m239_4
# 240| m240_7(unknown) = Chi : total:m239_4, partial:m240_6 # 240| m240_7(unknown) = Chi : total:m239_4, partial:m240_6
# 240| m240_8(Constructible) = ^IndirectMayWriteSideEffect[-1] : &:r240_1 # 240| m240_8(Constructible) = ^IndirectMayWriteSideEffect[-1] : &:r240_1
# 240| m240_9(Constructible) = Chi : total:m240_2, partial:m240_8 # 240| m240_9(Constructible) = Chi : total:m240_2, partial:m240_8
# 241| r241_1(glval<Constructible>) = VariableAddress[c] : # 241| r241_1(glval<Constructible>) = VariableAddress[c] :
# 241| r241_2(glval<unknown>) = FunctionAddress[g] : # 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_4(unknown) = ^CallSideEffect : ~m240_7
# 241| m241_5(unknown) = Chi : total:m240_7, partial:m241_4 # 241| m241_5(unknown) = Chi : total:m240_7, partial:m241_4
# 241| v241_6(void) = ^BufferReadSideEffect[-1] : &:r241_1, ~m240_9 # 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 # 241| m241_8(Constructible) = Chi : total:m240_9, partial:m241_7
# 242| r242_1(glval<Constructible>) = VariableAddress[c] : # 242| r242_1(glval<Constructible>) = VariableAddress[c] :
# 242| r242_2(glval<unknown>) = FunctionAddress[g] : # 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_4(unknown) = ^CallSideEffect : ~m241_5
# 242| m242_5(unknown) = Chi : total:m241_5, partial:m242_4 # 242| m242_5(unknown) = Chi : total:m241_5, partial:m242_4
# 242| v242_6(void) = ^BufferReadSideEffect[-1] : &:r242_1, ~m241_8 # 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| m243_2(Constructible) = Uninitialized[c2] : &:r243_1
# 243| r243_3(glval<unknown>) = FunctionAddress[Constructible] : # 243| r243_3(glval<unknown>) = FunctionAddress[Constructible] :
# 243| r243_4(int) = Constant[2] : # 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_6(unknown) = ^CallSideEffect : ~m242_5
# 243| m243_7(unknown) = Chi : total:m242_5, partial:m243_6 # 243| m243_7(unknown) = Chi : total:m242_5, partial:m243_6
# 243| m243_8(Constructible) = ^IndirectMayWriteSideEffect[-1] : &:r243_1 # 243| m243_8(Constructible) = ^IndirectMayWriteSideEffect[-1] : &:r243_1
# 243| m243_9(Constructible) = Chi : total:m243_2, partial:m243_8 # 243| m243_9(Constructible) = Chi : total:m243_2, partial:m243_8
# 244| r244_1(glval<Constructible>) = VariableAddress[c2] : # 244| r244_1(glval<Constructible>) = VariableAddress[c2] :
# 244| r244_2(glval<unknown>) = FunctionAddress[g] : # 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_4(unknown) = ^CallSideEffect : ~m243_7
# 244| m244_5(unknown) = Chi : total:m243_7, partial:m244_4 # 244| m244_5(unknown) = Chi : total:m243_7, partial:m244_4
# 244| v244_6(void) = ^BufferReadSideEffect[-1] : &:r244_1, ~m243_9 # 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_5(unsigned long) = Convert : r248_4
# 248| r248_6(unsigned long) = Constant[1] : # 248| r248_6(unsigned long) = Constant[1] :
# 248| r248_7(unsigned long) = Mul : r248_5, r248_6 # 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_9(unknown) = ^CallSideEffect : ~m247_9
# 248| m248_10(unknown) = Chi : total:m247_9, partial:m248_9 # 248| m248_10(unknown) = Chi : total:m247_9, partial:m248_9
# 248| m248_11(unknown) = ^InitializeDynamicAllocation : &:r248_8 # 248| m248_11(unknown) = ^InitializeDynamicAllocation : &:r248_8
@@ -1136,7 +1136,7 @@ ssa.cpp:
# 250| r250_7(void *) = Convert : r250_6 # 250| r250_7(void *) = Convert : r250_6
# 250| r250_8(glval<int>) = VariableAddress[size] : # 250| r250_8(glval<int>) = VariableAddress[size] :
# 250| r250_9(int) = Load : &:r250_8, m247_11 # 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| v250_11(void) = ^SizedBufferReadSideEffect[1] : &:r250_7, r250_9, ~m249_6
# 250| m250_12(unknown) = ^SizedBufferMustWriteSideEffect[0] : &:r250_4, r250_9 # 250| m250_12(unknown) = ^SizedBufferMustWriteSideEffect[0] : &:r250_4, r250_9
# 250| m250_13(unknown) = Chi : total:m249_6, partial:m250_12 # 250| m250_13(unknown) = Chi : total:m249_6, partial:m250_12
@@ -1166,14 +1166,14 @@ ssa.cpp:
# 256| Block 1 # 256| Block 1
# 256| r256_1(glval<unknown>) = FunctionAddress[ExternalFunc] : # 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_3(unknown) = ^CallSideEffect : ~m254_4
# 256| m256_4(unknown) = Chi : total:m254_4, partial:m256_3 # 256| m256_4(unknown) = Chi : total:m254_4, partial:m256_3
#-----| Goto -> Block 3 #-----| Goto -> Block 3
# 259| Block 2 # 259| Block 2
# 259| r259_1(glval<unknown>) = FunctionAddress[ExternalFunc] : # 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_3(unknown) = ^CallSideEffect : ~m254_4
# 259| m259_4(unknown) = Chi : total:m254_4, partial:m259_3 # 259| m259_4(unknown) = Chi : total:m254_4, partial:m259_3
#-----| Goto -> Block 3 #-----| Goto -> Block 3
@@ -1213,7 +1213,7 @@ ssa.cpp:
# 269| r269_2(glval<unknown>) = FunctionAddress[malloc] : # 269| r269_2(glval<unknown>) = FunctionAddress[malloc] :
# 269| r269_3(glval<int>) = VariableAddress[size] : # 269| r269_3(glval<int>) = VariableAddress[size] :
# 269| r269_4(int) = Load : &:r269_3, m268_11 # 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_6(unknown) = ^CallSideEffect : ~m268_9
# 269| m269_7(unknown) = Chi : total:m268_9, partial:m269_6 # 269| m269_7(unknown) = Chi : total:m268_9, partial:m269_6
# 269| m269_8(unknown) = ^InitializeDynamicAllocation : &:r269_5 # 269| m269_8(unknown) = ^InitializeDynamicAllocation : &:r269_5
@@ -1226,7 +1226,7 @@ ssa.cpp:
# 270| r270_5(void *) = Load : &:r270_4, m268_6 # 270| r270_5(void *) = Load : &:r270_4, m268_6
# 270| r270_6(glval<int>) = VariableAddress[size] : # 270| r270_6(glval<int>) = VariableAddress[size] :
# 270| r270_7(int) = Load : &:r270_6, m268_11 # 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| v270_9(void) = ^SizedBufferReadSideEffect[1] : &:r270_5, r270_7, ~m269_7
# 270| m270_10(unknown) = ^SizedBufferMustWriteSideEffect[0] : &:r270_3, r270_7 # 270| m270_10(unknown) = ^SizedBufferMustWriteSideEffect[0] : &:r270_3, r270_7
# 270| m270_11(unknown) = Chi : total:m269_9, partial:m270_10 # 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_1(glval<Point *>) = VariableAddress[p] :
# 292| r292_2(glval<unknown>) = FunctionAddress[operator new] : # 292| r292_2(glval<unknown>) = FunctionAddress[operator new] :
# 292| r292_3(unsigned long) = Constant[8] : # 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_5(unknown) = ^CallSideEffect : ~m291_4
# 292| m292_6(unknown) = Chi : total:m291_4, partial:m292_5 # 292| m292_6(unknown) = Chi : total:m291_4, partial:m292_5
# 292| m292_7(unknown) = ^InitializeDynamicAllocation : &:r292_4 # 292| m292_7(unknown) = ^InitializeDynamicAllocation : &:r292_4
@@ -1371,7 +1371,7 @@ ssa.cpp:
# 293| r293_1(glval<Point *>) = VariableAddress[q] : # 293| r293_1(glval<Point *>) = VariableAddress[q] :
# 293| r293_2(glval<unknown>) = FunctionAddress[operator new] : # 293| r293_2(glval<unknown>) = FunctionAddress[operator new] :
# 293| r293_3(unsigned long) = Constant[8] : # 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_5(unknown) = ^CallSideEffect : ~m292_6
# 293| m293_6(unknown) = Chi : total:m292_6, partial:m293_5 # 293| m293_6(unknown) = Chi : total:m292_6, partial:m293_5
# 293| m293_7(unknown) = ^InitializeDynamicAllocation : &:r293_4 # 293| m293_7(unknown) = ^InitializeDynamicAllocation : &:r293_4
@@ -1380,7 +1380,7 @@ ssa.cpp:
# 294| r294_1(glval<int>) = VariableAddress[j] : # 294| r294_1(glval<int>) = VariableAddress[j] :
# 294| r294_2(glval<unknown>) = FunctionAddress[operator new] : # 294| r294_2(glval<unknown>) = FunctionAddress[operator new] :
# 294| r294_3(unsigned long) = Constant[4] : # 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_5(unknown) = ^CallSideEffect : ~m293_6
# 294| m294_6(unknown) = Chi : total:m293_6, partial:m294_5 # 294| m294_6(unknown) = Chi : total:m293_6, partial:m294_5
# 294| m294_7(unknown) = ^InitializeDynamicAllocation : &:r294_4 # 294| m294_7(unknown) = ^InitializeDynamicAllocation : &:r294_4
@@ -1388,7 +1388,7 @@ ssa.cpp:
# 294| r294_9(glval<unknown>) = FunctionAddress[A] : # 294| r294_9(glval<unknown>) = FunctionAddress[A] :
# 294| r294_10(glval<unknown>) = FunctionAddress[operator new] : # 294| r294_10(glval<unknown>) = FunctionAddress[operator new] :
# 294| r294_11(unsigned long) = Constant[4] : # 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_13(unknown) = ^CallSideEffect : ~m294_6
# 294| m294_14(unknown) = Chi : total:m294_6, partial:m294_13 # 294| m294_14(unknown) = Chi : total:m294_6, partial:m294_13
# 294| m294_15(unknown) = ^InitializeDynamicAllocation : &:r294_12 # 294| m294_15(unknown) = ^InitializeDynamicAllocation : &:r294_12
@@ -1396,12 +1396,12 @@ ssa.cpp:
# 294| r294_17(glval<unknown>) = FunctionAddress[A] : # 294| r294_17(glval<unknown>) = FunctionAddress[A] :
# 294| r294_18(glval<int>) = VariableAddress[x] : # 294| r294_18(glval<int>) = VariableAddress[x] :
# 294| r294_19(int) = Load : &:r294_18, m291_6 # 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_21(unknown) = ^CallSideEffect : ~m294_14
# 294| m294_22(unknown) = Chi : total:m294_14, partial:m294_21 # 294| m294_22(unknown) = Chi : total:m294_14, partial:m294_21
# 294| m294_23(A) = ^IndirectMayWriteSideEffect[-1] : &:r294_16 # 294| m294_23(A) = ^IndirectMayWriteSideEffect[-1] : &:r294_16
# 294| m294_24(unknown) = Chi : total:m294_15, partial:m294_23 # 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_26(unknown) = ^CallSideEffect : ~m294_22
# 294| m294_27(unknown) = Chi : total:m294_22, partial:m294_26 # 294| m294_27(unknown) = Chi : total:m294_22, partial:m294_26
# 294| m294_28(A) = ^IndirectMayWriteSideEffect[-1] : &:r294_8 # 294| m294_28(A) = ^IndirectMayWriteSideEffect[-1] : &:r294_8
@@ -1415,13 +1415,13 @@ ssa.cpp:
# 295| r295_1(glval<A *>) = VariableAddress[a] : # 295| r295_1(glval<A *>) = VariableAddress[a] :
# 295| r295_2(glval<unknown>) = FunctionAddress[operator new] : # 295| r295_2(glval<unknown>) = FunctionAddress[operator new] :
# 295| r295_3(unsigned long) = Constant[4] : # 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_5(unknown) = ^CallSideEffect : ~m294_27
# 295| m295_6(unknown) = Chi : total:m294_27, partial:m295_5 # 295| m295_6(unknown) = Chi : total:m294_27, partial:m295_5
# 295| m295_7(unknown) = ^InitializeDynamicAllocation : &:r295_4 # 295| m295_7(unknown) = ^InitializeDynamicAllocation : &:r295_4
# 295| r295_8(A *) = Convert : r295_4 # 295| r295_8(A *) = Convert : r295_4
# 295| r295_9(glval<unknown>) = FunctionAddress[A] : # 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_11(unknown) = ^CallSideEffect : ~m295_6
# 295| m295_12(unknown) = Chi : total:m295_6, partial:m295_11 # 295| m295_12(unknown) = Chi : total:m295_6, partial:m295_11
# 295| m295_13(A) = ^IndirectMayWriteSideEffect[-1] : &:r295_8 # 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_3(int) = Load : &:r302_2, m301_6
# 302| r302_4(glval<char **>) = VariableAddress[argv] : # 302| r302_4(glval<char **>) = VariableAddress[argv] :
# 302| r302_5(char **) = Load : &:r302_4, m301_8 # 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_7(unknown) = ^CallSideEffect : ~m301_11
# 302| m302_8(unknown) = Chi : total:m301_11, partial:m302_7 # 302| m302_8(unknown) = Chi : total:m301_11, partial:m302_7
# 302| v302_9(void) = ^BufferReadSideEffect[1] : &:r302_5, ~m302_8 # 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_3(int) = Load : &:r303_2, m301_6
# 303| r303_4(glval<char **>) = VariableAddress[argv] : # 303| r303_4(glval<char **>) = VariableAddress[argv] :
# 303| r303_5(char **) = Load : &:r303_4, m301_8 # 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_7(unknown) = ^CallSideEffect : ~m302_11
# 303| m303_8(unknown) = Chi : total:m302_11, partial:m303_7 # 303| m303_8(unknown) = Chi : total:m302_11, partial:m303_7
# 303| v303_9(void) = ^BufferReadSideEffect[1] : &:r303_5, ~m303_8 # 303| v303_9(void) = ^BufferReadSideEffect[1] : &:r303_5, ~m303_8

View File

@@ -345,7 +345,7 @@ ssa.cpp:
# 97| r97_2(glval<Point>) = VariableAddress[a] : # 97| r97_2(glval<Point>) = VariableAddress[a] :
# 97| r97_3(Point *) = CopyValue : r97_2 # 97| r97_3(Point *) = CopyValue : r97_2
# 97| r97_4(void *) = Convert : r97_3 # 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_6(unknown) = ^CallSideEffect : ~m95_4
# 97| m97_7(unknown) = Chi : total:m95_4, partial:m97_6 # 97| m97_7(unknown) = Chi : total:m95_4, partial:m97_6
# 97| v97_8(void) = ^BufferReadSideEffect[0] : &:r97_4, ~m95_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_2(glval<Point>) = VariableAddress[a] :
# 108| r108_3(Point *) = CopyValue : r108_2 # 108| r108_3(Point *) = CopyValue : r108_2
# 108| r108_4(void *) = Convert : r108_3 # 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_6(unknown) = ^CallSideEffect : ~m105_4
# 108| m108_7(unknown) = Chi : total:m105_4, partial:m108_6 # 108| m108_7(unknown) = Chi : total:m105_4, partial:m108_6
# 108| v108_8(void) = ^BufferReadSideEffect[0] : &:r108_4, ~m105_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_2(glval<Point>) = VariableAddress[a] :
# 119| r119_3(Point *) = CopyValue : r119_2 # 119| r119_3(Point *) = CopyValue : r119_2
# 119| r119_4(void *) = Convert : r119_3 # 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_6(unknown) = ^CallSideEffect : ~m116_4
# 119| m119_7(unknown) = Chi : total:m116_4, partial:m119_6 # 119| m119_7(unknown) = Chi : total:m116_4, partial:m119_6
# 119| v119_8(void) = ^BufferReadSideEffect[0] : &:r119_4, ~m117_12 # 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_6(glval<char *>) = VariableAddress[str2] :
# 199| r199_7(char *) = Load : &:r199_6, m198_10 # 199| r199_7(char *) = Load : &:r199_6, m198_10
# 199| r199_8(char *) = Convert : r199_7 # 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_10(void) = ^BufferReadSideEffect[0] : &:r199_5, ~m198_8
# 199| v199_11(void) = ^BufferReadSideEffect[1] : &:r199_8, ~m198_12 # 199| v199_11(void) = ^BufferReadSideEffect[1] : &:r199_8, ~m198_12
# 199| m199_12(int) = Store : &:r199_1, r199_9 # 199| m199_12(int) = Store : &:r199_1, r199_9
@@ -851,7 +851,7 @@ ssa.cpp:
# 200| r200_2(glval<char *>) = VariableAddress[str1] : # 200| r200_2(glval<char *>) = VariableAddress[str1] :
# 200| r200_3(char *) = Load : &:r200_2, m198_6 # 200| r200_3(char *) = Load : &:r200_2, m198_6
# 200| r200_4(char *) = Convert : r200_3 # 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| v200_6(void) = ^BufferReadSideEffect[0] : &:r200_4, ~m198_8
# 200| r200_7(glval<int>) = VariableAddress[ret] : # 200| r200_7(glval<int>) = VariableAddress[ret] :
# 200| r200_8(int) = Load : &:r200_7, m199_12 # 200| r200_8(int) = Load : &:r200_7, m199_12
@@ -860,7 +860,7 @@ ssa.cpp:
# 201| r201_1(glval<unknown>) = FunctionAddress[abs] : # 201| r201_1(glval<unknown>) = FunctionAddress[abs] :
# 201| r201_2(glval<int>) = VariableAddress[x] : # 201| r201_2(glval<int>) = VariableAddress[x] :
# 201| r201_3(int) = Load : &:r201_2, m198_14 # 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_5(glval<int>) = VariableAddress[ret] :
# 201| r201_6(int) = Load : &:r201_5, m200_10 # 201| r201_6(int) = Load : &:r201_5, m200_10
# 201| r201_7(int) = Add : r201_6, r201_4 # 201| r201_7(int) = Add : r201_6, r201_4
@@ -894,7 +894,7 @@ ssa.cpp:
# 209| r209_6(int *) = CopyValue : r209_5 # 209| r209_6(int *) = CopyValue : r209_5
# 209| r209_7(void *) = Convert : r209_6 # 209| r209_7(void *) = Convert : r209_6
# 209| r209_8(int) = Constant[4] : # 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| v209_10(void) = ^SizedBufferReadSideEffect[1] : &:r209_7, r209_8, ~m207_6
# 209| m209_11(unknown) = ^SizedBufferMustWriteSideEffect[0] : &:r209_4, r209_8 # 209| m209_11(unknown) = ^SizedBufferMustWriteSideEffect[0] : &:r209_4, r209_8
# 209| m209_12(int) = Chi : total:m208_2, partial:m209_11 # 209| m209_12(int) = Chi : total:m208_2, partial:m209_11
@@ -981,7 +981,7 @@ ssa.cpp:
# 226| m226_3(unknown) = InitializeNonLocal : # 226| m226_3(unknown) = InitializeNonLocal :
# 226| m226_4(unknown) = Chi : total:m226_2, partial:m226_3 # 226| m226_4(unknown) = Chi : total:m226_2, partial:m226_3
# 227| r227_1(glval<unknown>) = FunctionAddress[ExternalFunc] : # 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_3(unknown) = ^CallSideEffect : ~m226_4
# 227| m227_4(unknown) = Chi : total:m226_4, partial:m227_3 # 227| m227_4(unknown) = Chi : total:m226_4, partial:m227_3
# 229| r229_1(glval<char *>) = VariableAddress[s] : # 229| r229_1(glval<char *>) = VariableAddress[s] :
@@ -1044,14 +1044,14 @@ ssa.cpp:
# 240| m240_2(Constructible) = Uninitialized[c] : &:r240_1 # 240| m240_2(Constructible) = Uninitialized[c] : &:r240_1
# 240| r240_3(glval<unknown>) = FunctionAddress[Constructible] : # 240| r240_3(glval<unknown>) = FunctionAddress[Constructible] :
# 240| r240_4(int) = Constant[1] : # 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_6(unknown) = ^CallSideEffect : ~m239_4
# 240| m240_7(unknown) = Chi : total:m239_4, partial:m240_6 # 240| m240_7(unknown) = Chi : total:m239_4, partial:m240_6
# 240| m240_8(Constructible) = ^IndirectMayWriteSideEffect[-1] : &:r240_1 # 240| m240_8(Constructible) = ^IndirectMayWriteSideEffect[-1] : &:r240_1
# 240| m240_9(Constructible) = Chi : total:m240_2, partial:m240_8 # 240| m240_9(Constructible) = Chi : total:m240_2, partial:m240_8
# 241| r241_1(glval<Constructible>) = VariableAddress[c] : # 241| r241_1(glval<Constructible>) = VariableAddress[c] :
# 241| r241_2(glval<unknown>) = FunctionAddress[g] : # 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_4(unknown) = ^CallSideEffect : ~m240_7
# 241| m241_5(unknown) = Chi : total:m240_7, partial:m241_4 # 241| m241_5(unknown) = Chi : total:m240_7, partial:m241_4
# 241| v241_6(void) = ^BufferReadSideEffect[-1] : &:r241_1, ~m240_9 # 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 # 241| m241_8(Constructible) = Chi : total:m240_9, partial:m241_7
# 242| r242_1(glval<Constructible>) = VariableAddress[c] : # 242| r242_1(glval<Constructible>) = VariableAddress[c] :
# 242| r242_2(glval<unknown>) = FunctionAddress[g] : # 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_4(unknown) = ^CallSideEffect : ~m241_5
# 242| m242_5(unknown) = Chi : total:m241_5, partial:m242_4 # 242| m242_5(unknown) = Chi : total:m241_5, partial:m242_4
# 242| v242_6(void) = ^BufferReadSideEffect[-1] : &:r242_1, ~m241_8 # 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| m243_2(Constructible) = Uninitialized[c2] : &:r243_1
# 243| r243_3(glval<unknown>) = FunctionAddress[Constructible] : # 243| r243_3(glval<unknown>) = FunctionAddress[Constructible] :
# 243| r243_4(int) = Constant[2] : # 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_6(unknown) = ^CallSideEffect : ~m242_5
# 243| m243_7(unknown) = Chi : total:m242_5, partial:m243_6 # 243| m243_7(unknown) = Chi : total:m242_5, partial:m243_6
# 243| m243_8(Constructible) = ^IndirectMayWriteSideEffect[-1] : &:r243_1 # 243| m243_8(Constructible) = ^IndirectMayWriteSideEffect[-1] : &:r243_1
# 243| m243_9(Constructible) = Chi : total:m243_2, partial:m243_8 # 243| m243_9(Constructible) = Chi : total:m243_2, partial:m243_8
# 244| r244_1(glval<Constructible>) = VariableAddress[c2] : # 244| r244_1(glval<Constructible>) = VariableAddress[c2] :
# 244| r244_2(glval<unknown>) = FunctionAddress[g] : # 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_4(unknown) = ^CallSideEffect : ~m243_7
# 244| m244_5(unknown) = Chi : total:m243_7, partial:m244_4 # 244| m244_5(unknown) = Chi : total:m243_7, partial:m244_4
# 244| v244_6(void) = ^BufferReadSideEffect[-1] : &:r244_1, ~m243_9 # 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_5(unsigned long) = Convert : r248_4
# 248| r248_6(unsigned long) = Constant[1] : # 248| r248_6(unsigned long) = Constant[1] :
# 248| r248_7(unsigned long) = Mul : r248_5, r248_6 # 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_9(unknown) = ^CallSideEffect : ~m247_4
# 248| m248_10(unknown) = Chi : total:m247_4, partial:m248_9 # 248| m248_10(unknown) = Chi : total:m247_4, partial:m248_9
# 248| m248_11(unknown) = ^InitializeDynamicAllocation : &:r248_8 # 248| m248_11(unknown) = ^InitializeDynamicAllocation : &:r248_8
@@ -1127,7 +1127,7 @@ ssa.cpp:
# 250| r250_7(void *) = Convert : r250_6 # 250| r250_7(void *) = Convert : r250_6
# 250| r250_8(glval<int>) = VariableAddress[size] : # 250| r250_8(glval<int>) = VariableAddress[size] :
# 250| r250_9(int) = Load : &:r250_8, m247_10 # 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| v250_11(void) = ^SizedBufferReadSideEffect[1] : &:r250_7, r250_9, ~m249_6
# 250| m250_12(unknown) = ^SizedBufferMustWriteSideEffect[0] : &:r250_4, r250_9 # 250| m250_12(unknown) = ^SizedBufferMustWriteSideEffect[0] : &:r250_4, r250_9
# 250| m250_13(unknown) = Chi : total:m248_11, partial:m250_12 # 250| m250_13(unknown) = Chi : total:m248_11, partial:m250_12
@@ -1157,14 +1157,14 @@ ssa.cpp:
# 256| Block 1 # 256| Block 1
# 256| r256_1(glval<unknown>) = FunctionAddress[ExternalFunc] : # 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_3(unknown) = ^CallSideEffect : ~m254_4
# 256| m256_4(unknown) = Chi : total:m254_4, partial:m256_3 # 256| m256_4(unknown) = Chi : total:m254_4, partial:m256_3
#-----| Goto -> Block 3 #-----| Goto -> Block 3
# 259| Block 2 # 259| Block 2
# 259| r259_1(glval<unknown>) = FunctionAddress[ExternalFunc] : # 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_3(unknown) = ^CallSideEffect : ~m254_4
# 259| m259_4(unknown) = Chi : total:m254_4, partial:m259_3 # 259| m259_4(unknown) = Chi : total:m254_4, partial:m259_3
#-----| Goto -> Block 3 #-----| Goto -> Block 3
@@ -1203,7 +1203,7 @@ ssa.cpp:
# 269| r269_2(glval<unknown>) = FunctionAddress[malloc] : # 269| r269_2(glval<unknown>) = FunctionAddress[malloc] :
# 269| r269_3(glval<int>) = VariableAddress[size] : # 269| r269_3(glval<int>) = VariableAddress[size] :
# 269| r269_4(int) = Load : &:r269_3, m268_10 # 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_6(unknown) = ^CallSideEffect : ~m268_4
# 269| m269_7(unknown) = Chi : total:m268_4, partial:m269_6 # 269| m269_7(unknown) = Chi : total:m268_4, partial:m269_6
# 269| m269_8(unknown) = ^InitializeDynamicAllocation : &:r269_5 # 269| m269_8(unknown) = ^InitializeDynamicAllocation : &:r269_5
@@ -1215,7 +1215,7 @@ ssa.cpp:
# 270| r270_5(void *) = Load : &:r270_4, m268_6 # 270| r270_5(void *) = Load : &:r270_4, m268_6
# 270| r270_6(glval<int>) = VariableAddress[size] : # 270| r270_6(glval<int>) = VariableAddress[size] :
# 270| r270_7(int) = Load : &:r270_6, m268_10 # 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| v270_9(void) = ^SizedBufferReadSideEffect[1] : &:r270_5, r270_7, ~m268_8
# 270| m270_10(unknown) = ^SizedBufferMustWriteSideEffect[0] : &:r270_3, r270_7 # 270| m270_10(unknown) = ^SizedBufferMustWriteSideEffect[0] : &:r270_3, r270_7
# 270| m270_11(unknown) = Chi : total:m269_8, partial:m270_10 # 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_1(glval<Point *>) = VariableAddress[p] :
# 292| r292_2(glval<unknown>) = FunctionAddress[operator new] : # 292| r292_2(glval<unknown>) = FunctionAddress[operator new] :
# 292| r292_3(unsigned long) = Constant[8] : # 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_5(unknown) = ^CallSideEffect : ~m291_4
# 292| m292_6(unknown) = Chi : total:m291_4, partial:m292_5 # 292| m292_6(unknown) = Chi : total:m291_4, partial:m292_5
# 292| m292_7(unknown) = ^InitializeDynamicAllocation : &:r292_4 # 292| m292_7(unknown) = ^InitializeDynamicAllocation : &:r292_4
@@ -1359,7 +1359,7 @@ ssa.cpp:
# 293| r293_1(glval<Point *>) = VariableAddress[q] : # 293| r293_1(glval<Point *>) = VariableAddress[q] :
# 293| r293_2(glval<unknown>) = FunctionAddress[operator new] : # 293| r293_2(glval<unknown>) = FunctionAddress[operator new] :
# 293| r293_3(unsigned long) = Constant[8] : # 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_5(unknown) = ^CallSideEffect : ~m292_6
# 293| m293_6(unknown) = Chi : total:m292_6, partial:m293_5 # 293| m293_6(unknown) = Chi : total:m292_6, partial:m293_5
# 293| m293_7(unknown) = ^InitializeDynamicAllocation : &:r293_4 # 293| m293_7(unknown) = ^InitializeDynamicAllocation : &:r293_4
@@ -1368,7 +1368,7 @@ ssa.cpp:
# 294| r294_1(glval<int>) = VariableAddress[j] : # 294| r294_1(glval<int>) = VariableAddress[j] :
# 294| r294_2(glval<unknown>) = FunctionAddress[operator new] : # 294| r294_2(glval<unknown>) = FunctionAddress[operator new] :
# 294| r294_3(unsigned long) = Constant[4] : # 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_5(unknown) = ^CallSideEffect : ~m293_6
# 294| m294_6(unknown) = Chi : total:m293_6, partial:m294_5 # 294| m294_6(unknown) = Chi : total:m293_6, partial:m294_5
# 294| m294_7(unknown) = ^InitializeDynamicAllocation : &:r294_4 # 294| m294_7(unknown) = ^InitializeDynamicAllocation : &:r294_4
@@ -1376,7 +1376,7 @@ ssa.cpp:
# 294| r294_9(glval<unknown>) = FunctionAddress[A] : # 294| r294_9(glval<unknown>) = FunctionAddress[A] :
# 294| r294_10(glval<unknown>) = FunctionAddress[operator new] : # 294| r294_10(glval<unknown>) = FunctionAddress[operator new] :
# 294| r294_11(unsigned long) = Constant[4] : # 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_13(unknown) = ^CallSideEffect : ~m294_6
# 294| m294_14(unknown) = Chi : total:m294_6, partial:m294_13 # 294| m294_14(unknown) = Chi : total:m294_6, partial:m294_13
# 294| m294_15(unknown) = ^InitializeDynamicAllocation : &:r294_12 # 294| m294_15(unknown) = ^InitializeDynamicAllocation : &:r294_12
@@ -1384,12 +1384,12 @@ ssa.cpp:
# 294| r294_17(glval<unknown>) = FunctionAddress[A] : # 294| r294_17(glval<unknown>) = FunctionAddress[A] :
# 294| r294_18(glval<int>) = VariableAddress[x] : # 294| r294_18(glval<int>) = VariableAddress[x] :
# 294| r294_19(int) = Load : &:r294_18, m291_6 # 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_21(unknown) = ^CallSideEffect : ~m294_14
# 294| m294_22(unknown) = Chi : total:m294_14, partial:m294_21 # 294| m294_22(unknown) = Chi : total:m294_14, partial:m294_21
# 294| m294_23(A) = ^IndirectMayWriteSideEffect[-1] : &:r294_16 # 294| m294_23(A) = ^IndirectMayWriteSideEffect[-1] : &:r294_16
# 294| m294_24(unknown) = Chi : total:m294_15, partial:m294_23 # 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_26(unknown) = ^CallSideEffect : ~m294_22
# 294| m294_27(unknown) = Chi : total:m294_22, partial:m294_26 # 294| m294_27(unknown) = Chi : total:m294_22, partial:m294_26
# 294| m294_28(A) = ^IndirectMayWriteSideEffect[-1] : &:r294_8 # 294| m294_28(A) = ^IndirectMayWriteSideEffect[-1] : &:r294_8
@@ -1403,13 +1403,13 @@ ssa.cpp:
# 295| r295_1(glval<A *>) = VariableAddress[a] : # 295| r295_1(glval<A *>) = VariableAddress[a] :
# 295| r295_2(glval<unknown>) = FunctionAddress[operator new] : # 295| r295_2(glval<unknown>) = FunctionAddress[operator new] :
# 295| r295_3(unsigned long) = Constant[4] : # 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_5(unknown) = ^CallSideEffect : ~m294_27
# 295| m295_6(unknown) = Chi : total:m294_27, partial:m295_5 # 295| m295_6(unknown) = Chi : total:m294_27, partial:m295_5
# 295| m295_7(unknown) = ^InitializeDynamicAllocation : &:r295_4 # 295| m295_7(unknown) = ^InitializeDynamicAllocation : &:r295_4
# 295| r295_8(A *) = Convert : r295_4 # 295| r295_8(A *) = Convert : r295_4
# 295| r295_9(glval<unknown>) = FunctionAddress[A] : # 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_11(unknown) = ^CallSideEffect : ~m295_6
# 295| m295_12(unknown) = Chi : total:m295_6, partial:m295_11 # 295| m295_12(unknown) = Chi : total:m295_6, partial:m295_11
# 295| m295_13(A) = ^IndirectMayWriteSideEffect[-1] : &:r295_8 # 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_3(int) = Load : &:r302_2, m301_6
# 302| r302_4(glval<char **>) = VariableAddress[argv] : # 302| r302_4(glval<char **>) = VariableAddress[argv] :
# 302| r302_5(char **) = Load : &:r302_4, m301_8 # 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_7(unknown) = ^CallSideEffect : ~m301_4
# 302| m302_8(unknown) = Chi : total:m301_4, partial:m302_7 # 302| m302_8(unknown) = Chi : total:m301_4, partial:m302_7
# 302| v302_9(void) = ^BufferReadSideEffect[1] : &:r302_5, ~m301_10 # 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_3(int) = Load : &:r303_2, m301_6
# 303| r303_4(glval<char **>) = VariableAddress[argv] : # 303| r303_4(glval<char **>) = VariableAddress[argv] :
# 303| r303_5(char **) = Load : &:r303_4, m301_8 # 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_7(unknown) = ^CallSideEffect : ~m302_8
# 303| m303_8(unknown) = Chi : total:m302_8, partial:m303_7 # 303| m303_8(unknown) = Chi : total:m302_8, partial:m303_7
# 303| v303_9(void) = ^BufferReadSideEffect[1] : &:r303_5, ~m302_11 # 303| v303_9(void) = ^BufferReadSideEffect[1] : &:r303_5, ~m302_11

View File

@@ -334,7 +334,7 @@ ssa.cpp:
# 97| r97_2(glval<Point>) = VariableAddress[a] : # 97| r97_2(glval<Point>) = VariableAddress[a] :
# 97| r97_3(Point *) = CopyValue : r97_2 # 97| r97_3(Point *) = CopyValue : r97_2
# 97| r97_4(void *) = Convert : r97_3 # 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| mu97_6(unknown) = ^CallSideEffect : ~m?
# 97| v97_7(void) = ^BufferReadSideEffect[0] : &:r97_4, ~m? # 97| v97_7(void) = ^BufferReadSideEffect[0] : &:r97_4, ~m?
# 97| mu97_8(unknown) = ^BufferMayWriteSideEffect[0] : &:r97_4 # 97| mu97_8(unknown) = ^BufferMayWriteSideEffect[0] : &:r97_4
@@ -386,7 +386,7 @@ ssa.cpp:
# 108| r108_2(glval<Point>) = VariableAddress[a] : # 108| r108_2(glval<Point>) = VariableAddress[a] :
# 108| r108_3(Point *) = CopyValue : r108_2 # 108| r108_3(Point *) = CopyValue : r108_2
# 108| r108_4(void *) = Convert : r108_3 # 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| mu108_6(unknown) = ^CallSideEffect : ~m?
# 108| v108_7(void) = ^BufferReadSideEffect[0] : &:r108_4, ~m? # 108| v108_7(void) = ^BufferReadSideEffect[0] : &:r108_4, ~m?
# 108| mu108_8(unknown) = ^BufferMayWriteSideEffect[0] : &:r108_4 # 108| mu108_8(unknown) = ^BufferMayWriteSideEffect[0] : &:r108_4
@@ -450,7 +450,7 @@ ssa.cpp:
# 119| r119_2(glval<Point>) = VariableAddress[a] : # 119| r119_2(glval<Point>) = VariableAddress[a] :
# 119| r119_3(Point *) = CopyValue : r119_2 # 119| r119_3(Point *) = CopyValue : r119_2
# 119| r119_4(void *) = Convert : r119_3 # 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| mu119_6(unknown) = ^CallSideEffect : ~m?
# 119| v119_7(void) = ^BufferReadSideEffect[0] : &:r119_4, ~m? # 119| v119_7(void) = ^BufferReadSideEffect[0] : &:r119_4, ~m?
# 119| mu119_8(unknown) = ^BufferMayWriteSideEffect[0] : &:r119_4 # 119| mu119_8(unknown) = ^BufferMayWriteSideEffect[0] : &:r119_4
@@ -789,7 +789,7 @@ ssa.cpp:
# 199| r199_6(glval<char *>) = VariableAddress[str2] : # 199| r199_6(glval<char *>) = VariableAddress[str2] :
# 199| r199_7(char *) = Load : &:r199_6, m198_9 # 199| r199_7(char *) = Load : &:r199_6, m198_9
# 199| r199_8(char *) = Convert : r199_7 # 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_10(void) = ^BufferReadSideEffect[0] : &:r199_5, ~m?
# 199| v199_11(void) = ^BufferReadSideEffect[1] : &:r199_8, ~m? # 199| v199_11(void) = ^BufferReadSideEffect[1] : &:r199_8, ~m?
# 199| m199_12(int) = Store : &:r199_1, r199_9 # 199| m199_12(int) = Store : &:r199_1, r199_9
@@ -797,7 +797,7 @@ ssa.cpp:
# 200| r200_2(glval<char *>) = VariableAddress[str1] : # 200| r200_2(glval<char *>) = VariableAddress[str1] :
# 200| r200_3(char *) = Load : &:r200_2, m198_5 # 200| r200_3(char *) = Load : &:r200_2, m198_5
# 200| r200_4(char *) = Convert : r200_3 # 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| v200_6(void) = ^BufferReadSideEffect[0] : &:r200_4, ~m?
# 200| r200_7(glval<int>) = VariableAddress[ret] : # 200| r200_7(glval<int>) = VariableAddress[ret] :
# 200| r200_8(int) = Load : &:r200_7, m199_12 # 200| r200_8(int) = Load : &:r200_7, m199_12
@@ -806,7 +806,7 @@ ssa.cpp:
# 201| r201_1(glval<unknown>) = FunctionAddress[abs] : # 201| r201_1(glval<unknown>) = FunctionAddress[abs] :
# 201| r201_2(glval<int>) = VariableAddress[x] : # 201| r201_2(glval<int>) = VariableAddress[x] :
# 201| r201_3(int) = Load : &:r201_2, m198_13 # 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_5(glval<int>) = VariableAddress[ret] :
# 201| r201_6(int) = Load : &:r201_5, m200_10 # 201| r201_6(int) = Load : &:r201_5, m200_10
# 201| r201_7(int) = Add : r201_6, r201_4 # 201| r201_7(int) = Add : r201_6, r201_4
@@ -839,7 +839,7 @@ ssa.cpp:
# 209| r209_6(int *) = CopyValue : r209_5 # 209| r209_6(int *) = CopyValue : r209_5
# 209| r209_7(void *) = Convert : r209_6 # 209| r209_7(void *) = Convert : r209_6
# 209| r209_8(int) = Constant[4] : # 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| v209_10(void) = ^SizedBufferReadSideEffect[1] : &:r209_7, r209_8, ~m?
# 209| mu209_11(unknown) = ^SizedBufferMustWriteSideEffect[0] : &:r209_4, r209_8 # 209| mu209_11(unknown) = ^SizedBufferMustWriteSideEffect[0] : &:r209_4, r209_8
# 210| r210_1(glval<int>) = VariableAddress[#return] : # 210| r210_1(glval<int>) = VariableAddress[#return] :
@@ -917,7 +917,7 @@ ssa.cpp:
# 226| mu226_2(unknown) = AliasedDefinition : # 226| mu226_2(unknown) = AliasedDefinition :
# 226| mu226_3(unknown) = InitializeNonLocal : # 226| mu226_3(unknown) = InitializeNonLocal :
# 227| r227_1(glval<unknown>) = FunctionAddress[ExternalFunc] : # 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? # 227| mu227_3(unknown) = ^CallSideEffect : ~m?
# 229| r229_1(glval<char *>) = VariableAddress[s] : # 229| r229_1(glval<char *>) = VariableAddress[s] :
# 229| r229_2(glval<char[8]>) = StringConstant["Literal"] : # 229| r229_2(glval<char[8]>) = StringConstant["Literal"] :
@@ -976,18 +976,18 @@ ssa.cpp:
# 240| mu240_2(Constructible) = Uninitialized[c] : &:r240_1 # 240| mu240_2(Constructible) = Uninitialized[c] : &:r240_1
# 240| r240_3(glval<unknown>) = FunctionAddress[Constructible] : # 240| r240_3(glval<unknown>) = FunctionAddress[Constructible] :
# 240| r240_4(int) = Constant[1] : # 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_6(unknown) = ^CallSideEffect : ~m?
# 240| mu240_7(Constructible) = ^IndirectMayWriteSideEffect[-1] : &:r240_1 # 240| mu240_7(Constructible) = ^IndirectMayWriteSideEffect[-1] : &:r240_1
# 241| r241_1(glval<Constructible>) = VariableAddress[c] : # 241| r241_1(glval<Constructible>) = VariableAddress[c] :
# 241| r241_2(glval<unknown>) = FunctionAddress[g] : # 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| mu241_4(unknown) = ^CallSideEffect : ~m?
# 241| v241_5(void) = ^BufferReadSideEffect[-1] : &:r241_1, ~m? # 241| v241_5(void) = ^BufferReadSideEffect[-1] : &:r241_1, ~m?
# 241| mu241_6(Constructible) = ^IndirectMayWriteSideEffect[-1] : &:r241_1 # 241| mu241_6(Constructible) = ^IndirectMayWriteSideEffect[-1] : &:r241_1
# 242| r242_1(glval<Constructible>) = VariableAddress[c] : # 242| r242_1(glval<Constructible>) = VariableAddress[c] :
# 242| r242_2(glval<unknown>) = FunctionAddress[g] : # 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| mu242_4(unknown) = ^CallSideEffect : ~m?
# 242| v242_5(void) = ^BufferReadSideEffect[-1] : &:r242_1, ~m? # 242| v242_5(void) = ^BufferReadSideEffect[-1] : &:r242_1, ~m?
# 242| mu242_6(Constructible) = ^IndirectMayWriteSideEffect[-1] : &:r242_1 # 242| mu242_6(Constructible) = ^IndirectMayWriteSideEffect[-1] : &:r242_1
@@ -995,12 +995,12 @@ ssa.cpp:
# 243| mu243_2(Constructible) = Uninitialized[c2] : &:r243_1 # 243| mu243_2(Constructible) = Uninitialized[c2] : &:r243_1
# 243| r243_3(glval<unknown>) = FunctionAddress[Constructible] : # 243| r243_3(glval<unknown>) = FunctionAddress[Constructible] :
# 243| r243_4(int) = Constant[2] : # 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_6(unknown) = ^CallSideEffect : ~m?
# 243| mu243_7(Constructible) = ^IndirectMayWriteSideEffect[-1] : &:r243_1 # 243| mu243_7(Constructible) = ^IndirectMayWriteSideEffect[-1] : &:r243_1
# 244| r244_1(glval<Constructible>) = VariableAddress[c2] : # 244| r244_1(glval<Constructible>) = VariableAddress[c2] :
# 244| r244_2(glval<unknown>) = FunctionAddress[g] : # 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| mu244_4(unknown) = ^CallSideEffect : ~m?
# 244| v244_5(void) = ^BufferReadSideEffect[-1] : &:r244_1, ~m? # 244| v244_5(void) = ^BufferReadSideEffect[-1] : &:r244_1, ~m?
# 244| mu244_6(Constructible) = ^IndirectMayWriteSideEffect[-1] : &:r244_1 # 244| mu244_6(Constructible) = ^IndirectMayWriteSideEffect[-1] : &:r244_1
@@ -1027,7 +1027,7 @@ ssa.cpp:
# 248| r248_5(unsigned long) = Convert : r248_4 # 248| r248_5(unsigned long) = Convert : r248_4
# 248| r248_6(unsigned long) = Constant[1] : # 248| r248_6(unsigned long) = Constant[1] :
# 248| r248_7(unsigned long) = Mul : r248_5, r248_6 # 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_9(unknown) = ^CallSideEffect : ~m?
# 248| mu248_10(unknown) = ^InitializeDynamicAllocation : &:r248_8 # 248| mu248_10(unknown) = ^InitializeDynamicAllocation : &:r248_8
# 248| r248_11(char *) = Convert : r248_8 # 248| r248_11(char *) = Convert : r248_8
@@ -1046,7 +1046,7 @@ ssa.cpp:
# 250| r250_7(void *) = Convert : r250_6 # 250| r250_7(void *) = Convert : r250_6
# 250| r250_8(glval<int>) = VariableAddress[size] : # 250| r250_8(glval<int>) = VariableAddress[size] :
# 250| r250_9(int) = Load : &:r250_8, m247_9 # 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| v250_11(void) = ^SizedBufferReadSideEffect[1] : &:r250_7, r250_9, ~m?
# 250| mu250_12(unknown) = ^SizedBufferMustWriteSideEffect[0] : &:r250_4, r250_9 # 250| mu250_12(unknown) = ^SizedBufferMustWriteSideEffect[0] : &:r250_4, r250_9
# 251| r251_1(glval<char *>) = VariableAddress[#return] : # 251| r251_1(glval<char *>) = VariableAddress[#return] :
@@ -1074,13 +1074,13 @@ ssa.cpp:
# 256| Block 1 # 256| Block 1
# 256| r256_1(glval<unknown>) = FunctionAddress[ExternalFunc] : # 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? # 256| mu256_3(unknown) = ^CallSideEffect : ~m?
#-----| Goto -> Block 3 #-----| Goto -> Block 3
# 259| Block 2 # 259| Block 2
# 259| r259_1(glval<unknown>) = FunctionAddress[ExternalFunc] : # 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? # 259| mu259_3(unknown) = ^CallSideEffect : ~m?
#-----| Goto -> Block 3 #-----| Goto -> Block 3
@@ -1116,7 +1116,7 @@ ssa.cpp:
# 269| r269_2(glval<unknown>) = FunctionAddress[malloc] : # 269| r269_2(glval<unknown>) = FunctionAddress[malloc] :
# 269| r269_3(glval<int>) = VariableAddress[size] : # 269| r269_3(glval<int>) = VariableAddress[size] :
# 269| r269_4(int) = Load : &:r269_3, m268_9 # 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_6(unknown) = ^CallSideEffect : ~m?
# 269| mu269_7(unknown) = ^InitializeDynamicAllocation : &:r269_5 # 269| mu269_7(unknown) = ^InitializeDynamicAllocation : &:r269_5
# 269| m269_8(void *) = Store : &:r269_1, 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_5(void *) = Load : &:r270_4, m268_5
# 270| r270_6(glval<int>) = VariableAddress[size] : # 270| r270_6(glval<int>) = VariableAddress[size] :
# 270| r270_7(int) = Load : &:r270_6, m268_9 # 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| v270_9(void) = ^SizedBufferReadSideEffect[1] : &:r270_5, r270_7, ~m?
# 270| mu270_10(unknown) = ^SizedBufferMustWriteSideEffect[0] : &:r270_3, r270_7 # 270| mu270_10(unknown) = ^SizedBufferMustWriteSideEffect[0] : &:r270_3, r270_7
# 271| r271_1(glval<void *>) = VariableAddress[#return] : # 271| r271_1(glval<void *>) = VariableAddress[#return] :
@@ -1250,7 +1250,7 @@ ssa.cpp:
# 292| r292_1(glval<Point *>) = VariableAddress[p] : # 292| r292_1(glval<Point *>) = VariableAddress[p] :
# 292| r292_2(glval<unknown>) = FunctionAddress[operator new] : # 292| r292_2(glval<unknown>) = FunctionAddress[operator new] :
# 292| r292_3(unsigned long) = Constant[8] : # 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_5(unknown) = ^CallSideEffect : ~m?
# 292| mu292_6(unknown) = ^InitializeDynamicAllocation : &:r292_4 # 292| mu292_6(unknown) = ^InitializeDynamicAllocation : &:r292_4
# 292| r292_7(Point *) = Convert : r292_4 # 292| r292_7(Point *) = Convert : r292_4
@@ -1258,7 +1258,7 @@ ssa.cpp:
# 293| r293_1(glval<Point *>) = VariableAddress[q] : # 293| r293_1(glval<Point *>) = VariableAddress[q] :
# 293| r293_2(glval<unknown>) = FunctionAddress[operator new] : # 293| r293_2(glval<unknown>) = FunctionAddress[operator new] :
# 293| r293_3(unsigned long) = Constant[8] : # 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_5(unknown) = ^CallSideEffect : ~m?
# 293| mu293_6(unknown) = ^InitializeDynamicAllocation : &:r293_4 # 293| mu293_6(unknown) = ^InitializeDynamicAllocation : &:r293_4
# 293| r293_7(Point *) = Convert : r293_4 # 293| r293_7(Point *) = Convert : r293_4
@@ -1266,24 +1266,24 @@ ssa.cpp:
# 294| r294_1(glval<int>) = VariableAddress[j] : # 294| r294_1(glval<int>) = VariableAddress[j] :
# 294| r294_2(glval<unknown>) = FunctionAddress[operator new] : # 294| r294_2(glval<unknown>) = FunctionAddress[operator new] :
# 294| r294_3(unsigned long) = Constant[4] : # 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_5(unknown) = ^CallSideEffect : ~m?
# 294| mu294_6(unknown) = ^InitializeDynamicAllocation : &:r294_4 # 294| mu294_6(unknown) = ^InitializeDynamicAllocation : &:r294_4
# 294| r294_7(A *) = Convert : r294_4 # 294| r294_7(A *) = Convert : r294_4
# 294| r294_8(glval<unknown>) = FunctionAddress[A] : # 294| r294_8(glval<unknown>) = FunctionAddress[A] :
# 294| r294_9(glval<unknown>) = FunctionAddress[operator new] : # 294| r294_9(glval<unknown>) = FunctionAddress[operator new] :
# 294| r294_10(unsigned long) = Constant[4] : # 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_12(unknown) = ^CallSideEffect : ~m?
# 294| mu294_13(unknown) = ^InitializeDynamicAllocation : &:r294_11 # 294| mu294_13(unknown) = ^InitializeDynamicAllocation : &:r294_11
# 294| r294_14(A *) = Convert : r294_11 # 294| r294_14(A *) = Convert : r294_11
# 294| r294_15(glval<unknown>) = FunctionAddress[A] : # 294| r294_15(glval<unknown>) = FunctionAddress[A] :
# 294| r294_16(glval<int>) = VariableAddress[x] : # 294| r294_16(glval<int>) = VariableAddress[x] :
# 294| r294_17(int) = Load : &:r294_16, m291_5 # 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_19(unknown) = ^CallSideEffect : ~m?
# 294| mu294_20(A) = ^IndirectMayWriteSideEffect[-1] : &:r294_14 # 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_22(unknown) = ^CallSideEffect : ~m?
# 294| mu294_23(A) = ^IndirectMayWriteSideEffect[-1] : &:r294_7 # 294| mu294_23(A) = ^IndirectMayWriteSideEffect[-1] : &:r294_7
# 294| v294_24(void) = ^BufferReadSideEffect[0] : &:r294_14, ~m? # 294| v294_24(void) = ^BufferReadSideEffect[0] : &:r294_14, ~m?
@@ -1294,12 +1294,12 @@ ssa.cpp:
# 295| r295_1(glval<A *>) = VariableAddress[a] : # 295| r295_1(glval<A *>) = VariableAddress[a] :
# 295| r295_2(glval<unknown>) = FunctionAddress[operator new] : # 295| r295_2(glval<unknown>) = FunctionAddress[operator new] :
# 295| r295_3(unsigned long) = Constant[4] : # 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_5(unknown) = ^CallSideEffect : ~m?
# 295| mu295_6(unknown) = ^InitializeDynamicAllocation : &:r295_4 # 295| mu295_6(unknown) = ^InitializeDynamicAllocation : &:r295_4
# 295| r295_7(A *) = Convert : r295_4 # 295| r295_7(A *) = Convert : r295_4
# 295| r295_8(glval<unknown>) = FunctionAddress[A] : # 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_10(unknown) = ^CallSideEffect : ~m?
# 295| mu295_11(A) = ^IndirectMayWriteSideEffect[-1] : &:r295_7 # 295| mu295_11(A) = ^IndirectMayWriteSideEffect[-1] : &:r295_7
# 295| m295_12(A *) = Store : &:r295_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_3(int) = Load : &:r302_2, m301_5
# 302| r302_4(glval<char **>) = VariableAddress[argv] : # 302| r302_4(glval<char **>) = VariableAddress[argv] :
# 302| r302_5(char **) = Load : &:r302_4, m301_7 # 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| mu302_7(unknown) = ^CallSideEffect : ~m?
# 302| v302_8(void) = ^BufferReadSideEffect[1] : &:r302_5, ~m? # 302| v302_8(void) = ^BufferReadSideEffect[1] : &:r302_5, ~m?
# 302| mu302_9(unknown) = ^BufferMayWriteSideEffect[1] : &:r302_5 # 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_3(int) = Load : &:r303_2, m301_5
# 303| r303_4(glval<char **>) = VariableAddress[argv] : # 303| r303_4(glval<char **>) = VariableAddress[argv] :
# 303| r303_5(char **) = Load : &:r303_4, m301_7 # 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| mu303_7(unknown) = ^CallSideEffect : ~m?
# 303| v303_8(void) = ^BufferReadSideEffect[1] : &:r303_5, ~m? # 303| v303_8(void) = ^BufferReadSideEffect[1] : &:r303_5, ~m?
# 303| mu303_9(unknown) = ^BufferMayWriteSideEffect[1] : &:r303_5 # 303| mu303_9(unknown) = ^BufferMayWriteSideEffect[1] : &:r303_5

View File

@@ -334,7 +334,7 @@ ssa.cpp:
# 97| r97_2(glval<Point>) = VariableAddress[a] : # 97| r97_2(glval<Point>) = VariableAddress[a] :
# 97| r97_3(Point *) = CopyValue : r97_2 # 97| r97_3(Point *) = CopyValue : r97_2
# 97| r97_4(void *) = Convert : r97_3 # 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| mu97_6(unknown) = ^CallSideEffect : ~m?
# 97| v97_7(void) = ^BufferReadSideEffect[0] : &:r97_4, ~m? # 97| v97_7(void) = ^BufferReadSideEffect[0] : &:r97_4, ~m?
# 97| mu97_8(unknown) = ^BufferMayWriteSideEffect[0] : &:r97_4 # 97| mu97_8(unknown) = ^BufferMayWriteSideEffect[0] : &:r97_4
@@ -386,7 +386,7 @@ ssa.cpp:
# 108| r108_2(glval<Point>) = VariableAddress[a] : # 108| r108_2(glval<Point>) = VariableAddress[a] :
# 108| r108_3(Point *) = CopyValue : r108_2 # 108| r108_3(Point *) = CopyValue : r108_2
# 108| r108_4(void *) = Convert : r108_3 # 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| mu108_6(unknown) = ^CallSideEffect : ~m?
# 108| v108_7(void) = ^BufferReadSideEffect[0] : &:r108_4, ~m? # 108| v108_7(void) = ^BufferReadSideEffect[0] : &:r108_4, ~m?
# 108| mu108_8(unknown) = ^BufferMayWriteSideEffect[0] : &:r108_4 # 108| mu108_8(unknown) = ^BufferMayWriteSideEffect[0] : &:r108_4
@@ -450,7 +450,7 @@ ssa.cpp:
# 119| r119_2(glval<Point>) = VariableAddress[a] : # 119| r119_2(glval<Point>) = VariableAddress[a] :
# 119| r119_3(Point *) = CopyValue : r119_2 # 119| r119_3(Point *) = CopyValue : r119_2
# 119| r119_4(void *) = Convert : r119_3 # 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| mu119_6(unknown) = ^CallSideEffect : ~m?
# 119| v119_7(void) = ^BufferReadSideEffect[0] : &:r119_4, ~m? # 119| v119_7(void) = ^BufferReadSideEffect[0] : &:r119_4, ~m?
# 119| mu119_8(unknown) = ^BufferMayWriteSideEffect[0] : &:r119_4 # 119| mu119_8(unknown) = ^BufferMayWriteSideEffect[0] : &:r119_4
@@ -789,7 +789,7 @@ ssa.cpp:
# 199| r199_6(glval<char *>) = VariableAddress[str2] : # 199| r199_6(glval<char *>) = VariableAddress[str2] :
# 199| r199_7(char *) = Load : &:r199_6, m198_9 # 199| r199_7(char *) = Load : &:r199_6, m198_9
# 199| r199_8(char *) = Convert : r199_7 # 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_10(void) = ^BufferReadSideEffect[0] : &:r199_5, ~m?
# 199| v199_11(void) = ^BufferReadSideEffect[1] : &:r199_8, ~m? # 199| v199_11(void) = ^BufferReadSideEffect[1] : &:r199_8, ~m?
# 199| m199_12(int) = Store : &:r199_1, r199_9 # 199| m199_12(int) = Store : &:r199_1, r199_9
@@ -797,7 +797,7 @@ ssa.cpp:
# 200| r200_2(glval<char *>) = VariableAddress[str1] : # 200| r200_2(glval<char *>) = VariableAddress[str1] :
# 200| r200_3(char *) = Load : &:r200_2, m198_5 # 200| r200_3(char *) = Load : &:r200_2, m198_5
# 200| r200_4(char *) = Convert : r200_3 # 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| v200_6(void) = ^BufferReadSideEffect[0] : &:r200_4, ~m?
# 200| r200_7(glval<int>) = VariableAddress[ret] : # 200| r200_7(glval<int>) = VariableAddress[ret] :
# 200| r200_8(int) = Load : &:r200_7, m199_12 # 200| r200_8(int) = Load : &:r200_7, m199_12
@@ -806,7 +806,7 @@ ssa.cpp:
# 201| r201_1(glval<unknown>) = FunctionAddress[abs] : # 201| r201_1(glval<unknown>) = FunctionAddress[abs] :
# 201| r201_2(glval<int>) = VariableAddress[x] : # 201| r201_2(glval<int>) = VariableAddress[x] :
# 201| r201_3(int) = Load : &:r201_2, m198_13 # 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_5(glval<int>) = VariableAddress[ret] :
# 201| r201_6(int) = Load : &:r201_5, m200_10 # 201| r201_6(int) = Load : &:r201_5, m200_10
# 201| r201_7(int) = Add : r201_6, r201_4 # 201| r201_7(int) = Add : r201_6, r201_4
@@ -839,7 +839,7 @@ ssa.cpp:
# 209| r209_6(int *) = CopyValue : r209_5 # 209| r209_6(int *) = CopyValue : r209_5
# 209| r209_7(void *) = Convert : r209_6 # 209| r209_7(void *) = Convert : r209_6
# 209| r209_8(int) = Constant[4] : # 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| v209_10(void) = ^SizedBufferReadSideEffect[1] : &:r209_7, r209_8, ~m?
# 209| mu209_11(unknown) = ^SizedBufferMustWriteSideEffect[0] : &:r209_4, r209_8 # 209| mu209_11(unknown) = ^SizedBufferMustWriteSideEffect[0] : &:r209_4, r209_8
# 210| r210_1(glval<int>) = VariableAddress[#return] : # 210| r210_1(glval<int>) = VariableAddress[#return] :
@@ -917,7 +917,7 @@ ssa.cpp:
# 226| mu226_2(unknown) = AliasedDefinition : # 226| mu226_2(unknown) = AliasedDefinition :
# 226| mu226_3(unknown) = InitializeNonLocal : # 226| mu226_3(unknown) = InitializeNonLocal :
# 227| r227_1(glval<unknown>) = FunctionAddress[ExternalFunc] : # 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? # 227| mu227_3(unknown) = ^CallSideEffect : ~m?
# 229| r229_1(glval<char *>) = VariableAddress[s] : # 229| r229_1(glval<char *>) = VariableAddress[s] :
# 229| r229_2(glval<char[8]>) = StringConstant["Literal"] : # 229| r229_2(glval<char[8]>) = StringConstant["Literal"] :
@@ -976,18 +976,18 @@ ssa.cpp:
# 240| mu240_2(Constructible) = Uninitialized[c] : &:r240_1 # 240| mu240_2(Constructible) = Uninitialized[c] : &:r240_1
# 240| r240_3(glval<unknown>) = FunctionAddress[Constructible] : # 240| r240_3(glval<unknown>) = FunctionAddress[Constructible] :
# 240| r240_4(int) = Constant[1] : # 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_6(unknown) = ^CallSideEffect : ~m?
# 240| mu240_7(Constructible) = ^IndirectMayWriteSideEffect[-1] : &:r240_1 # 240| mu240_7(Constructible) = ^IndirectMayWriteSideEffect[-1] : &:r240_1
# 241| r241_1(glval<Constructible>) = VariableAddress[c] : # 241| r241_1(glval<Constructible>) = VariableAddress[c] :
# 241| r241_2(glval<unknown>) = FunctionAddress[g] : # 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| mu241_4(unknown) = ^CallSideEffect : ~m?
# 241| v241_5(void) = ^BufferReadSideEffect[-1] : &:r241_1, ~m? # 241| v241_5(void) = ^BufferReadSideEffect[-1] : &:r241_1, ~m?
# 241| mu241_6(Constructible) = ^IndirectMayWriteSideEffect[-1] : &:r241_1 # 241| mu241_6(Constructible) = ^IndirectMayWriteSideEffect[-1] : &:r241_1
# 242| r242_1(glval<Constructible>) = VariableAddress[c] : # 242| r242_1(glval<Constructible>) = VariableAddress[c] :
# 242| r242_2(glval<unknown>) = FunctionAddress[g] : # 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| mu242_4(unknown) = ^CallSideEffect : ~m?
# 242| v242_5(void) = ^BufferReadSideEffect[-1] : &:r242_1, ~m? # 242| v242_5(void) = ^BufferReadSideEffect[-1] : &:r242_1, ~m?
# 242| mu242_6(Constructible) = ^IndirectMayWriteSideEffect[-1] : &:r242_1 # 242| mu242_6(Constructible) = ^IndirectMayWriteSideEffect[-1] : &:r242_1
@@ -995,12 +995,12 @@ ssa.cpp:
# 243| mu243_2(Constructible) = Uninitialized[c2] : &:r243_1 # 243| mu243_2(Constructible) = Uninitialized[c2] : &:r243_1
# 243| r243_3(glval<unknown>) = FunctionAddress[Constructible] : # 243| r243_3(glval<unknown>) = FunctionAddress[Constructible] :
# 243| r243_4(int) = Constant[2] : # 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_6(unknown) = ^CallSideEffect : ~m?
# 243| mu243_7(Constructible) = ^IndirectMayWriteSideEffect[-1] : &:r243_1 # 243| mu243_7(Constructible) = ^IndirectMayWriteSideEffect[-1] : &:r243_1
# 244| r244_1(glval<Constructible>) = VariableAddress[c2] : # 244| r244_1(glval<Constructible>) = VariableAddress[c2] :
# 244| r244_2(glval<unknown>) = FunctionAddress[g] : # 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| mu244_4(unknown) = ^CallSideEffect : ~m?
# 244| v244_5(void) = ^BufferReadSideEffect[-1] : &:r244_1, ~m? # 244| v244_5(void) = ^BufferReadSideEffect[-1] : &:r244_1, ~m?
# 244| mu244_6(Constructible) = ^IndirectMayWriteSideEffect[-1] : &:r244_1 # 244| mu244_6(Constructible) = ^IndirectMayWriteSideEffect[-1] : &:r244_1
@@ -1027,7 +1027,7 @@ ssa.cpp:
# 248| r248_5(unsigned long) = Convert : r248_4 # 248| r248_5(unsigned long) = Convert : r248_4
# 248| r248_6(unsigned long) = Constant[1] : # 248| r248_6(unsigned long) = Constant[1] :
# 248| r248_7(unsigned long) = Mul : r248_5, r248_6 # 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_9(unknown) = ^CallSideEffect : ~m?
# 248| mu248_10(unknown) = ^InitializeDynamicAllocation : &:r248_8 # 248| mu248_10(unknown) = ^InitializeDynamicAllocation : &:r248_8
# 248| r248_11(char *) = Convert : r248_8 # 248| r248_11(char *) = Convert : r248_8
@@ -1046,7 +1046,7 @@ ssa.cpp:
# 250| r250_7(void *) = Convert : r250_6 # 250| r250_7(void *) = Convert : r250_6
# 250| r250_8(glval<int>) = VariableAddress[size] : # 250| r250_8(glval<int>) = VariableAddress[size] :
# 250| r250_9(int) = Load : &:r250_8, m247_9 # 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| v250_11(void) = ^SizedBufferReadSideEffect[1] : &:r250_7, r250_9, ~m?
# 250| mu250_12(unknown) = ^SizedBufferMustWriteSideEffect[0] : &:r250_4, r250_9 # 250| mu250_12(unknown) = ^SizedBufferMustWriteSideEffect[0] : &:r250_4, r250_9
# 251| r251_1(glval<char *>) = VariableAddress[#return] : # 251| r251_1(glval<char *>) = VariableAddress[#return] :
@@ -1074,13 +1074,13 @@ ssa.cpp:
# 256| Block 1 # 256| Block 1
# 256| r256_1(glval<unknown>) = FunctionAddress[ExternalFunc] : # 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? # 256| mu256_3(unknown) = ^CallSideEffect : ~m?
#-----| Goto -> Block 3 #-----| Goto -> Block 3
# 259| Block 2 # 259| Block 2
# 259| r259_1(glval<unknown>) = FunctionAddress[ExternalFunc] : # 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? # 259| mu259_3(unknown) = ^CallSideEffect : ~m?
#-----| Goto -> Block 3 #-----| Goto -> Block 3
@@ -1116,7 +1116,7 @@ ssa.cpp:
# 269| r269_2(glval<unknown>) = FunctionAddress[malloc] : # 269| r269_2(glval<unknown>) = FunctionAddress[malloc] :
# 269| r269_3(glval<int>) = VariableAddress[size] : # 269| r269_3(glval<int>) = VariableAddress[size] :
# 269| r269_4(int) = Load : &:r269_3, m268_9 # 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_6(unknown) = ^CallSideEffect : ~m?
# 269| mu269_7(unknown) = ^InitializeDynamicAllocation : &:r269_5 # 269| mu269_7(unknown) = ^InitializeDynamicAllocation : &:r269_5
# 269| m269_8(void *) = Store : &:r269_1, 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_5(void *) = Load : &:r270_4, m268_5
# 270| r270_6(glval<int>) = VariableAddress[size] : # 270| r270_6(glval<int>) = VariableAddress[size] :
# 270| r270_7(int) = Load : &:r270_6, m268_9 # 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| v270_9(void) = ^SizedBufferReadSideEffect[1] : &:r270_5, r270_7, ~m?
# 270| mu270_10(unknown) = ^SizedBufferMustWriteSideEffect[0] : &:r270_3, r270_7 # 270| mu270_10(unknown) = ^SizedBufferMustWriteSideEffect[0] : &:r270_3, r270_7
# 271| r271_1(glval<void *>) = VariableAddress[#return] : # 271| r271_1(glval<void *>) = VariableAddress[#return] :
@@ -1250,7 +1250,7 @@ ssa.cpp:
# 292| r292_1(glval<Point *>) = VariableAddress[p] : # 292| r292_1(glval<Point *>) = VariableAddress[p] :
# 292| r292_2(glval<unknown>) = FunctionAddress[operator new] : # 292| r292_2(glval<unknown>) = FunctionAddress[operator new] :
# 292| r292_3(unsigned long) = Constant[8] : # 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_5(unknown) = ^CallSideEffect : ~m?
# 292| mu292_6(unknown) = ^InitializeDynamicAllocation : &:r292_4 # 292| mu292_6(unknown) = ^InitializeDynamicAllocation : &:r292_4
# 292| r292_7(Point *) = Convert : r292_4 # 292| r292_7(Point *) = Convert : r292_4
@@ -1258,7 +1258,7 @@ ssa.cpp:
# 293| r293_1(glval<Point *>) = VariableAddress[q] : # 293| r293_1(glval<Point *>) = VariableAddress[q] :
# 293| r293_2(glval<unknown>) = FunctionAddress[operator new] : # 293| r293_2(glval<unknown>) = FunctionAddress[operator new] :
# 293| r293_3(unsigned long) = Constant[8] : # 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_5(unknown) = ^CallSideEffect : ~m?
# 293| mu293_6(unknown) = ^InitializeDynamicAllocation : &:r293_4 # 293| mu293_6(unknown) = ^InitializeDynamicAllocation : &:r293_4
# 293| r293_7(Point *) = Convert : r293_4 # 293| r293_7(Point *) = Convert : r293_4
@@ -1266,24 +1266,24 @@ ssa.cpp:
# 294| r294_1(glval<int>) = VariableAddress[j] : # 294| r294_1(glval<int>) = VariableAddress[j] :
# 294| r294_2(glval<unknown>) = FunctionAddress[operator new] : # 294| r294_2(glval<unknown>) = FunctionAddress[operator new] :
# 294| r294_3(unsigned long) = Constant[4] : # 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_5(unknown) = ^CallSideEffect : ~m?
# 294| mu294_6(unknown) = ^InitializeDynamicAllocation : &:r294_4 # 294| mu294_6(unknown) = ^InitializeDynamicAllocation : &:r294_4
# 294| r294_7(A *) = Convert : r294_4 # 294| r294_7(A *) = Convert : r294_4
# 294| r294_8(glval<unknown>) = FunctionAddress[A] : # 294| r294_8(glval<unknown>) = FunctionAddress[A] :
# 294| r294_9(glval<unknown>) = FunctionAddress[operator new] : # 294| r294_9(glval<unknown>) = FunctionAddress[operator new] :
# 294| r294_10(unsigned long) = Constant[4] : # 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_12(unknown) = ^CallSideEffect : ~m?
# 294| mu294_13(unknown) = ^InitializeDynamicAllocation : &:r294_11 # 294| mu294_13(unknown) = ^InitializeDynamicAllocation : &:r294_11
# 294| r294_14(A *) = Convert : r294_11 # 294| r294_14(A *) = Convert : r294_11
# 294| r294_15(glval<unknown>) = FunctionAddress[A] : # 294| r294_15(glval<unknown>) = FunctionAddress[A] :
# 294| r294_16(glval<int>) = VariableAddress[x] : # 294| r294_16(glval<int>) = VariableAddress[x] :
# 294| r294_17(int) = Load : &:r294_16, m291_5 # 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_19(unknown) = ^CallSideEffect : ~m?
# 294| mu294_20(A) = ^IndirectMayWriteSideEffect[-1] : &:r294_14 # 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_22(unknown) = ^CallSideEffect : ~m?
# 294| mu294_23(A) = ^IndirectMayWriteSideEffect[-1] : &:r294_7 # 294| mu294_23(A) = ^IndirectMayWriteSideEffect[-1] : &:r294_7
# 294| v294_24(void) = ^BufferReadSideEffect[0] : &:r294_14, ~m? # 294| v294_24(void) = ^BufferReadSideEffect[0] : &:r294_14, ~m?
@@ -1294,12 +1294,12 @@ ssa.cpp:
# 295| r295_1(glval<A *>) = VariableAddress[a] : # 295| r295_1(glval<A *>) = VariableAddress[a] :
# 295| r295_2(glval<unknown>) = FunctionAddress[operator new] : # 295| r295_2(glval<unknown>) = FunctionAddress[operator new] :
# 295| r295_3(unsigned long) = Constant[4] : # 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_5(unknown) = ^CallSideEffect : ~m?
# 295| mu295_6(unknown) = ^InitializeDynamicAllocation : &:r295_4 # 295| mu295_6(unknown) = ^InitializeDynamicAllocation : &:r295_4
# 295| r295_7(A *) = Convert : r295_4 # 295| r295_7(A *) = Convert : r295_4
# 295| r295_8(glval<unknown>) = FunctionAddress[A] : # 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_10(unknown) = ^CallSideEffect : ~m?
# 295| mu295_11(A) = ^IndirectMayWriteSideEffect[-1] : &:r295_7 # 295| mu295_11(A) = ^IndirectMayWriteSideEffect[-1] : &:r295_7
# 295| m295_12(A *) = Store : &:r295_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_3(int) = Load : &:r302_2, m301_5
# 302| r302_4(glval<char **>) = VariableAddress[argv] : # 302| r302_4(glval<char **>) = VariableAddress[argv] :
# 302| r302_5(char **) = Load : &:r302_4, m301_7 # 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| mu302_7(unknown) = ^CallSideEffect : ~m?
# 302| v302_8(void) = ^BufferReadSideEffect[1] : &:r302_5, ~m? # 302| v302_8(void) = ^BufferReadSideEffect[1] : &:r302_5, ~m?
# 302| mu302_9(unknown) = ^BufferMayWriteSideEffect[1] : &:r302_5 # 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_3(int) = Load : &:r303_2, m301_5
# 303| r303_4(glval<char **>) = VariableAddress[argv] : # 303| r303_4(glval<char **>) = VariableAddress[argv] :
# 303| r303_5(char **) = Load : &:r303_4, m301_7 # 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| mu303_7(unknown) = ^CallSideEffect : ~m?
# 303| v303_8(void) = ^BufferReadSideEffect[1] : &:r303_5, ~m? # 303| v303_8(void) = ^BufferReadSideEffect[1] : &:r303_5, ~m?
# 303| mu303_9(unknown) = ^BufferMayWriteSideEffect[1] : &:r303_5 # 303| mu303_9(unknown) = ^BufferMayWriteSideEffect[1] : &:r303_5

View File

@@ -202,7 +202,7 @@ test.cpp:
# 29| valnum = m29_10, r29_8 # 29| valnum = m29_10, r29_8
# 30| r30_1(glval<unknown>) = FunctionAddress[change_global02] : # 30| r30_1(glval<unknown>) = FunctionAddress[change_global02] :
# 30| valnum = unique # 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| m30_3(unknown) = ^CallSideEffect : ~m25_4
# 30| valnum = unique # 30| valnum = unique
# 30| m30_4(unknown) = Chi : total:m25_4, partial:m30_3 # 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| valnum = r77_1, r79_1, r80_6
# 77| r77_2(glval<unknown>) = FunctionAddress[getAValue] : # 77| r77_2(glval<unknown>) = FunctionAddress[getAValue] :
# 77| valnum = unique # 77| valnum = unique
# 77| r77_3(int) = Call : func:r77_2 # 77| r77_3(int) = Call[getAValue] : func:r77_2
# 77| valnum = unique # 77| valnum = unique
# 77| m77_4(unknown) = ^CallSideEffect : ~m75_4 # 77| m77_4(unknown) = ^CallSideEffect : ~m75_4
# 77| valnum = unique # 77| valnum = unique
@@ -585,7 +585,7 @@ test.cpp:
# 80| Block 1 # 80| Block 1
# 80| r80_1(glval<unknown>) = FunctionAddress[getAValue] : # 80| r80_1(glval<unknown>) = FunctionAddress[getAValue] :
# 80| valnum = unique # 80| valnum = unique
# 80| r80_2(int) = Call : func:r80_1 # 80| r80_2(int) = Call[getAValue] : func:r80_1
# 80| valnum = unique # 80| valnum = unique
# 80| m80_3(unknown) = ^CallSideEffect : ~m77_5 # 80| m80_3(unknown) = ^CallSideEffect : ~m77_5
# 80| valnum = unique # 80| valnum = unique

View File

@@ -20,15 +20,15 @@ namespace Semmle.Autobuild.CSharp.Tests
/// <summary> /// <summary>
/// List of strings passed to FileDelete. /// List of strings passed to FileDelete.
/// </summary> /// </summary>
public readonly IList<string> FileDeleteIn = new List<string>(); public IList<string> FileDeleteIn { get; } = new List<string>();
void IBuildActions.FileDelete(string file) void IBuildActions.FileDelete(string file)
{ {
FileDeleteIn.Add(file); FileDeleteIn.Add(file);
} }
public readonly IList<string> FileExistsIn = new List<string>(); public IList<string> FileExistsIn { get; } = new List<string>();
public readonly IDictionary<string, bool> FileExists = new Dictionary<string, bool>(); public IDictionary<string, bool> FileExists { get; } = new Dictionary<string, bool>();
bool IBuildActions.FileExists(string file) bool IBuildActions.FileExists(string file)
{ {
@@ -42,12 +42,12 @@ namespace Semmle.Autobuild.CSharp.Tests
throw new ArgumentException("Missing FileExists " + file); throw new ArgumentException("Missing FileExists " + file);
} }
public readonly IList<string> RunProcessIn = new List<string>(); public IList<string> RunProcessIn { get; } = new List<string>();
public readonly IDictionary<string, int> RunProcess = new Dictionary<string, int>(); public IDictionary<string, int> RunProcess { get; } = new Dictionary<string, int>();
public readonly IDictionary<string, string> RunProcessOut = new Dictionary<string, string>(); public IDictionary<string, string> RunProcessOut { get; } = new Dictionary<string, string>();
public readonly IDictionary<string, string> RunProcessWorkingDirectory = new Dictionary<string, string>(); public IDictionary<string, string> RunProcessWorkingDirectory { get; } = new Dictionary<string, string>();
public readonly HashSet<string> CreateDirectories = new HashSet<string>(); public HashSet<string> CreateDirectories { get; } = new HashSet<string>();
public readonly HashSet<(string, string)> DownloadFiles = new HashSet<(string, 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) 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; 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) void IBuildActions.DirectoryDelete(string dir, bool recursive)
{ {
DirectoryDeleteIn.Add(dir); 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) bool IBuildActions.DirectoryExists(string dir)
{ {
@@ -102,7 +102,7 @@ namespace Semmle.Autobuild.CSharp.Tests
return ret; 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) string? IBuildActions.GetEnvironmentVariable(string name)
{ {
@@ -112,14 +112,14 @@ namespace Semmle.Autobuild.CSharp.Tests
return ret; return ret;
} }
public string GetCurrentDirectory = ""; public string GetCurrentDirectory { get; set; } = "";
string IBuildActions.GetCurrentDirectory() string IBuildActions.GetCurrentDirectory()
{ {
return 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) IEnumerable<string> IBuildActions.EnumerateFiles(string dir)
{ {
@@ -129,7 +129,7 @@ namespace Semmle.Autobuild.CSharp.Tests
return str.Split("\n").Select(p => PathCombine(dir, p)); 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) IEnumerable<string> IBuildActions.EnumerateDirectories(string dir)
{ {
@@ -141,7 +141,7 @@ namespace Semmle.Autobuild.CSharp.Tests
: str.Split("\n").Select(p => PathCombine(dir, p)); : str.Split("\n").Select(p => PathCombine(dir, p));
} }
public bool IsWindows; public bool IsWindows { get; set; }
bool IBuildActions.IsWindows() => IsWindows; 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) XmlDocument IBuildActions.LoadXml(string filename)
{ {

View File

@@ -227,6 +227,6 @@ namespace Semmle.Autobuild.Shared
public void DownloadFile(string address, string fileName) => public void DownloadFile(string address, string fileName) =>
DownloadFileAsync(address, fileName).Wait(); DownloadFileAsync(address, fileName).Wait();
public static readonly IBuildActions Instance = new SystemBuildActions(); public static IBuildActions Instance { get; } = new SystemBuildActions();
} }
} }

View File

@@ -232,13 +232,13 @@ namespace Semmle.Autobuild.Shared
/// <summary> /// <summary>
/// The empty build script that always returns exit code 0. /// The empty build script that always returns exit code 0.
/// </summary> /// </summary>
public static readonly BuildScript Success = Create(actions => successCode); public static BuildScript Success { get; } = Create(actions => successCode);
private const int failureCode = 1; private const int failureCode = 1;
/// <summary> /// <summary>
/// The empty build script that always returns exit code 1. /// The empty build script that always returns exit code 1.
/// </summary> /// </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; private static bool Succeeded(int i) => i == successCode;

View File

@@ -16,7 +16,7 @@ namespace Semmle.Extraction.CIL.Driver
/// </summary> /// </summary>
internal class AssemblyInfo 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) private static AssemblyName CreateAssemblyName(MetadataReader mdReader, StringHandle name, System.Version version, StringHandle culture)
{ {
@@ -59,7 +59,7 @@ namespace Semmle.Extraction.CIL.Driver
/// </exception> /// </exception>
public AssemblyInfo(string path) public AssemblyInfo(string path)
{ {
filename = path; Filename = path;
// Attempt to open the file and see if it's a valid assembly. // Attempt to open the file and see if it's a valid assembly.
using var stream = File.OpenRead(path); using var stream = File.OpenRead(path);
@@ -75,9 +75,9 @@ namespace Semmle.Extraction.CIL.Driver
throw new InvalidAssemblyException(); throw new InvalidAssemblyException();
// Get our own assembly name // 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(r => mdReader.GetAssemblyReference(r))
.Select(ar => CreateAssemblyName(mdReader, ar)) .Select(ar => CreateAssemblyName(mdReader, ar))
.ToArray(); .ToArray();
@@ -91,10 +91,10 @@ namespace Semmle.Extraction.CIL.Driver
} }
} }
public readonly AssemblyName name; public AssemblyName Name { get; }
public readonly string filename; public string Filename { get; }
public bool extract; public bool Extract { get; set; }
public readonly AssemblyName[] references; public AssemblyName[] References { get; }
} }
/// <summary> /// <summary>
@@ -125,19 +125,19 @@ namespace Semmle.Extraction.CIL.Driver
{ {
var info = new AssemblyInfo(assemblyPath) var info = new AssemblyInfo(assemblyPath)
{ {
extract = extractAll Extract = extractAll
}; };
if (!assembliesRead.ContainsKey(info.name)) if (!assembliesRead.ContainsKey(info.Name))
assembliesRead.Add(info.name, info); assembliesRead.Add(info.Name, info);
} }
catch (InvalidAssemblyException) 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() public void ResolveReferences()
{ {
@@ -148,22 +148,22 @@ namespace Semmle.Extraction.CIL.Driver
var item = assembliesToReference.Pop(); var item = assembliesToReference.Pop();
if (assembliesRead.TryGetValue(item, out var info)) if (assembliesRead.TryGetValue(item, out var info))
{ {
if (!info.extract) if (!info.Extract)
{ {
info.extract = true; info.Extract = true;
foreach (var reference in info.references) foreach (var reference in info.References)
assembliesToReference.Push(reference); assembliesToReference.Push(reference);
} }
} }
else else
{ {
missingReferences.Add(item); MissingReferences.Add(item);
} }
} }
} }
private readonly HashSet<string> filesAnalyzed = new HashSet<string>(); 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> /// <summary>
@@ -235,7 +235,7 @@ namespace Semmle.Extraction.CIL.Driver
/// extracted. This is not an error, it just means that the database is not /// extracted. This is not an error, it just means that the database is not
/// as complete as it could be. /// as complete as it could be.
/// </summary> /// </summary>
public IEnumerable<AssemblyName> MissingReferences => assemblyList.missingReferences; public IEnumerable<AssemblyName> MissingReferences => assemblyList.MissingReferences;
private void ParseArgs(string[] args) private void ParseArgs(string[] args)
{ {

View File

@@ -42,7 +42,7 @@ namespace Semmle.Extraction.CIL.Driver
using var logger = new ConsoleLogger(options.Verbosity); using var logger = new ConsoleLogger(options.Verbosity);
var actions = options.AssembliesToExtract var actions = options.AssembliesToExtract
.Select(asm => asm.filename) .Select(asm => asm.Filename)
.Select<string, Action>(filename => .Select<string, Action>(filename =>
() => ExtractAssembly(layout, filename, logger, options.NoCache, options.PDB, options.TrapCompression)) () => ExtractAssembly(layout, filename, logger, options.NoCache, options.PDB, options.TrapCompression))
.ToArray(); .ToArray();

View File

@@ -38,7 +38,7 @@ namespace Semmle.Extraction.CIL.Entities
/// <summary> /// <summary>
/// For each Payload, how many additional bytes in the bytestream need to be read. /// For each Payload, how many additional bytes in the bytestream need to be read.
/// </summary> /// </summary>
internal static readonly int[] payloadSizes = { private static readonly int[] payloadSizes = {
0, 4, 4, 1, 4, 0, 4, 4, 1, 4,
4, 1, 1, 4, 1, 4, 1, 1, 4, 1,
2, 4, 8, 4, 8, 2, 4, 8, 4, 8,
@@ -46,7 +46,7 @@ namespace Semmle.Extraction.CIL.Entities
4, 2, 1, 4, 2, 4 }; 4, 2, 1, 4, 2, 4 };
// Maps opcodes to payloads for each instruction. // 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.Nop, Payload.None },
{ ILOpCode.Break, Payload.None }, { ILOpCode.Break, Payload.None },
@@ -268,10 +268,10 @@ namespace Semmle.Extraction.CIL.Entities
{ ILOpCode.Readonly, Payload.None } { ILOpCode.Readonly, Payload.None }
}; };
public readonly DefinitionMethod Method; public DefinitionMethod Method { get; }
public readonly ILOpCode OpCode; public ILOpCode OpCode { get; }
public readonly int Offset; public int Offset { get; }
public readonly int Index; public int Index { get; }
private readonly int payloadValue; private readonly int payloadValue;
private readonly uint unsignedPayloadValue; private readonly uint unsignedPayloadValue;

View File

@@ -12,11 +12,11 @@ namespace Semmle.Extraction.CSharp.Standalone
{ {
public Extraction(string directory) public Extraction(string directory)
{ {
this.directory = directory; Directory = directory;
} }
public readonly string directory; public string Directory { get; }
public readonly List<string> Sources = new List<string>(); public List<string> Sources { get; } = new List<string>();
}; };
/// <summary> /// <summary>

View File

@@ -83,7 +83,7 @@ namespace Semmle.Extraction.CSharp.Entities
private class AccessorFactory : ICachedEntityFactory<IMethodSymbol, Accessor> 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); public Accessor Create(Context cx, IMethodSymbol init) => new Accessor(cx, init);
} }

View File

@@ -39,7 +39,7 @@ namespace Semmle.Extraction.CSharp.Entities
private class CommentBlockFactory : ICachedEntityFactory<ICommentBlock, CommentBlock> 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); public CommentBlock Create(Context cx, ICommentBlock init) => new CommentBlock(cx, init);
} }

View File

@@ -139,7 +139,7 @@ namespace Semmle.Extraction.CSharp.Entities
private class CommentLineFactory : ICachedEntityFactory<(Microsoft.CodeAnalysis.Location, CommentLineType, string, string), CommentLine> 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) => public CommentLine Create(Context cx, (Microsoft.CodeAnalysis.Location, CommentLineType, string, string) init) =>
new CommentLine(cx, init.Item1, init.Item2, init.Item3, init.Item4); new CommentLine(cx, init.Item1, init.Item2, init.Item3, init.Item4);

View File

@@ -147,7 +147,7 @@ namespace Semmle.Extraction.CSharp.Entities
private class ConstructorFactory : ICachedEntityFactory<IMethodSymbol, Constructor> 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); public Constructor Create(Context cx, IMethodSymbol init) => new Constructor(cx, init);
} }

View File

@@ -28,7 +28,7 @@ namespace Semmle.Extraction.CSharp.Entities
private class ConversionFactory : ICachedEntityFactory<IMethodSymbol, Conversion> 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); public Conversion Create(Context cx, IMethodSymbol init) => new Conversion(cx, init);
} }

View File

@@ -28,7 +28,7 @@ namespace Semmle.Extraction.CSharp.Entities
private class DestructorFactory : ICachedEntityFactory<IMethodSymbol, Destructor> 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); public Destructor Create(Context cx, IMethodSymbol init) => new Destructor(cx, init);
} }

View File

@@ -67,7 +67,7 @@ namespace Semmle.Extraction.CSharp.Entities
private class EventFactory : ICachedEntityFactory<IEventSymbol, Event> 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); public Event Create(Context cx, IEventSymbol init) => new Event(cx, init);
} }

View File

@@ -57,7 +57,7 @@ namespace Semmle.Extraction.CSharp.Entities
private class EventAccessorFactory : ICachedEntityFactory<IMethodSymbol, EventAccessor> 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); public EventAccessor Create(Context cx, IMethodSymbol init) => new EventAccessor(cx, init);
} }

View File

@@ -20,9 +20,9 @@ namespace Semmle.Extraction.CSharp.Entities
internal class Expression : FreshEntity, IExpressionParentEntity internal class Expression : FreshEntity, IExpressionParentEntity
{ {
private readonly IExpressionInfo info; private readonly IExpressionInfo info;
public readonly AnnotatedType Type; public AnnotatedType Type { get; }
public readonly Extraction.Entities.Location Location; public Extraction.Entities.Location Location { get; }
public readonly ExprKind Kind; public ExprKind Kind { get; }
internal Expression(IExpressionInfo info) internal Expression(IExpressionInfo info)
: base(info.Context) : base(info.Context)
@@ -294,7 +294,7 @@ namespace Semmle.Extraction.CSharp.Entities
internal abstract class Expression<TExpressionSyntax> : Expression internal abstract class Expression<TExpressionSyntax> : Expression
where TExpressionSyntax : ExpressionSyntax where TExpressionSyntax : ExpressionSyntax
{ {
public readonly TExpressionSyntax Syntax; public TExpressionSyntax Syntax { get; }
protected Expression(ExpressionNodeInfo info) protected Expression(ExpressionNodeInfo info)
: base(info) : base(info)

View File

@@ -131,7 +131,7 @@ namespace Semmle.Extraction.CSharp.Entities
private class FieldFactory : ICachedEntityFactory<IFieldSymbol, Field> 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); public Field Create(Context cx, IFieldSymbol init) => new Field(cx, init);
} }

View File

@@ -100,7 +100,7 @@ namespace Semmle.Extraction.CSharp.Entities
private class IndexerFactory : ICachedEntityFactory<IPropertySymbol, Indexer> 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); public Indexer Create(Context cx, IPropertySymbol init) => new Indexer(cx, init);
} }

View File

@@ -26,7 +26,7 @@ namespace Semmle.Extraction.CSharp.Entities
private class LocalFunctionFactory : ICachedEntityFactory<IMethodSymbol, LocalFunction> 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); public LocalFunction Create(Context cx, IMethodSymbol init) => new LocalFunction(cx, init);
} }

View File

@@ -55,7 +55,7 @@ namespace Semmle.Extraction.CSharp.Entities
private class LocalVariableFactory : ICachedEntityFactory<ISymbol, LocalVariable> 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); public LocalVariable Create(Context cx, ISymbol init) => new LocalVariable(cx, init);
} }

View File

@@ -142,7 +142,7 @@ namespace Semmle.Extraction.CSharp.Entities
private class ModifierFactory : ICachedEntityFactory<string, Modifier> 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); public Modifier Create(Context cx, string init) => new Modifier(cx, init);
} }

View File

@@ -38,7 +38,7 @@ namespace Semmle.Extraction.CSharp.Entities
private class NamespaceFactory : ICachedEntityFactory<INamespaceSymbol, Namespace> 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); public Namespace Create(Context cx, INamespaceSymbol init) => new Namespace(cx, init);
} }

View File

@@ -57,7 +57,7 @@ namespace Semmle.Extraction.CSharp.Entities
private class OrdinaryMethodFactory : ICachedEntityFactory<IMethodSymbol, OrdinaryMethod> 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); public OrdinaryMethod Create(Context cx, IMethodSymbol init) => new OrdinaryMethod(cx, init);
} }

View File

@@ -171,7 +171,7 @@ namespace Semmle.Extraction.CSharp.Entities
private class ParameterFactory : ICachedEntityFactory<(IParameterSymbol, IEntity, Parameter), Parameter> 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); 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> 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); 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> 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); 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> 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) => public ConstructedExtensionParameter Create(Context cx, (Method, Parameter) init) =>
new ConstructedExtensionParameter(cx, init.Item1, init.Item2); new ConstructedExtensionParameter(cx, init.Item1, init.Item2);

View File

@@ -126,7 +126,7 @@ namespace Semmle.Extraction.CSharp.Entities
private class PropertyFactory : ICachedEntityFactory<IPropertySymbol, Property> 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); public Property Create(Context cx, IPropertySymbol init) => new Property(cx, init);
} }

View File

@@ -8,7 +8,7 @@ namespace Semmle.Extraction.CSharp.Entities.Statements
internal class Switch : Statement<SwitchStatementSyntax> internal class Switch : Statement<SwitchStatementSyntax>
{ {
private static readonly object nullLabel = new object(); 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. // Sometimes, the literal "null" is used as a label.
// This is inconveniently represented by the "null" object. // This is inconveniently represented by the "null" object.

View File

@@ -40,7 +40,7 @@ namespace Semmle.Extraction.CSharp.Entities
private class ArrayTypeFactory : ICachedEntityFactory<IArrayTypeSymbol, ArrayType> 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); public ArrayType Create(Context cx, IArrayTypeSymbol init) => new ArrayType(cx, init);
} }

View File

@@ -29,7 +29,7 @@ namespace Semmle.Extraction.CSharp.Entities
private class DynamicTypeFactory : ICachedEntityFactory<IDynamicTypeSymbol, DynamicType> 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); public DynamicType Create(Context cx, IDynamicTypeSymbol init) => new DynamicType(cx, init);
} }

View File

@@ -176,14 +176,14 @@ namespace Semmle.Extraction.CSharp.Entities
private class NamedTypeFactory : ICachedEntityFactory<INamedTypeSymbol, NamedType> 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); public NamedType Create(Context cx, INamedTypeSymbol init) => new NamedType(cx, init, false);
} }
private class UnderlyingTupleTypeFactory : ICachedEntityFactory<INamedTypeSymbol, NamedType> 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); 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> 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); public NamedTypeRef Create(Context cx, INamedTypeSymbol init) => new NamedTypeRef(cx, init);
} }

View File

@@ -31,7 +31,7 @@ namespace Semmle.Extraction.CSharp.Entities
private class NullTypeFactory : ICachedEntityFactory<ITypeSymbol, NullType> 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); public NullType Create(Context cx, ITypeSymbol init) => new NullType(cx);
} }

View File

@@ -129,7 +129,7 @@ namespace Semmle.Extraction.CSharp.Entities
private class NullabilityFactory : ICachedEntityFactory<Nullability, NullabilityEntity> 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); public NullabilityEntity Create(Context cx, Nullability init) => new NullabilityEntity(cx, init);
} }

View File

@@ -33,7 +33,7 @@ namespace Semmle.Extraction.CSharp.Entities
private class PointerTypeFactory : ICachedEntityFactory<IPointerTypeSymbol, PointerType> 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); public PointerType Create(Context cx, IPointerTypeSymbol init) => new PointerType(cx, init);
} }

View File

@@ -17,7 +17,7 @@ namespace Semmle.Extraction.CSharp.Entities
private class TupleTypeFactory : ICachedEntityFactory<INamedTypeSymbol, TupleType> 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); public TupleType Create(Context cx, INamedTypeSymbol init) => new TupleType(cx, init);
} }

View File

@@ -305,7 +305,7 @@ namespace Semmle.Extraction.CSharp.Entities
private class DelegateTypeParameterFactory : ICachedEntityFactory<(IParameterSymbol, IEntity, Parameter), DelegateTypeParameter> 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) => public DelegateTypeParameter Create(Context cx, (IParameterSymbol, IEntity, Parameter) init) =>
new DelegateTypeParameter(cx, init.Item1, init.Item2, init.Item3); new DelegateTypeParameter(cx, init.Item1, init.Item2, init.Item3);

View File

@@ -129,7 +129,7 @@ namespace Semmle.Extraction.CSharp.Entities
private class TypeParameterFactory : ICachedEntityFactory<ITypeParameterSymbol, TypeParameter> 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); public TypeParameter Create(Context cx, ITypeParameterSymbol init) => new TypeParameter(cx, init);
} }

View File

@@ -187,7 +187,7 @@ namespace Semmle.Extraction.CSharp.Entities
private class UserOperatorFactory : ICachedEntityFactory<IMethodSymbol, UserOperator> 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); public UserOperator Create(Context cx, IMethodSymbol init) => new UserOperator(cx, init);
} }

View File

@@ -53,7 +53,7 @@ namespace Semmle.Extraction.Entities
private class AssemblyConstructorFactory : ICachedEntityFactory<Microsoft.CodeAnalysis.Location?, Assembly> 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); public Assembly Create(Context cx, Microsoft.CodeAnalysis.Location? init) => new Assembly(cx, init);
} }

View File

@@ -78,7 +78,7 @@ namespace Semmle.Extraction.Entities
private class GeneratedFileFactory : ICachedEntityFactory<string?, GeneratedFile> 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); public GeneratedFile Create(Context cx, string? init) => new GeneratedFile(cx);
} }
@@ -88,7 +88,7 @@ namespace Semmle.Extraction.Entities
private class FileFactory : ICachedEntityFactory<string, File> 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); public File Create(Context cx, string init) => new File(cx, init);
} }

View File

@@ -28,7 +28,7 @@ namespace Semmle.Extraction.Entities
private class FolderFactory : ICachedEntityFactory<PathTransformer.ITransformedPath, Folder> 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); public Folder Create(Context cx, PathTransformer.ITransformedPath init) => new Folder(cx, init);
} }

View File

@@ -32,7 +32,7 @@ namespace Semmle.Extraction.Entities
private class GeneratedLocationFactory : ICachedEntityFactory<string?, GeneratedLocation> 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); public GeneratedLocation Create(Context cx, string? init) => new GeneratedLocation(cx);
} }

View File

@@ -58,7 +58,7 @@ namespace Semmle.Extraction.Entities
private class SourceLocationFactory : ICachedEntityFactory<Microsoft.CodeAnalysis.Location, SourceLocation> 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); public SourceLocation Create(Context cx, Microsoft.CodeAnalysis.Location init) => new NonGeneratedSourceLocation(cx, init);
} }

View File

@@ -101,11 +101,6 @@ namespace Semmle.Extraction
/// </summary> /// </summary>
public class Extractor : IExtractor 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 public bool Standalone
{ {
get; private set; get; private set;

View File

@@ -116,7 +116,7 @@ namespace Semmle.Extraction
public int Value { get; private set; } 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; public bool Valid => Value > 0;

View File

@@ -171,7 +171,7 @@ namespace Semmle.Extraction
{ {
private readonly List<FilePattern> filePatterns = new List<FilePattern>(); 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) private static string? ReadVariable(string name, string line)
{ {

View File

@@ -12,7 +12,7 @@ namespace Semmle.Extraction
/// <summary> /// <summary>
/// The specified number of threads, or the default if unspecified. /// The specified number of threads, or the default if unspecified.
/// </summary> /// </summary>
public int Threads { get; private set; } = Extractor.DefaultNumberOfThreads; public int Threads { get; private set; } = System.Environment.ProcessorCount;
/// <summary> /// <summary>
/// The verbosity used in output and logging. /// The verbosity used in output and logging.

View File

@@ -40,7 +40,17 @@ abstract class OperandTag extends TOperandTag {
/** /**
* Gets a label that will appear before the operand when the IR is printed. * 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 int getSortOrder() { result = 0 }
final override string getLabel() { result = "&:" } final override predicate alwaysPrintLabel() { any() }
final override string getId() { result = "&" }
} }
AddressOperandTag addressOperand() { result = TAddressOperand() } AddressOperandTag addressOperand() { result = TAddressOperand() }
@@ -82,6 +94,8 @@ class BufferSizeOperandTag extends RegisterOperandTag, TBufferSizeOperand {
final override string toString() { result = "BufferSize" } final override string toString() { result = "BufferSize" }
final override int getSortOrder() { result = 1 } final override int getSortOrder() { result = 1 }
final override string getId() { result = "size" }
} }
BufferSizeOperandTag bufferSizeOperand() { result = TBufferSizeOperand() } BufferSizeOperandTag bufferSizeOperand() { result = TBufferSizeOperand() }
@@ -93,6 +107,8 @@ class SideEffectOperandTag extends TypedOperandTag, TSideEffectOperand {
final override string toString() { result = "SideEffect" } final override string toString() { result = "SideEffect" }
final override int getSortOrder() { result = 2 } final override int getSortOrder() { result = 2 }
final override string getId() { result = "side_effect" }
} }
SideEffectOperandTag sideEffectOperand() { result = TSideEffectOperand() } SideEffectOperandTag sideEffectOperand() { result = TSideEffectOperand() }
@@ -105,6 +121,8 @@ class LoadOperandTag extends TypedOperandTag, TLoadOperand {
final override string toString() { result = "Load" } final override string toString() { result = "Load" }
final override int getSortOrder() { result = 3 } final override int getSortOrder() { result = 3 }
final override string getId() { result = "load" }
} }
LoadOperandTag loadOperand() { result = TLoadOperand() } LoadOperandTag loadOperand() { result = TLoadOperand() }
@@ -116,6 +134,8 @@ class StoreValueOperandTag extends RegisterOperandTag, TStoreValueOperand {
final override string toString() { result = "StoreValue" } final override string toString() { result = "StoreValue" }
final override int getSortOrder() { result = 4 } final override int getSortOrder() { result = 4 }
final override string getId() { result = "store" }
} }
StoreValueOperandTag storeValueOperand() { result = TStoreValueOperand() } StoreValueOperandTag storeValueOperand() { result = TStoreValueOperand() }
@@ -127,6 +147,8 @@ class UnaryOperandTag extends RegisterOperandTag, TUnaryOperand {
final override string toString() { result = "Unary" } final override string toString() { result = "Unary" }
final override int getSortOrder() { result = 5 } final override int getSortOrder() { result = 5 }
final override string getId() { result = "unary" }
} }
UnaryOperandTag unaryOperand() { result = TUnaryOperand() } UnaryOperandTag unaryOperand() { result = TUnaryOperand() }
@@ -138,6 +160,8 @@ class LeftOperandTag extends RegisterOperandTag, TLeftOperand {
final override string toString() { result = "Left" } final override string toString() { result = "Left" }
final override int getSortOrder() { result = 6 } final override int getSortOrder() { result = 6 }
final override string getId() { result = "left" }
} }
LeftOperandTag leftOperand() { result = TLeftOperand() } LeftOperandTag leftOperand() { result = TLeftOperand() }
@@ -149,6 +173,8 @@ class RightOperandTag extends RegisterOperandTag, TRightOperand {
final override string toString() { result = "Right" } final override string toString() { result = "Right" }
final override int getSortOrder() { result = 7 } final override int getSortOrder() { result = 7 }
final override string getId() { result = "right" }
} }
RightOperandTag rightOperand() { result = TRightOperand() } RightOperandTag rightOperand() { result = TRightOperand() }
@@ -160,6 +186,8 @@ class ConditionOperandTag extends RegisterOperandTag, TConditionOperand {
final override string toString() { result = "Condition" } final override string toString() { result = "Condition" }
final override int getSortOrder() { result = 8 } final override int getSortOrder() { result = 8 }
final override string getId() { result = "cond" }
} }
ConditionOperandTag conditionOperand() { result = TConditionOperand() } ConditionOperandTag conditionOperand() { result = TConditionOperand() }
@@ -172,7 +200,9 @@ class CallTargetOperandTag extends RegisterOperandTag, TCallTargetOperand {
final override int getSortOrder() { result = 10 } 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() } CallTargetOperandTag callTargetOperand() { result = TCallTargetOperand() }
@@ -195,7 +225,9 @@ class ThisArgumentOperandTag extends ArgumentOperandTag, TThisArgumentOperand {
final override int getSortOrder() { result = 11 } 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() } ThisArgumentOperandTag thisArgumentOperand() { result = TThisArgumentOperand() }
@@ -212,9 +244,11 @@ class PositionalArgumentOperandTag extends ArgumentOperandTag, TPositionalArgume
final override int getSortOrder() { result = 12 + argIndex } 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 int getArgIndex() { result = argIndex }
final override string getId() { result = argIndex.toString() }
} }
PositionalArgumentOperandTag positionalArgumentOperand(int argIndex) { PositionalArgumentOperandTag positionalArgumentOperand(int argIndex) {
@@ -228,7 +262,9 @@ class ChiTotalOperandTag extends ChiOperandTag, TChiTotalOperand {
final override int getSortOrder() { result = 13 } 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() } ChiTotalOperandTag chiTotalOperand() { result = TChiTotalOperand() }
@@ -238,7 +274,9 @@ class ChiPartialOperandTag extends ChiOperandTag, TChiPartialOperand {
final override int getSortOrder() { result = 14 } 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() } ChiPartialOperandTag chiPartialOperand() { result = TChiPartialOperand() }
@@ -252,7 +290,9 @@ class AsmOperandTag extends RegisterOperandTag, TAsmOperand {
final override int getSortOrder() { result = 15 + index } 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) } AsmOperandTag asmOperand(int index) { result = TAsmOperand(index) }

View File

@@ -72,4 +72,9 @@ class IRPropertyProvider extends TIRPropertyProvider {
* Gets the value of the property named `key` for the specified block. * Gets the value of the property named `key` for the specified block.
*/ */
string getBlockProperty(IRBlock block, string key) { none() } 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() }
} }

View File

@@ -1501,6 +1501,12 @@ class SwitchInstruction extends Instruction {
class CallInstruction extends Instruction { class CallInstruction extends Instruction {
CallInstruction() { getOpcode() instanceof Opcode::Call } 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. * Gets the operand the specifies the target function of the call.
*/ */

View File

@@ -151,6 +151,11 @@ class Operand extends TOperand {
*/ */
string getDumpLabel() { result = "" } 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 * 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 * 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 getDumpLabel() { result = tag.getLabel() }
final override string getDumpId() { result = tag.getId() }
final override int getDumpSortOrder() { result = tag.getSortOrder() } final override int getDumpSortOrder() { result = tag.getSortOrder() }
/** /**
@@ -477,6 +484,8 @@ class PhiInputOperand extends MemoryOperand, PhiOperandBase {
result = "from " + getPredecessorBlock().getDisplayIndex().toString() + ":" result = "from " + getPredecessorBlock().getDisplayIndex().toString() + ":"
} }
final override string getDumpId() { result = getPredecessorBlock().getDisplayIndex().toString() }
/** /**
* Gets the predecessor block from which this value comes. * Gets the predecessor block from which this value comes.
*/ */

View File

@@ -50,6 +50,37 @@ private string getAdditionalBlockProperty(IRBlock block, string key) {
exists(IRPropertyProvider provider | result = provider.getBlockProperty(block, 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 = private newtype TPrintableIRNode =
TPrintableIRFunction(IRFunction irFunc) { shouldPrintFunction(irFunc.getFunction()) } or TPrintableIRFunction(IRFunction irFunc) { shouldPrintFunction(irFunc.getFunction()) } or
TPrintableIRBlock(IRBlock block) { shouldPrintFunction(block.getEnclosingFunction()) } or TPrintableIRBlock(IRBlock block) { shouldPrintFunction(block.getEnclosingFunction()) } or
@@ -190,7 +221,7 @@ private class PrintableInstruction extends PrintableIRNode, TPrintableInstructio
| |
resultString = instr.getResultString() and resultString = instr.getResultString() and
operationString = instr.getOperationString() and operationString = instr.getOperationString() and
operandsString = instr.getOperandsString() and operandsString = getOperandsString() and
columnWidths(block, resultWidth, operationWidth) and columnWidths(block, resultWidth, operationWidth) and
result = result =
resultString + getPaddingString(resultWidth - resultString.length()) + " = " + resultString + getPaddingString(resultWidth - resultString.length()) + " = " +
@@ -210,6 +241,22 @@ private class PrintableInstruction extends PrintableIRNode, TPrintableInstructio
result = PrintableIRNode.super.getProperty(key) or result = PrintableIRNode.super.getProperty(key) or
result = getAdditionalInstructionProperty(instr, key) 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) { private predicate columnWidths(IRBlock block, int resultWidth, int operationWidth) {

View File

@@ -72,4 +72,9 @@ class IRPropertyProvider extends TIRPropertyProvider {
* Gets the value of the property named `key` for the specified block. * Gets the value of the property named `key` for the specified block.
*/ */
string getBlockProperty(IRBlock block, string key) { none() } 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() }
} }

View File

@@ -1501,6 +1501,12 @@ class SwitchInstruction extends Instruction {
class CallInstruction extends Instruction { class CallInstruction extends Instruction {
CallInstruction() { getOpcode() instanceof Opcode::Call } 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. * Gets the operand the specifies the target function of the call.
*/ */

View File

@@ -151,6 +151,11 @@ class Operand extends TOperand {
*/ */
string getDumpLabel() { result = "" } 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 * 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 * 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 getDumpLabel() { result = tag.getLabel() }
final override string getDumpId() { result = tag.getId() }
final override int getDumpSortOrder() { result = tag.getSortOrder() } final override int getDumpSortOrder() { result = tag.getSortOrder() }
/** /**
@@ -477,6 +484,8 @@ class PhiInputOperand extends MemoryOperand, PhiOperandBase {
result = "from " + getPredecessorBlock().getDisplayIndex().toString() + ":" result = "from " + getPredecessorBlock().getDisplayIndex().toString() + ":"
} }
final override string getDumpId() { result = getPredecessorBlock().getDisplayIndex().toString() }
/** /**
* Gets the predecessor block from which this value comes. * Gets the predecessor block from which this value comes.
*/ */

View File

@@ -50,6 +50,37 @@ private string getAdditionalBlockProperty(IRBlock block, string key) {
exists(IRPropertyProvider provider | result = provider.getBlockProperty(block, 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 = private newtype TPrintableIRNode =
TPrintableIRFunction(IRFunction irFunc) { shouldPrintFunction(irFunc.getFunction()) } or TPrintableIRFunction(IRFunction irFunc) { shouldPrintFunction(irFunc.getFunction()) } or
TPrintableIRBlock(IRBlock block) { shouldPrintFunction(block.getEnclosingFunction()) } or TPrintableIRBlock(IRBlock block) { shouldPrintFunction(block.getEnclosingFunction()) } or
@@ -190,7 +221,7 @@ private class PrintableInstruction extends PrintableIRNode, TPrintableInstructio
| |
resultString = instr.getResultString() and resultString = instr.getResultString() and
operationString = instr.getOperationString() and operationString = instr.getOperationString() and
operandsString = instr.getOperandsString() and operandsString = getOperandsString() and
columnWidths(block, resultWidth, operationWidth) and columnWidths(block, resultWidth, operationWidth) and
result = result =
resultString + getPaddingString(resultWidth - resultString.length()) + " = " + resultString + getPaddingString(resultWidth - resultString.length()) + " = " +
@@ -210,6 +241,22 @@ private class PrintableInstruction extends PrintableIRNode, TPrintableInstructio
result = PrintableIRNode.super.getProperty(key) or result = PrintableIRNode.super.getProperty(key) or
result = getAdditionalInstructionProperty(instr, key) 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) { private predicate columnWidths(IRBlock block, int resultWidth, int operationWidth) {

View File

@@ -11,10 +11,7 @@ cached
private newtype TCallContext = private newtype TCallContext =
TEmptyCallContext() or TEmptyCallContext() or
TArgNonDelegateCallContext(Expr arg) { exists(DispatchCall dc | arg = dc.getArgument(_)) } or TArgNonDelegateCallContext(Expr arg) { exists(DispatchCall dc | arg = dc.getArgument(_)) } or
TArgDelegateCallContext(DelegateCall dc, int i) { exists(dc.getArgument(i)) } or TArgDelegateCallContext(DelegateCall dc, int i) { exists(dc.getArgument(i)) }
TDelegateToLibraryCallableArgCallContext(DelegateArgumentToLibraryCallable arg, int i) {
exists(arg.getDelegateType().getParameter(i))
}
/** /**
* A call context. * A call context.
@@ -79,31 +76,3 @@ class DelegateCallArgumentCallContext extends ArgumentCallContext, TArgDelegateC
override Location getLocation() { result = dc.getArgument(arg).getLocation() } 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() }
}

View File

@@ -199,27 +199,13 @@ class CallableFlowSink extends TCallableFlowSink {
/** Gets the sink of flow for call `c`, if any. */ /** Gets the sink of flow for call `c`, if any. */
Expr getSink(Call c) { none() } 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. */ /** A flow sink specification: (method call) qualifier. */
class CallableFlowSinkQualifier extends CallableFlowSink, TCallableFlowSinkQualifier { class CallableFlowSinkQualifier extends CallableFlowSink, TCallableFlowSinkQualifier {
override string toString() { result = "qualifier" } override string toString() { result = "qualifier" }
override Expr getSink(Call c) { override Expr getSink(Call c) { result = c.getChild(-1) }
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
}
} }
/** A flow sink specification: return value. */ /** 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 // The uses of the `i`th argument are the actual sinks
none() none()
} }
override Type getSinkType(Call c) { result = this.getArgument(c).getType() }
} }
private predicate isCollectionType(ValueOrRefType t) { 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 // The uses of the `j`th parameter are the actual sinks
none() 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. */ /** A specification of data flow for a library (non-source code) type. */

View File

@@ -1018,7 +1018,7 @@ module Ssa {
private predicate intraInstanceCallEdge(Callable c1, InstanceCallable c2) { private predicate intraInstanceCallEdge(Callable c1, InstanceCallable c2) {
exists(Call c | exists(Call c |
c.getEnclosingCallable() = c1 and c.getEnclosingCallable() = c1 and
c2 = getARuntimeTarget(c) and c2 = getARuntimeTarget(c, _) and
c.(QualifiableExpr).targetIsLocalInstance() c.(QualifiableExpr).targetIsLocalInstance()
) )
} }
@@ -1034,15 +1034,28 @@ module Ssa {
* the SSA library and `Call.getARuntimeTarget()` mutually recursive), and * the SSA library and `Call.getARuntimeTarget()` mutually recursive), and
* *
* (3) indirect calls to delegates via calls to library callables are included. * (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 // Non-delegate call: use dispatch library
exists(DispatchCall dc | dc.getCall() = c | exists(DispatchCall dc | dc.getCall() = c |
result = dc.getADynamicTarget().getSourceDeclaration() result = dc.getADynamicTarget().getSourceDeclaration() and
libraryDelegateCall = false
) )
or or
// Delegate call: use simple analysis // Delegate call: use simple analysis
result = SimpleDelegateAnalysis::getARuntimeDelegateTarget(c) result = SimpleDelegateAnalysis::getARuntimeDelegateTarget(c, libraryDelegateCall)
} }
private module SimpleDelegateAnalysis { 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 * 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. * a library callable and `e` is a delegate argument.
*/ */
private predicate delegateCall(Call c, Expr e) { private predicate delegateCall(Call c, Expr e, boolean libraryDelegateCall) {
c = any(DelegateCall dc | e = dc.getDelegateExpr()) c = any(DelegateCall dc | e = dc.getDelegateExpr()) and
libraryDelegateCall = false
or or
c.getTarget().fromLibrary() and c.getTarget().fromLibrary() and
e = c.getAnArgument() 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`. */ /** 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() or
callable = call.getTarget().(Method).getAnOverrider+() or callable = call.getTarget().(Method).getAnOverrider+() or
callable = call.getTarget().(Method).getAnUltimateImplementor() or callable = call.getTarget().(Method).getAnUltimateImplementor() or
callable = getARuntimeDelegateTarget(call) callable = getARuntimeDelegateTarget(call, false)
) )
or or
pred = succ.(DelegateCreation).getArgument() pred = succ.(DelegateCreation).getArgument()
@@ -1110,7 +1125,7 @@ module Ssa {
} }
private predicate reachesDelegateCall(Expr e) { private predicate reachesDelegateCall(Expr e) {
delegateCall(_, e) delegateCall(_, e, _)
or or
exists(Expr mid | reachesDelegateCall(mid) | delegateFlowStep(e, mid)) exists(Expr mid | reachesDelegateCall(mid) | delegateFlowStep(e, mid))
} }
@@ -1128,12 +1143,14 @@ module Ssa {
} }
/** Gets a run-time target for the delegate call `c`. */ /** 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. */ /** Holds if `(c1,c2)` is an edge in the call graph. */
predicate callEdge(Callable c1, Callable c2) { 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] pragma[noinline]
predicate callAt(BasicBlock bb, int i, Call call) { predicate callAt(BasicBlock bb, int i, Call call) {
bb.getNode(i) = call.getAControlFlowNode() and bb.getNode(i) = call.getAControlFlowNode() and
getARuntimeTarget(call).hasBody() getARuntimeTarget(call, _).hasBody()
} }
/** /**
@@ -1201,7 +1218,7 @@ module Ssa {
private predicate pruneFromLeft(Callable c) { private predicate pruneFromLeft(Callable c) {
exists(Call call, TrackedFieldOrProp f | exists(Call call, TrackedFieldOrProp f |
updateCandidate(_, _, f, call) and updateCandidate(_, _, f, call) and
c = getARuntimeTarget(call) and c = getARuntimeTarget(call, _) and
generalSetter(_, f.getAssignable(), _) generalSetter(_, f.getAssignable(), _)
) )
or or
@@ -1238,7 +1255,7 @@ module Ssa {
updateCandidate(_, _, tfp, call) and updateCandidate(_, _, tfp, call) and
fp = tfp.getAssignable() and fp = tfp.getAssignable() and
generalSetter(_, fp, _) and generalSetter(_, fp, _) and
c1 = getARuntimeTarget(call) c1 = getARuntimeTarget(call, _)
} }
pragma[noinline] pragma[noinline]
@@ -1279,7 +1296,7 @@ module Ssa {
Call call, TrackedFieldOrProp tfp, Callable setter Call call, TrackedFieldOrProp tfp, Callable setter
) { ) {
updateCandidate(_, _, tfp, call) and updateCandidate(_, _, tfp, call) and
setsOwnFieldOrPropTransitive(getARuntimeTarget(call), tfp.getAssignable(), setter) setsOwnFieldOrPropTransitive(getARuntimeTarget(call, _), tfp.getAssignable(), setter)
} }
private predicate updatesNamedFieldOrPropPossiblyLive( private predicate updatesNamedFieldOrPropPossiblyLive(
@@ -1447,7 +1464,7 @@ module Ssa {
private predicate pruneFromLeft(Callable c) { private predicate pruneFromLeft(Callable c) {
exists(Call call, CapturedWrittenLocalScopeSourceVariable v | exists(Call call, CapturedWrittenLocalScopeSourceVariable v |
updateCandidate(_, _, v, call) and updateCandidate(_, _, v, call) and
c = getARuntimeTarget(call) and c = getARuntimeTarget(call, _) and
relevantDefinition(_, v.getAssignable(), _) relevantDefinition(_, v.getAssignable(), _)
) )
or or
@@ -1485,12 +1502,12 @@ module Ssa {
pragma[noinline] pragma[noinline]
private predicate updatesCapturedVariablePrefix( private predicate updatesCapturedVariablePrefix(
Call call, CapturedWrittenLocalScopeSourceVariable v, PrunedCallable c, Call call, CapturedWrittenLocalScopeSourceVariable v, PrunedCallable c,
CapturedWrittenLocalScopeVariable captured CapturedWrittenLocalScopeVariable captured, boolean libraryDelegateCall
) { ) {
updateCandidate(_, _, v, call) and updateCandidate(_, _, v, call) and
captured = v.getAssignable() and captured = v.getAssignable() and
relevantDefinitionProj(_, captured) and relevantDefinitionProj(_, captured) and
c = getARuntimeTarget(call) c = getARuntimeTarget(call, libraryDelegateCall)
} }
/** /**
@@ -1505,11 +1522,13 @@ module Ssa {
Call call, CapturedWrittenLocalScopeSourceVariable v, PrunedCallable writer, Call call, CapturedWrittenLocalScopeSourceVariable v, PrunedCallable writer,
boolean additionalCalls boolean additionalCalls
) { ) {
exists(PrunedCallable c, CapturedWrittenLocalScopeVariable captured | exists(
updatesCapturedVariablePrefix(call, v, c, captured) and PrunedCallable c, CapturedWrittenLocalScopeVariable captured, boolean libraryDelegateCall
|
updatesCapturedVariablePrefix(call, v, c, captured, libraryDelegateCall) and
relevantDefinitionProj(writer, captured) and relevantDefinitionProj(writer, captured) and
( (
c = writer and additionalCalls = false c = writer and additionalCalls = libraryDelegateCall
or or
callEdgePrunedPlus(c, writer) and additionalCalls = true callEdgePrunedPlus(c, writer) and additionalCalls = true
) )
@@ -1667,7 +1686,7 @@ module Ssa {
private predicate pruneFromLeft(Callable c) { private predicate pruneFromLeft(Callable c) {
exists(Call call, CapturedReadLocalScopeSourceVariable v | exists(Call call, CapturedReadLocalScopeSourceVariable v |
implicitReadCandidate(_, _, call.getAControlFlowNode(), v) and implicitReadCandidate(_, _, call.getAControlFlowNode(), v) and
c = getARuntimeTarget(call) c = getARuntimeTarget(call, _)
) )
or or
exists(Callable mid | pruneFromLeft(mid) | callEdge(mid, c)) exists(Callable mid | pruneFromLeft(mid) | callEdge(mid, c))
@@ -1702,12 +1721,12 @@ module Ssa {
pragma[noinline] pragma[noinline]
private predicate readsCapturedVariablePrefix( private predicate readsCapturedVariablePrefix(
ControlFlow::Node call, CapturedReadLocalScopeSourceVariable v, PrunedCallable c, ControlFlow::Node call, CapturedReadLocalScopeSourceVariable v, PrunedCallable c,
CapturedReadLocalScopeVariable captured CapturedReadLocalScopeVariable captured, boolean libraryDelegateCall
) { ) {
implicitReadCandidate(_, _, call, v) and implicitReadCandidate(_, _, call, v) and
captured = v.getAssignable() and captured = v.getAssignable() and
capturerReads(_, captured) 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, ControlFlow::Nodes::ElementNode call, CapturedReadLocalScopeSourceVariable v, Callable reader,
boolean additionalCalls boolean additionalCalls
) { ) {
exists(PrunedCallable c, CapturedReadLocalScopeVariable captured | exists(
readsCapturedVariablePrefix(call, v, c, captured) and PrunedCallable c, CapturedReadLocalScopeVariable captured, boolean libraryDelegateCall
|
readsCapturedVariablePrefix(call, v, c, captured, libraryDelegateCall) and
capturerReads(reader, captured) and capturerReads(reader, captured) and
( (
c = reader and additionalCalls = false c = reader and additionalCalls = libraryDelegateCall
or or
callEdgePrunedPlus(c, reader) and additionalCalls = true callEdgePrunedPlus(c, reader) and additionalCalls = true
) )
@@ -1765,7 +1786,6 @@ module Ssa {
def.getSourceVariable().getAssignable() = lsv def.getSourceVariable().getAssignable() = lsv
| |
lsv = v.getAssignable() and lsv = v.getAssignable() and
adef = def.getAPossibleDefinition() and
bb.getNode(i) = adef.getAControlFlowNode() and bb.getNode(i) = adef.getAControlFlowNode() and
updatesCapturedVariable(def.getCall(), _, adef, additionalCalls) updatesCapturedVariable(def.getCall(), _, adef, additionalCalls)
) )

View File

@@ -3,18 +3,24 @@ private import cil
private import dotnet private import dotnet
private import DataFlowPrivate private import DataFlowPrivate
private import DelegateDataFlow private import DelegateDataFlow
private import semmle.code.csharp.dataflow.LibraryTypeDataFlow
private import semmle.code.csharp.dispatch.Dispatch private import semmle.code.csharp.dispatch.Dispatch
private import semmle.code.csharp.frameworks.system.Collections private import semmle.code.csharp.frameworks.system.Collections
private import semmle.code.csharp.frameworks.system.collections.Generic 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 * If the callable has both CIL and source code, return only the source
* code version. * code version.
*/ */
DotNet::Callable getCallableForDataFlow(DotNet::Callable c) { DotNet::Callable getCallableForDataFlow(DotNet::Callable c) {
result.hasBody() and
exists(DotNet::Callable sourceDecl | sourceDecl = c.getSourceDeclaration() | exists(DotNet::Callable sourceDecl | sourceDecl = c.getSourceDeclaration() |
result = sourceDecl and
Summaries::summary(result, _, _, _, _, _)
or
result.hasBody() and
if sourceDecl.getFile().fromSource() if sourceDecl.getFile().fromSource()
then then
// C# callable with C# implementation in the database // C# callable with C# implementation in the database
@@ -83,7 +89,8 @@ private module Cached {
exists(Ssa::ExplicitDefinition def | def.isCapturedVariableDefinitionFlowOut(_, _) | exists(Ssa::ExplicitDefinition def | def.isCapturedVariableDefinitionFlowOut(_, _) |
v = def.getSourceVariable().getAssignable() v = def.getSourceVariable().getAssignable()
) )
} } or
TQualifierReturnKind()
cached cached
newtype TDataFlowCall = newtype TDataFlowCall =
@@ -93,15 +100,23 @@ private module Cached {
TExplicitDelegateCall(ControlFlow::Nodes::ElementNode cfn, DelegateCall dc) { TExplicitDelegateCall(ControlFlow::Nodes::ElementNode cfn, DelegateCall dc) {
cfn.getElement() = dc cfn.getElement() = dc
} or } or
TImplicitDelegateCall(ControlFlow::Nodes::ElementNode cfn, DelegateArgumentToLibraryCallable arg) {
cfn.getElement() = arg
} or
TTransitiveCapturedCall(ControlFlow::Nodes::ElementNode cfn, Callable target) { TTransitiveCapturedCall(ControlFlow::Nodes::ElementNode cfn, Callable target) {
transitiveCapturedCallTarget(cfn, target) transitiveCapturedCallTarget(cfn, target)
} or } or
TCilCall(CIL::Call call) { TCilCall(CIL::Call call) {
// No need to include calls that are compiled from source // No need to include calls that are compiled from source
not call.getImplementation().getMethod().compiledFromSource() 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`. */ /** 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 * Gets a viable run-time target for the delegate call `call`, requiring
* call context `cc`. * call context `cc`.
*/ */
private DotNet::Callable viableDelegateCallable(DataFlowCall call, CallContext cc) { private DataFlowCallable viableDelegateCallable(DataFlowCall call, CallContext cc) {
result = call.(DelegateDataFlowCall).getARuntimeTarget(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 * 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. * 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) | exists(ArgumentCallContext cc | result = viableDelegateCallable(call, cc) |
cc.isArgument(ctx.getExpr(), _) cc.isArgument(ctx.getExpr(), _)
) )
@@ -153,6 +168,7 @@ private module DispatchImpl {
.(NonDelegateDataFlowCall) .(NonDelegateDataFlowCall)
.getDispatchCall() .getDispatchCall()
.getADynamicTargetInCallContext(ctx.(NonDelegateDataFlowCall).getDispatchCall()) .getADynamicTargetInCallContext(ctx.(NonDelegateDataFlowCall).getDispatchCall())
.getSourceDeclaration()
} }
} }
@@ -218,6 +234,11 @@ class ImplicitCapturedReturnKind extends ReturnKind, TImplicitCapturedReturnKind
override string toString() { result = "captured " + v } 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; class DataFlowCallable = DotNet::Callable;
/** A call relevant for data flow. */ /** A call relevant for data flow. */
@@ -261,7 +282,7 @@ class NonDelegateDataFlowCall extends DataFlowCall, TNonDelegateCall {
/** Gets the underlying call. */ /** Gets the underlying call. */
DispatchCall getDispatchCall() { result = dc } DispatchCall getDispatchCall() { result = dc }
override DotNet::Callable getARuntimeTarget() { override DataFlowCallable getARuntimeTarget() {
result = getCallableForDataFlow(dc.getADynamicTarget()) result = getCallableForDataFlow(dc.getADynamicTarget())
} }
@@ -279,9 +300,9 @@ class NonDelegateDataFlowCall extends DataFlowCall, TNonDelegateCall {
/** A delegate call relevant for data flow. */ /** A delegate call relevant for data flow. */
abstract class DelegateDataFlowCall extends DataFlowCall { abstract class DelegateDataFlowCall extends DataFlowCall {
/** Gets a viable run-time target of this call requiring call context `cc`. */ /** 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. */ /** An explicit delegate call relevant for data flow. */
@@ -291,8 +312,8 @@ class ExplicitDelegateDataFlowCall extends DelegateDataFlowCall, TExplicitDelega
ExplicitDelegateDataFlowCall() { this = TExplicitDelegateCall(cfn, dc) } ExplicitDelegateDataFlowCall() { this = TExplicitDelegateCall(cfn, dc) }
override DotNet::Callable getARuntimeTarget(CallContext::CallContext cc) { override DataFlowCallable getARuntimeTarget(CallContext::CallContext cc) {
result = dc.getARuntimeTarget(cc) result = getCallableForDataFlow(dc.getARuntimeTarget(cc))
} }
override ControlFlow::Nodes::ElementNode getControlFlowNode() { result = cfn } override ControlFlow::Nodes::ElementNode getControlFlowNode() { result = cfn }
@@ -306,50 +327,6 @@ class ExplicitDelegateDataFlowCall extends DelegateDataFlowCall, TExplicitDelega
override Location getLocation() { result = cfn.getLocation() } 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 * 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 * 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) } 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 // There is no dispatch library for CIL, so do not consider overrides for now
result = getCallableForDataFlow(call.getTarget()) result = getCallableForDataFlow(call.getTarget())
} }
@@ -395,3 +372,34 @@ class CilDataFlowCall extends DataFlowCall, TCilCall {
override Location getLocation() { result = call.getLocation() } 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() }
}

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