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
* Angular-specific taint sources and sinks are now recognized by the security queries.
* Support for the following frameworks and libraries has been improved:
- [@angular/*](https://www.npmjs.com/package/@angular/core)
- [AWS Serverless](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/sam-resource-function.html)
- [Alibaba Serverless](https://www.alibabacloud.com/help/doc-detail/156876.htm)
- [bluebird](https://www.npmjs.com/package/bluebird)

View File

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

File diff suppressed because it is too large Load Diff

View File

@@ -2,6 +2,30 @@ private import DataFlowImplSpecific::Private
private import DataFlowImplSpecific::Public
import Cached
/**
* The cost limits for the `AccessPathFront` to `AccessPathApprox` expansion.
*
* `apLimit` bounds the acceptable fan-out, and `tupleLimit` bounds the
* estimated per-`AccessPathFront` tuple cost. Access paths exceeding both of
* these limits are represented with lower precision during pruning.
*/
predicate accessPathApproxCostLimits(int apLimit, int tupleLimit) {
apLimit = 10 and
tupleLimit = 10000
}
/**
* The cost limits for the `AccessPathApprox` to `AccessPath` expansion.
*
* `apLimit` bounds the acceptable fan-out, and `tupleLimit` bounds the
* estimated per-`AccessPathApprox` tuple cost. Access paths exceeding both of
* these limits are represented with lower precision.
*/
predicate accessPathCostLimits(int apLimit, int tupleLimit) {
apLimit = 5 and
tupleLimit = 1000
}
cached
private module Cached {
/**

View File

@@ -2,6 +2,30 @@ private import DataFlowImplSpecific::Private
private import DataFlowImplSpecific::Public
import Cached
/**
* The cost limits for the `AccessPathFront` to `AccessPathApprox` expansion.
*
* `apLimit` bounds the acceptable fan-out, and `tupleLimit` bounds the
* estimated per-`AccessPathFront` tuple cost. Access paths exceeding both of
* these limits are represented with lower precision during pruning.
*/
predicate accessPathApproxCostLimits(int apLimit, int tupleLimit) {
apLimit = 10 and
tupleLimit = 10000
}
/**
* The cost limits for the `AccessPathApprox` to `AccessPath` expansion.
*
* `apLimit` bounds the acceptable fan-out, and `tupleLimit` bounds the
* estimated per-`AccessPathApprox` tuple cost. Access paths exceeding both of
* these limits are represented with lower precision.
*/
predicate accessPathCostLimits(int apLimit, int tupleLimit) {
apLimit = 5 and
tupleLimit = 1000
}
cached
private module Cached {
/**

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.
*/
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 {
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.
*/

View File

@@ -151,6 +151,11 @@ class Operand extends TOperand {
*/
string getDumpLabel() { result = "" }
/**
* Gets a string that uniquely identifies this operand on its use instruction.
*/
string getDumpId() { result = "" }
/**
* Gets a string describing this operand, suitable for display in IR dumps. This consists of the
* result ID of the instruction consumed by the operand, plus a label identifying the operand
@@ -280,6 +285,8 @@ class NonPhiOperand extends Operand {
final override string getDumpLabel() { result = tag.getLabel() }
final override string getDumpId() { result = tag.getId() }
final override int getDumpSortOrder() { result = tag.getSortOrder() }
/**
@@ -477,6 +484,8 @@ class PhiInputOperand extends MemoryOperand, PhiOperandBase {
result = "from " + getPredecessorBlock().getDisplayIndex().toString() + ":"
}
final override string getDumpId() { result = getPredecessorBlock().getDisplayIndex().toString() }
/**
* Gets the predecessor block from which this value comes.
*/

View File

@@ -50,6 +50,37 @@ private string getAdditionalBlockProperty(IRBlock block, string key) {
exists(IRPropertyProvider provider | result = provider.getBlockProperty(block, key))
}
/**
* Gets the properties of an operand from any active property providers.
*/
private string getAdditionalOperandProperty(Operand operand, string key) {
exists(IRPropertyProvider provider | result = provider.getOperandProperty(operand, key))
}
/**
* Gets a string listing the properties of the operand and their corresponding values. If the
* operand has no properties, this predicate has no result.
*/
private string getOperandPropertyListString(Operand operand) {
result =
strictconcat(string key, string value |
value = getAdditionalOperandProperty(operand, key)
|
key + ":" + value, ", "
)
}
/**
* Gets a string listing the properties of the operand and their corresponding values. The list is
* surrounded by curly braces. If the operand has no properties, this predicate returns an empty
* string.
*/
private string getOperandPropertyString(Operand operand) {
result = "{" + getOperandPropertyListString(operand) + "}"
or
not exists(getOperandPropertyListString(operand)) and result = ""
}
private newtype TPrintableIRNode =
TPrintableIRFunction(IRFunction irFunc) { shouldPrintFunction(irFunc.getFunction()) } or
TPrintableIRBlock(IRBlock block) { shouldPrintFunction(block.getEnclosingFunction()) } or
@@ -190,7 +221,7 @@ private class PrintableInstruction extends PrintableIRNode, TPrintableInstructio
|
resultString = instr.getResultString() and
operationString = instr.getOperationString() and
operandsString = instr.getOperandsString() and
operandsString = getOperandsString() and
columnWidths(block, resultWidth, operationWidth) and
result =
resultString + getPaddingString(resultWidth - resultString.length()) + " = " +
@@ -210,6 +241,22 @@ private class PrintableInstruction extends PrintableIRNode, TPrintableInstructio
result = PrintableIRNode.super.getProperty(key) or
result = getAdditionalInstructionProperty(instr, key)
}
/**
* Gets the string representation of the operand list. This is the same as
* `Instruction::getOperandsString()`, except that each operand is annotated with any properties
* provided by active `IRPropertyProvider` instances.
*/
private string getOperandsString() {
result =
concat(Operand operand |
operand = instr.getAnOperand()
|
operand.getDumpString() + getOperandPropertyString(operand), ", "
order by
operand.getDumpSortOrder()
)
}
}
private predicate columnWidths(IRBlock block, int resultWidth, int operationWidth) {

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.
*/
string getLabel() { result = "" }
final string getLabel() { if alwaysPrintLabel() then result = getId() + ":" else result = "" }
/**
* Gets an identifier that uniquely identifies this operand within its instruction.
*/
abstract string getId();
/**
* Holds if the operand should always be prefixed with its label in the dump of its instruction.
*/
predicate alwaysPrintLabel() { none() }
}
/**
@@ -69,7 +79,9 @@ class AddressOperandTag extends RegisterOperandTag, TAddressOperand {
final override int getSortOrder() { result = 0 }
final override string getLabel() { result = "&:" }
final override predicate alwaysPrintLabel() { any() }
final override string getId() { result = "&" }
}
AddressOperandTag addressOperand() { result = TAddressOperand() }
@@ -82,6 +94,8 @@ class BufferSizeOperandTag extends RegisterOperandTag, TBufferSizeOperand {
final override string toString() { result = "BufferSize" }
final override int getSortOrder() { result = 1 }
final override string getId() { result = "size" }
}
BufferSizeOperandTag bufferSizeOperand() { result = TBufferSizeOperand() }
@@ -93,6 +107,8 @@ class SideEffectOperandTag extends TypedOperandTag, TSideEffectOperand {
final override string toString() { result = "SideEffect" }
final override int getSortOrder() { result = 2 }
final override string getId() { result = "side_effect" }
}
SideEffectOperandTag sideEffectOperand() { result = TSideEffectOperand() }
@@ -105,6 +121,8 @@ class LoadOperandTag extends TypedOperandTag, TLoadOperand {
final override string toString() { result = "Load" }
final override int getSortOrder() { result = 3 }
final override string getId() { result = "load" }
}
LoadOperandTag loadOperand() { result = TLoadOperand() }
@@ -116,6 +134,8 @@ class StoreValueOperandTag extends RegisterOperandTag, TStoreValueOperand {
final override string toString() { result = "StoreValue" }
final override int getSortOrder() { result = 4 }
final override string getId() { result = "store" }
}
StoreValueOperandTag storeValueOperand() { result = TStoreValueOperand() }
@@ -127,6 +147,8 @@ class UnaryOperandTag extends RegisterOperandTag, TUnaryOperand {
final override string toString() { result = "Unary" }
final override int getSortOrder() { result = 5 }
final override string getId() { result = "unary" }
}
UnaryOperandTag unaryOperand() { result = TUnaryOperand() }
@@ -138,6 +160,8 @@ class LeftOperandTag extends RegisterOperandTag, TLeftOperand {
final override string toString() { result = "Left" }
final override int getSortOrder() { result = 6 }
final override string getId() { result = "left" }
}
LeftOperandTag leftOperand() { result = TLeftOperand() }
@@ -149,6 +173,8 @@ class RightOperandTag extends RegisterOperandTag, TRightOperand {
final override string toString() { result = "Right" }
final override int getSortOrder() { result = 7 }
final override string getId() { result = "right" }
}
RightOperandTag rightOperand() { result = TRightOperand() }
@@ -160,6 +186,8 @@ class ConditionOperandTag extends RegisterOperandTag, TConditionOperand {
final override string toString() { result = "Condition" }
final override int getSortOrder() { result = 8 }
final override string getId() { result = "cond" }
}
ConditionOperandTag conditionOperand() { result = TConditionOperand() }
@@ -172,7 +200,9 @@ class CallTargetOperandTag extends RegisterOperandTag, TCallTargetOperand {
final override int getSortOrder() { result = 10 }
final override string getLabel() { result = "func:" }
final override predicate alwaysPrintLabel() { any() }
final override string getId() { result = "func" }
}
CallTargetOperandTag callTargetOperand() { result = TCallTargetOperand() }
@@ -195,7 +225,9 @@ class ThisArgumentOperandTag extends ArgumentOperandTag, TThisArgumentOperand {
final override int getSortOrder() { result = 11 }
final override string getLabel() { result = "this:" }
final override predicate alwaysPrintLabel() { any() }
final override string getId() { result = "this" }
}
ThisArgumentOperandTag thisArgumentOperand() { result = TThisArgumentOperand() }
@@ -212,9 +244,11 @@ class PositionalArgumentOperandTag extends ArgumentOperandTag, TPositionalArgume
final override int getSortOrder() { result = 12 + argIndex }
final override string getLabel() { result = argIndex.toString() + ":" }
final override predicate alwaysPrintLabel() { any() }
final int getArgIndex() { result = argIndex }
final override string getId() { result = argIndex.toString() }
}
PositionalArgumentOperandTag positionalArgumentOperand(int argIndex) {
@@ -228,7 +262,9 @@ class ChiTotalOperandTag extends ChiOperandTag, TChiTotalOperand {
final override int getSortOrder() { result = 13 }
final override string getLabel() { result = "total:" }
final override predicate alwaysPrintLabel() { any() }
final override string getId() { result = "total" }
}
ChiTotalOperandTag chiTotalOperand() { result = TChiTotalOperand() }
@@ -238,7 +274,9 @@ class ChiPartialOperandTag extends ChiOperandTag, TChiPartialOperand {
final override int getSortOrder() { result = 14 }
final override string getLabel() { result = "partial:" }
final override predicate alwaysPrintLabel() { any() }
final override string getId() { result = "partial" }
}
ChiPartialOperandTag chiPartialOperand() { result = TChiPartialOperand() }
@@ -252,7 +290,9 @@ class AsmOperandTag extends RegisterOperandTag, TAsmOperand {
final override int getSortOrder() { result = 15 + index }
final override string getLabel() { result = index.toString() + ":" }
final override predicate alwaysPrintLabel() { any() }
final override string getId() { result = index.toString() }
}
AsmOperandTag asmOperand(int index) { result = TAsmOperand(index) }

View File

@@ -72,4 +72,9 @@ class IRPropertyProvider extends TIRPropertyProvider {
* Gets the value of the property named `key` for the specified block.
*/
string getBlockProperty(IRBlock block, string key) { none() }
/**
* Gets the value of the property named `key` for the specified operand.
*/
string getOperandProperty(Operand operand, string key) { none() }
}

View File

@@ -1501,6 +1501,12 @@ class SwitchInstruction extends Instruction {
class CallInstruction extends Instruction {
CallInstruction() { getOpcode() instanceof Opcode::Call }
final override string getImmediateString() {
result = getStaticCallTarget().toString()
or
not exists(getStaticCallTarget()) and result = "?"
}
/**
* Gets the operand the specifies the target function of the call.
*/

View File

@@ -151,6 +151,11 @@ class Operand extends TOperand {
*/
string getDumpLabel() { result = "" }
/**
* Gets a string that uniquely identifies this operand on its use instruction.
*/
string getDumpId() { result = "" }
/**
* Gets a string describing this operand, suitable for display in IR dumps. This consists of the
* result ID of the instruction consumed by the operand, plus a label identifying the operand
@@ -280,6 +285,8 @@ class NonPhiOperand extends Operand {
final override string getDumpLabel() { result = tag.getLabel() }
final override string getDumpId() { result = tag.getId() }
final override int getDumpSortOrder() { result = tag.getSortOrder() }
/**
@@ -477,6 +484,8 @@ class PhiInputOperand extends MemoryOperand, PhiOperandBase {
result = "from " + getPredecessorBlock().getDisplayIndex().toString() + ":"
}
final override string getDumpId() { result = getPredecessorBlock().getDisplayIndex().toString() }
/**
* Gets the predecessor block from which this value comes.
*/

View File

@@ -50,6 +50,37 @@ private string getAdditionalBlockProperty(IRBlock block, string key) {
exists(IRPropertyProvider provider | result = provider.getBlockProperty(block, key))
}
/**
* Gets the properties of an operand from any active property providers.
*/
private string getAdditionalOperandProperty(Operand operand, string key) {
exists(IRPropertyProvider provider | result = provider.getOperandProperty(operand, key))
}
/**
* Gets a string listing the properties of the operand and their corresponding values. If the
* operand has no properties, this predicate has no result.
*/
private string getOperandPropertyListString(Operand operand) {
result =
strictconcat(string key, string value |
value = getAdditionalOperandProperty(operand, key)
|
key + ":" + value, ", "
)
}
/**
* Gets a string listing the properties of the operand and their corresponding values. The list is
* surrounded by curly braces. If the operand has no properties, this predicate returns an empty
* string.
*/
private string getOperandPropertyString(Operand operand) {
result = "{" + getOperandPropertyListString(operand) + "}"
or
not exists(getOperandPropertyListString(operand)) and result = ""
}
private newtype TPrintableIRNode =
TPrintableIRFunction(IRFunction irFunc) { shouldPrintFunction(irFunc.getFunction()) } or
TPrintableIRBlock(IRBlock block) { shouldPrintFunction(block.getEnclosingFunction()) } or
@@ -190,7 +221,7 @@ private class PrintableInstruction extends PrintableIRNode, TPrintableInstructio
|
resultString = instr.getResultString() and
operationString = instr.getOperationString() and
operandsString = instr.getOperandsString() and
operandsString = getOperandsString() and
columnWidths(block, resultWidth, operationWidth) and
result =
resultString + getPaddingString(resultWidth - resultString.length()) + " = " +
@@ -210,6 +241,22 @@ private class PrintableInstruction extends PrintableIRNode, TPrintableInstructio
result = PrintableIRNode.super.getProperty(key) or
result = getAdditionalInstructionProperty(instr, key)
}
/**
* Gets the string representation of the operand list. This is the same as
* `Instruction::getOperandsString()`, except that each operand is annotated with any properties
* provided by active `IRPropertyProvider` instances.
*/
private string getOperandsString() {
result =
concat(Operand operand |
operand = instr.getAnOperand()
|
operand.getDumpString() + getOperandPropertyString(operand), ", "
order by
operand.getDumpSortOrder()
)
}
}
private predicate columnWidths(IRBlock block, int resultWidth, int operationWidth) {

View File

@@ -72,4 +72,9 @@ class IRPropertyProvider extends TIRPropertyProvider {
* Gets the value of the property named `key` for the specified block.
*/
string getBlockProperty(IRBlock block, string key) { none() }
/**
* Gets the value of the property named `key` for the specified operand.
*/
string getOperandProperty(Operand operand, string key) { none() }
}

View File

@@ -1501,6 +1501,12 @@ class SwitchInstruction extends Instruction {
class CallInstruction extends Instruction {
CallInstruction() { getOpcode() instanceof Opcode::Call }
final override string getImmediateString() {
result = getStaticCallTarget().toString()
or
not exists(getStaticCallTarget()) and result = "?"
}
/**
* Gets the operand the specifies the target function of the call.
*/

View File

@@ -151,6 +151,11 @@ class Operand extends TOperand {
*/
string getDumpLabel() { result = "" }
/**
* Gets a string that uniquely identifies this operand on its use instruction.
*/
string getDumpId() { result = "" }
/**
* Gets a string describing this operand, suitable for display in IR dumps. This consists of the
* result ID of the instruction consumed by the operand, plus a label identifying the operand
@@ -280,6 +285,8 @@ class NonPhiOperand extends Operand {
final override string getDumpLabel() { result = tag.getLabel() }
final override string getDumpId() { result = tag.getId() }
final override int getDumpSortOrder() { result = tag.getSortOrder() }
/**
@@ -477,6 +484,8 @@ class PhiInputOperand extends MemoryOperand, PhiOperandBase {
result = "from " + getPredecessorBlock().getDisplayIndex().toString() + ":"
}
final override string getDumpId() { result = getPredecessorBlock().getDisplayIndex().toString() }
/**
* Gets the predecessor block from which this value comes.
*/

View File

@@ -50,6 +50,37 @@ private string getAdditionalBlockProperty(IRBlock block, string key) {
exists(IRPropertyProvider provider | result = provider.getBlockProperty(block, key))
}
/**
* Gets the properties of an operand from any active property providers.
*/
private string getAdditionalOperandProperty(Operand operand, string key) {
exists(IRPropertyProvider provider | result = provider.getOperandProperty(operand, key))
}
/**
* Gets a string listing the properties of the operand and their corresponding values. If the
* operand has no properties, this predicate has no result.
*/
private string getOperandPropertyListString(Operand operand) {
result =
strictconcat(string key, string value |
value = getAdditionalOperandProperty(operand, key)
|
key + ":" + value, ", "
)
}
/**
* Gets a string listing the properties of the operand and their corresponding values. The list is
* surrounded by curly braces. If the operand has no properties, this predicate returns an empty
* string.
*/
private string getOperandPropertyString(Operand operand) {
result = "{" + getOperandPropertyListString(operand) + "}"
or
not exists(getOperandPropertyListString(operand)) and result = ""
}
private newtype TPrintableIRNode =
TPrintableIRFunction(IRFunction irFunc) { shouldPrintFunction(irFunc.getFunction()) } or
TPrintableIRBlock(IRBlock block) { shouldPrintFunction(block.getEnclosingFunction()) } or
@@ -190,7 +221,7 @@ private class PrintableInstruction extends PrintableIRNode, TPrintableInstructio
|
resultString = instr.getResultString() and
operationString = instr.getOperationString() and
operandsString = instr.getOperandsString() and
operandsString = getOperandsString() and
columnWidths(block, resultWidth, operationWidth) and
result =
resultString + getPaddingString(resultWidth - resultString.length()) + " = " +
@@ -210,6 +241,22 @@ private class PrintableInstruction extends PrintableIRNode, TPrintableInstructio
result = PrintableIRNode.super.getProperty(key) or
result = getAdditionalInstructionProperty(instr, key)
}
/**
* Gets the string representation of the operand list. This is the same as
* `Instruction::getOperandsString()`, except that each operand is annotated with any properties
* provided by active `IRPropertyProvider` instances.
*/
private string getOperandsString() {
result =
concat(Operand operand |
operand = instr.getAnOperand()
|
operand.getDumpString() + getOperandPropertyString(operand), ", "
order by
operand.getDumpSortOrder()
)
}
}
private predicate columnWidths(IRBlock block, int resultWidth, int operationWidth) {

View File

@@ -39,17 +39,8 @@ void sink(int x)
void bar(Outer &b)
{
// The library correctly finds that the four `user_input` sources can make it
// to the `sink` calls, but it also finds some source/sink combinations that
// are impossible. Those false positives here are a consequence of how the
// shared data flow library overapproximates field flow. The library only
// tracks the final two fields (`f` and `inner`) and the length (3) of the field
// access path, and then it tracks that both `a_` and `b_` have followed `f.inner`
// in _some_ access path somewhere in the search. That makes the library conclude
// that there could be flow to `b.inner.f.a_` even when the flow was actually to
// `b.inner.f.b_`.
sink(b.inner.f.a()); // $ast=62:19 $f+:ast=63:19 $ast=64:19 $f+:ast=65:19 $ir=62:19 $f+:ir=63:19 $ir=64:19 $f+:ir=65:19
sink(b.inner.f.b()); // $f+:ast=62:19 $ast=63:19 $f+:ast=64:19 $ast=65:19 $f+:ir=62:19 $ir=63:19 $f+:ir=64:19 $ir=65:19
sink(b.inner.f.a()); // $ast=53:19 $ast=55:19 $ir=53:19 $ir=55:19
sink(b.inner.f.b()); // $ast=54:19 $ast=56:19 $ir=54:19 $ir=56:19
}
void foo()

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:88:13:88:22 | call to user_input | by_reference.cpp:131:25:131:25 | a | AST only |
| by_reference.cpp:88:13:88:22 | call to user_input | by_reference.cpp:135:27:135:27 | a | AST only |
| complex.cpp:62:19:62:28 | call to user_input | complex.cpp:52:18:52:18 | call to b | AST only |
| complex.cpp:63:19:63:28 | call to user_input | complex.cpp:51:18:51:18 | call to a | AST only |
| complex.cpp:64:19:64:28 | call to user_input | complex.cpp:52:18:52:18 | call to b | AST only |
| complex.cpp:65:19:65:28 | call to user_input | complex.cpp:51:18:51:18 | call to a | AST only |
| qualifiers.cpp:22:27:22:36 | call to user_input | qualifiers.cpp:23:23:23:23 | a | AST only |
| qualifiers.cpp:27:28:27:37 | call to user_input | qualifiers.cpp:28:23:28:23 | a | AST only |
| qualifiers.cpp:32:35:32:44 | call to user_input | qualifiers.cpp:33:23:33:23 | a | AST only |

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 [a] | by_reference.cpp:136:16:136:16 | a |
| by_reference.cpp:128:15:128:23 | taint_a_ref output argument [array content] | by_reference.cpp:128:15:128:23 | Chi |
| complex.cpp:40:17:40:17 | *b [a_] | complex.cpp:51:18:51:18 | call to a |
| complex.cpp:40:17:40:17 | *b [b_] | complex.cpp:51:16:51:16 | a output argument [b_] |
| complex.cpp:40:17:40:17 | *b [b_] | complex.cpp:52:18:52:18 | call to b |
| complex.cpp:51:16:51:16 | a output argument [b_] | complex.cpp:52:18:52:18 | call to b |
| complex.cpp:62:12:62:12 | setA output argument [a_] | complex.cpp:40:17:40:17 | *b [a_] |
| complex.cpp:62:19:62:28 | call to user_input | complex.cpp:62:12:62:12 | setA output argument [a_] |
| complex.cpp:63:12:63:12 | setB output argument [b_] | complex.cpp:40:17:40:17 | *b [b_] |
| complex.cpp:63:19:63:28 | call to user_input | complex.cpp:63:12:63:12 | setB output argument [b_] |
| complex.cpp:64:12:64:12 | setA output argument [a_] | complex.cpp:40:17:40:17 | *b [a_] |
| complex.cpp:64:12:64:12 | setA output argument [a_] | complex.cpp:65:12:65:12 | setB output argument [a_] |
| complex.cpp:64:19:64:28 | call to user_input | complex.cpp:64:12:64:12 | setA output argument [a_] |
| complex.cpp:65:12:65:12 | setB output argument [a_] | complex.cpp:40:17:40:17 | *b [a_] |
| complex.cpp:65:12:65:12 | setB output argument [b_] | complex.cpp:40:17:40:17 | *b [b_] |
| complex.cpp:65:19:65:28 | call to user_input | complex.cpp:65:12:65:12 | setB output argument [b_] |
| complex.cpp:40:17:40:17 | *b [a_] | complex.cpp:42:18:42:18 | call to a |
| complex.cpp:40:17:40:17 | *b [b_] | complex.cpp:42:16:42:16 | a output argument [b_] |
| complex.cpp:40:17:40:17 | *b [b_] | complex.cpp:43:18:43:18 | call to b |
| complex.cpp:42:16:42:16 | a output argument [b_] | complex.cpp:43:18:43:18 | call to b |
| complex.cpp:53:12:53:12 | setA output argument [a_] | complex.cpp:40:17:40:17 | *b [a_] |
| complex.cpp:53:19:53:28 | call to user_input | complex.cpp:53:12:53:12 | setA output argument [a_] |
| complex.cpp:54:12:54:12 | setB output argument [b_] | complex.cpp:40:17:40:17 | *b [b_] |
| complex.cpp:54:19:54:28 | call to user_input | complex.cpp:54:12:54:12 | setB output argument [b_] |
| complex.cpp:55:12:55:12 | setA output argument [a_] | complex.cpp:40:17:40:17 | *b [a_] |
| complex.cpp:55:12:55:12 | setA output argument [a_] | complex.cpp:56:12:56:12 | setB output argument [a_] |
| complex.cpp:55:19:55:28 | call to user_input | complex.cpp:55:12:55:12 | setA output argument [a_] |
| complex.cpp:56:12:56:12 | setB output argument [a_] | complex.cpp:40:17:40:17 | *b [a_] |
| complex.cpp:56:12:56:12 | setB output argument [b_] | complex.cpp:40:17:40:17 | *b [b_] |
| complex.cpp:56:19:56:28 | call to user_input | complex.cpp:56:12:56:12 | setB output argument [b_] |
| constructors.cpp:26:15:26:15 | *f [a_] | constructors.cpp:28:12:28:12 | call to a |
| constructors.cpp:26:15:26:15 | *f [b_] | constructors.cpp:28:10:28:10 | a output argument [b_] |
| constructors.cpp:26:15:26:15 | *f [b_] | constructors.cpp:29:12:29:12 | call to b |
@@ -371,18 +371,18 @@ nodes
| by_reference.cpp:136:16:136:16 | a | semmle.label | a |
| complex.cpp:40:17:40:17 | *b [a_] | semmle.label | *b [a_] |
| complex.cpp:40:17:40:17 | *b [b_] | semmle.label | *b [b_] |
| complex.cpp:51:16:51:16 | a output argument [b_] | semmle.label | a output argument [b_] |
| complex.cpp:51:18:51:18 | call to a | semmle.label | call to a |
| complex.cpp:52:18:52:18 | call to b | semmle.label | call to b |
| complex.cpp:62:12:62:12 | setA output argument [a_] | semmle.label | setA output argument [a_] |
| complex.cpp:62:19:62:28 | call to user_input | semmle.label | call to user_input |
| complex.cpp:63:12:63:12 | setB output argument [b_] | semmle.label | setB output argument [b_] |
| complex.cpp:63:19:63:28 | call to user_input | semmle.label | call to user_input |
| complex.cpp:64:12:64:12 | setA output argument [a_] | semmle.label | setA output argument [a_] |
| complex.cpp:64:19:64:28 | call to user_input | semmle.label | call to user_input |
| complex.cpp:65:12:65:12 | setB output argument [a_] | semmle.label | setB output argument [a_] |
| complex.cpp:65:12:65:12 | setB output argument [b_] | semmle.label | setB output argument [b_] |
| complex.cpp:65:19:65:28 | call to user_input | semmle.label | call to user_input |
| complex.cpp:42:16:42:16 | a output argument [b_] | semmle.label | a output argument [b_] |
| complex.cpp:42:18:42:18 | call to a | semmle.label | call to a |
| complex.cpp:43:18:43:18 | call to b | semmle.label | call to b |
| complex.cpp:53:12:53:12 | setA output argument [a_] | semmle.label | setA output argument [a_] |
| complex.cpp:53:19:53:28 | call to user_input | semmle.label | call to user_input |
| complex.cpp:54:12:54:12 | setB output argument [b_] | semmle.label | setB output argument [b_] |
| complex.cpp:54:19:54:28 | call to user_input | semmle.label | call to user_input |
| complex.cpp:55:12:55:12 | setA output argument [a_] | semmle.label | setA output argument [a_] |
| complex.cpp:55:19:55:28 | call to user_input | semmle.label | call to user_input |
| complex.cpp:56:12:56:12 | setB output argument [a_] | semmle.label | setB output argument [a_] |
| complex.cpp:56:12:56:12 | setB output argument [b_] | semmle.label | setB output argument [b_] |
| complex.cpp:56:19:56:28 | call to user_input | semmle.label | call to user_input |
| constructors.cpp:26:15:26:15 | *f [a_] | semmle.label | *f [a_] |
| constructors.cpp:26:15:26:15 | *f [b_] | semmle.label | *f [b_] |
| constructors.cpp:28:10:28:10 | a output argument [b_] | semmle.label | a output argument [b_] |
@@ -478,10 +478,10 @@ nodes
| by_reference.cpp:132:14:132:14 | a | by_reference.cpp:96:8:96:17 | call to user_input | by_reference.cpp:132:14:132:14 | a | a flows from $@ | by_reference.cpp:96:8:96:17 | call to user_input | call to user_input |
| by_reference.cpp:134:29:134:29 | a | by_reference.cpp:88:13:88:22 | call to user_input | by_reference.cpp:134:29:134:29 | a | a flows from $@ | by_reference.cpp:88:13:88:22 | call to user_input | call to user_input |
| by_reference.cpp:136:16:136:16 | a | by_reference.cpp:96:8:96:17 | call to user_input | by_reference.cpp:136:16:136:16 | a | a flows from $@ | by_reference.cpp:96:8:96:17 | call to user_input | call to user_input |
| complex.cpp:51:18:51:18 | call to a | complex.cpp:62:19:62:28 | call to user_input | complex.cpp:51:18:51:18 | call to a | call to a flows from $@ | complex.cpp:62:19:62:28 | call to user_input | call to user_input |
| complex.cpp:51:18:51:18 | call to a | complex.cpp:64:19:64:28 | call to user_input | complex.cpp:51:18:51:18 | call to a | call to a flows from $@ | complex.cpp:64:19:64:28 | call to user_input | call to user_input |
| complex.cpp:52:18:52:18 | call to b | complex.cpp:63:19:63:28 | call to user_input | complex.cpp:52:18:52:18 | call to b | call to b flows from $@ | complex.cpp:63:19:63:28 | call to user_input | call to user_input |
| complex.cpp:52:18:52:18 | call to b | complex.cpp:65:19:65:28 | call to user_input | complex.cpp:52:18:52:18 | call to b | call to b flows from $@ | complex.cpp:65:19:65:28 | call to user_input | call to user_input |
| complex.cpp:42:18:42:18 | call to a | complex.cpp:53:19:53:28 | call to user_input | complex.cpp:42:18:42:18 | call to a | call to a flows from $@ | complex.cpp:53:19:53:28 | call to user_input | call to user_input |
| complex.cpp:42:18:42:18 | call to a | complex.cpp:55:19:55:28 | call to user_input | complex.cpp:42:18:42:18 | call to a | call to a flows from $@ | complex.cpp:55:19:55:28 | call to user_input | call to user_input |
| complex.cpp:43:18:43:18 | call to b | complex.cpp:54:19:54:28 | call to user_input | complex.cpp:43:18:43:18 | call to b | call to b flows from $@ | complex.cpp:54:19:54:28 | call to user_input | call to user_input |
| complex.cpp:43:18:43:18 | call to b | complex.cpp:56:19:56:28 | call to user_input | complex.cpp:43:18:43:18 | call to b | call to b flows from $@ | complex.cpp:56:19:56:28 | call to user_input | call to user_input |
| constructors.cpp:28:12:28:12 | call to a | constructors.cpp:34:11:34:20 | call to user_input | constructors.cpp:28:12:28:12 | call to a | call to a flows from $@ | constructors.cpp:34:11:34:20 | call to user_input | call to user_input |
| constructors.cpp:28:12:28:12 | call to a | constructors.cpp:36:11:36:20 | call to user_input | constructors.cpp:28:12:28:12 | call to a | call to a flows from $@ | constructors.cpp:36:11:36:20 | call to user_input | call to user_input |
| constructors.cpp:29:12:29:12 | call to b | constructors.cpp:35:14:35:23 | call to user_input | constructors.cpp:29:12:29:12 | call to b | call to b flows from $@ | constructors.cpp:35:14:35:23 | call to user_input | call to user_input |

View File

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

View File

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

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:161:18:161:40 | call to MyList [next, head] | A.cpp:162:38:162:39 | l2 [next, head] |
| A.cpp:161:38:161:39 | l1 [head] | A.cpp:161:18:161:40 | call to MyList [next, head] |
| A.cpp:162:18:162:40 | call to MyList [next, next, ... (3)] | A.cpp:165:10:165:11 | l3 [next, next, ... (3)] |
| A.cpp:162:18:162:40 | call to MyList [next, next, ... (3)] | A.cpp:167:44:167:44 | l [next, next, ... (3)] |
| A.cpp:162:38:162:39 | l2 [next, head] | A.cpp:162:18:162:40 | call to MyList [next, next, ... (3)] |
| A.cpp:165:10:165:11 | l3 [next, next, ... (3)] | A.cpp:165:14:165:17 | next [next, head] |
| A.cpp:162:18:162:40 | call to MyList [next, next, head] | A.cpp:165:10:165:11 | l3 [next, next, head] |
| A.cpp:162:18:162:40 | call to MyList [next, next, head] | A.cpp:167:44:167:44 | l [next, next, head] |
| A.cpp:162:38:162:39 | l2 [next, head] | A.cpp:162:18:162:40 | call to MyList [next, next, head] |
| A.cpp:165:10:165:11 | l3 [next, next, head] | A.cpp:165:14:165:17 | next [next, head] |
| A.cpp:165:14:165:17 | next [next, head] | A.cpp:165:20:165:23 | next [head] |
| A.cpp:165:20:165:23 | next [head] | A.cpp:165:26:165:29 | head |
| A.cpp:167:44:167:44 | l [next, head] | A.cpp:167:47:167:50 | next [head] |
| A.cpp:167:44:167:44 | l [next, next, ... (3)] | A.cpp:167:47:167:50 | next [next, head] |
| A.cpp:167:44:167:44 | l [next, next, head] | A.cpp:167:47:167:50 | next [next, head] |
| A.cpp:167:47:167:50 | next [head] | A.cpp:169:12:169:12 | l [head] |
| A.cpp:167:47:167:50 | next [next, head] | A.cpp:167:44:167:44 | l [next, head] |
| A.cpp:169:12:169:12 | l [head] | A.cpp:169:15:169:18 | head |
@@ -113,14 +113,14 @@ edges
| D.cpp:51:27:51:27 | e | D.cpp:51:8:51:14 | ref arg call to getBox1 [elem] |
| D.cpp:52:14:52:14 | b [box, elem] | D.cpp:21:30:21:31 | b2 [box, elem] |
| D.cpp:56:15:56:24 | new | D.cpp:58:5:58:27 | ... = ... |
| D.cpp:58:5:58:12 | boxfield [post update] [box, elem] | D.cpp:58:5:58:12 | this [post update] [boxfield, box, ... (3)] |
| D.cpp:58:5:58:12 | this [post update] [boxfield, box, ... (3)] | D.cpp:59:5:59:7 | this [boxfield, box, ... (3)] |
| D.cpp:58:5:58:12 | boxfield [post update] [box, elem] | D.cpp:58:5:58:12 | this [post update] [boxfield, box, elem] |
| D.cpp:58:5:58:12 | this [post update] [boxfield, box, elem] | D.cpp:59:5:59:7 | this [boxfield, box, elem] |
| D.cpp:58:5:58:27 | ... = ... | D.cpp:58:15:58:17 | box [post update] [elem] |
| D.cpp:58:15:58:17 | box [post update] [elem] | D.cpp:58:5:58:12 | boxfield [post update] [box, elem] |
| D.cpp:59:5:59:7 | this [boxfield, box, ... (3)] | D.cpp:63:8:63:10 | this [boxfield, box, ... (3)] |
| D.cpp:63:8:63:10 | this [boxfield, box, ... (3)] | D.cpp:64:10:64:17 | this [boxfield, box, ... (3)] |
| D.cpp:59:5:59:7 | this [boxfield, box, elem] | D.cpp:63:8:63:10 | this [boxfield, box, elem] |
| D.cpp:63:8:63:10 | this [boxfield, box, elem] | D.cpp:64:10:64:17 | this [boxfield, box, elem] |
| D.cpp:64:10:64:17 | boxfield [box, elem] | D.cpp:64:20:64:22 | box [elem] |
| D.cpp:64:10:64:17 | this [boxfield, box, ... (3)] | D.cpp:64:10:64:17 | boxfield [box, elem] |
| D.cpp:64:10:64:17 | this [boxfield, box, elem] | D.cpp:64:10:64:17 | boxfield [box, elem] |
| D.cpp:64:20:64:22 | box [elem] | D.cpp:64:25:64:28 | elem |
| E.cpp:19:27:19:27 | p [data, buffer] | E.cpp:21:10:21:10 | p [data, buffer] |
| E.cpp:21:10:21:10 | p [data, buffer] | E.cpp:21:13:21:16 | data [buffer] |
@@ -193,33 +193,33 @@ edges
| arrays.cpp:6:12:6:21 | call to user_input | arrays.cpp:10:8:10:15 | * ... |
| arrays.cpp:15:14:15:23 | call to user_input | arrays.cpp:16:8:16:13 | access to array |
| arrays.cpp:15:14:15:23 | call to user_input | arrays.cpp:17:8:17:13 | access to array |
| arrays.cpp:36:3:36:3 | o [post update] [nested, arr, ... (3)] | arrays.cpp:37:8:37:8 | o [nested, arr, ... (3)] |
| arrays.cpp:36:3:36:3 | o [post update] [nested, arr, ... (3)] | arrays.cpp:38:8:38:8 | o [nested, arr, ... (3)] |
| arrays.cpp:36:3:36:3 | o [post update] [nested, arr, data] | arrays.cpp:37:8:37:8 | o [nested, arr, data] |
| arrays.cpp:36:3:36:3 | o [post update] [nested, arr, data] | arrays.cpp:38:8:38:8 | o [nested, arr, data] |
| arrays.cpp:36:3:36:17 | access to array [post update] [data] | arrays.cpp:36:12:36:14 | arr [inner post update] [data] |
| arrays.cpp:36:3:36:37 | ... = ... | arrays.cpp:36:3:36:17 | access to array [post update] [data] |
| arrays.cpp:36:5:36:10 | nested [post update] [arr, data] | arrays.cpp:36:3:36:3 | o [post update] [nested, arr, ... (3)] |
| arrays.cpp:36:5:36:10 | nested [post update] [arr, data] | arrays.cpp:36:3:36:3 | o [post update] [nested, arr, data] |
| arrays.cpp:36:12:36:14 | arr [inner post update] [data] | arrays.cpp:36:5:36:10 | nested [post update] [arr, data] |
| arrays.cpp:36:26:36:35 | call to user_input | arrays.cpp:36:3:36:37 | ... = ... |
| arrays.cpp:37:8:37:8 | o [nested, arr, ... (3)] | arrays.cpp:37:10:37:15 | nested [arr, data] |
| arrays.cpp:37:8:37:8 | o [nested, arr, data] | arrays.cpp:37:10:37:15 | nested [arr, data] |
| arrays.cpp:37:8:37:22 | access to array [data] | arrays.cpp:37:24:37:27 | data |
| arrays.cpp:37:10:37:15 | nested [arr, data] | arrays.cpp:37:17:37:19 | arr [data] |
| arrays.cpp:37:17:37:19 | arr [data] | arrays.cpp:37:8:37:22 | access to array [data] |
| arrays.cpp:38:8:38:8 | o [nested, arr, ... (3)] | arrays.cpp:38:10:38:15 | nested [arr, data] |
| arrays.cpp:38:8:38:8 | o [nested, arr, data] | arrays.cpp:38:10:38:15 | nested [arr, data] |
| arrays.cpp:38:8:38:22 | access to array [data] | arrays.cpp:38:24:38:27 | data |
| arrays.cpp:38:10:38:15 | nested [arr, data] | arrays.cpp:38:17:38:19 | arr [data] |
| arrays.cpp:38:17:38:19 | arr [data] | arrays.cpp:38:8:38:22 | access to array [data] |
| arrays.cpp:42:3:42:3 | o [post update] [indirect, arr, ... (3)] | arrays.cpp:43:8:43:8 | o [indirect, arr, ... (3)] |
| arrays.cpp:42:3:42:3 | o [post update] [indirect, arr, ... (3)] | arrays.cpp:44:8:44:8 | o [indirect, arr, ... (3)] |
| arrays.cpp:42:3:42:3 | o [post update] [indirect, arr, data] | arrays.cpp:43:8:43:8 | o [indirect, arr, data] |
| arrays.cpp:42:3:42:3 | o [post update] [indirect, arr, data] | arrays.cpp:44:8:44:8 | o [indirect, arr, data] |
| arrays.cpp:42:3:42:20 | access to array [post update] [data] | arrays.cpp:42:15:42:17 | arr [inner post update] [data] |
| arrays.cpp:42:3:42:40 | ... = ... | arrays.cpp:42:3:42:20 | access to array [post update] [data] |
| arrays.cpp:42:5:42:12 | indirect [post update] [arr, data] | arrays.cpp:42:3:42:3 | o [post update] [indirect, arr, ... (3)] |
| arrays.cpp:42:5:42:12 | indirect [post update] [arr, data] | arrays.cpp:42:3:42:3 | o [post update] [indirect, arr, data] |
| arrays.cpp:42:15:42:17 | arr [inner post update] [data] | arrays.cpp:42:5:42:12 | indirect [post update] [arr, data] |
| arrays.cpp:42:29:42:38 | call to user_input | arrays.cpp:42:3:42:40 | ... = ... |
| arrays.cpp:43:8:43:8 | o [indirect, arr, ... (3)] | arrays.cpp:43:10:43:17 | indirect [arr, data] |
| arrays.cpp:43:8:43:8 | o [indirect, arr, data] | arrays.cpp:43:10:43:17 | indirect [arr, data] |
| arrays.cpp:43:8:43:25 | access to array [data] | arrays.cpp:43:27:43:30 | data |
| arrays.cpp:43:10:43:17 | indirect [arr, data] | arrays.cpp:43:20:43:22 | arr [data] |
| arrays.cpp:43:20:43:22 | arr [data] | arrays.cpp:43:8:43:25 | access to array [data] |
| arrays.cpp:44:8:44:8 | o [indirect, arr, ... (3)] | arrays.cpp:44:10:44:17 | indirect [arr, data] |
| arrays.cpp:44:8:44:8 | o [indirect, arr, data] | arrays.cpp:44:10:44:17 | indirect [arr, data] |
| arrays.cpp:44:8:44:25 | access to array [data] | arrays.cpp:44:27:44:30 | data |
| arrays.cpp:44:10:44:17 | indirect [arr, data] | arrays.cpp:44:20:44:22 | arr [data] |
| arrays.cpp:44:20:44:22 | arr [data] | arrays.cpp:44:8:44:25 | access to array [data] |
@@ -308,33 +308,34 @@ edges
| by_reference.cpp:135:8:135:13 | pouter [inner_ptr, a] | by_reference.cpp:135:16:135:24 | inner_ptr [a] |
| by_reference.cpp:135:16:135:24 | inner_ptr [a] | by_reference.cpp:135:27:135:27 | a |
| by_reference.cpp:136:8:136:13 | pouter [a] | by_reference.cpp:136:16:136:16 | a |
| complex.cpp:40:17:40:17 | b [inner, f, ... (3)] | complex.cpp:51:8:51:8 | b [inner, f, ... (3)] |
| complex.cpp:40:17:40:17 | b [inner, f, ... (3)] | complex.cpp:52:8:52:8 | b [inner, f, ... (3)] |
| complex.cpp:51:8:51:8 | b [inner, f, ... (3)] | complex.cpp:51:10:51:14 | inner [f, a_] |
| complex.cpp:51:10:51:14 | inner [f, a_] | complex.cpp:51:16:51:16 | f [a_] |
| complex.cpp:51:16:51:16 | f [a_] | complex.cpp:51:18:51:18 | call to a |
| complex.cpp:52:8:52:8 | b [inner, f, ... (3)] | complex.cpp:52:10:52:14 | inner [f, b_] |
| complex.cpp:52:10:52:14 | inner [f, b_] | complex.cpp:52:16:52:16 | f [b_] |
| complex.cpp:52:16:52:16 | f [b_] | complex.cpp:52:18:52:18 | call to b |
| complex.cpp:62:3:62:4 | b1 [post update] [inner, f, ... (3)] | complex.cpp:68:7:68:8 | b1 [inner, f, ... (3)] |
| complex.cpp:62:6:62:10 | inner [post update] [f, a_] | complex.cpp:62:3:62:4 | b1 [post update] [inner, f, ... (3)] |
| complex.cpp:62:12:62:12 | ref arg f [a_] | complex.cpp:62:6:62:10 | inner [post update] [f, a_] |
| complex.cpp:62:19:62:28 | call to user_input | complex.cpp:62:12:62:12 | ref arg f [a_] |
| complex.cpp:63:3:63:4 | b2 [post update] [inner, f, ... (3)] | complex.cpp:71:7:71:8 | b2 [inner, f, ... (3)] |
| complex.cpp:63:6:63:10 | inner [post update] [f, b_] | complex.cpp:63:3:63:4 | b2 [post update] [inner, f, ... (3)] |
| complex.cpp:63:12:63:12 | ref arg f [b_] | complex.cpp:63:6:63:10 | inner [post update] [f, b_] |
| complex.cpp:63:19:63:28 | call to user_input | complex.cpp:63:12:63:12 | ref arg f [b_] |
| complex.cpp:64:3:64:4 | b3 [post update] [inner, f, ... (3)] | complex.cpp:74:7:74:8 | b3 [inner, f, ... (3)] |
| complex.cpp:64:6:64:10 | inner [post update] [f, a_] | complex.cpp:64:3:64:4 | b3 [post update] [inner, f, ... (3)] |
| complex.cpp:64:12:64:12 | ref arg f [a_] | complex.cpp:64:6:64:10 | inner [post update] [f, a_] |
| complex.cpp:64:19:64:28 | call to user_input | complex.cpp:64:12:64:12 | ref arg f [a_] |
| complex.cpp:65:3:65:4 | b3 [post update] [inner, f, ... (3)] | complex.cpp:74:7:74:8 | b3 [inner, f, ... (3)] |
| complex.cpp:65:6:65:10 | inner [post update] [f, b_] | complex.cpp:65:3:65:4 | b3 [post update] [inner, f, ... (3)] |
| complex.cpp:65:12:65:12 | ref arg f [b_] | complex.cpp:65:6:65:10 | inner [post update] [f, b_] |
| complex.cpp:65:19:65:28 | call to user_input | complex.cpp:65:12:65:12 | ref arg f [b_] |
| complex.cpp:68:7:68:8 | b1 [inner, f, ... (3)] | complex.cpp:40:17:40:17 | b [inner, f, ... (3)] |
| complex.cpp:71:7:71:8 | b2 [inner, f, ... (3)] | complex.cpp:40:17:40:17 | b [inner, f, ... (3)] |
| complex.cpp:74:7:74:8 | b3 [inner, f, ... (3)] | complex.cpp:40:17:40:17 | b [inner, f, ... (3)] |
| complex.cpp:40:17:40:17 | b [inner, f, a_] | complex.cpp:42:8:42:8 | b [inner, f, a_] |
| complex.cpp:40:17:40:17 | b [inner, f, b_] | complex.cpp:43:8:43:8 | b [inner, f, b_] |
| complex.cpp:42:8:42:8 | b [inner, f, a_] | complex.cpp:42:10:42:14 | inner [f, a_] |
| complex.cpp:42:10:42:14 | inner [f, a_] | complex.cpp:42:16:42:16 | f [a_] |
| complex.cpp:42:16:42:16 | f [a_] | complex.cpp:42:18:42:18 | call to a |
| complex.cpp:43:8:43:8 | b [inner, f, b_] | complex.cpp:43:10:43:14 | inner [f, b_] |
| complex.cpp:43:10:43:14 | inner [f, b_] | complex.cpp:43:16:43:16 | f [b_] |
| complex.cpp:43:16:43:16 | f [b_] | complex.cpp:43:18:43:18 | call to b |
| complex.cpp:53:3:53:4 | b1 [post update] [inner, f, a_] | complex.cpp:59:7:59:8 | b1 [inner, f, a_] |
| complex.cpp:53:6:53:10 | inner [post update] [f, a_] | complex.cpp:53:3:53:4 | b1 [post update] [inner, f, a_] |
| complex.cpp:53:12:53:12 | ref arg f [a_] | complex.cpp:53:6:53:10 | inner [post update] [f, a_] |
| complex.cpp:53:19:53:28 | call to user_input | complex.cpp:53:12:53:12 | ref arg f [a_] |
| complex.cpp:54:3:54:4 | b2 [post update] [inner, f, b_] | complex.cpp:62:7:62:8 | b2 [inner, f, b_] |
| complex.cpp:54:6:54:10 | inner [post update] [f, b_] | complex.cpp:54:3:54:4 | b2 [post update] [inner, f, b_] |
| complex.cpp:54:12:54:12 | ref arg f [b_] | complex.cpp:54:6:54:10 | inner [post update] [f, b_] |
| complex.cpp:54:19:54:28 | call to user_input | complex.cpp:54:12:54:12 | ref arg f [b_] |
| complex.cpp:55:3:55:4 | b3 [post update] [inner, f, a_] | complex.cpp:65:7:65:8 | b3 [inner, f, a_] |
| complex.cpp:55:6:55:10 | inner [post update] [f, a_] | complex.cpp:55:3:55:4 | b3 [post update] [inner, f, a_] |
| complex.cpp:55:12:55:12 | ref arg f [a_] | complex.cpp:55:6:55:10 | inner [post update] [f, a_] |
| complex.cpp:55:19:55:28 | call to user_input | complex.cpp:55:12:55:12 | ref arg f [a_] |
| complex.cpp:56:3:56:4 | b3 [post update] [inner, f, b_] | complex.cpp:65:7:65:8 | b3 [inner, f, b_] |
| complex.cpp:56:6:56:10 | inner [post update] [f, b_] | complex.cpp:56:3:56:4 | b3 [post update] [inner, f, b_] |
| complex.cpp:56:12:56:12 | ref arg f [b_] | complex.cpp:56:6:56:10 | inner [post update] [f, b_] |
| complex.cpp:56:19:56:28 | call to user_input | complex.cpp:56:12:56:12 | ref arg f [b_] |
| complex.cpp:59:7:59:8 | b1 [inner, f, a_] | complex.cpp:40:17:40:17 | b [inner, f, a_] |
| complex.cpp:62:7:62:8 | b2 [inner, f, b_] | complex.cpp:40:17:40:17 | b [inner, f, b_] |
| complex.cpp:65:7:65:8 | b3 [inner, f, a_] | complex.cpp:40:17:40:17 | b [inner, f, a_] |
| complex.cpp:65:7:65:8 | b3 [inner, f, b_] | complex.cpp:40:17:40:17 | b [inner, f, b_] |
| constructors.cpp:26:15:26:15 | f [a_] | constructors.cpp:28:10:28:10 | f [a_] |
| constructors.cpp:26:15:26:15 | f [b_] | constructors.cpp:29:10:29:10 | f [b_] |
| constructors.cpp:28:10:28:10 | f [a_] | constructors.cpp:28:12:28:12 | call to a |
@@ -386,16 +387,16 @@ edges
| qualifiers.cpp:47:31:47:40 | call to user_input | qualifiers.cpp:47:5:47:42 | ... = ... |
| qualifiers.cpp:48:10:48:14 | outer [inner, a] | qualifiers.cpp:48:16:48:20 | inner [a] |
| qualifiers.cpp:48:16:48:20 | inner [a] | qualifiers.cpp:48:23:48:23 | a |
| realistic.cpp:53:9:53:11 | foo [post update] [bar, baz, ... (4)] | realistic.cpp:61:21:61:23 | foo [bar, baz, ... (4)] |
| realistic.cpp:53:9:53:18 | access to array [post update] [baz, userInput, ... (3)] | realistic.cpp:53:13:53:15 | bar [inner post update] [baz, userInput, ... (3)] |
| realistic.cpp:53:9:53:11 | foo [post update] [bar, baz, userInput, bufferLen] | realistic.cpp:61:21:61:23 | foo [bar, baz, userInput, bufferLen] |
| realistic.cpp:53:9:53:18 | access to array [post update] [baz, userInput, bufferLen] | realistic.cpp:53:13:53:15 | bar [inner post update] [baz, userInput, bufferLen] |
| realistic.cpp:53:9:53:66 | ... = ... | realistic.cpp:53:25:53:33 | userInput [post update] [bufferLen] |
| realistic.cpp:53:13:53:15 | bar [inner post update] [baz, userInput, ... (3)] | realistic.cpp:53:9:53:11 | foo [post update] [bar, baz, ... (4)] |
| realistic.cpp:53:20:53:22 | baz [post update] [userInput, bufferLen] | realistic.cpp:53:9:53:18 | access to array [post update] [baz, userInput, ... (3)] |
| realistic.cpp:53:13:53:15 | bar [inner post update] [baz, userInput, bufferLen] | realistic.cpp:53:9:53:11 | foo [post update] [bar, baz, userInput, bufferLen] |
| realistic.cpp:53:20:53:22 | baz [post update] [userInput, bufferLen] | realistic.cpp:53:9:53:18 | access to array [post update] [baz, userInput, bufferLen] |
| realistic.cpp:53:25:53:33 | userInput [post update] [bufferLen] | realistic.cpp:53:20:53:22 | baz [post update] [userInput, bufferLen] |
| realistic.cpp:53:55:53:64 | call to user_input | realistic.cpp:53:9:53:66 | ... = ... |
| realistic.cpp:61:21:61:23 | foo [bar, baz, ... (4)] | realistic.cpp:61:25:61:27 | bar [baz, userInput, ... (3)] |
| realistic.cpp:61:21:61:30 | access to array [baz, userInput, ... (3)] | realistic.cpp:61:32:61:34 | baz [userInput, bufferLen] |
| realistic.cpp:61:25:61:27 | bar [baz, userInput, ... (3)] | realistic.cpp:61:21:61:30 | access to array [baz, userInput, ... (3)] |
| realistic.cpp:61:21:61:23 | foo [bar, baz, userInput, bufferLen] | realistic.cpp:61:25:61:27 | bar [baz, userInput, bufferLen] |
| realistic.cpp:61:21:61:30 | access to array [baz, userInput, bufferLen] | realistic.cpp:61:32:61:34 | baz [userInput, bufferLen] |
| realistic.cpp:61:25:61:27 | bar [baz, userInput, bufferLen] | realistic.cpp:61:21:61:30 | access to array [baz, userInput, bufferLen] |
| realistic.cpp:61:32:61:34 | baz [userInput, bufferLen] | realistic.cpp:61:37:61:45 | userInput [bufferLen] |
| realistic.cpp:61:37:61:45 | userInput [bufferLen] | realistic.cpp:61:47:61:55 | bufferLen |
| simple.cpp:26:15:26:15 | f [a_] | simple.cpp:28:10:28:10 | f [a_] |
@@ -517,14 +518,14 @@ nodes
| A.cpp:160:29:160:29 | b | semmle.label | b |
| A.cpp:161:18:161:40 | call to MyList [next, head] | semmle.label | call to MyList [next, head] |
| A.cpp:161:38:161:39 | l1 [head] | semmle.label | l1 [head] |
| A.cpp:162:18:162:40 | call to MyList [next, next, ... (3)] | semmle.label | call to MyList [next, next, ... (3)] |
| A.cpp:162:18:162:40 | call to MyList [next, next, head] | semmle.label | call to MyList [next, next, head] |
| A.cpp:162:38:162:39 | l2 [next, head] | semmle.label | l2 [next, head] |
| A.cpp:165:10:165:11 | l3 [next, next, ... (3)] | semmle.label | l3 [next, next, ... (3)] |
| A.cpp:165:10:165:11 | l3 [next, next, head] | semmle.label | l3 [next, next, head] |
| A.cpp:165:14:165:17 | next [next, head] | semmle.label | next [next, head] |
| A.cpp:165:20:165:23 | next [head] | semmle.label | next [head] |
| A.cpp:165:26:165:29 | head | semmle.label | head |
| A.cpp:167:44:167:44 | l [next, head] | semmle.label | l [next, head] |
| A.cpp:167:44:167:44 | l [next, next, ... (3)] | semmle.label | l [next, next, ... (3)] |
| A.cpp:167:44:167:44 | l [next, next, head] | semmle.label | l [next, next, head] |
| A.cpp:167:47:167:50 | next [head] | semmle.label | next [head] |
| A.cpp:167:47:167:50 | next [next, head] | semmle.label | next [next, head] |
| A.cpp:169:12:169:12 | l [head] | semmle.label | l [head] |
@@ -586,13 +587,13 @@ nodes
| D.cpp:52:14:52:14 | b [box, elem] | semmle.label | b [box, elem] |
| D.cpp:56:15:56:24 | new | semmle.label | new |
| D.cpp:58:5:58:12 | boxfield [post update] [box, elem] | semmle.label | boxfield [post update] [box, elem] |
| D.cpp:58:5:58:12 | this [post update] [boxfield, box, ... (3)] | semmle.label | this [post update] [boxfield, box, ... (3)] |
| D.cpp:58:5:58:12 | this [post update] [boxfield, box, elem] | semmle.label | this [post update] [boxfield, box, elem] |
| D.cpp:58:5:58:27 | ... = ... | semmle.label | ... = ... |
| D.cpp:58:15:58:17 | box [post update] [elem] | semmle.label | box [post update] [elem] |
| D.cpp:59:5:59:7 | this [boxfield, box, ... (3)] | semmle.label | this [boxfield, box, ... (3)] |
| D.cpp:63:8:63:10 | this [boxfield, box, ... (3)] | semmle.label | this [boxfield, box, ... (3)] |
| D.cpp:59:5:59:7 | this [boxfield, box, elem] | semmle.label | this [boxfield, box, elem] |
| D.cpp:63:8:63:10 | this [boxfield, box, elem] | semmle.label | this [boxfield, box, elem] |
| D.cpp:64:10:64:17 | boxfield [box, elem] | semmle.label | boxfield [box, elem] |
| D.cpp:64:10:64:17 | this [boxfield, box, ... (3)] | semmle.label | this [boxfield, box, ... (3)] |
| D.cpp:64:10:64:17 | this [boxfield, box, elem] | semmle.label | this [boxfield, box, elem] |
| D.cpp:64:20:64:22 | box [elem] | semmle.label | box [elem] |
| D.cpp:64:25:64:28 | elem | semmle.label | elem |
| E.cpp:19:27:19:27 | p [data, buffer] | semmle.label | p [data, buffer] |
@@ -675,34 +676,34 @@ nodes
| arrays.cpp:15:14:15:23 | call to user_input | semmle.label | call to user_input |
| arrays.cpp:16:8:16:13 | access to array | semmle.label | access to array |
| arrays.cpp:17:8:17:13 | access to array | semmle.label | access to array |
| arrays.cpp:36:3:36:3 | o [post update] [nested, arr, ... (3)] | semmle.label | o [post update] [nested, arr, ... (3)] |
| arrays.cpp:36:3:36:3 | o [post update] [nested, arr, data] | semmle.label | o [post update] [nested, arr, data] |
| arrays.cpp:36:3:36:17 | access to array [post update] [data] | semmle.label | access to array [post update] [data] |
| arrays.cpp:36:3:36:37 | ... = ... | semmle.label | ... = ... |
| arrays.cpp:36:5:36:10 | nested [post update] [arr, data] | semmle.label | nested [post update] [arr, data] |
| arrays.cpp:36:12:36:14 | arr [inner post update] [data] | semmle.label | arr [inner post update] [data] |
| arrays.cpp:36:26:36:35 | call to user_input | semmle.label | call to user_input |
| arrays.cpp:37:8:37:8 | o [nested, arr, ... (3)] | semmle.label | o [nested, arr, ... (3)] |
| arrays.cpp:37:8:37:8 | o [nested, arr, data] | semmle.label | o [nested, arr, data] |
| arrays.cpp:37:8:37:22 | access to array [data] | semmle.label | access to array [data] |
| arrays.cpp:37:10:37:15 | nested [arr, data] | semmle.label | nested [arr, data] |
| arrays.cpp:37:17:37:19 | arr [data] | semmle.label | arr [data] |
| arrays.cpp:37:24:37:27 | data | semmle.label | data |
| arrays.cpp:38:8:38:8 | o [nested, arr, ... (3)] | semmle.label | o [nested, arr, ... (3)] |
| arrays.cpp:38:8:38:8 | o [nested, arr, data] | semmle.label | o [nested, arr, data] |
| arrays.cpp:38:8:38:22 | access to array [data] | semmle.label | access to array [data] |
| arrays.cpp:38:10:38:15 | nested [arr, data] | semmle.label | nested [arr, data] |
| arrays.cpp:38:17:38:19 | arr [data] | semmle.label | arr [data] |
| arrays.cpp:38:24:38:27 | data | semmle.label | data |
| arrays.cpp:42:3:42:3 | o [post update] [indirect, arr, ... (3)] | semmle.label | o [post update] [indirect, arr, ... (3)] |
| arrays.cpp:42:3:42:3 | o [post update] [indirect, arr, data] | semmle.label | o [post update] [indirect, arr, data] |
| arrays.cpp:42:3:42:20 | access to array [post update] [data] | semmle.label | access to array [post update] [data] |
| arrays.cpp:42:3:42:40 | ... = ... | semmle.label | ... = ... |
| arrays.cpp:42:5:42:12 | indirect [post update] [arr, data] | semmle.label | indirect [post update] [arr, data] |
| arrays.cpp:42:15:42:17 | arr [inner post update] [data] | semmle.label | arr [inner post update] [data] |
| arrays.cpp:42:29:42:38 | call to user_input | semmle.label | call to user_input |
| arrays.cpp:43:8:43:8 | o [indirect, arr, ... (3)] | semmle.label | o [indirect, arr, ... (3)] |
| arrays.cpp:43:8:43:8 | o [indirect, arr, data] | semmle.label | o [indirect, arr, data] |
| arrays.cpp:43:8:43:25 | access to array [data] | semmle.label | access to array [data] |
| arrays.cpp:43:10:43:17 | indirect [arr, data] | semmle.label | indirect [arr, data] |
| arrays.cpp:43:20:43:22 | arr [data] | semmle.label | arr [data] |
| arrays.cpp:43:27:43:30 | data | semmle.label | data |
| arrays.cpp:44:8:44:8 | o [indirect, arr, ... (3)] | semmle.label | o [indirect, arr, ... (3)] |
| arrays.cpp:44:8:44:8 | o [indirect, arr, data] | semmle.label | o [indirect, arr, data] |
| arrays.cpp:44:8:44:25 | access to array [data] | semmle.label | access to array [data] |
| arrays.cpp:44:10:44:17 | indirect [arr, data] | semmle.label | indirect [arr, data] |
| arrays.cpp:44:20:44:22 | arr [data] | semmle.label | arr [data] |
@@ -796,34 +797,36 @@ nodes
| by_reference.cpp:135:27:135:27 | a | semmle.label | a |
| by_reference.cpp:136:8:136:13 | pouter [a] | semmle.label | pouter [a] |
| by_reference.cpp:136:16:136:16 | a | semmle.label | a |
| complex.cpp:40:17:40:17 | b [inner, f, ... (3)] | semmle.label | b [inner, f, ... (3)] |
| complex.cpp:51:8:51:8 | b [inner, f, ... (3)] | semmle.label | b [inner, f, ... (3)] |
| complex.cpp:51:10:51:14 | inner [f, a_] | semmle.label | inner [f, a_] |
| complex.cpp:51:16:51:16 | f [a_] | semmle.label | f [a_] |
| complex.cpp:51:18:51:18 | call to a | semmle.label | call to a |
| complex.cpp:52:8:52:8 | b [inner, f, ... (3)] | semmle.label | b [inner, f, ... (3)] |
| complex.cpp:52:10:52:14 | inner [f, b_] | semmle.label | inner [f, b_] |
| complex.cpp:52:16:52:16 | f [b_] | semmle.label | f [b_] |
| complex.cpp:52:18:52:18 | call to b | semmle.label | call to b |
| complex.cpp:62:3:62:4 | b1 [post update] [inner, f, ... (3)] | semmle.label | b1 [post update] [inner, f, ... (3)] |
| complex.cpp:62:6:62:10 | inner [post update] [f, a_] | semmle.label | inner [post update] [f, a_] |
| complex.cpp:62:12:62:12 | ref arg f [a_] | semmle.label | ref arg f [a_] |
| complex.cpp:62:19:62:28 | call to user_input | semmle.label | call to user_input |
| complex.cpp:63:3:63:4 | b2 [post update] [inner, f, ... (3)] | semmle.label | b2 [post update] [inner, f, ... (3)] |
| complex.cpp:63:6:63:10 | inner [post update] [f, b_] | semmle.label | inner [post update] [f, b_] |
| complex.cpp:63:12:63:12 | ref arg f [b_] | semmle.label | ref arg f [b_] |
| complex.cpp:63:19:63:28 | call to user_input | semmle.label | call to user_input |
| complex.cpp:64:3:64:4 | b3 [post update] [inner, f, ... (3)] | semmle.label | b3 [post update] [inner, f, ... (3)] |
| complex.cpp:64:6:64:10 | inner [post update] [f, a_] | semmle.label | inner [post update] [f, a_] |
| complex.cpp:64:12:64:12 | ref arg f [a_] | semmle.label | ref arg f [a_] |
| complex.cpp:64:19:64:28 | call to user_input | semmle.label | call to user_input |
| complex.cpp:65:3:65:4 | b3 [post update] [inner, f, ... (3)] | semmle.label | b3 [post update] [inner, f, ... (3)] |
| complex.cpp:65:6:65:10 | inner [post update] [f, b_] | semmle.label | inner [post update] [f, b_] |
| complex.cpp:65:12:65:12 | ref arg f [b_] | semmle.label | ref arg f [b_] |
| complex.cpp:65:19:65:28 | call to user_input | semmle.label | call to user_input |
| complex.cpp:68:7:68:8 | b1 [inner, f, ... (3)] | semmle.label | b1 [inner, f, ... (3)] |
| complex.cpp:71:7:71:8 | b2 [inner, f, ... (3)] | semmle.label | b2 [inner, f, ... (3)] |
| complex.cpp:74:7:74:8 | b3 [inner, f, ... (3)] | semmle.label | b3 [inner, f, ... (3)] |
| complex.cpp:40:17:40:17 | b [inner, f, a_] | semmle.label | b [inner, f, a_] |
| complex.cpp:40:17:40:17 | b [inner, f, b_] | semmle.label | b [inner, f, b_] |
| complex.cpp:42:8:42:8 | b [inner, f, a_] | semmle.label | b [inner, f, a_] |
| complex.cpp:42:10:42:14 | inner [f, a_] | semmle.label | inner [f, a_] |
| complex.cpp:42:16:42:16 | f [a_] | semmle.label | f [a_] |
| complex.cpp:42:18:42:18 | call to a | semmle.label | call to a |
| complex.cpp:43:8:43:8 | b [inner, f, b_] | semmle.label | b [inner, f, b_] |
| complex.cpp:43:10:43:14 | inner [f, b_] | semmle.label | inner [f, b_] |
| complex.cpp:43:16:43:16 | f [b_] | semmle.label | f [b_] |
| complex.cpp:43:18:43:18 | call to b | semmle.label | call to b |
| complex.cpp:53:3:53:4 | b1 [post update] [inner, f, a_] | semmle.label | b1 [post update] [inner, f, a_] |
| complex.cpp:53:6:53:10 | inner [post update] [f, a_] | semmle.label | inner [post update] [f, a_] |
| complex.cpp:53:12:53:12 | ref arg f [a_] | semmle.label | ref arg f [a_] |
| complex.cpp:53:19:53:28 | call to user_input | semmle.label | call to user_input |
| complex.cpp:54:3:54:4 | b2 [post update] [inner, f, b_] | semmle.label | b2 [post update] [inner, f, b_] |
| complex.cpp:54:6:54:10 | inner [post update] [f, b_] | semmle.label | inner [post update] [f, b_] |
| complex.cpp:54:12:54:12 | ref arg f [b_] | semmle.label | ref arg f [b_] |
| complex.cpp:54:19:54:28 | call to user_input | semmle.label | call to user_input |
| complex.cpp:55:3:55:4 | b3 [post update] [inner, f, a_] | semmle.label | b3 [post update] [inner, f, a_] |
| complex.cpp:55:6:55:10 | inner [post update] [f, a_] | semmle.label | inner [post update] [f, a_] |
| complex.cpp:55:12:55:12 | ref arg f [a_] | semmle.label | ref arg f [a_] |
| complex.cpp:55:19:55:28 | call to user_input | semmle.label | call to user_input |
| complex.cpp:56:3:56:4 | b3 [post update] [inner, f, b_] | semmle.label | b3 [post update] [inner, f, b_] |
| complex.cpp:56:6:56:10 | inner [post update] [f, b_] | semmle.label | inner [post update] [f, b_] |
| complex.cpp:56:12:56:12 | ref arg f [b_] | semmle.label | ref arg f [b_] |
| complex.cpp:56:19:56:28 | call to user_input | semmle.label | call to user_input |
| complex.cpp:59:7:59:8 | b1 [inner, f, a_] | semmle.label | b1 [inner, f, a_] |
| complex.cpp:62:7:62:8 | b2 [inner, f, b_] | semmle.label | b2 [inner, f, b_] |
| complex.cpp:65:7:65:8 | b3 [inner, f, a_] | semmle.label | b3 [inner, f, a_] |
| complex.cpp:65:7:65:8 | b3 [inner, f, b_] | semmle.label | b3 [inner, f, b_] |
| constructors.cpp:26:15:26:15 | f [a_] | semmle.label | f [a_] |
| constructors.cpp:26:15:26:15 | f [b_] | semmle.label | f [b_] |
| constructors.cpp:28:10:28:10 | f [a_] | semmle.label | f [a_] |
@@ -883,16 +886,16 @@ nodes
| qualifiers.cpp:48:10:48:14 | outer [inner, a] | semmle.label | outer [inner, a] |
| qualifiers.cpp:48:16:48:20 | inner [a] | semmle.label | inner [a] |
| qualifiers.cpp:48:23:48:23 | a | semmle.label | a |
| realistic.cpp:53:9:53:11 | foo [post update] [bar, baz, ... (4)] | semmle.label | foo [post update] [bar, baz, ... (4)] |
| realistic.cpp:53:9:53:18 | access to array [post update] [baz, userInput, ... (3)] | semmle.label | access to array [post update] [baz, userInput, ... (3)] |
| realistic.cpp:53:9:53:11 | foo [post update] [bar, baz, userInput, bufferLen] | semmle.label | foo [post update] [bar, baz, userInput, bufferLen] |
| realistic.cpp:53:9:53:18 | access to array [post update] [baz, userInput, bufferLen] | semmle.label | access to array [post update] [baz, userInput, bufferLen] |
| realistic.cpp:53:9:53:66 | ... = ... | semmle.label | ... = ... |
| realistic.cpp:53:13:53:15 | bar [inner post update] [baz, userInput, ... (3)] | semmle.label | bar [inner post update] [baz, userInput, ... (3)] |
| realistic.cpp:53:13:53:15 | bar [inner post update] [baz, userInput, bufferLen] | semmle.label | bar [inner post update] [baz, userInput, bufferLen] |
| realistic.cpp:53:20:53:22 | baz [post update] [userInput, bufferLen] | semmle.label | baz [post update] [userInput, bufferLen] |
| realistic.cpp:53:25:53:33 | userInput [post update] [bufferLen] | semmle.label | userInput [post update] [bufferLen] |
| realistic.cpp:53:55:53:64 | call to user_input | semmle.label | call to user_input |
| realistic.cpp:61:21:61:23 | foo [bar, baz, ... (4)] | semmle.label | foo [bar, baz, ... (4)] |
| realistic.cpp:61:21:61:30 | access to array [baz, userInput, ... (3)] | semmle.label | access to array [baz, userInput, ... (3)] |
| realistic.cpp:61:25:61:27 | bar [baz, userInput, ... (3)] | semmle.label | bar [baz, userInput, ... (3)] |
| realistic.cpp:61:21:61:23 | foo [bar, baz, userInput, bufferLen] | semmle.label | foo [bar, baz, userInput, bufferLen] |
| realistic.cpp:61:21:61:30 | access to array [baz, userInput, bufferLen] | semmle.label | access to array [baz, userInput, bufferLen] |
| realistic.cpp:61:25:61:27 | bar [baz, userInput, bufferLen] | semmle.label | bar [baz, userInput, bufferLen] |
| realistic.cpp:61:32:61:34 | baz [userInput, bufferLen] | semmle.label | baz [userInput, bufferLen] |
| realistic.cpp:61:37:61:45 | userInput [bufferLen] | semmle.label | userInput [bufferLen] |
| realistic.cpp:61:47:61:55 | bufferLen | semmle.label | bufferLen |
@@ -1021,14 +1024,10 @@ nodes
| by_reference.cpp:134:29:134:29 | a | by_reference.cpp:88:13:88:22 | call to user_input | by_reference.cpp:134:29:134:29 | a | a flows from $@ | by_reference.cpp:88:13:88:22 | call to user_input | call to user_input |
| by_reference.cpp:135:27:135:27 | a | by_reference.cpp:88:13:88:22 | call to user_input | by_reference.cpp:135:27:135:27 | a | a flows from $@ | by_reference.cpp:88:13:88:22 | call to user_input | call to user_input |
| by_reference.cpp:136:16:136:16 | a | by_reference.cpp:96:8:96:17 | call to user_input | by_reference.cpp:136:16:136:16 | a | a flows from $@ | by_reference.cpp:96:8:96:17 | call to user_input | call to user_input |
| complex.cpp:51:18:51:18 | call to a | complex.cpp:62:19:62:28 | call to user_input | complex.cpp:51:18:51:18 | call to a | call to a flows from $@ | complex.cpp:62:19:62:28 | call to user_input | call to user_input |
| complex.cpp:51:18:51:18 | call to a | complex.cpp:63:19:63:28 | call to user_input | complex.cpp:51:18:51:18 | call to a | call to a flows from $@ | complex.cpp:63:19:63:28 | call to user_input | call to user_input |
| complex.cpp:51:18:51:18 | call to a | complex.cpp:64:19:64:28 | call to user_input | complex.cpp:51:18:51:18 | call to a | call to a flows from $@ | complex.cpp:64:19:64:28 | call to user_input | call to user_input |
| complex.cpp:51:18:51:18 | call to a | complex.cpp:65:19:65:28 | call to user_input | complex.cpp:51:18:51:18 | call to a | call to a flows from $@ | complex.cpp:65:19:65:28 | call to user_input | call to user_input |
| complex.cpp:52:18:52:18 | call to b | complex.cpp:62:19:62:28 | call to user_input | complex.cpp:52:18:52:18 | call to b | call to b flows from $@ | complex.cpp:62:19:62:28 | call to user_input | call to user_input |
| complex.cpp:52:18:52:18 | call to b | complex.cpp:63:19:63:28 | call to user_input | complex.cpp:52:18:52:18 | call to b | call to b flows from $@ | complex.cpp:63:19:63:28 | call to user_input | call to user_input |
| complex.cpp:52:18:52:18 | call to b | complex.cpp:64:19:64:28 | call to user_input | complex.cpp:52:18:52:18 | call to b | call to b flows from $@ | complex.cpp:64:19:64:28 | call to user_input | call to user_input |
| complex.cpp:52:18:52:18 | call to b | complex.cpp:65:19:65:28 | call to user_input | complex.cpp:52:18:52:18 | call to b | call to b flows from $@ | complex.cpp:65:19:65:28 | call to user_input | call to user_input |
| complex.cpp:42:18:42:18 | call to a | complex.cpp:53:19:53:28 | call to user_input | complex.cpp:42:18:42:18 | call to a | call to a flows from $@ | complex.cpp:53:19:53:28 | call to user_input | call to user_input |
| complex.cpp:42:18:42:18 | call to a | complex.cpp:55:19:55:28 | call to user_input | complex.cpp:42:18:42:18 | call to a | call to a flows from $@ | complex.cpp:55:19:55:28 | call to user_input | call to user_input |
| complex.cpp:43:18:43:18 | call to b | complex.cpp:54:19:54:28 | call to user_input | complex.cpp:43:18:43:18 | call to b | call to b flows from $@ | complex.cpp:54:19:54:28 | call to user_input | call to user_input |
| complex.cpp:43:18:43:18 | call to b | complex.cpp:56:19:56:28 | call to user_input | complex.cpp:43:18:43:18 | call to b | call to b flows from $@ | complex.cpp:56:19:56:28 | call to user_input | call to user_input |
| constructors.cpp:28:12:28:12 | call to a | constructors.cpp:34:11:34:20 | call to user_input | constructors.cpp:28:12:28:12 | call to a | call to a flows from $@ | constructors.cpp:34:11:34:20 | call to user_input | call to user_input |
| constructors.cpp:28:12:28:12 | call to a | constructors.cpp:36:11:36:20 | call to user_input | constructors.cpp:28:12:28:12 | call to a | call to a flows from $@ | constructors.cpp:36:11:36:20 | call to user_input | call to user_input |
| constructors.cpp:29:12:29:12 | call to b | constructors.cpp:35:14:35:23 | call to user_input | constructors.cpp:29:12:29:12 | call to b | call to b flows from $@ | constructors.cpp:35:14:35:23 | call to user_input | call to user_input |

File diff suppressed because it is too large Load Diff

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -83,7 +83,7 @@ namespace Semmle.Extraction.CSharp.Entities
private class AccessorFactory : ICachedEntityFactory<IMethodSymbol, Accessor>
{
public static readonly AccessorFactory Instance = new AccessorFactory();
public static AccessorFactory Instance { get; } = new AccessorFactory();
public Accessor Create(Context cx, IMethodSymbol init) => new Accessor(cx, init);
}

View File

@@ -39,7 +39,7 @@ namespace Semmle.Extraction.CSharp.Entities
private class CommentBlockFactory : ICachedEntityFactory<ICommentBlock, CommentBlock>
{
public static readonly CommentBlockFactory Instance = new CommentBlockFactory();
public static CommentBlockFactory Instance { get; } = new CommentBlockFactory();
public CommentBlock Create(Context cx, ICommentBlock init) => new CommentBlock(cx, init);
}

View File

@@ -139,7 +139,7 @@ namespace Semmle.Extraction.CSharp.Entities
private class CommentLineFactory : ICachedEntityFactory<(Microsoft.CodeAnalysis.Location, CommentLineType, string, string), CommentLine>
{
public static readonly CommentLineFactory Instance = new CommentLineFactory();
public static CommentLineFactory Instance { get; } = new CommentLineFactory();
public CommentLine Create(Context cx, (Microsoft.CodeAnalysis.Location, CommentLineType, string, string) init) =>
new CommentLine(cx, init.Item1, init.Item2, init.Item3, init.Item4);

View File

@@ -147,7 +147,7 @@ namespace Semmle.Extraction.CSharp.Entities
private class ConstructorFactory : ICachedEntityFactory<IMethodSymbol, Constructor>
{
public static readonly ConstructorFactory Instance = new ConstructorFactory();
public static ConstructorFactory Instance { get; } = new ConstructorFactory();
public Constructor Create(Context cx, IMethodSymbol init) => new Constructor(cx, init);
}

View File

@@ -28,7 +28,7 @@ namespace Semmle.Extraction.CSharp.Entities
private class ConversionFactory : ICachedEntityFactory<IMethodSymbol, Conversion>
{
public static readonly ConversionFactory Instance = new ConversionFactory();
public static ConversionFactory Instance { get; } = new ConversionFactory();
public Conversion Create(Context cx, IMethodSymbol init) => new Conversion(cx, init);
}

View File

@@ -28,7 +28,7 @@ namespace Semmle.Extraction.CSharp.Entities
private class DestructorFactory : ICachedEntityFactory<IMethodSymbol, Destructor>
{
public static readonly DestructorFactory Instance = new DestructorFactory();
public static DestructorFactory Instance { get; } = new DestructorFactory();
public Destructor Create(Context cx, IMethodSymbol init) => new Destructor(cx, init);
}

View File

@@ -67,7 +67,7 @@ namespace Semmle.Extraction.CSharp.Entities
private class EventFactory : ICachedEntityFactory<IEventSymbol, Event>
{
public static readonly EventFactory Instance = new EventFactory();
public static EventFactory Instance { get; } = new EventFactory();
public Event Create(Context cx, IEventSymbol init) => new Event(cx, init);
}

View File

@@ -57,7 +57,7 @@ namespace Semmle.Extraction.CSharp.Entities
private class EventAccessorFactory : ICachedEntityFactory<IMethodSymbol, EventAccessor>
{
public static readonly EventAccessorFactory Instance = new EventAccessorFactory();
public static EventAccessorFactory Instance { get; } = new EventAccessorFactory();
public EventAccessor Create(Context cx, IMethodSymbol init) => new EventAccessor(cx, init);
}

View File

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

View File

@@ -131,7 +131,7 @@ namespace Semmle.Extraction.CSharp.Entities
private class FieldFactory : ICachedEntityFactory<IFieldSymbol, Field>
{
public static readonly FieldFactory Instance = new FieldFactory();
public static FieldFactory Instance { get; } = new FieldFactory();
public Field Create(Context cx, IFieldSymbol init) => new Field(cx, init);
}

View File

@@ -100,7 +100,7 @@ namespace Semmle.Extraction.CSharp.Entities
private class IndexerFactory : ICachedEntityFactory<IPropertySymbol, Indexer>
{
public static readonly IndexerFactory Instance = new IndexerFactory();
public static IndexerFactory Instance { get; } = new IndexerFactory();
public Indexer Create(Context cx, IPropertySymbol init) => new Indexer(cx, init);
}

View File

@@ -26,7 +26,7 @@ namespace Semmle.Extraction.CSharp.Entities
private class LocalFunctionFactory : ICachedEntityFactory<IMethodSymbol, LocalFunction>
{
public static readonly LocalFunctionFactory Instance = new LocalFunctionFactory();
public static LocalFunctionFactory Instance { get; } = new LocalFunctionFactory();
public LocalFunction Create(Context cx, IMethodSymbol init) => new LocalFunction(cx, init);
}

View File

@@ -55,7 +55,7 @@ namespace Semmle.Extraction.CSharp.Entities
private class LocalVariableFactory : ICachedEntityFactory<ISymbol, LocalVariable>
{
public static readonly LocalVariableFactory Instance = new LocalVariableFactory();
public static LocalVariableFactory Instance { get; } = new LocalVariableFactory();
public LocalVariable Create(Context cx, ISymbol init) => new LocalVariable(cx, init);
}

View File

@@ -142,7 +142,7 @@ namespace Semmle.Extraction.CSharp.Entities
private class ModifierFactory : ICachedEntityFactory<string, Modifier>
{
public static readonly ModifierFactory Instance = new ModifierFactory();
public static ModifierFactory Instance { get; } = new ModifierFactory();
public Modifier Create(Context cx, string init) => new Modifier(cx, init);
}

View File

@@ -38,7 +38,7 @@ namespace Semmle.Extraction.CSharp.Entities
private class NamespaceFactory : ICachedEntityFactory<INamespaceSymbol, Namespace>
{
public static readonly NamespaceFactory Instance = new NamespaceFactory();
public static NamespaceFactory Instance { get; } = new NamespaceFactory();
public Namespace Create(Context cx, INamespaceSymbol init) => new Namespace(cx, init);
}

View File

@@ -57,7 +57,7 @@ namespace Semmle.Extraction.CSharp.Entities
private class OrdinaryMethodFactory : ICachedEntityFactory<IMethodSymbol, OrdinaryMethod>
{
public static readonly OrdinaryMethodFactory Instance = new OrdinaryMethodFactory();
public static OrdinaryMethodFactory Instance { get; } = new OrdinaryMethodFactory();
public OrdinaryMethod Create(Context cx, IMethodSymbol init) => new OrdinaryMethod(cx, init);
}

View File

@@ -171,7 +171,7 @@ namespace Semmle.Extraction.CSharp.Entities
private class ParameterFactory : ICachedEntityFactory<(IParameterSymbol, IEntity, Parameter), Parameter>
{
public static readonly ParameterFactory Instance = new ParameterFactory();
public static ParameterFactory Instance { get; } = new ParameterFactory();
public Parameter Create(Context cx, (IParameterSymbol, IEntity, Parameter) init) => new Parameter(cx, init.Item1, init.Item2, init.Item3);
}
@@ -212,7 +212,7 @@ namespace Semmle.Extraction.CSharp.Entities
private class VarargsTypeFactory : ICachedEntityFactory<string, VarargsType>
{
public static readonly VarargsTypeFactory Instance = new VarargsTypeFactory();
public static VarargsTypeFactory Instance { get; } = new VarargsTypeFactory();
public VarargsType Create(Context cx, string init) => new VarargsType(cx);
}
@@ -247,7 +247,7 @@ namespace Semmle.Extraction.CSharp.Entities
private class VarargsParamFactory : ICachedEntityFactory<Method, VarargsParam>
{
public static readonly VarargsParamFactory Instance = new VarargsParamFactory();
public static VarargsParamFactory Instance { get; } = new VarargsParamFactory();
public VarargsParam Create(Context cx, Method init) => new VarargsParam(cx, init);
}
@@ -275,7 +275,7 @@ namespace Semmle.Extraction.CSharp.Entities
private class ExtensionParamFactory : ICachedEntityFactory<(Method, Parameter), ConstructedExtensionParameter>
{
public static readonly ExtensionParamFactory Instance = new ExtensionParamFactory();
public static ExtensionParamFactory Instance { get; } = new ExtensionParamFactory();
public ConstructedExtensionParameter Create(Context cx, (Method, Parameter) init) =>
new ConstructedExtensionParameter(cx, init.Item1, init.Item2);

View File

@@ -126,7 +126,7 @@ namespace Semmle.Extraction.CSharp.Entities
private class PropertyFactory : ICachedEntityFactory<IPropertySymbol, Property>
{
public static readonly PropertyFactory Instance = new PropertyFactory();
public static PropertyFactory Instance { get; } = new PropertyFactory();
public Property Create(Context cx, IPropertySymbol init) => new Property(cx, init);
}

View File

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

View File

@@ -40,7 +40,7 @@ namespace Semmle.Extraction.CSharp.Entities
private class ArrayTypeFactory : ICachedEntityFactory<IArrayTypeSymbol, ArrayType>
{
public static readonly ArrayTypeFactory Instance = new ArrayTypeFactory();
public static ArrayTypeFactory Instance { get; } = new ArrayTypeFactory();
public ArrayType Create(Context cx, IArrayTypeSymbol init) => new ArrayType(cx, init);
}

View File

@@ -29,7 +29,7 @@ namespace Semmle.Extraction.CSharp.Entities
private class DynamicTypeFactory : ICachedEntityFactory<IDynamicTypeSymbol, DynamicType>
{
public static readonly DynamicTypeFactory Instance = new DynamicTypeFactory();
public static DynamicTypeFactory Instance { get; } = new DynamicTypeFactory();
public DynamicType Create(Context cx, IDynamicTypeSymbol init) => new DynamicType(cx, init);
}

View File

@@ -176,14 +176,14 @@ namespace Semmle.Extraction.CSharp.Entities
private class NamedTypeFactory : ICachedEntityFactory<INamedTypeSymbol, NamedType>
{
public static readonly NamedTypeFactory Instance = new NamedTypeFactory();
public static NamedTypeFactory Instance { get; } = new NamedTypeFactory();
public NamedType Create(Context cx, INamedTypeSymbol init) => new NamedType(cx, init, false);
}
private class UnderlyingTupleTypeFactory : ICachedEntityFactory<INamedTypeSymbol, NamedType>
{
public static readonly UnderlyingTupleTypeFactory Instance = new UnderlyingTupleTypeFactory();
public static UnderlyingTupleTypeFactory Instance { get; } = new UnderlyingTupleTypeFactory();
public NamedType Create(Context cx, INamedTypeSymbol init) => new NamedType(cx, init, true);
}
@@ -213,7 +213,7 @@ namespace Semmle.Extraction.CSharp.Entities
private class NamedTypeRefFactory : ICachedEntityFactory<INamedTypeSymbol, NamedTypeRef>
{
public static readonly NamedTypeRefFactory Instance = new NamedTypeRefFactory();
public static NamedTypeRefFactory Instance { get; } = new NamedTypeRefFactory();
public NamedTypeRef Create(Context cx, INamedTypeSymbol init) => new NamedTypeRef(cx, init);
}

View File

@@ -31,7 +31,7 @@ namespace Semmle.Extraction.CSharp.Entities
private class NullTypeFactory : ICachedEntityFactory<ITypeSymbol, NullType>
{
public static readonly NullTypeFactory Instance = new NullTypeFactory();
public static NullTypeFactory Instance { get; } = new NullTypeFactory();
public NullType Create(Context cx, ITypeSymbol init) => new NullType(cx);
}

View File

@@ -129,7 +129,7 @@ namespace Semmle.Extraction.CSharp.Entities
private class NullabilityFactory : ICachedEntityFactory<Nullability, NullabilityEntity>
{
public static readonly NullabilityFactory Instance = new NullabilityFactory();
public static NullabilityFactory Instance { get; } = new NullabilityFactory();
public NullabilityEntity Create(Context cx, Nullability init) => new NullabilityEntity(cx, init);
}

View File

@@ -33,7 +33,7 @@ namespace Semmle.Extraction.CSharp.Entities
private class PointerTypeFactory : ICachedEntityFactory<IPointerTypeSymbol, PointerType>
{
public static readonly PointerTypeFactory Instance = new PointerTypeFactory();
public static PointerTypeFactory Instance { get; } = new PointerTypeFactory();
public PointerType Create(Context cx, IPointerTypeSymbol init) => new PointerType(cx, init);
}

View File

@@ -17,7 +17,7 @@ namespace Semmle.Extraction.CSharp.Entities
private class TupleTypeFactory : ICachedEntityFactory<INamedTypeSymbol, TupleType>
{
public static readonly TupleTypeFactory Instance = new TupleTypeFactory();
public static TupleTypeFactory Instance { get; } = new TupleTypeFactory();
public TupleType Create(Context cx, INamedTypeSymbol init) => new TupleType(cx, init);
}

View File

@@ -305,7 +305,7 @@ namespace Semmle.Extraction.CSharp.Entities
private class DelegateTypeParameterFactory : ICachedEntityFactory<(IParameterSymbol, IEntity, Parameter), DelegateTypeParameter>
{
public static readonly DelegateTypeParameterFactory Instance = new DelegateTypeParameterFactory();
public static DelegateTypeParameterFactory Instance { get; } = new DelegateTypeParameterFactory();
public DelegateTypeParameter Create(Context cx, (IParameterSymbol, IEntity, Parameter) init) =>
new DelegateTypeParameter(cx, init.Item1, init.Item2, init.Item3);

View File

@@ -129,7 +129,7 @@ namespace Semmle.Extraction.CSharp.Entities
private class TypeParameterFactory : ICachedEntityFactory<ITypeParameterSymbol, TypeParameter>
{
public static readonly TypeParameterFactory Instance = new TypeParameterFactory();
public static TypeParameterFactory Instance { get; } = new TypeParameterFactory();
public TypeParameter Create(Context cx, ITypeParameterSymbol init) => new TypeParameter(cx, init);
}

View File

@@ -187,7 +187,7 @@ namespace Semmle.Extraction.CSharp.Entities
private class UserOperatorFactory : ICachedEntityFactory<IMethodSymbol, UserOperator>
{
public static readonly UserOperatorFactory Instance = new UserOperatorFactory();
public static UserOperatorFactory Instance { get; } = new UserOperatorFactory();
public UserOperator Create(Context cx, IMethodSymbol init) => new UserOperator(cx, init);
}

View File

@@ -53,7 +53,7 @@ namespace Semmle.Extraction.Entities
private class AssemblyConstructorFactory : ICachedEntityFactory<Microsoft.CodeAnalysis.Location?, Assembly>
{
public static readonly AssemblyConstructorFactory Instance = new AssemblyConstructorFactory();
public static AssemblyConstructorFactory Instance { get; } = new AssemblyConstructorFactory();
public Assembly Create(Context cx, Microsoft.CodeAnalysis.Location? init) => new Assembly(cx, init);
}

View File

@@ -78,7 +78,7 @@ namespace Semmle.Extraction.Entities
private class GeneratedFileFactory : ICachedEntityFactory<string?, GeneratedFile>
{
public static readonly GeneratedFileFactory Instance = new GeneratedFileFactory();
public static GeneratedFileFactory Instance { get; } = new GeneratedFileFactory();
public GeneratedFile Create(Context cx, string? init) => new GeneratedFile(cx);
}
@@ -88,7 +88,7 @@ namespace Semmle.Extraction.Entities
private class FileFactory : ICachedEntityFactory<string, File>
{
public static readonly FileFactory Instance = new FileFactory();
public static FileFactory Instance { get; } = new FileFactory();
public File Create(Context cx, string init) => new File(cx, init);
}

View File

@@ -28,7 +28,7 @@ namespace Semmle.Extraction.Entities
private class FolderFactory : ICachedEntityFactory<PathTransformer.ITransformedPath, Folder>
{
public static readonly FolderFactory Instance = new FolderFactory();
public static FolderFactory Instance { get; } = new FolderFactory();
public Folder Create(Context cx, PathTransformer.ITransformedPath init) => new Folder(cx, init);
}

View File

@@ -32,7 +32,7 @@ namespace Semmle.Extraction.Entities
private class GeneratedLocationFactory : ICachedEntityFactory<string?, GeneratedLocation>
{
public static readonly GeneratedLocationFactory Instance = new GeneratedLocationFactory();
public static GeneratedLocationFactory Instance { get; } = new GeneratedLocationFactory();
public GeneratedLocation Create(Context cx, string? init) => new GeneratedLocation(cx);
}

View File

@@ -58,7 +58,7 @@ namespace Semmle.Extraction.Entities
private class SourceLocationFactory : ICachedEntityFactory<Microsoft.CodeAnalysis.Location, SourceLocation>
{
public static readonly SourceLocationFactory Instance = new SourceLocationFactory();
public static SourceLocationFactory Instance { get; } = new SourceLocationFactory();
public SourceLocation Create(Context cx, Microsoft.CodeAnalysis.Location init) => new NonGeneratedSourceLocation(cx, init);
}

View File

@@ -101,11 +101,6 @@ namespace Semmle.Extraction
/// </summary>
public class Extractor : IExtractor
{
/// <summary>
/// The default number of threads to use for extraction.
/// </summary>
public static readonly int DefaultNumberOfThreads = Environment.ProcessorCount;
public bool Standalone
{
get; private set;

View File

@@ -116,7 +116,7 @@ namespace Semmle.Extraction
public int Value { get; private set; }
public static readonly Label InvalidLabel = new Label(0);
public static Label InvalidLabel { get; } = new Label(0);
public bool Valid => Value > 0;

View File

@@ -171,7 +171,7 @@ namespace Semmle.Extraction
{
private readonly List<FilePattern> filePatterns = new List<FilePattern>();
public readonly Layout.SubProject Directories;
public Layout.SubProject Directories { get; }
private static string? ReadVariable(string name, string line)
{

View File

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

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.
*/
string getLabel() { result = "" }
final string getLabel() { if alwaysPrintLabel() then result = getId() + ":" else result = "" }
/**
* Gets an identifier that uniquely identifies this operand within its instruction.
*/
abstract string getId();
/**
* Holds if the operand should always be prefixed with its label in the dump of its instruction.
*/
predicate alwaysPrintLabel() { none() }
}
/**
@@ -69,7 +79,9 @@ class AddressOperandTag extends RegisterOperandTag, TAddressOperand {
final override int getSortOrder() { result = 0 }
final override string getLabel() { result = "&:" }
final override predicate alwaysPrintLabel() { any() }
final override string getId() { result = "&" }
}
AddressOperandTag addressOperand() { result = TAddressOperand() }
@@ -82,6 +94,8 @@ class BufferSizeOperandTag extends RegisterOperandTag, TBufferSizeOperand {
final override string toString() { result = "BufferSize" }
final override int getSortOrder() { result = 1 }
final override string getId() { result = "size" }
}
BufferSizeOperandTag bufferSizeOperand() { result = TBufferSizeOperand() }
@@ -93,6 +107,8 @@ class SideEffectOperandTag extends TypedOperandTag, TSideEffectOperand {
final override string toString() { result = "SideEffect" }
final override int getSortOrder() { result = 2 }
final override string getId() { result = "side_effect" }
}
SideEffectOperandTag sideEffectOperand() { result = TSideEffectOperand() }
@@ -105,6 +121,8 @@ class LoadOperandTag extends TypedOperandTag, TLoadOperand {
final override string toString() { result = "Load" }
final override int getSortOrder() { result = 3 }
final override string getId() { result = "load" }
}
LoadOperandTag loadOperand() { result = TLoadOperand() }
@@ -116,6 +134,8 @@ class StoreValueOperandTag extends RegisterOperandTag, TStoreValueOperand {
final override string toString() { result = "StoreValue" }
final override int getSortOrder() { result = 4 }
final override string getId() { result = "store" }
}
StoreValueOperandTag storeValueOperand() { result = TStoreValueOperand() }
@@ -127,6 +147,8 @@ class UnaryOperandTag extends RegisterOperandTag, TUnaryOperand {
final override string toString() { result = "Unary" }
final override int getSortOrder() { result = 5 }
final override string getId() { result = "unary" }
}
UnaryOperandTag unaryOperand() { result = TUnaryOperand() }
@@ -138,6 +160,8 @@ class LeftOperandTag extends RegisterOperandTag, TLeftOperand {
final override string toString() { result = "Left" }
final override int getSortOrder() { result = 6 }
final override string getId() { result = "left" }
}
LeftOperandTag leftOperand() { result = TLeftOperand() }
@@ -149,6 +173,8 @@ class RightOperandTag extends RegisterOperandTag, TRightOperand {
final override string toString() { result = "Right" }
final override int getSortOrder() { result = 7 }
final override string getId() { result = "right" }
}
RightOperandTag rightOperand() { result = TRightOperand() }
@@ -160,6 +186,8 @@ class ConditionOperandTag extends RegisterOperandTag, TConditionOperand {
final override string toString() { result = "Condition" }
final override int getSortOrder() { result = 8 }
final override string getId() { result = "cond" }
}
ConditionOperandTag conditionOperand() { result = TConditionOperand() }
@@ -172,7 +200,9 @@ class CallTargetOperandTag extends RegisterOperandTag, TCallTargetOperand {
final override int getSortOrder() { result = 10 }
final override string getLabel() { result = "func:" }
final override predicate alwaysPrintLabel() { any() }
final override string getId() { result = "func" }
}
CallTargetOperandTag callTargetOperand() { result = TCallTargetOperand() }
@@ -195,7 +225,9 @@ class ThisArgumentOperandTag extends ArgumentOperandTag, TThisArgumentOperand {
final override int getSortOrder() { result = 11 }
final override string getLabel() { result = "this:" }
final override predicate alwaysPrintLabel() { any() }
final override string getId() { result = "this" }
}
ThisArgumentOperandTag thisArgumentOperand() { result = TThisArgumentOperand() }
@@ -212,9 +244,11 @@ class PositionalArgumentOperandTag extends ArgumentOperandTag, TPositionalArgume
final override int getSortOrder() { result = 12 + argIndex }
final override string getLabel() { result = argIndex.toString() + ":" }
final override predicate alwaysPrintLabel() { any() }
final int getArgIndex() { result = argIndex }
final override string getId() { result = argIndex.toString() }
}
PositionalArgumentOperandTag positionalArgumentOperand(int argIndex) {
@@ -228,7 +262,9 @@ class ChiTotalOperandTag extends ChiOperandTag, TChiTotalOperand {
final override int getSortOrder() { result = 13 }
final override string getLabel() { result = "total:" }
final override predicate alwaysPrintLabel() { any() }
final override string getId() { result = "total" }
}
ChiTotalOperandTag chiTotalOperand() { result = TChiTotalOperand() }
@@ -238,7 +274,9 @@ class ChiPartialOperandTag extends ChiOperandTag, TChiPartialOperand {
final override int getSortOrder() { result = 14 }
final override string getLabel() { result = "partial:" }
final override predicate alwaysPrintLabel() { any() }
final override string getId() { result = "partial" }
}
ChiPartialOperandTag chiPartialOperand() { result = TChiPartialOperand() }
@@ -252,7 +290,9 @@ class AsmOperandTag extends RegisterOperandTag, TAsmOperand {
final override int getSortOrder() { result = 15 + index }
final override string getLabel() { result = index.toString() + ":" }
final override predicate alwaysPrintLabel() { any() }
final override string getId() { result = index.toString() }
}
AsmOperandTag asmOperand(int index) { result = TAsmOperand(index) }

View File

@@ -72,4 +72,9 @@ class IRPropertyProvider extends TIRPropertyProvider {
* Gets the value of the property named `key` for the specified block.
*/
string getBlockProperty(IRBlock block, string key) { none() }
/**
* Gets the value of the property named `key` for the specified operand.
*/
string getOperandProperty(Operand operand, string key) { none() }
}

View File

@@ -1501,6 +1501,12 @@ class SwitchInstruction extends Instruction {
class CallInstruction extends Instruction {
CallInstruction() { getOpcode() instanceof Opcode::Call }
final override string getImmediateString() {
result = getStaticCallTarget().toString()
or
not exists(getStaticCallTarget()) and result = "?"
}
/**
* Gets the operand the specifies the target function of the call.
*/

View File

@@ -151,6 +151,11 @@ class Operand extends TOperand {
*/
string getDumpLabel() { result = "" }
/**
* Gets a string that uniquely identifies this operand on its use instruction.
*/
string getDumpId() { result = "" }
/**
* Gets a string describing this operand, suitable for display in IR dumps. This consists of the
* result ID of the instruction consumed by the operand, plus a label identifying the operand
@@ -280,6 +285,8 @@ class NonPhiOperand extends Operand {
final override string getDumpLabel() { result = tag.getLabel() }
final override string getDumpId() { result = tag.getId() }
final override int getDumpSortOrder() { result = tag.getSortOrder() }
/**
@@ -477,6 +484,8 @@ class PhiInputOperand extends MemoryOperand, PhiOperandBase {
result = "from " + getPredecessorBlock().getDisplayIndex().toString() + ":"
}
final override string getDumpId() { result = getPredecessorBlock().getDisplayIndex().toString() }
/**
* Gets the predecessor block from which this value comes.
*/

View File

@@ -50,6 +50,37 @@ private string getAdditionalBlockProperty(IRBlock block, string key) {
exists(IRPropertyProvider provider | result = provider.getBlockProperty(block, key))
}
/**
* Gets the properties of an operand from any active property providers.
*/
private string getAdditionalOperandProperty(Operand operand, string key) {
exists(IRPropertyProvider provider | result = provider.getOperandProperty(operand, key))
}
/**
* Gets a string listing the properties of the operand and their corresponding values. If the
* operand has no properties, this predicate has no result.
*/
private string getOperandPropertyListString(Operand operand) {
result =
strictconcat(string key, string value |
value = getAdditionalOperandProperty(operand, key)
|
key + ":" + value, ", "
)
}
/**
* Gets a string listing the properties of the operand and their corresponding values. The list is
* surrounded by curly braces. If the operand has no properties, this predicate returns an empty
* string.
*/
private string getOperandPropertyString(Operand operand) {
result = "{" + getOperandPropertyListString(operand) + "}"
or
not exists(getOperandPropertyListString(operand)) and result = ""
}
private newtype TPrintableIRNode =
TPrintableIRFunction(IRFunction irFunc) { shouldPrintFunction(irFunc.getFunction()) } or
TPrintableIRBlock(IRBlock block) { shouldPrintFunction(block.getEnclosingFunction()) } or
@@ -190,7 +221,7 @@ private class PrintableInstruction extends PrintableIRNode, TPrintableInstructio
|
resultString = instr.getResultString() and
operationString = instr.getOperationString() and
operandsString = instr.getOperandsString() and
operandsString = getOperandsString() and
columnWidths(block, resultWidth, operationWidth) and
result =
resultString + getPaddingString(resultWidth - resultString.length()) + " = " +
@@ -210,6 +241,22 @@ private class PrintableInstruction extends PrintableIRNode, TPrintableInstructio
result = PrintableIRNode.super.getProperty(key) or
result = getAdditionalInstructionProperty(instr, key)
}
/**
* Gets the string representation of the operand list. This is the same as
* `Instruction::getOperandsString()`, except that each operand is annotated with any properties
* provided by active `IRPropertyProvider` instances.
*/
private string getOperandsString() {
result =
concat(Operand operand |
operand = instr.getAnOperand()
|
operand.getDumpString() + getOperandPropertyString(operand), ", "
order by
operand.getDumpSortOrder()
)
}
}
private predicate columnWidths(IRBlock block, int resultWidth, int operationWidth) {

View File

@@ -72,4 +72,9 @@ class IRPropertyProvider extends TIRPropertyProvider {
* Gets the value of the property named `key` for the specified block.
*/
string getBlockProperty(IRBlock block, string key) { none() }
/**
* Gets the value of the property named `key` for the specified operand.
*/
string getOperandProperty(Operand operand, string key) { none() }
}

View File

@@ -1501,6 +1501,12 @@ class SwitchInstruction extends Instruction {
class CallInstruction extends Instruction {
CallInstruction() { getOpcode() instanceof Opcode::Call }
final override string getImmediateString() {
result = getStaticCallTarget().toString()
or
not exists(getStaticCallTarget()) and result = "?"
}
/**
* Gets the operand the specifies the target function of the call.
*/

View File

@@ -151,6 +151,11 @@ class Operand extends TOperand {
*/
string getDumpLabel() { result = "" }
/**
* Gets a string that uniquely identifies this operand on its use instruction.
*/
string getDumpId() { result = "" }
/**
* Gets a string describing this operand, suitable for display in IR dumps. This consists of the
* result ID of the instruction consumed by the operand, plus a label identifying the operand
@@ -280,6 +285,8 @@ class NonPhiOperand extends Operand {
final override string getDumpLabel() { result = tag.getLabel() }
final override string getDumpId() { result = tag.getId() }
final override int getDumpSortOrder() { result = tag.getSortOrder() }
/**
@@ -477,6 +484,8 @@ class PhiInputOperand extends MemoryOperand, PhiOperandBase {
result = "from " + getPredecessorBlock().getDisplayIndex().toString() + ":"
}
final override string getDumpId() { result = getPredecessorBlock().getDisplayIndex().toString() }
/**
* Gets the predecessor block from which this value comes.
*/

View File

@@ -50,6 +50,37 @@ private string getAdditionalBlockProperty(IRBlock block, string key) {
exists(IRPropertyProvider provider | result = provider.getBlockProperty(block, key))
}
/**
* Gets the properties of an operand from any active property providers.
*/
private string getAdditionalOperandProperty(Operand operand, string key) {
exists(IRPropertyProvider provider | result = provider.getOperandProperty(operand, key))
}
/**
* Gets a string listing the properties of the operand and their corresponding values. If the
* operand has no properties, this predicate has no result.
*/
private string getOperandPropertyListString(Operand operand) {
result =
strictconcat(string key, string value |
value = getAdditionalOperandProperty(operand, key)
|
key + ":" + value, ", "
)
}
/**
* Gets a string listing the properties of the operand and their corresponding values. The list is
* surrounded by curly braces. If the operand has no properties, this predicate returns an empty
* string.
*/
private string getOperandPropertyString(Operand operand) {
result = "{" + getOperandPropertyListString(operand) + "}"
or
not exists(getOperandPropertyListString(operand)) and result = ""
}
private newtype TPrintableIRNode =
TPrintableIRFunction(IRFunction irFunc) { shouldPrintFunction(irFunc.getFunction()) } or
TPrintableIRBlock(IRBlock block) { shouldPrintFunction(block.getEnclosingFunction()) } or
@@ -190,7 +221,7 @@ private class PrintableInstruction extends PrintableIRNode, TPrintableInstructio
|
resultString = instr.getResultString() and
operationString = instr.getOperationString() and
operandsString = instr.getOperandsString() and
operandsString = getOperandsString() and
columnWidths(block, resultWidth, operationWidth) and
result =
resultString + getPaddingString(resultWidth - resultString.length()) + " = " +
@@ -210,6 +241,22 @@ private class PrintableInstruction extends PrintableIRNode, TPrintableInstructio
result = PrintableIRNode.super.getProperty(key) or
result = getAdditionalInstructionProperty(instr, key)
}
/**
* Gets the string representation of the operand list. This is the same as
* `Instruction::getOperandsString()`, except that each operand is annotated with any properties
* provided by active `IRPropertyProvider` instances.
*/
private string getOperandsString() {
result =
concat(Operand operand |
operand = instr.getAnOperand()
|
operand.getDumpString() + getOperandPropertyString(operand), ", "
order by
operand.getDumpSortOrder()
)
}
}
private predicate columnWidths(IRBlock block, int resultWidth, int operationWidth) {

View File

@@ -11,10 +11,7 @@ cached
private newtype TCallContext =
TEmptyCallContext() or
TArgNonDelegateCallContext(Expr arg) { exists(DispatchCall dc | arg = dc.getArgument(_)) } or
TArgDelegateCallContext(DelegateCall dc, int i) { exists(dc.getArgument(i)) } or
TDelegateToLibraryCallableArgCallContext(DelegateArgumentToLibraryCallable arg, int i) {
exists(arg.getDelegateType().getParameter(i))
}
TArgDelegateCallContext(DelegateCall dc, int i) { exists(dc.getArgument(i)) }
/**
* A call context.
@@ -79,31 +76,3 @@ class DelegateCallArgumentCallContext extends ArgumentCallContext, TArgDelegateC
override Location getLocation() { result = dc.getArgument(arg).getLocation() }
}
/**
* An argument of a call to a delegate supplied to a library callable,
* identified by the delegate argument itself.
*
* For example, in `x.Select(y => y)` the call to the supplied delegate
* that happens inside the library callable `Select` is not available
* in the database, so the delegate argument `y => y` is used to
* represent the call.
*/
class DelegateArgumentToLibraryCallableArgumentContext extends ArgumentCallContext,
TDelegateToLibraryCallableArgCallContext {
Expr delegate;
int arg;
DelegateArgumentToLibraryCallableArgumentContext() {
this = TDelegateToLibraryCallableArgCallContext(delegate, arg)
}
override predicate isArgument(Expr call, int i) {
call = delegate and
i = arg
}
override string toString() { result = "argument " + arg + " of " + delegate.toString() }
override Location getLocation() { result = delegate.getLocation() }
}

View File

@@ -199,27 +199,13 @@ class CallableFlowSink extends TCallableFlowSink {
/** Gets the sink of flow for call `c`, if any. */
Expr getSink(Call c) { none() }
/**
* Gets the type of the sink for call `c`. Unlike `getSink()`, this is defined
* for all flow sink specifications.
*/
Type getSinkType(Call c) { result = this.getSink(c).getType() }
}
/** A flow sink specification: (method call) qualifier. */
class CallableFlowSinkQualifier extends CallableFlowSink, TCallableFlowSinkQualifier {
override string toString() { result = "qualifier" }
override Expr getSink(Call c) {
result = c.getChild(-1)
or
// E.g. `new Dictionary<int, string>{ {0, "a"}, {1, "b"} }`
result.(CollectionInitializer).getAnElementInitializer() = c
or
// E.g. `new Dictionary<int, string>() { [0] = "a", [1] = "b" }`
result.(ObjectInitializer).getAMemberInitializer().getLValue() = c
}
override Expr getSink(Call c) { result = c.getChild(-1) }
}
/** A flow sink specification: return value. */
@@ -253,8 +239,6 @@ class CallableFlowSinkArg extends CallableFlowSink, TCallableFlowSinkArg {
// The uses of the `i`th argument are the actual sinks
none()
}
override Type getSinkType(Call c) { result = this.getArgument(c).getType() }
}
private predicate isCollectionType(ValueOrRefType t) {
@@ -312,16 +296,6 @@ class CallableFlowSinkDelegateArg extends CallableFlowSink, TCallableFlowSinkDel
// The uses of the `j`th parameter are the actual sinks
none()
}
override Type getSinkType(Call c) {
result =
c
.getArgument(delegateIndex)
.(DelegateArgumentToLibraryCallable)
.getDelegateType()
.getParameter(parameterIndex)
.getType()
}
}
/** A specification of data flow for a library (non-source code) type. */

View File

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

View File

@@ -3,18 +3,24 @@ private import cil
private import dotnet
private import DataFlowPrivate
private import DelegateDataFlow
private import semmle.code.csharp.dataflow.LibraryTypeDataFlow
private import semmle.code.csharp.dispatch.Dispatch
private import semmle.code.csharp.frameworks.system.Collections
private import semmle.code.csharp.frameworks.system.collections.Generic
/**
* Gets a source declaration of callable `c` that has a body.
* Gets a source declaration of callable `c` that has a body or has
* a flow summary.
*
* If the callable has both CIL and source code, return only the source
* code version.
*/
DotNet::Callable getCallableForDataFlow(DotNet::Callable c) {
result.hasBody() and
exists(DotNet::Callable sourceDecl | sourceDecl = c.getSourceDeclaration() |
result = sourceDecl and
Summaries::summary(result, _, _, _, _, _)
or
result.hasBody() and
if sourceDecl.getFile().fromSource()
then
// C# callable with C# implementation in the database
@@ -83,7 +89,8 @@ private module Cached {
exists(Ssa::ExplicitDefinition def | def.isCapturedVariableDefinitionFlowOut(_, _) |
v = def.getSourceVariable().getAssignable()
)
}
} or
TQualifierReturnKind()
cached
newtype TDataFlowCall =
@@ -93,15 +100,23 @@ private module Cached {
TExplicitDelegateCall(ControlFlow::Nodes::ElementNode cfn, DelegateCall dc) {
cfn.getElement() = dc
} or
TImplicitDelegateCall(ControlFlow::Nodes::ElementNode cfn, DelegateArgumentToLibraryCallable arg) {
cfn.getElement() = arg
} or
TTransitiveCapturedCall(ControlFlow::Nodes::ElementNode cfn, Callable target) {
transitiveCapturedCallTarget(cfn, target)
} or
TCilCall(CIL::Call call) {
// No need to include calls that are compiled from source
not call.getImplementation().getMethod().compiledFromSource()
} or
TSummaryDelegateCall(SourceDeclarationCallable c, int pos) {
exists(CallableFlowSourceDelegateArg source |
Summaries::summary(c, source, _, _, _, _) and
pos = source.getArgumentIndex()
)
or
exists(CallableFlowSinkDelegateArg sink |
Summaries::summary(c, _, _, sink, _, _) and
pos = sink.getDelegateIndex()
)
}
/** Gets a viable run-time target for the call `call`. */
@@ -118,7 +133,7 @@ private module DispatchImpl {
* Gets a viable run-time target for the delegate call `call`, requiring
* call context `cc`.
*/
private DotNet::Callable viableDelegateCallable(DataFlowCall call, CallContext cc) {
private DataFlowCallable viableDelegateCallable(DataFlowCall call, CallContext cc) {
result = call.(DelegateDataFlowCall).getARuntimeTarget(cc)
}
@@ -143,7 +158,7 @@ private module DispatchImpl {
* Gets a viable dispatch target of `call` in the context `ctx`. This is
* restricted to those `call`s for which a context might make a difference.
*/
DotNet::Callable viableImplInCallContext(DataFlowCall call, DataFlowCall ctx) {
DataFlowCallable viableImplInCallContext(DataFlowCall call, DataFlowCall ctx) {
exists(ArgumentCallContext cc | result = viableDelegateCallable(call, cc) |
cc.isArgument(ctx.getExpr(), _)
)
@@ -153,6 +168,7 @@ private module DispatchImpl {
.(NonDelegateDataFlowCall)
.getDispatchCall()
.getADynamicTargetInCallContext(ctx.(NonDelegateDataFlowCall).getDispatchCall())
.getSourceDeclaration()
}
}
@@ -218,6 +234,11 @@ class ImplicitCapturedReturnKind extends ReturnKind, TImplicitCapturedReturnKind
override string toString() { result = "captured " + v }
}
/** A value returned through the qualifier of a call. */
class QualifierReturnKind extends ReturnKind, TQualifierReturnKind {
override string toString() { result = "qualifier" }
}
class DataFlowCallable = DotNet::Callable;
/** A call relevant for data flow. */
@@ -261,7 +282,7 @@ class NonDelegateDataFlowCall extends DataFlowCall, TNonDelegateCall {
/** Gets the underlying call. */
DispatchCall getDispatchCall() { result = dc }
override DotNet::Callable getARuntimeTarget() {
override DataFlowCallable getARuntimeTarget() {
result = getCallableForDataFlow(dc.getADynamicTarget())
}
@@ -279,9 +300,9 @@ class NonDelegateDataFlowCall extends DataFlowCall, TNonDelegateCall {
/** A delegate call relevant for data flow. */
abstract class DelegateDataFlowCall extends DataFlowCall {
/** Gets a viable run-time target of this call requiring call context `cc`. */
abstract DotNet::Callable getARuntimeTarget(CallContext::CallContext cc);
abstract DataFlowCallable getARuntimeTarget(CallContext::CallContext cc);
override DotNet::Callable getARuntimeTarget() { result = this.getARuntimeTarget(_) }
override DataFlowCallable getARuntimeTarget() { result = this.getARuntimeTarget(_) }
}
/** An explicit delegate call relevant for data flow. */
@@ -291,8 +312,8 @@ class ExplicitDelegateDataFlowCall extends DelegateDataFlowCall, TExplicitDelega
ExplicitDelegateDataFlowCall() { this = TExplicitDelegateCall(cfn, dc) }
override DotNet::Callable getARuntimeTarget(CallContext::CallContext cc) {
result = dc.getARuntimeTarget(cc)
override DataFlowCallable getARuntimeTarget(CallContext::CallContext cc) {
result = getCallableForDataFlow(dc.getARuntimeTarget(cc))
}
override ControlFlow::Nodes::ElementNode getControlFlowNode() { result = cfn }
@@ -306,50 +327,6 @@ class ExplicitDelegateDataFlowCall extends DelegateDataFlowCall, TExplicitDelega
override Location getLocation() { result = cfn.getLocation() }
}
/**
* An implicit delegate call in a call to a library method. For example, we add
* an implicit call to `M` in `new Lazy<int>(M)` (although, technically, the delegate
* would first be called when accessing the `Value` property).
*/
class ImplicitDelegateDataFlowCall extends DelegateDataFlowCall, TImplicitDelegateCall {
private ControlFlow::Nodes::ElementNode cfn;
private DelegateArgumentToLibraryCallable arg;
ImplicitDelegateDataFlowCall() { this = TImplicitDelegateCall(cfn, arg) }
/**
* Holds if the underlying delegate argument is the `i`th argument of the
* call `c` targeting a library callable. For example, `M` is the `0`th
* argument of `new Lazy<int>(M)`.
*/
predicate isArgumentOf(NonDelegateDataFlowCall c, int i) {
exists(ImplicitDelegateOutNode out | out.getControlFlowNode() = cfn | out.isArgumentOf(c, i))
}
/** Gets the number of parameters of the supplied delegate. */
int getNumberOfDelegateParameters() { result = arg.getDelegateType().getNumberOfParameters() }
/** Gets the type of the `i`th parameter of the supplied delegate. */
Type getDelegateParameterType(int i) { result = arg.getDelegateType().getParameter(i).getType() }
/** Gets the return type of the supplied delegate. */
Type getDelegateReturnType() { result = arg.getDelegateType().getReturnType() }
override DotNet::Callable getARuntimeTarget(CallContext::CallContext cc) {
result = arg.getARuntimeTarget(cc)
}
override ControlFlow::Nodes::ElementNode getControlFlowNode() { result = cfn }
override ImplicitDelegateOutNode getNode() { result.getControlFlowNode() = cfn }
override Callable getEnclosingCallable() { result = cfn.getEnclosingCallable() }
override string toString() { result = "[implicit call] " + cfn.toString() }
override Location getLocation() { result = cfn.getLocation() }
}
/**
* A call that can reach a callable, using one or more additional calls, which
* reads or updates a captured variable. We model such a chain of calls as just
@@ -380,7 +357,7 @@ class CilDataFlowCall extends DataFlowCall, TCilCall {
CilDataFlowCall() { this = TCilCall(call) }
override DotNet::Callable getARuntimeTarget() {
override DataFlowCallable getARuntimeTarget() {
// There is no dispatch library for CIL, so do not consider overrides for now
result = getCallableForDataFlow(call.getTarget())
}
@@ -395,3 +372,34 @@ class CilDataFlowCall extends DataFlowCall, TCilCall {
override Location getLocation() { result = call.getLocation() }
}
/**
* A delegate call inside a callable with a flow summary.
*
* For example, in `ints.Select(i => i + 1)` there is a call to the delegate at
* parameter position `1` (counting the qualifier as the `0`th argument) inside
* the method `Select`.
*/
class SummaryDelegateCall extends DelegateDataFlowCall, TSummaryDelegateCall {
private SourceDeclarationCallable c;
private int pos;
SummaryDelegateCall() { this = TSummaryDelegateCall(c, pos) }
override DataFlowCallable getARuntimeTarget(CallContext::CallContext cc) {
exists(SummaryDelegateParameterSink p |
p = TSummaryParameterNode(c, pos) and
result = p.getARuntimeTarget(cc)
)
}
override ControlFlow::Nodes::ElementNode getControlFlowNode() { none() }
override DataFlow::Node getNode() { none() }
override Callable getEnclosingCallable() { result = c }
override string toString() { result = "[summary] delegate call, parameter " + pos + " of " + c }
override Location getLocation() { result = c.getLocation() }
}

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