зеркало из https://github.com/github/codeql.git
Merge branch 'main' into python/model-aiomysql
This commit is contained in:
Коммит
d23a920ed4
|
@ -449,7 +449,8 @@
|
|||
"csharp/ql/lib/semmle/code/csharp/controlflow/internal/pressa/SsaImplCommon.qll",
|
||||
"csharp/ql/lib/semmle/code/csharp/dataflow/internal/basessa/SsaImplCommon.qll",
|
||||
"csharp/ql/lib/semmle/code/cil/internal/SsaImplCommon.qll",
|
||||
"ruby/ql/lib/codeql/ruby/dataflow/internal/SsaImplCommon.qll"
|
||||
"ruby/ql/lib/codeql/ruby/dataflow/internal/SsaImplCommon.qll",
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/SsaImplCommon.qll"
|
||||
],
|
||||
"CryptoAlgorithms Python/JS": [
|
||||
"javascript/ql/lib/semmle/javascript/security/CryptoAlgorithms.qll",
|
||||
|
|
|
@ -63,8 +63,10 @@ private module VirtualDispatch {
|
|||
|
|
||||
// Call argument
|
||||
exists(DataFlowCall call, int i |
|
||||
other.(DataFlow::ParameterNode).isParameterOf(call.getStaticCallTarget(), i) and
|
||||
src.(ArgumentNode).argumentOf(call, i)
|
||||
other
|
||||
.(DataFlow::ParameterNode)
|
||||
.isParameterOf(pragma[only_bind_into](call).getStaticCallTarget(), i) and
|
||||
src.(ArgumentNode).argumentOf(call, pragma[only_bind_into](pragma[only_bind_out](i)))
|
||||
) and
|
||||
allowOtherFromArg = true and
|
||||
allowFromArg = true
|
||||
|
@ -128,6 +130,7 @@ private module VirtualDispatch {
|
|||
*
|
||||
* Used to fix a join ordering issue in flowsFrom.
|
||||
*/
|
||||
pragma[noinline]
|
||||
private predicate returnNodeWithKindAndEnclosingCallable(
|
||||
ReturnNode node, ReturnKind kind, DataFlowCallable callable
|
||||
) {
|
||||
|
|
|
@ -112,11 +112,9 @@ class ReturnNode extends InstructionNode {
|
|||
Instruction primary;
|
||||
|
||||
ReturnNode() {
|
||||
exists(ReturnValueInstruction ret | instr = ret.getReturnValue() and primary = ret)
|
||||
exists(ReturnValueInstruction ret | instr = ret and primary = ret)
|
||||
or
|
||||
exists(ReturnIndirectionInstruction rii |
|
||||
instr = rii.getSideEffectOperand().getAnyDef() and primary = rii
|
||||
)
|
||||
exists(ReturnIndirectionInstruction rii | instr = rii and primary = rii)
|
||||
}
|
||||
|
||||
/** Gets the kind of this returned value. */
|
||||
|
@ -190,108 +188,16 @@ OutNode getAnOutNode(DataFlowCall call, ReturnKind kind) {
|
|||
*/
|
||||
predicate jumpStep(Node n1, Node n2) { none() }
|
||||
|
||||
private predicate fieldStoreStepNoChi(Node node1, FieldContent f, PostUpdateNode node2) {
|
||||
exists(StoreInstruction store, Class c |
|
||||
store = node2.asInstruction() and
|
||||
store.getSourceValueOperand() = node1.asOperand() and
|
||||
getWrittenField(store, f.getAField(), c) and
|
||||
f.hasOffset(c, _, _)
|
||||
)
|
||||
}
|
||||
|
||||
private FieldAddressInstruction getFieldInstruction(Instruction instr) {
|
||||
result = instr or
|
||||
result = instr.(CopyValueInstruction).getUnary()
|
||||
}
|
||||
|
||||
pragma[noinline]
|
||||
private predicate getWrittenField(Instruction instr, Field f, Class c) {
|
||||
exists(FieldAddressInstruction fa |
|
||||
fa =
|
||||
getFieldInstruction([
|
||||
instr.(StoreInstruction).getDestinationAddress(),
|
||||
instr.(WriteSideEffectInstruction).getDestinationAddress()
|
||||
]) and
|
||||
f = fa.getField() and
|
||||
c = f.getDeclaringType()
|
||||
)
|
||||
}
|
||||
|
||||
private predicate fieldStoreStepChi(Node node1, FieldContent f, PostUpdateNode node2) {
|
||||
exists(ChiPartialOperand operand, ChiInstruction chi |
|
||||
chi.getPartialOperand() = operand and
|
||||
node1.asOperand() = operand and
|
||||
node2.asInstruction() = chi and
|
||||
exists(Class c |
|
||||
c = chi.getResultType() and
|
||||
exists(int startBit, int endBit |
|
||||
chi.getUpdatedInterval(startBit, endBit) and
|
||||
f.hasOffset(c, startBit, endBit)
|
||||
)
|
||||
or
|
||||
getWrittenField(operand.getDef(), f.getAField(), c) and
|
||||
f.hasOffset(c, _, _)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
private predicate arrayStoreStepChi(Node node1, ArrayContent a, PostUpdateNode node2) {
|
||||
exists(a) and
|
||||
exists(ChiPartialOperand operand, ChiInstruction chi, StoreInstruction store |
|
||||
chi.getPartialOperand() = operand and
|
||||
store = operand.getDef() and
|
||||
node1.asOperand() = operand and
|
||||
// This `ChiInstruction` will always have a non-conflated result because both `ArrayStoreNode`
|
||||
// and `PointerStoreNode` require it in their characteristic predicates.
|
||||
node2.asInstruction() = chi and
|
||||
(
|
||||
// `x[i] = taint()`
|
||||
// This matches the characteristic predicate in `ArrayStoreNode`.
|
||||
store.getDestinationAddress() instanceof PointerAddInstruction
|
||||
or
|
||||
// `*p = taint()`
|
||||
// This matches the characteristic predicate in `PointerStoreNode`.
|
||||
store.getDestinationAddress().(CopyValueInstruction).getUnary() instanceof LoadInstruction
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if data can flow from `node1` to `node2` via an assignment to `f`.
|
||||
* Thus, `node2` references an object with a field `f` that contains the
|
||||
* value of `node1`.
|
||||
*/
|
||||
predicate storeStep(Node node1, Content f, PostUpdateNode node2) {
|
||||
fieldStoreStepNoChi(node1, f, node2) or
|
||||
fieldStoreStepChi(node1, f, node2) or
|
||||
arrayStoreStepChi(node1, f, node2) or
|
||||
fieldStoreStepAfterArraySuppression(node1, f, node2)
|
||||
}
|
||||
|
||||
// This predicate pushes the correct `FieldContent` onto the access path when the
|
||||
// `suppressArrayRead` predicate has popped off an `ArrayContent`.
|
||||
private predicate fieldStoreStepAfterArraySuppression(
|
||||
Node node1, FieldContent f, PostUpdateNode node2
|
||||
) {
|
||||
exists(WriteSideEffectInstruction write, ChiInstruction chi, Class c |
|
||||
not chi.isResultConflated() and
|
||||
node1.asInstruction() = chi and
|
||||
node2.asInstruction() = chi and
|
||||
chi.getPartial() = write and
|
||||
getWrittenField(write, f.getAField(), c) and
|
||||
f.hasOffset(c, _, _)
|
||||
)
|
||||
}
|
||||
|
||||
bindingset[result, i]
|
||||
private int unbindInt(int i) { i <= result and i >= result }
|
||||
|
||||
pragma[noinline]
|
||||
private predicate getLoadedField(LoadInstruction load, Field f, Class c) {
|
||||
exists(FieldAddressInstruction fa |
|
||||
fa = load.getSourceAddress() and
|
||||
f = fa.getField() and
|
||||
c = f.getDeclaringType()
|
||||
predicate storeStep(StoreNodeInstr node1, FieldContent f, StoreNodeInstr node2) {
|
||||
exists(FieldAddressInstruction fai |
|
||||
node1.getInstruction() = fai and
|
||||
node2.getInstruction() = fai.getObjectAddress() and
|
||||
f.getField() = fai.getField()
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -300,122 +206,14 @@ private predicate getLoadedField(LoadInstruction load, Field f, Class c) {
|
|||
* Thus, `node1` references an object with a field `f` whose value ends up in
|
||||
* `node2`.
|
||||
*/
|
||||
private predicate fieldReadStep(Node node1, FieldContent f, Node node2) {
|
||||
exists(LoadOperand operand |
|
||||
node2.asOperand() = operand and
|
||||
node1.asInstruction() = operand.getAnyDef() and
|
||||
exists(Class c |
|
||||
c = operand.getAnyDef().getResultType() and
|
||||
exists(int startBit, int endBit |
|
||||
operand.getUsedInterval(unbindInt(startBit), unbindInt(endBit)) and
|
||||
f.hasOffset(c, startBit, endBit)
|
||||
)
|
||||
or
|
||||
getLoadedField(operand.getUse(), f.getAField(), c) and
|
||||
f.hasOffset(c, _, _)
|
||||
)
|
||||
predicate readStep(ReadNode node1, FieldContent f, ReadNode node2) {
|
||||
exists(FieldAddressInstruction fai |
|
||||
node1.getInstruction() = fai.getObjectAddress() and
|
||||
node2.getInstruction() = fai and
|
||||
f.getField() = fai.getField()
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* When a store step happens in a function that looks like an array write such as:
|
||||
* ```cpp
|
||||
* void f(int* pa) {
|
||||
* pa = source();
|
||||
* }
|
||||
* ```
|
||||
* it can be a write to an array, but it can also happen that `f` is called as `f(&a.x)`. If that is
|
||||
* the case, the `ArrayContent` that was written by the call to `f` should be popped off the access
|
||||
* path, and a `FieldContent` containing `x` should be pushed instead.
|
||||
* So this case pops `ArrayContent` off the access path, and the `fieldStoreStepAfterArraySuppression`
|
||||
* predicate in `storeStep` ensures that we push the right `FieldContent` onto the access path.
|
||||
*/
|
||||
predicate suppressArrayRead(Node node1, ArrayContent a, Node node2) {
|
||||
exists(a) and
|
||||
exists(WriteSideEffectInstruction write, ChiInstruction chi |
|
||||
node1.asInstruction() = write and
|
||||
node2.asInstruction() = chi and
|
||||
chi.getPartial() = write and
|
||||
getWrittenField(write, _, _)
|
||||
)
|
||||
}
|
||||
|
||||
private class ArrayToPointerConvertInstruction extends ConvertInstruction {
|
||||
ArrayToPointerConvertInstruction() {
|
||||
this.getUnary().getResultType() instanceof ArrayType and
|
||||
this.getResultType() instanceof PointerType
|
||||
}
|
||||
}
|
||||
|
||||
private Instruction skipOneCopyValueInstructionRec(CopyValueInstruction copy) {
|
||||
copy.getUnary() = result and not result instanceof CopyValueInstruction
|
||||
or
|
||||
result = skipOneCopyValueInstructionRec(copy.getUnary())
|
||||
}
|
||||
|
||||
private Instruction skipCopyValueInstructions(Operand op) {
|
||||
not result instanceof CopyValueInstruction and result = op.getDef()
|
||||
or
|
||||
result = skipOneCopyValueInstructionRec(op.getDef())
|
||||
}
|
||||
|
||||
private predicate arrayReadStep(Node node1, ArrayContent a, Node node2) {
|
||||
exists(a) and
|
||||
// Explicit dereferences such as `*p` or `p[i]` where `p` is a pointer or array.
|
||||
exists(LoadOperand operand, Instruction address |
|
||||
operand.isDefinitionInexact() and
|
||||
node1.asInstruction() = operand.getAnyDef() and
|
||||
operand = node2.asOperand() and
|
||||
address = skipCopyValueInstructions(operand.getAddressOperand()) and
|
||||
(
|
||||
address instanceof LoadInstruction or
|
||||
address instanceof ArrayToPointerConvertInstruction or
|
||||
address instanceof PointerOffsetInstruction
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* In cases such as:
|
||||
* ```cpp
|
||||
* void f(int* pa) {
|
||||
* *pa = source();
|
||||
* }
|
||||
* ...
|
||||
* int x;
|
||||
* f(&x);
|
||||
* use(x);
|
||||
* ```
|
||||
* the load on `x` in `use(x)` will exactly overlap with its definition (in this case the definition
|
||||
* is a `WriteSideEffect`). This predicate pops the `ArrayContent` (pushed by the store in `f`)
|
||||
* from the access path.
|
||||
*/
|
||||
private predicate exactReadStep(Node node1, ArrayContent a, Node node2) {
|
||||
exists(a) and
|
||||
exists(WriteSideEffectInstruction write, ChiInstruction chi |
|
||||
not chi.isResultConflated() and
|
||||
chi.getPartial() = write and
|
||||
node1.asInstruction() = write and
|
||||
node2.asInstruction() = chi and
|
||||
// To distinquish this case from the `arrayReadStep` case we require that the entire variable was
|
||||
// overwritten by the `WriteSideEffectInstruction` (i.e., there is a load that reads the
|
||||
// entire variable).
|
||||
exists(LoadInstruction load | load.getSourceValue() = chi)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if data can flow from `node1` to `node2` via a read of `f`.
|
||||
* Thus, `node1` references an object with a field `f` whose value ends up in
|
||||
* `node2`.
|
||||
*/
|
||||
predicate readStep(Node node1, Content f, Node node2) {
|
||||
fieldReadStep(node1, f, node2) or
|
||||
arrayReadStep(node1, f, node2) or
|
||||
exactReadStep(node1, f, node2) or
|
||||
suppressArrayRead(node1, f, node2)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if values stored inside content `c` are cleared at node `n`.
|
||||
*/
|
||||
|
@ -447,7 +245,7 @@ private predicate suppressUnusedNode(Node n) { any() }
|
|||
// Java QL library compatibility wrappers
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
/** A node that performs a type cast. */
|
||||
class CastNode extends InstructionNode {
|
||||
class CastNode extends Node {
|
||||
CastNode() { none() } // stub implementation
|
||||
}
|
||||
|
||||
|
|
|
@ -10,19 +10,78 @@ private import semmle.code.cpp.ir.ValueNumbering
|
|||
private import semmle.code.cpp.ir.IR
|
||||
private import semmle.code.cpp.controlflow.IRGuards
|
||||
private import semmle.code.cpp.models.interfaces.DataFlow
|
||||
private import DataFlowPrivate
|
||||
private import SsaInternals as Ssa
|
||||
|
||||
cached
|
||||
private module Cached {
|
||||
/**
|
||||
* The IR dataflow graph consists of the following nodes:
|
||||
* - `InstructionNode`, which represents an `Instruction` in the graph.
|
||||
* - `OperandNode`, which represents an `Operand` in the graph.
|
||||
* - `VariableNode`, which is used to model global variables.
|
||||
* - Two kinds of `StoreNode`s:
|
||||
* 1. `StoreNodeInstr`, which represents the value of an address computed by an `Instruction` that
|
||||
* has been updated by a write operation.
|
||||
* 2. `StoreNodeOperand`, which represents the value of an address in an `ArgumentOperand` after a
|
||||
* function call that may have changed the value.
|
||||
* - `ReadNode`, which represents the result of reading a field of an object.
|
||||
* - `SsaPhiNode`, which represents phi nodes as computed by the shared SSA library.
|
||||
*
|
||||
* The following section describes how flow is generally transferred between these nodes:
|
||||
* - Flow between `InstructionNode`s and `OperandNode`s follow the def-use information as computed by
|
||||
* the IR. Because the IR compute must-alias information for memory operands, we only follow def-use
|
||||
* flow for register operands.
|
||||
* - Flow can enter a `StoreNode` in two ways (both done in `StoreNode.flowInto`):
|
||||
* 1. Flow is transferred from a `StoreValueOperand` to a `StoreNodeInstr`. Flow will then proceed
|
||||
* along the chain of addresses computed by `StoreNodeInstr.getInner` to identify field writes
|
||||
* and call `storeStep` accordingly (i.e., for an expression like `a.b.c = x`, we visit `c`, then
|
||||
* `b`, then `a`).
|
||||
* 2. Flow is transfered from a `WriteSideEffectInstruction` to a `StoreNodeOperand` after flow
|
||||
* returns to a caller. Flow will then proceed to the defining instruction of the operand (because
|
||||
* the `StoreNodeInstr` computed by `StoreNodeOperand.getInner()` is the `StoreNode` containing
|
||||
* the defining instruction), and then along the chain computed by `StoreNodeInstr.getInner` like
|
||||
* above.
|
||||
* In both cases, flow leaves a `StoreNode` once the entire chain has been traversed, and the shared
|
||||
* SSA library is used to find the next use of the variable at the end of the chain.
|
||||
* - Flow can enter a `ReadNode` through an `OperandNode` that represents an address of some variable.
|
||||
* Flow will then proceed along the chain of addresses computed by `ReadNode.getOuter` (i.e., for an
|
||||
* expression like `use(a.b.c)` we visit `a`, then `b`, then `c`) and call `readStep` accordingly.
|
||||
* Once the entire chain has been traversed, flow is transferred to the load instruction that reads
|
||||
* the final address of the chain.
|
||||
* - Flow can enter a `SsaPhiNode` from an `InstructionNode`, a `StoreNode` or another `SsaPhiNode`
|
||||
* (in `toPhiNode`), depending on which node provided the previous definition of the underlying
|
||||
* variable. Flow leaves a `SsaPhiNode` (in `fromPhiNode`) by using the shared SSA library to
|
||||
* determine the next use of the variable.
|
||||
*/
|
||||
cached
|
||||
newtype TIRDataFlowNode =
|
||||
TInstructionNode(Instruction i) or
|
||||
TOperandNode(Operand op) or
|
||||
TVariableNode(Variable var)
|
||||
TVariableNode(Variable var) or
|
||||
TStoreNodeInstr(Instruction i) { Ssa::explicitWrite(_, _, i) } or
|
||||
TStoreNodeOperand(ArgumentOperand op) { Ssa::explicitWrite(_, _, op.getDef()) } or
|
||||
TReadNode(Instruction i) { needsPostReadNode(i) } or
|
||||
TSsaPhiNode(Ssa::PhiNode phi)
|
||||
|
||||
cached
|
||||
predicate localFlowStepCached(Node nodeFrom, Node nodeTo) {
|
||||
simpleLocalFlowStep(nodeFrom, nodeTo)
|
||||
}
|
||||
|
||||
private predicate needsPostReadNode(Instruction iFrom) {
|
||||
// If the instruction generates an address that flows to a load.
|
||||
Ssa::addressFlowTC(iFrom, Ssa::getSourceAddress(_)) and
|
||||
(
|
||||
// And it is either a field address
|
||||
iFrom instanceof FieldAddressInstruction
|
||||
or
|
||||
// Or it is instruction that either uses or is used for an address that needs a post read node.
|
||||
exists(Instruction mid | needsPostReadNode(mid) |
|
||||
Ssa::addressFlow(mid, iFrom) or Ssa::addressFlow(iFrom, mid)
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private import Cached
|
||||
|
@ -180,6 +239,234 @@ class OperandNode extends Node, TOperandNode {
|
|||
override string toString() { result = this.getOperand().toString() }
|
||||
}
|
||||
|
||||
/**
|
||||
* INTERNAL: do not use.
|
||||
*
|
||||
* A `StoreNode` is a node that has been (or is about to be) the
|
||||
* source or target of a `storeStep`.
|
||||
*/
|
||||
abstract private class StoreNode extends Node {
|
||||
/** Holds if this node should receive flow from `addr`. */
|
||||
abstract predicate flowInto(Instruction addr);
|
||||
|
||||
override Declaration getEnclosingCallable() { result = this.getFunction() }
|
||||
|
||||
/** Holds if this `StoreNode` is the root of the address computation used by a store operation. */
|
||||
predicate isTerminal() {
|
||||
not exists(this.getInner()) and
|
||||
not storeStep(this, _, _)
|
||||
}
|
||||
|
||||
/** Gets the store operation that uses the address computed by this `StoreNode`. */
|
||||
abstract Instruction getStoreInstruction();
|
||||
|
||||
/** Holds if the store operation associated with this `StoreNode` overwrites the entire variable. */
|
||||
final predicate isCertain() { Ssa::explicitWrite(true, this.getStoreInstruction(), _) }
|
||||
|
||||
/**
|
||||
* Gets the `StoreNode` that computes the address used by this `StoreNode`.
|
||||
*/
|
||||
abstract StoreNode getInner();
|
||||
|
||||
/** The inverse of `StoreNode.getInner`. */
|
||||
final StoreNode getOuter() { result.getInner() = this }
|
||||
}
|
||||
|
||||
class StoreNodeInstr extends StoreNode, TStoreNodeInstr {
|
||||
Instruction instr;
|
||||
|
||||
StoreNodeInstr() { this = TStoreNodeInstr(instr) }
|
||||
|
||||
override predicate flowInto(Instruction addr) { this.getInstruction() = addr }
|
||||
|
||||
/** Gets the underlying instruction. */
|
||||
Instruction getInstruction() { result = instr }
|
||||
|
||||
override Function getFunction() { result = this.getInstruction().getEnclosingFunction() }
|
||||
|
||||
override IRType getType() { result = this.getInstruction().getResultIRType() }
|
||||
|
||||
override Location getLocation() { result = this.getInstruction().getLocation() }
|
||||
|
||||
override string toString() {
|
||||
result = instructionNode(this.getInstruction()).toString() + " [store]"
|
||||
}
|
||||
|
||||
override Instruction getStoreInstruction() {
|
||||
Ssa::explicitWrite(_, result, this.getInstruction())
|
||||
}
|
||||
|
||||
override StoreNodeInstr getInner() {
|
||||
Ssa::addressFlow(result.getInstruction(), this.getInstruction())
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* To avoid having `PostUpdateNode`s with multiple pre-update nodes (which can cause performance
|
||||
* problems) we attach the `PostUpdateNode` that represent output arguments to an operand instead of
|
||||
* an instruction.
|
||||
*
|
||||
* To see why we need this, consider the expression `b->set(new C())`. The IR of this expression looks
|
||||
* like (simplified):
|
||||
* ```
|
||||
* r1(glval<unknown>) = FunctionAddress[set] :
|
||||
* r2(glval<unknown>) = FunctionAddress[operator new] :
|
||||
* r3(unsigned long) = Constant[8] :
|
||||
* r4(void *) = Call[operator new] : func:r2, 0:r3
|
||||
* r5(C *) = Convert : r4
|
||||
* r6(glval<unknown>) = FunctionAddress[C] :
|
||||
* v1(void) = Call[C] : func:r6, this:r5
|
||||
* v2(void) = Call[set] : func:r1, this:r0, 0:r5
|
||||
* ```
|
||||
*
|
||||
* Notice that both the call to `C` and the call to `set` will have an argument that is the
|
||||
* result of calling `operator new` (i.e., `r4`). If we only have `PostUpdateNode`s that are
|
||||
* instructions, both `PostUpdateNode`s would have `r4` as their pre-update node.
|
||||
*
|
||||
* We avoid this issue by having a `PostUpdateNode` for each argument, and let the pre-update node of
|
||||
* each `PostUpdateNode` be the argument _operand_, instead of the defining instruction.
|
||||
*/
|
||||
class StoreNodeOperand extends StoreNode, TStoreNodeOperand {
|
||||
ArgumentOperand operand;
|
||||
|
||||
StoreNodeOperand() { this = TStoreNodeOperand(operand) }
|
||||
|
||||
override predicate flowInto(Instruction addr) { this.getOperand().getDef() = addr }
|
||||
|
||||
/** Gets the underlying operand. */
|
||||
Operand getOperand() { result = operand }
|
||||
|
||||
override Function getFunction() { result = operand.getDef().getEnclosingFunction() }
|
||||
|
||||
override IRType getType() { result = operand.getIRType() }
|
||||
|
||||
override Location getLocation() { result = operand.getLocation() }
|
||||
|
||||
override string toString() { result = operandNode(this.getOperand()).toString() + " [store]" }
|
||||
|
||||
override WriteSideEffectInstruction getStoreInstruction() {
|
||||
Ssa::explicitWrite(_, result, operand.getDef())
|
||||
}
|
||||
|
||||
/**
|
||||
* The result of `StoreNodeOperand.getInner` is the `StoreNodeInstr` representation the instruction
|
||||
* that defines this operand. This means the graph of `getInner` looks like this:
|
||||
* ```
|
||||
* I---I---I
|
||||
* \ \ \
|
||||
* O O O
|
||||
* ```
|
||||
* where each `StoreNodeOperand` "hooks" into the chain computed by `StoreNodeInstr.getInner`.
|
||||
* This means that the chain of `getInner` calls on the argument `&o.f` on an expression
|
||||
* like `func(&o.f)` is:
|
||||
* ```
|
||||
* r4---r3---r2
|
||||
* \
|
||||
* 0:r4
|
||||
* ```
|
||||
* where the IR for `func(&o.f)` looks like (simplified):
|
||||
* ```
|
||||
* r1(glval<unknown>) = FunctionAddress[func] :
|
||||
* r2(glval<O>) = VariableAddress[o] :
|
||||
* r3(glval<int>) = FieldAddress[f] : r2
|
||||
* r4(int *) = CopyValue : r3
|
||||
* v1(void) = Call[func] : func:r1, 0:r4
|
||||
* ```
|
||||
*/
|
||||
override StoreNodeInstr getInner() { operand.getDef() = result.getInstruction() }
|
||||
}
|
||||
|
||||
/**
|
||||
* INTERNAL: do not use.
|
||||
*
|
||||
* A `ReadNode` is a node that has been (or is about to be) the
|
||||
* source or target of a `readStep`.
|
||||
*/
|
||||
class ReadNode extends Node, TReadNode {
|
||||
Instruction i;
|
||||
|
||||
ReadNode() { this = TReadNode(i) }
|
||||
|
||||
/** Gets the underlying instruction. */
|
||||
Instruction getInstruction() { result = i }
|
||||
|
||||
override Declaration getEnclosingCallable() { result = this.getFunction() }
|
||||
|
||||
override Function getFunction() { result = this.getInstruction().getEnclosingFunction() }
|
||||
|
||||
override IRType getType() { result = this.getInstruction().getResultIRType() }
|
||||
|
||||
override Location getLocation() { result = this.getInstruction().getLocation() }
|
||||
|
||||
override string toString() {
|
||||
result = instructionNode(this.getInstruction()).toString() + " [read]"
|
||||
}
|
||||
|
||||
/** Gets a load instruction that uses the address computed by this read node. */
|
||||
final Instruction getALoadInstruction() {
|
||||
Ssa::addressFlowTC(this.getInstruction(), Ssa::getSourceAddress(result))
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a read node with an underlying instruction that is used by this
|
||||
* underlying instruction to compute an address of a load instruction.
|
||||
*/
|
||||
final ReadNode getInner() { Ssa::addressFlow(result.getInstruction(), this.getInstruction()) }
|
||||
|
||||
/** The inverse of `ReadNode.getInner`. */
|
||||
final ReadNode getOuter() { result.getInner() = this }
|
||||
|
||||
/** Holds if this read node computes a value that will not be used for any future read nodes. */
|
||||
final predicate isTerminal() {
|
||||
not exists(this.getOuter()) and
|
||||
not readStep(this, _, _)
|
||||
}
|
||||
|
||||
/** Holds if this read node computes a value that has not yet been used for any read operations. */
|
||||
final predicate isInitial() {
|
||||
not exists(this.getInner()) and
|
||||
not readStep(_, _, this)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* INTERNAL: do not use.
|
||||
*
|
||||
* A phi node produced by the shared SSA library, viewed as a node in a data flow graph.
|
||||
*/
|
||||
class SsaPhiNode extends Node, TSsaPhiNode {
|
||||
Ssa::PhiNode phi;
|
||||
|
||||
SsaPhiNode() { this = TSsaPhiNode(phi) }
|
||||
|
||||
/* Get the phi node associated with this node. */
|
||||
Ssa::PhiNode getPhiNode() { result = phi }
|
||||
|
||||
override Declaration getEnclosingCallable() { result = this.getFunction() }
|
||||
|
||||
override Function getFunction() { result = phi.getBasicBlock().getEnclosingFunction() }
|
||||
|
||||
override IRType getType() { result instanceof IRVoidType }
|
||||
|
||||
override Location getLocation() { result = phi.getBasicBlock().getLocation() }
|
||||
|
||||
/** Holds if this phi node has input from the `rnk`'th write operation in block `block`. */
|
||||
final predicate hasInputAtRankInBlock(IRBlock block, int rnk) {
|
||||
hasInputAtRankInBlock(block, rnk, _)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if this phi node has input from the definition `input` (which is the `rnk`'th write
|
||||
* operation in block `block`).
|
||||
*/
|
||||
cached
|
||||
final predicate hasInputAtRankInBlock(IRBlock block, int rnk, Ssa::Definition input) {
|
||||
Ssa::phiHasInputFromBlock(phi, input, _) and input.definesAt(_, block, rnk)
|
||||
}
|
||||
|
||||
override string toString() { result = "Phi" }
|
||||
}
|
||||
|
||||
/**
|
||||
* An expression, viewed as a node in a data flow graph.
|
||||
*/
|
||||
|
@ -313,15 +600,14 @@ deprecated class UninitializedNode extends Node {
|
|||
* Nodes corresponding to AST elements, for example `ExprNode`, usually refer
|
||||
* to the value before the update with the exception of `ClassInstanceExpr`,
|
||||
* which represents the value after the constructor has run.
|
||||
*
|
||||
* This class exists to match the interface used by Java. There are currently no non-abstract
|
||||
* classes that extend it. When we implement field flow, we can revisit this.
|
||||
*/
|
||||
abstract class PostUpdateNode extends InstructionNode {
|
||||
abstract class PostUpdateNode extends Node {
|
||||
/**
|
||||
* Gets the node before the state update.
|
||||
*/
|
||||
abstract Node getPreUpdateNode();
|
||||
|
||||
override string toString() { result = this.getPreUpdateNode() + " [post update]" }
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -332,7 +618,7 @@ abstract class PostUpdateNode extends InstructionNode {
|
|||
* value, but does not necessarily replace it entirely. For example:
|
||||
* ```
|
||||
* x.y = 1; // a partial definition of the object `x`.
|
||||
* x.y.z = 1; // a partial definition of the object `x.y`.
|
||||
* x.y.z = 1; // a partial definition of the object `x.y` and `x`.
|
||||
* x.setY(1); // a partial definition of the object `x`.
|
||||
* setY(&x); // a partial definition of the object `x`.
|
||||
* ```
|
||||
|
@ -341,135 +627,34 @@ abstract private class PartialDefinitionNode extends PostUpdateNode {
|
|||
abstract Expr getDefinedExpr();
|
||||
}
|
||||
|
||||
private class ExplicitFieldStoreQualifierNode extends PartialDefinitionNode {
|
||||
override ChiInstruction instr;
|
||||
StoreInstruction store;
|
||||
|
||||
ExplicitFieldStoreQualifierNode() {
|
||||
not instr.isResultConflated() and
|
||||
instr.getPartial() = store and
|
||||
(
|
||||
instr.getUpdatedInterval(_, _) or
|
||||
store.getDestinationAddress() instanceof FieldAddressInstruction
|
||||
)
|
||||
private class FieldPartialDefinitionNode extends PartialDefinitionNode, StoreNodeInstr {
|
||||
FieldPartialDefinitionNode() {
|
||||
this.getInstruction() = any(FieldAddressInstruction fai).getObjectAddress()
|
||||
}
|
||||
|
||||
// By using an operand as the result of this predicate we avoid the dataflow inconsistency errors
|
||||
// caused by having multiple nodes sharing the same pre update node. This inconsistency error can cause
|
||||
// a tuple explosion in the big step dataflow relation since it can make many nodes be the entry node
|
||||
// into a big step.
|
||||
override Node getPreUpdateNode() { result.asOperand() = instr.getTotalOperand() }
|
||||
override Node getPreUpdateNode() { result.asInstruction() = this.getInstruction() }
|
||||
|
||||
override Expr getDefinedExpr() { result = this.getInstruction().getUnconvertedResultExpression() }
|
||||
|
||||
override string toString() { result = PartialDefinitionNode.super.toString() }
|
||||
}
|
||||
|
||||
private class NonPartialDefinitionPostUpdate extends PostUpdateNode, StoreNodeInstr {
|
||||
NonPartialDefinitionPostUpdate() { not this instanceof PartialDefinitionNode }
|
||||
|
||||
override Node getPreUpdateNode() { result.asInstruction() = this.getInstruction() }
|
||||
|
||||
override string toString() { result = PostUpdateNode.super.toString() }
|
||||
}
|
||||
|
||||
private class ArgumentPostUpdateNode extends PartialDefinitionNode, StoreNodeOperand {
|
||||
override ArgumentNode getPreUpdateNode() { result.asOperand() = operand }
|
||||
|
||||
override Expr getDefinedExpr() {
|
||||
result =
|
||||
store
|
||||
.getDestinationAddress()
|
||||
.(FieldAddressInstruction)
|
||||
.getObjectAddress()
|
||||
.getUnconvertedResultExpression()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Not every store instruction generates a chi instruction that we can attach a PostUpdateNode to.
|
||||
* For instance, an update to a field of a struct containing only one field. Even if the store does
|
||||
* have a chi instruction, a subsequent use of the result of the store may be linked directly to the
|
||||
* result of the store as an inexact definition if the store totally overlaps the use. For these
|
||||
* cases we attach the PostUpdateNode to the store instruction. There's no obvious pre update node
|
||||
* for this case (as the entire memory is updated), so `getPreUpdateNode` is implemented as
|
||||
* `none()`.
|
||||
*/
|
||||
private class ExplicitSingleFieldStoreQualifierNode extends PartialDefinitionNode {
|
||||
override StoreInstruction instr;
|
||||
|
||||
ExplicitSingleFieldStoreQualifierNode() {
|
||||
(
|
||||
instr.getAUse().isDefinitionInexact()
|
||||
or
|
||||
not exists(ChiInstruction chi | chi.getPartial() = instr)
|
||||
) and
|
||||
// Without this condition any store would create a `PostUpdateNode`.
|
||||
instr.getDestinationAddress() instanceof FieldAddressInstruction
|
||||
result = this.getOperand().getDef().getUnconvertedResultExpression()
|
||||
}
|
||||
|
||||
override Node getPreUpdateNode() { none() }
|
||||
|
||||
override Expr getDefinedExpr() {
|
||||
result =
|
||||
instr
|
||||
.getDestinationAddress()
|
||||
.(FieldAddressInstruction)
|
||||
.getObjectAddress()
|
||||
.getUnconvertedResultExpression()
|
||||
}
|
||||
}
|
||||
|
||||
private FieldAddressInstruction getFieldInstruction(Instruction instr) {
|
||||
result = instr or
|
||||
result = instr.(CopyValueInstruction).getUnary()
|
||||
}
|
||||
|
||||
/**
|
||||
* The target of a `fieldStoreStepAfterArraySuppression` store step, which is used to convert
|
||||
* an `ArrayContent` to a `FieldContent` when the `WriteSideEffect` instruction stores
|
||||
* into a field. See the QLDoc for `suppressArrayRead` for an example of where such a conversion
|
||||
* is inserted.
|
||||
*/
|
||||
private class WriteSideEffectFieldStoreQualifierNode extends PartialDefinitionNode {
|
||||
override ChiInstruction instr;
|
||||
WriteSideEffectInstruction write;
|
||||
FieldAddressInstruction field;
|
||||
|
||||
WriteSideEffectFieldStoreQualifierNode() {
|
||||
not instr.isResultConflated() and
|
||||
instr.getPartial() = write and
|
||||
field = getFieldInstruction(write.getDestinationAddress())
|
||||
}
|
||||
|
||||
override Node getPreUpdateNode() { result.asOperand() = instr.getTotalOperand() }
|
||||
|
||||
override Expr getDefinedExpr() {
|
||||
result = field.getObjectAddress().getUnconvertedResultExpression()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The `PostUpdateNode` that is the target of a `arrayStoreStepChi` store step. The overriden
|
||||
* `ChiInstruction` corresponds to the instruction represented by `node2` in `arrayStoreStepChi`.
|
||||
*/
|
||||
private class ArrayStoreNode extends PartialDefinitionNode {
|
||||
override ChiInstruction instr;
|
||||
PointerAddInstruction add;
|
||||
|
||||
ArrayStoreNode() {
|
||||
not instr.isResultConflated() and
|
||||
exists(StoreInstruction store |
|
||||
instr.getPartial() = store and
|
||||
add = store.getDestinationAddress()
|
||||
)
|
||||
}
|
||||
|
||||
override Node getPreUpdateNode() { result.asOperand() = instr.getTotalOperand() }
|
||||
|
||||
override Expr getDefinedExpr() { result = add.getLeft().getUnconvertedResultExpression() }
|
||||
}
|
||||
|
||||
/**
|
||||
* The `PostUpdateNode` that is the target of a `arrayStoreStepChi` store step. The overriden
|
||||
* `ChiInstruction` corresponds to the instruction represented by `node2` in `arrayStoreStepChi`.
|
||||
*/
|
||||
private class PointerStoreNode extends PostUpdateNode {
|
||||
override ChiInstruction instr;
|
||||
|
||||
PointerStoreNode() {
|
||||
not instr.isResultConflated() and
|
||||
exists(StoreInstruction store |
|
||||
instr.getPartial() = store and
|
||||
store.getDestinationAddress().(CopyValueInstruction).getUnary() instanceof LoadInstruction
|
||||
)
|
||||
}
|
||||
|
||||
override Node getPreUpdateNode() { result.asOperand() = instr.getTotalOperand() }
|
||||
override string toString() { result = PartialDefinitionNode.super.toString() }
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -548,6 +733,11 @@ class VariableNode extends Node, TVariableNode {
|
|||
*/
|
||||
InstructionNode instructionNode(Instruction instr) { result.getInstruction() = instr }
|
||||
|
||||
/**
|
||||
* Gets the node corresponding to `operand`.
|
||||
*/
|
||||
OperandNode operandNode(Operand operand) { result.getOperand() = operand }
|
||||
|
||||
/**
|
||||
* DEPRECATED: use `definitionByReferenceNodeFromArgument` instead.
|
||||
*
|
||||
|
@ -614,61 +804,167 @@ predicate simpleLocalFlowStep(Node nodeFrom, Node nodeTo) {
|
|||
or
|
||||
// Instruction -> Operand flow
|
||||
simpleOperandLocalFlowStep(nodeFrom.asInstruction(), nodeTo.asOperand())
|
||||
or
|
||||
// Flow into, through, and out of store nodes
|
||||
StoreNodeFlow::flowInto(nodeFrom, nodeTo)
|
||||
or
|
||||
StoreNodeFlow::flowThrough(nodeFrom, nodeTo)
|
||||
or
|
||||
StoreNodeFlow::flowOutOf(nodeFrom, nodeTo)
|
||||
or
|
||||
// Flow into, through, and out of read nodes
|
||||
ReadNodeFlow::flowInto(nodeFrom, nodeTo)
|
||||
or
|
||||
ReadNodeFlow::flowThrough(nodeFrom, nodeTo)
|
||||
or
|
||||
ReadNodeFlow::flowOutOf(nodeFrom, nodeTo)
|
||||
or
|
||||
// Adjacent-def-use and adjacent-use-use flow
|
||||
adjacentDefUseFlow(nodeFrom, nodeTo)
|
||||
}
|
||||
|
||||
pragma[noinline]
|
||||
private predicate getFieldSizeOfClass(Class c, Type type, int size) {
|
||||
exists(Field f |
|
||||
f.getDeclaringType() = c and
|
||||
f.getUnderlyingType() = type and
|
||||
type.getSize() = size
|
||||
private predicate adjacentDefUseFlow(Node nodeFrom, Node nodeTo) {
|
||||
// Flow that isn't already covered by field flow out of store/read nodes.
|
||||
not nodeFrom.asInstruction() = any(StoreNode pun).getStoreInstruction() and
|
||||
not nodeFrom.asInstruction() = any(ReadNode pun).getALoadInstruction() and
|
||||
(
|
||||
//Def-use flow
|
||||
Ssa::ssaFlow(nodeFrom, nodeTo)
|
||||
or
|
||||
exists(Instruction loadAddress | loadAddress = Ssa::getSourceAddressFromNode(nodeFrom) |
|
||||
// Use-use flow through reads
|
||||
exists(Node address |
|
||||
Ssa::addressFlowTC(address.asInstruction(), loadAddress) and
|
||||
Ssa::ssaFlow(address, nodeTo)
|
||||
)
|
||||
or
|
||||
// Use-use flow through stores.
|
||||
exists(Node store |
|
||||
Ssa::explicitWrite(_, store.asInstruction(), loadAddress) and
|
||||
Ssa::ssaFlow(store, nodeTo)
|
||||
)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
private predicate isSingleFieldClass(Type type, Operand op) {
|
||||
exists(int size, Class c |
|
||||
c = op.getType().getUnderlyingType() and
|
||||
c.getSize() = size and
|
||||
getFieldSizeOfClass(c, type, size)
|
||||
)
|
||||
private module ReadNodeFlow {
|
||||
/** Holds if the read node `nodeTo` should receive flow from `nodeFrom`. */
|
||||
predicate flowInto(Node nodeFrom, ReadNode nodeTo) {
|
||||
nodeTo.isInitial() and
|
||||
(
|
||||
// If we entered through an address operand.
|
||||
nodeFrom.asOperand().getDef() = nodeTo.getInstruction()
|
||||
or
|
||||
// If we entered flow through a memory-producing instruction.
|
||||
// This can happen if we have flow to an `InitializeParameterIndirection` through
|
||||
// a `ReadSideEffectInstruction`.
|
||||
exists(Instruction load, Instruction def |
|
||||
def = nodeFrom.asInstruction() and
|
||||
def = Ssa::getSourceValueOperand(load).getAnyDef() and
|
||||
not def = any(StoreNode store).getStoreInstruction() and
|
||||
pragma[only_bind_into](nodeTo).getALoadInstruction() = load
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
/** Holds if the read node `nodeTo` should receive flow from the read node `nodeFrom`. */
|
||||
predicate flowThrough(ReadNode nodeFrom, ReadNode nodeTo) {
|
||||
not readStep(nodeFrom, _, _) and
|
||||
nodeFrom.getOuter() = nodeTo
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if flow should leave the read node `nFrom` and enter the node `nodeTo`.
|
||||
* This happens either because there is use-use flow from one of the variables used in
|
||||
* the read operation, or because we have traversed all the field dereferences in the
|
||||
* read operation.
|
||||
*/
|
||||
predicate flowOutOf(ReadNode nFrom, Node nodeTo) {
|
||||
// Use-use flow to another use of the same variable instruction
|
||||
Ssa::ssaFlow(nFrom, nodeTo)
|
||||
or
|
||||
not exists(nFrom.getInner()) and
|
||||
exists(Node store |
|
||||
Ssa::explicitWrite(_, store.asInstruction(), nFrom.getInstruction()) and
|
||||
Ssa::ssaFlow(store, nodeTo)
|
||||
)
|
||||
or
|
||||
// Flow out of read nodes and into memory instructions if we cannot move any further through
|
||||
// read nodes.
|
||||
nFrom.isTerminal() and
|
||||
(
|
||||
exists(Instruction load |
|
||||
load = nodeTo.asInstruction() and
|
||||
Ssa::getSourceAddress(load) = nFrom.getInstruction()
|
||||
)
|
||||
or
|
||||
exists(CallInstruction call, int i |
|
||||
call.getArgument(i) = nodeTo.asInstruction() and
|
||||
call.getArgument(i) = nFrom.getInstruction()
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private module StoreNodeFlow {
|
||||
/** Holds if the store node `nodeTo` should receive flow from `nodeFrom`. */
|
||||
predicate flowInto(Node nodeFrom, StoreNode nodeTo) {
|
||||
nodeTo.flowInto(Ssa::getDestinationAddress(nodeFrom.asInstruction()))
|
||||
}
|
||||
|
||||
/** Holds if the store node `nodeTo` should receive flow from `nodeFom`. */
|
||||
predicate flowThrough(StoreNode nFrom, StoreNode nodeTo) {
|
||||
// Flow through a post update node that doesn't need a store step.
|
||||
not storeStep(nFrom, _, _) and
|
||||
nodeTo.getOuter() = nFrom
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if flow should leave the store node `nodeFrom` and enter the node `nodeTo`.
|
||||
* This happens because we have traversed an entire chain of field dereferences
|
||||
* after a store operation.
|
||||
*/
|
||||
predicate flowOutOf(StoreNodeInstr nFrom, Node nodeTo) {
|
||||
nFrom.isTerminal() and
|
||||
Ssa::ssaFlow(nFrom, nodeTo)
|
||||
}
|
||||
}
|
||||
|
||||
private predicate simpleOperandLocalFlowStep(Instruction iFrom, Operand opTo) {
|
||||
// Propagate flow from an instruction to its exact uses.
|
||||
// We do this for all instruction/operand pairs, except when the operand is the
|
||||
// side effect operand of a ReturnIndirectionInstruction, or the load operand of a LoadInstruction.
|
||||
// This is because we get these flows through the shared SSA library already, and including this
|
||||
// flow here will create multiple dataflow paths which creates a blowup in stage 3 of dataflow.
|
||||
(
|
||||
not any(ReturnIndirectionInstruction ret).getSideEffectOperand() = opTo and
|
||||
not any(LoadInstruction load).getSourceValueOperand() = opTo and
|
||||
not any(ReturnValueInstruction ret).getReturnValueOperand() = opTo
|
||||
) and
|
||||
opTo.getDef() = iFrom
|
||||
or
|
||||
opTo = any(ReadSideEffectInstruction read).getSideEffectOperand() and
|
||||
not iFrom.isResultConflated() and
|
||||
iFrom = opTo.getAnyDef()
|
||||
or
|
||||
// Loading a single `int` from an `int *` parameter is not an exact load since
|
||||
// the parameter may point to an entire array rather than a single `int`. The
|
||||
// following rule ensures that any flow going into the
|
||||
// `InitializeIndirectionInstruction`, even if it's for a different array
|
||||
// element, will propagate to a load of the first element.
|
||||
//
|
||||
// Since we're linking `InitializeIndirectionInstruction` and
|
||||
// `LoadInstruction` together directly, this rule will break if there's any
|
||||
// reassignment of the parameter indirection, including a conditional one that
|
||||
// leads to a phi node.
|
||||
exists(InitializeIndirectionInstruction init |
|
||||
iFrom = init and
|
||||
opTo.(LoadOperand).getAnyDef() = init and
|
||||
// Check that the types match. Otherwise we can get flow from an object to
|
||||
// its fields, which leads to field conflation when there's flow from other
|
||||
// fields to the object elsewhere.
|
||||
init.getParameter().getType().getUnspecifiedType().(DerivedType).getBaseType() =
|
||||
opTo.getType().getUnspecifiedType()
|
||||
)
|
||||
or
|
||||
// Flow from stores to structs with a single field to a load of that field.
|
||||
exists(LoadInstruction load |
|
||||
load.getSourceValueOperand() = opTo and
|
||||
opTo.getAnyDef() = iFrom and
|
||||
isSingleFieldClass(pragma[only_bind_out](pragma[only_bind_out](iFrom).getResultType()), opTo)
|
||||
}
|
||||
|
||||
pragma[noinline]
|
||||
private predicate getAddressType(LoadInstruction load, Type t) {
|
||||
exists(Instruction address |
|
||||
address = load.getSourceAddress() and
|
||||
t = address.getResultType()
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Like the AST dataflow library, we want to conflate the address and value of a reference. This class
|
||||
* represents the `LoadInstruction` that is generated from a reference dereference.
|
||||
*/
|
||||
private class ReferenceDereferenceInstruction extends LoadInstruction {
|
||||
ReferenceDereferenceInstruction() {
|
||||
exists(ReferenceType ref |
|
||||
getAddressType(this, ref) and
|
||||
this.getResultType() = ref.getBaseType()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private predicate simpleInstructionLocalFlowStep(Operand opFrom, Instruction iTo) {
|
||||
iTo.(CopyInstruction).getSourceValueOperand() = opFrom
|
||||
or
|
||||
|
@ -681,40 +977,8 @@ private predicate simpleInstructionLocalFlowStep(Operand opFrom, Instruction iTo
|
|||
or
|
||||
iTo.(InheritanceConversionInstruction).getUnaryOperand() = opFrom
|
||||
or
|
||||
// A chi instruction represents a point where a new value (the _partial_
|
||||
// operand) may overwrite an old value (the _total_ operand), but the alias
|
||||
// analysis couldn't determine that it surely will overwrite every bit of it or
|
||||
// that it surely will overwrite no bit of it.
|
||||
//
|
||||
// By allowing flow through the total operand, we ensure that flow is not lost
|
||||
// due to shortcomings of the alias analysis. We may get false flow in cases
|
||||
// where the data is indeed overwritten.
|
||||
//
|
||||
// Flow through the partial operand belongs in the taint-tracking libraries
|
||||
// for now.
|
||||
iTo.getAnOperand().(ChiTotalOperand) = opFrom
|
||||
or
|
||||
// Add flow from write side-effects to non-conflated chi instructions through their
|
||||
// partial operands. From there, a `readStep` will find subsequent reads of that field.
|
||||
// Consider the following example:
|
||||
// ```
|
||||
// void setX(Point* p, int new_x) {
|
||||
// p->x = new_x;
|
||||
// }
|
||||
// ...
|
||||
// setX(&p, taint());
|
||||
// ```
|
||||
// Here, a `WriteSideEffectInstruction` will provide a new definition for `p->x` after the call to
|
||||
// `setX`, which will be melded into `p` through a chi instruction.
|
||||
exists(ChiInstruction chi | chi = iTo |
|
||||
opFrom.getAnyDef() instanceof WriteSideEffectInstruction and
|
||||
chi.getPartialOperand() = opFrom and
|
||||
not chi.isResultConflated() and
|
||||
// In a call such as `set_value(&x->val);` we don't want the memory representing `x` to receive
|
||||
// dataflow by a simple step. Instead, this is handled by field flow. If we add a simple step here
|
||||
// we can get field-to-object flow.
|
||||
not chi.isPartialUpdate()
|
||||
)
|
||||
// Conflate references and values like in AST dataflow.
|
||||
iTo.(ReferenceDereferenceInstruction).getSourceAddressOperand() = opFrom
|
||||
or
|
||||
// Flow through modeled functions
|
||||
modelFlow(opFrom, iTo)
|
||||
|
@ -788,25 +1052,14 @@ predicate localInstructionFlow(Instruction e1, Instruction e2) {
|
|||
*/
|
||||
predicate localExprFlow(Expr e1, Expr e2) { localFlow(exprNode(e1), exprNode(e2)) }
|
||||
|
||||
/**
|
||||
* Gets a field corresponding to the bit range `[startBit..endBit)` of class `c`, if any.
|
||||
*/
|
||||
private Field getAField(Class c, int startBit, int endBit) {
|
||||
result.getDeclaringType() = c and
|
||||
startBit = 8 * result.getByteOffset() and
|
||||
endBit = 8 * result.getType().getSize() + startBit
|
||||
or
|
||||
exists(Field f, Class cInner |
|
||||
f = c.getAField() and
|
||||
cInner = f.getUnderlyingType() and
|
||||
result = getAField(cInner, startBit - 8 * f.getByteOffset(), endBit - 8 * f.getByteOffset())
|
||||
)
|
||||
}
|
||||
|
||||
private newtype TContent =
|
||||
TFieldContent(Class c, int startBit, int endBit) { exists(getAField(c, startBit, endBit)) } or
|
||||
TCollectionContent() or
|
||||
TArrayContent()
|
||||
TFieldContent(Field f) {
|
||||
// As reads and writes to union fields can create flow even though the reads and writes
|
||||
// target different fields, we don't want a read (write) to create a read (write) step.
|
||||
not f.getDeclaringType() instanceof Union
|
||||
} or
|
||||
TCollectionContent() or // Not used in C/C++
|
||||
TArrayContent() // Not used in C/C++.
|
||||
|
||||
/**
|
||||
* A description of the way data may be stored inside an object. Examples
|
||||
|
@ -824,18 +1077,13 @@ class Content extends TContent {
|
|||
|
||||
/** A reference through an instance field. */
|
||||
class FieldContent extends Content, TFieldContent {
|
||||
Class c;
|
||||
int startBit;
|
||||
int endBit;
|
||||
Field f;
|
||||
|
||||
FieldContent() { this = TFieldContent(c, startBit, endBit) }
|
||||
FieldContent() { this = TFieldContent(f) }
|
||||
|
||||
// Ensure that there's just 1 result for `toString`.
|
||||
override string toString() { result = min(Field f | f = this.getAField() | f.toString()) }
|
||||
override string toString() { result = f.toString() }
|
||||
|
||||
predicate hasOffset(Class cl, int start, int end) { cl = c and start = startBit and end = endBit }
|
||||
|
||||
Field getAField() { result = getAField(c, startBit, endBit) }
|
||||
Field getField() { result = f }
|
||||
}
|
||||
|
||||
/** A reference through an array. */
|
||||
|
|
|
@ -0,0 +1,636 @@
|
|||
/**
|
||||
* Provides a language-independent implementation of static single assignment
|
||||
* (SSA) form.
|
||||
*/
|
||||
|
||||
private import SsaImplSpecific
|
||||
|
||||
private BasicBlock getABasicBlockPredecessor(BasicBlock bb) { getABasicBlockSuccessor(result) = bb }
|
||||
|
||||
/**
|
||||
* Liveness analysis (based on source variables) to restrict the size of the
|
||||
* SSA representation.
|
||||
*/
|
||||
private module Liveness {
|
||||
/**
|
||||
* A classification of variable references into reads (of a given kind) and
|
||||
* (certain or uncertain) writes.
|
||||
*/
|
||||
private newtype TRefKind =
|
||||
Read(boolean certain) { certain in [false, true] } or
|
||||
Write(boolean certain) { certain in [false, true] }
|
||||
|
||||
private class RefKind extends TRefKind {
|
||||
string toString() {
|
||||
exists(boolean certain | this = Read(certain) and result = "read (" + certain + ")")
|
||||
or
|
||||
exists(boolean certain | this = Write(certain) and result = "write (" + certain + ")")
|
||||
}
|
||||
|
||||
int getOrder() {
|
||||
this = Read(_) and
|
||||
result = 0
|
||||
or
|
||||
this = Write(_) and
|
||||
result = 1
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if the `i`th node of basic block `bb` is a reference to `v` of kind `k`.
|
||||
*/
|
||||
private predicate ref(BasicBlock bb, int i, SourceVariable v, RefKind k) {
|
||||
exists(boolean certain | variableRead(bb, i, v, certain) | k = Read(certain))
|
||||
or
|
||||
exists(boolean certain | variableWrite(bb, i, v, certain) | k = Write(certain))
|
||||
}
|
||||
|
||||
private newtype OrderedRefIndex =
|
||||
MkOrderedRefIndex(int i, int tag) {
|
||||
exists(RefKind rk | ref(_, i, _, rk) | tag = rk.getOrder())
|
||||
}
|
||||
|
||||
private OrderedRefIndex refOrd(BasicBlock bb, int i, SourceVariable v, RefKind k, int ord) {
|
||||
ref(bb, i, v, k) and
|
||||
result = MkOrderedRefIndex(i, ord) and
|
||||
ord = k.getOrder()
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the (1-based) rank of the reference to `v` at the `i`th node of
|
||||
* basic block `bb`, which has the given reference kind `k`.
|
||||
*
|
||||
* Reads are considered before writes when they happen at the same index.
|
||||
*/
|
||||
private int refRank(BasicBlock bb, int i, SourceVariable v, RefKind k) {
|
||||
refOrd(bb, i, v, k, _) =
|
||||
rank[result](int j, int ord, OrderedRefIndex res |
|
||||
res = refOrd(bb, j, v, _, ord)
|
||||
|
|
||||
res order by j, ord
|
||||
)
|
||||
}
|
||||
|
||||
private int maxRefRank(BasicBlock bb, SourceVariable v) {
|
||||
result = refRank(bb, _, v, _) and
|
||||
not result + 1 = refRank(bb, _, v, _)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the (1-based) rank of the first reference to `v` inside basic block `bb`
|
||||
* that is either a read or a certain write.
|
||||
*/
|
||||
private int firstReadOrCertainWrite(BasicBlock bb, SourceVariable v) {
|
||||
result =
|
||||
min(int r, RefKind k |
|
||||
r = refRank(bb, _, v, k) and
|
||||
k != Write(false)
|
||||
|
|
||||
r
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if source variable `v` is live at the beginning of basic block `bb`.
|
||||
*/
|
||||
predicate liveAtEntry(BasicBlock bb, SourceVariable v) {
|
||||
// The first read or certain write to `v` inside `bb` is a read
|
||||
refRank(bb, _, v, Read(_)) = firstReadOrCertainWrite(bb, v)
|
||||
or
|
||||
// There is no certain write to `v` inside `bb`, but `v` is live at entry
|
||||
// to a successor basic block of `bb`
|
||||
not exists(firstReadOrCertainWrite(bb, v)) and
|
||||
liveAtExit(bb, v)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if source variable `v` is live at the end of basic block `bb`.
|
||||
*/
|
||||
predicate liveAtExit(BasicBlock bb, SourceVariable v) {
|
||||
liveAtEntry(getABasicBlockSuccessor(bb), v)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if variable `v` is live in basic block `bb` at index `i`.
|
||||
* The rank of `i` is `rnk` as defined by `refRank()`.
|
||||
*/
|
||||
private predicate liveAtRank(BasicBlock bb, int i, SourceVariable v, int rnk) {
|
||||
exists(RefKind kind | rnk = refRank(bb, i, v, kind) |
|
||||
rnk = maxRefRank(bb, v) and
|
||||
liveAtExit(bb, v)
|
||||
or
|
||||
ref(bb, i, v, kind) and
|
||||
kind = Read(_)
|
||||
or
|
||||
exists(RefKind nextKind |
|
||||
liveAtRank(bb, _, v, rnk + 1) and
|
||||
rnk + 1 = refRank(bb, _, v, nextKind) and
|
||||
nextKind != Write(true)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if variable `v` is live after the (certain or uncertain) write at
|
||||
* index `i` inside basic block `bb`.
|
||||
*/
|
||||
predicate liveAfterWrite(BasicBlock bb, int i, SourceVariable v) {
|
||||
exists(int rnk | rnk = refRank(bb, i, v, Write(_)) | liveAtRank(bb, i, v, rnk))
|
||||
}
|
||||
}
|
||||
|
||||
private import Liveness
|
||||
|
||||
/**
|
||||
* Holds if `df` is in the dominance frontier of `bb`.
|
||||
*
|
||||
* This is equivalent to:
|
||||
*
|
||||
* ```ql
|
||||
* bb = getImmediateBasicBlockDominator*(getABasicBlockPredecessor(df)) and
|
||||
* not bb = getImmediateBasicBlockDominator+(df)
|
||||
* ```
|
||||
*/
|
||||
private predicate inDominanceFrontier(BasicBlock bb, BasicBlock df) {
|
||||
bb = getABasicBlockPredecessor(df) and not bb = getImmediateBasicBlockDominator(df)
|
||||
or
|
||||
exists(BasicBlock prev | inDominanceFrontier(prev, df) |
|
||||
bb = getImmediateBasicBlockDominator(prev) and
|
||||
not bb = getImmediateBasicBlockDominator(df)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `bb` is in the dominance frontier of a block containing a
|
||||
* definition of `v`.
|
||||
*/
|
||||
pragma[noinline]
|
||||
private predicate inDefDominanceFrontier(BasicBlock bb, SourceVariable v) {
|
||||
exists(BasicBlock defbb, Definition def |
|
||||
def.definesAt(v, defbb, _) and
|
||||
inDominanceFrontier(defbb, bb)
|
||||
)
|
||||
}
|
||||
|
||||
cached
|
||||
newtype TDefinition =
|
||||
TWriteDef(SourceVariable v, BasicBlock bb, int i) {
|
||||
variableWrite(bb, i, v, _) and
|
||||
liveAfterWrite(bb, i, v)
|
||||
} or
|
||||
TPhiNode(SourceVariable v, BasicBlock bb) {
|
||||
inDefDominanceFrontier(bb, v) and
|
||||
liveAtEntry(bb, v)
|
||||
}
|
||||
|
||||
private module SsaDefReaches {
|
||||
newtype TSsaRefKind =
|
||||
SsaRead() or
|
||||
SsaDef()
|
||||
|
||||
/**
|
||||
* A classification of SSA variable references into reads and definitions.
|
||||
*/
|
||||
class SsaRefKind extends TSsaRefKind {
|
||||
string toString() {
|
||||
this = SsaRead() and
|
||||
result = "SsaRead"
|
||||
or
|
||||
this = SsaDef() and
|
||||
result = "SsaDef"
|
||||
}
|
||||
|
||||
int getOrder() {
|
||||
this = SsaRead() and
|
||||
result = 0
|
||||
or
|
||||
this = SsaDef() and
|
||||
result = 1
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if the `i`th node of basic block `bb` is a reference to `v`,
|
||||
* either a read (when `k` is `SsaRead()`) or an SSA definition (when `k`
|
||||
* is `SsaDef()`).
|
||||
*
|
||||
* Unlike `Liveness::ref`, this includes `phi` nodes.
|
||||
*/
|
||||
predicate ssaRef(BasicBlock bb, int i, SourceVariable v, SsaRefKind k) {
|
||||
variableRead(bb, i, v, _) and
|
||||
k = SsaRead()
|
||||
or
|
||||
exists(Definition def | def.definesAt(v, bb, i)) and
|
||||
k = SsaDef()
|
||||
}
|
||||
|
||||
private newtype OrderedSsaRefIndex =
|
||||
MkOrderedSsaRefIndex(int i, SsaRefKind k) { ssaRef(_, i, _, k) }
|
||||
|
||||
private OrderedSsaRefIndex ssaRefOrd(BasicBlock bb, int i, SourceVariable v, SsaRefKind k, int ord) {
|
||||
ssaRef(bb, i, v, k) and
|
||||
result = MkOrderedSsaRefIndex(i, k) and
|
||||
ord = k.getOrder()
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the (1-based) rank of the reference to `v` at the `i`th node of basic
|
||||
* block `bb`, which has the given reference kind `k`.
|
||||
*
|
||||
* For example, if `bb` is a basic block with a phi node for `v` (considered
|
||||
* to be at index -1), reads `v` at node 2, and defines it at node 5, we have:
|
||||
*
|
||||
* ```ql
|
||||
* ssaRefRank(bb, -1, v, SsaDef()) = 1 // phi node
|
||||
* ssaRefRank(bb, 2, v, Read()) = 2 // read at node 2
|
||||
* ssaRefRank(bb, 5, v, SsaDef()) = 3 // definition at node 5
|
||||
* ```
|
||||
*
|
||||
* Reads are considered before writes when they happen at the same index.
|
||||
*/
|
||||
int ssaRefRank(BasicBlock bb, int i, SourceVariable v, SsaRefKind k) {
|
||||
ssaRefOrd(bb, i, v, k, _) =
|
||||
rank[result](int j, int ord, OrderedSsaRefIndex res |
|
||||
res = ssaRefOrd(bb, j, v, _, ord)
|
||||
|
|
||||
res order by j, ord
|
||||
)
|
||||
}
|
||||
|
||||
int maxSsaRefRank(BasicBlock bb, SourceVariable v) {
|
||||
result = ssaRefRank(bb, _, v, _) and
|
||||
not result + 1 = ssaRefRank(bb, _, v, _)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if the SSA definition `def` reaches rank index `rnk` in its own
|
||||
* basic block `bb`.
|
||||
*/
|
||||
predicate ssaDefReachesRank(BasicBlock bb, Definition def, int rnk, SourceVariable v) {
|
||||
exists(int i |
|
||||
rnk = ssaRefRank(bb, i, v, SsaDef()) and
|
||||
def.definesAt(v, bb, i)
|
||||
)
|
||||
or
|
||||
ssaDefReachesRank(bb, def, rnk - 1, v) and
|
||||
rnk = ssaRefRank(bb, _, v, SsaRead())
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if the SSA definition of `v` at `def` reaches index `i` in the same
|
||||
* basic block `bb`, without crossing another SSA definition of `v`.
|
||||
*/
|
||||
predicate ssaDefReachesReadWithinBlock(SourceVariable v, Definition def, BasicBlock bb, int i) {
|
||||
exists(int rnk |
|
||||
ssaDefReachesRank(bb, def, rnk, v) and
|
||||
rnk = ssaRefRank(bb, i, v, SsaRead())
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if the SSA definition of `v` at `def` reaches uncertain SSA definition
|
||||
* `redef` in the same basic block, without crossing another SSA definition of `v`.
|
||||
*/
|
||||
predicate ssaDefReachesUncertainDefWithinBlock(
|
||||
SourceVariable v, Definition def, UncertainWriteDefinition redef
|
||||
) {
|
||||
exists(BasicBlock bb, int rnk, int i |
|
||||
ssaDefReachesRank(bb, def, rnk, v) and
|
||||
rnk = ssaRefRank(bb, i, v, SsaDef()) - 1 and
|
||||
redef.definesAt(v, bb, i)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Same as `ssaRefRank()`, but restricted to a particular SSA definition `def`.
|
||||
*/
|
||||
int ssaDefRank(Definition def, SourceVariable v, BasicBlock bb, int i, SsaRefKind k) {
|
||||
v = def.getSourceVariable() and
|
||||
result = ssaRefRank(bb, i, v, k) and
|
||||
(
|
||||
ssaDefReachesRead(_, def, bb, i)
|
||||
or
|
||||
def.definesAt(_, bb, i)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if the reference to `def` at index `i` in basic block `bb` is the
|
||||
* last reference to `v` inside `bb`.
|
||||
*/
|
||||
pragma[noinline]
|
||||
predicate lastSsaRef(Definition def, SourceVariable v, BasicBlock bb, int i) {
|
||||
ssaDefRank(def, v, bb, i, _) = maxSsaRefRank(bb, v)
|
||||
}
|
||||
|
||||
predicate defOccursInBlock(Definition def, BasicBlock bb, SourceVariable v) {
|
||||
exists(ssaDefRank(def, v, bb, _, _))
|
||||
}
|
||||
|
||||
pragma[noinline]
|
||||
private predicate ssaDefReachesThroughBlock(Definition def, BasicBlock bb) {
|
||||
ssaDefReachesEndOfBlock(bb, def, _) and
|
||||
not defOccursInBlock(_, bb, def.getSourceVariable())
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `def` is accessed in basic block `bb1` (either a read or a write),
|
||||
* `bb2` is a transitive successor of `bb1`, `def` is live at the end of `bb1`,
|
||||
* and the underlying variable for `def` is neither read nor written in any block
|
||||
* on the path between `bb1` and `bb2`.
|
||||
*/
|
||||
predicate varBlockReaches(Definition def, BasicBlock bb1, BasicBlock bb2) {
|
||||
defOccursInBlock(def, bb1, _) and
|
||||
bb2 = getABasicBlockSuccessor(bb1)
|
||||
or
|
||||
exists(BasicBlock mid |
|
||||
varBlockReaches(def, bb1, mid) and
|
||||
ssaDefReachesThroughBlock(def, mid) and
|
||||
bb2 = getABasicBlockSuccessor(mid)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `def` is accessed in basic block `bb1` (either a read or a write),
|
||||
* `def` is read at index `i2` in basic block `bb2`, `bb2` is in a transitive
|
||||
* successor block of `bb1`, and `def` is neither read nor written in any block
|
||||
* on a path between `bb1` and `bb2`.
|
||||
*/
|
||||
predicate defAdjacentRead(Definition def, BasicBlock bb1, BasicBlock bb2, int i2) {
|
||||
varBlockReaches(def, bb1, bb2) and
|
||||
ssaRefRank(bb2, i2, def.getSourceVariable(), SsaRead()) = 1
|
||||
}
|
||||
}
|
||||
|
||||
private import SsaDefReaches
|
||||
|
||||
pragma[nomagic]
|
||||
predicate liveThrough(BasicBlock bb, SourceVariable v) {
|
||||
liveAtExit(bb, v) and
|
||||
not ssaRef(bb, _, v, SsaDef())
|
||||
}
|
||||
|
||||
/**
|
||||
* NB: If this predicate is exposed, it should be cached.
|
||||
*
|
||||
* Holds if the SSA definition of `v` at `def` reaches the end of basic
|
||||
* block `bb`, at which point it is still live, without crossing another
|
||||
* SSA definition of `v`.
|
||||
*/
|
||||
pragma[nomagic]
|
||||
predicate ssaDefReachesEndOfBlock(BasicBlock bb, Definition def, SourceVariable v) {
|
||||
exists(int last | last = maxSsaRefRank(bb, v) |
|
||||
ssaDefReachesRank(bb, def, last, v) and
|
||||
liveAtExit(bb, v)
|
||||
)
|
||||
or
|
||||
// The construction of SSA form ensures that each read of a variable is
|
||||
// dominated by its definition. An SSA definition therefore reaches a
|
||||
// control flow node if it is the _closest_ SSA definition that dominates
|
||||
// the node. If two definitions dominate a node then one must dominate the
|
||||
// other, so therefore the definition of _closest_ is given by the dominator
|
||||
// tree. Thus, reaching definitions can be calculated in terms of dominance.
|
||||
ssaDefReachesEndOfBlock(getImmediateBasicBlockDominator(bb), def, pragma[only_bind_into](v)) and
|
||||
liveThrough(bb, pragma[only_bind_into](v))
|
||||
}
|
||||
|
||||
/**
|
||||
* NB: If this predicate is exposed, it should be cached.
|
||||
*
|
||||
* Holds if `inp` is an input to the phi node `phi` along the edge originating in `bb`.
|
||||
*/
|
||||
pragma[nomagic]
|
||||
predicate phiHasInputFromBlock(PhiNode phi, Definition inp, BasicBlock bb) {
|
||||
exists(SourceVariable v, BasicBlock bbDef |
|
||||
phi.definesAt(v, bbDef, _) and
|
||||
getABasicBlockPredecessor(bbDef) = bb and
|
||||
ssaDefReachesEndOfBlock(bb, inp, v)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* NB: If this predicate is exposed, it should be cached.
|
||||
*
|
||||
* Holds if the SSA definition of `v` at `def` reaches a read at index `i` in
|
||||
* basic block `bb`, without crossing another SSA definition of `v`. The read
|
||||
* is of kind `rk`.
|
||||
*/
|
||||
pragma[nomagic]
|
||||
predicate ssaDefReachesRead(SourceVariable v, Definition def, BasicBlock bb, int i) {
|
||||
ssaDefReachesReadWithinBlock(v, def, bb, i)
|
||||
or
|
||||
variableRead(bb, i, v, _) and
|
||||
ssaDefReachesEndOfBlock(getABasicBlockPredecessor(bb), def, v) and
|
||||
not ssaDefReachesReadWithinBlock(v, _, bb, i)
|
||||
}
|
||||
|
||||
/**
|
||||
* NB: If this predicate is exposed, it should be cached.
|
||||
*
|
||||
* Holds if `def` is accessed at index `i1` in basic block `bb1` (either a read
|
||||
* or a write), `def` is read at index `i2` in basic block `bb2`, and there is a
|
||||
* path between them without any read of `def`.
|
||||
*/
|
||||
pragma[nomagic]
|
||||
predicate adjacentDefRead(Definition def, BasicBlock bb1, int i1, BasicBlock bb2, int i2) {
|
||||
exists(int rnk |
|
||||
rnk = ssaDefRank(def, _, bb1, i1, _) and
|
||||
rnk + 1 = ssaDefRank(def, _, bb1, i2, SsaRead()) and
|
||||
variableRead(bb1, i2, _, _) and
|
||||
bb2 = bb1
|
||||
)
|
||||
or
|
||||
lastSsaRef(def, _, bb1, i1) and
|
||||
defAdjacentRead(def, bb1, bb2, i2)
|
||||
}
|
||||
|
||||
pragma[noinline]
|
||||
private predicate adjacentDefRead(
|
||||
Definition def, BasicBlock bb1, int i1, BasicBlock bb2, int i2, SourceVariable v
|
||||
) {
|
||||
adjacentDefRead(def, bb1, i1, bb2, i2) and
|
||||
v = def.getSourceVariable()
|
||||
}
|
||||
|
||||
private predicate adjacentDefReachesRead(
|
||||
Definition def, BasicBlock bb1, int i1, BasicBlock bb2, int i2
|
||||
) {
|
||||
exists(SourceVariable v | adjacentDefRead(def, bb1, i1, bb2, i2, v) |
|
||||
ssaRef(bb1, i1, v, SsaDef())
|
||||
or
|
||||
variableRead(bb1, i1, v, true)
|
||||
)
|
||||
or
|
||||
exists(BasicBlock bb3, int i3 |
|
||||
adjacentDefReachesRead(def, bb1, i1, bb3, i3) and
|
||||
variableRead(bb3, i3, _, false) and
|
||||
adjacentDefRead(def, bb3, i3, bb2, i2)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* NB: If this predicate is exposed, it should be cached.
|
||||
*
|
||||
* Same as `adjacentDefRead`, but ignores uncertain reads.
|
||||
*/
|
||||
pragma[nomagic]
|
||||
predicate adjacentDefNoUncertainReads(Definition def, BasicBlock bb1, int i1, BasicBlock bb2, int i2) {
|
||||
adjacentDefReachesRead(def, bb1, i1, bb2, i2) and
|
||||
variableRead(bb2, i2, _, true)
|
||||
}
|
||||
|
||||
/**
|
||||
* NB: If this predicate is exposed, it should be cached.
|
||||
*
|
||||
* Holds if the node at index `i` in `bb` is a last reference to SSA definition
|
||||
* `def`. The reference is last because it can reach another write `next`,
|
||||
* without passing through another read or write.
|
||||
*/
|
||||
pragma[nomagic]
|
||||
predicate lastRefRedef(Definition def, BasicBlock bb, int i, Definition next) {
|
||||
exists(SourceVariable v |
|
||||
// Next reference to `v` inside `bb` is a write
|
||||
exists(int rnk, int j |
|
||||
rnk = ssaDefRank(def, v, bb, i, _) and
|
||||
next.definesAt(v, bb, j) and
|
||||
rnk + 1 = ssaRefRank(bb, j, v, SsaDef())
|
||||
)
|
||||
or
|
||||
// Can reach a write using one or more steps
|
||||
lastSsaRef(def, v, bb, i) and
|
||||
exists(BasicBlock bb2 |
|
||||
varBlockReaches(def, bb, bb2) and
|
||||
1 = ssaDefRank(next, v, bb2, _, SsaDef())
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* NB: If this predicate is exposed, it should be cached.
|
||||
*
|
||||
* Holds if `inp` is an immediately preceding definition of uncertain definition
|
||||
* `def`. Since `def` is uncertain, the value from the preceding definition might
|
||||
* still be valid.
|
||||
*/
|
||||
pragma[nomagic]
|
||||
predicate uncertainWriteDefinitionInput(UncertainWriteDefinition def, Definition inp) {
|
||||
lastRefRedef(inp, _, _, def)
|
||||
}
|
||||
|
||||
private predicate adjacentDefReachesUncertainRead(
|
||||
Definition def, BasicBlock bb1, int i1, BasicBlock bb2, int i2
|
||||
) {
|
||||
adjacentDefReachesRead(def, bb1, i1, bb2, i2) and
|
||||
variableRead(bb2, i2, _, false)
|
||||
}
|
||||
|
||||
/**
|
||||
* NB: If this predicate is exposed, it should be cached.
|
||||
*
|
||||
* Same as `lastRefRedef`, but ignores uncertain reads.
|
||||
*/
|
||||
pragma[nomagic]
|
||||
predicate lastRefRedefNoUncertainReads(Definition def, BasicBlock bb, int i, Definition next) {
|
||||
lastRefRedef(def, bb, i, next) and
|
||||
not variableRead(bb, i, def.getSourceVariable(), false)
|
||||
or
|
||||
exists(BasicBlock bb0, int i0 |
|
||||
lastRefRedef(def, bb0, i0, next) and
|
||||
adjacentDefReachesUncertainRead(def, bb, i, bb0, i0)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* NB: If this predicate is exposed, it should be cached.
|
||||
*
|
||||
* Holds if the node at index `i` in `bb` is a last reference to SSA
|
||||
* definition `def`.
|
||||
*
|
||||
* That is, the node can reach the end of the enclosing callable, or another
|
||||
* SSA definition for the underlying source variable, without passing through
|
||||
* another read.
|
||||
*/
|
||||
pragma[nomagic]
|
||||
predicate lastRef(Definition def, BasicBlock bb, int i) {
|
||||
lastRefRedef(def, bb, i, _)
|
||||
or
|
||||
lastSsaRef(def, _, bb, i) and
|
||||
(
|
||||
// Can reach exit directly
|
||||
bb instanceof ExitBasicBlock
|
||||
or
|
||||
// Can reach a block using one or more steps, where `def` is no longer live
|
||||
exists(BasicBlock bb2 | varBlockReaches(def, bb, bb2) |
|
||||
not defOccursInBlock(def, bb2, _) and
|
||||
not ssaDefReachesEndOfBlock(bb2, def, _)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* NB: If this predicate is exposed, it should be cached.
|
||||
*
|
||||
* Same as `lastRefRedef`, but ignores uncertain reads.
|
||||
*/
|
||||
pragma[nomagic]
|
||||
predicate lastRefNoUncertainReads(Definition def, BasicBlock bb, int i) {
|
||||
lastRef(def, bb, i) and
|
||||
not variableRead(bb, i, def.getSourceVariable(), false)
|
||||
or
|
||||
exists(BasicBlock bb0, int i0 |
|
||||
lastRef(def, bb0, i0) and
|
||||
adjacentDefReachesUncertainRead(def, bb, i, bb0, i0)
|
||||
)
|
||||
}
|
||||
|
||||
/** A static single assignment (SSA) definition. */
|
||||
class Definition extends TDefinition {
|
||||
/** Gets the source variable underlying this SSA definition. */
|
||||
SourceVariable getSourceVariable() { this.definesAt(result, _, _) }
|
||||
|
||||
/**
|
||||
* Holds if this SSA definition defines `v` at index `i` in basic block `bb`.
|
||||
* Phi nodes are considered to be at index `-1`, while normal variable writes
|
||||
* are at the index of the control flow node they wrap.
|
||||
*/
|
||||
final predicate definesAt(SourceVariable v, BasicBlock bb, int i) {
|
||||
this = TWriteDef(v, bb, i)
|
||||
or
|
||||
this = TPhiNode(v, bb) and i = -1
|
||||
}
|
||||
|
||||
/** Gets the basic block to which this SSA definition belongs. */
|
||||
final BasicBlock getBasicBlock() { this.definesAt(_, result, _) }
|
||||
|
||||
/** Gets a textual representation of this SSA definition. */
|
||||
string toString() { none() }
|
||||
}
|
||||
|
||||
/** An SSA definition that corresponds to a write. */
|
||||
class WriteDefinition extends Definition, TWriteDef {
|
||||
private SourceVariable v;
|
||||
private BasicBlock bb;
|
||||
private int i;
|
||||
|
||||
WriteDefinition() { this = TWriteDef(v, bb, i) }
|
||||
|
||||
override string toString() { result = "WriteDef" }
|
||||
}
|
||||
|
||||
/** A phi node. */
|
||||
class PhiNode extends Definition, TPhiNode {
|
||||
override string toString() { result = "Phi" }
|
||||
}
|
||||
|
||||
/**
|
||||
* An SSA definition that represents an uncertain update of the underlying
|
||||
* source variable.
|
||||
*/
|
||||
class UncertainWriteDefinition extends WriteDefinition {
|
||||
UncertainWriteDefinition() {
|
||||
exists(SourceVariable v, BasicBlock bb, int i |
|
||||
this.definesAt(v, bb, i) and
|
||||
variableWrite(bb, i, v, false)
|
||||
)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
private import semmle.code.cpp.ir.IR
|
||||
private import SsaInternals as Ssa
|
||||
|
||||
class BasicBlock = IRBlock;
|
||||
|
||||
class SourceVariable = Ssa::SourceVariable;
|
||||
|
||||
BasicBlock getImmediateBasicBlockDominator(BasicBlock bb) { result.immediatelyDominates(bb) }
|
||||
|
||||
BasicBlock getABasicBlockSuccessor(BasicBlock bb) { result = bb.getASuccessor() }
|
||||
|
||||
class ExitBasicBlock extends IRBlock {
|
||||
ExitBasicBlock() { this.getLastInstruction() instanceof ExitFunctionInstruction }
|
||||
}
|
||||
|
||||
predicate variableWrite = Ssa::variableWrite/4;
|
||||
|
||||
predicate variableRead = Ssa::variableRead/4;
|
|
@ -0,0 +1,600 @@
|
|||
import SsaImplCommon
|
||||
private import cpp as Cpp
|
||||
private import semmle.code.cpp.ir.IR
|
||||
private import DataFlowUtil
|
||||
private import DataFlowImplCommon as DataFlowImplCommon
|
||||
private import semmle.code.cpp.models.interfaces.Allocation as Alloc
|
||||
private import semmle.code.cpp.models.interfaces.DataFlow as DataFlow
|
||||
|
||||
private module SourceVariables {
|
||||
private newtype TSourceVariable =
|
||||
TSourceIRVariable(IRVariable var) or
|
||||
TSourceIRVariableIndirection(InitializeIndirectionInstruction init)
|
||||
|
||||
abstract class SourceVariable extends TSourceVariable {
|
||||
IRVariable var;
|
||||
|
||||
abstract string toString();
|
||||
}
|
||||
|
||||
class SourceIRVariable extends SourceVariable, TSourceIRVariable {
|
||||
SourceIRVariable() { this = TSourceIRVariable(var) }
|
||||
|
||||
IRVariable getIRVariable() { result = var }
|
||||
|
||||
override string toString() { result = this.getIRVariable().toString() }
|
||||
}
|
||||
|
||||
class SourceIRVariableIndirection extends SourceVariable, TSourceIRVariableIndirection {
|
||||
InitializeIndirectionInstruction init;
|
||||
|
||||
SourceIRVariableIndirection() {
|
||||
this = TSourceIRVariableIndirection(init) and var = init.getIRVariable()
|
||||
}
|
||||
|
||||
IRVariable getUnderlyingIRVariable() { result = var }
|
||||
|
||||
override string toString() { result = "*" + this.getUnderlyingIRVariable().toString() }
|
||||
}
|
||||
}
|
||||
|
||||
import SourceVariables
|
||||
|
||||
cached
|
||||
private newtype TDefOrUse =
|
||||
TExplicitDef(Instruction store) { explicitWrite(_, store, _) } or
|
||||
TInitializeParam(Instruction instr) {
|
||||
instr instanceof InitializeParameterInstruction
|
||||
or
|
||||
instr instanceof InitializeIndirectionInstruction
|
||||
} or
|
||||
TExplicitUse(Operand op) { isExplicitUse(op) } or
|
||||
TReturnParamIndirection(Operand op) { returnParameterIndirection(op, _) }
|
||||
|
||||
pragma[nomagic]
|
||||
private int getRank(DefOrUse defOrUse, IRBlock block) {
|
||||
defOrUse =
|
||||
rank[result](int i, DefOrUse cand |
|
||||
block.getInstruction(i) = toInstruction(cand)
|
||||
|
|
||||
cand order by i
|
||||
)
|
||||
}
|
||||
|
||||
private class DefOrUse extends TDefOrUse {
|
||||
/** Gets the instruction associated with this definition, if any. */
|
||||
Instruction asDef() { none() }
|
||||
|
||||
/** Gets the operand associated with this use, if any. */
|
||||
Operand asUse() { none() }
|
||||
|
||||
/** Gets a textual representation of this element. */
|
||||
abstract string toString();
|
||||
|
||||
/** Gets the block of this definition or use. */
|
||||
abstract IRBlock getBlock();
|
||||
|
||||
/** Holds if this definition or use has rank `rank` in block `block`. */
|
||||
cached
|
||||
final predicate hasRankInBlock(IRBlock block, int rnk) { rnk = getRank(this, block) }
|
||||
|
||||
/** Gets the location of this element. */
|
||||
abstract Cpp::Location getLocation();
|
||||
}
|
||||
|
||||
private Instruction toInstruction(DefOrUse defOrUse) {
|
||||
result = defOrUse.asDef()
|
||||
or
|
||||
result = defOrUse.asUse().getUse()
|
||||
}
|
||||
|
||||
abstract class Def extends DefOrUse {
|
||||
Instruction store;
|
||||
|
||||
/** Gets the instruction of this definition. */
|
||||
Instruction getInstruction() { result = store }
|
||||
|
||||
/** Gets the variable that is defined by this definition. */
|
||||
abstract SourceVariable getSourceVariable();
|
||||
|
||||
/** Holds if this definition is guaranteed to happen. */
|
||||
abstract predicate isCertain();
|
||||
|
||||
override Instruction asDef() { result = this.getInstruction() }
|
||||
|
||||
override string toString() { result = "Def" }
|
||||
|
||||
override IRBlock getBlock() { result = this.getInstruction().getBlock() }
|
||||
|
||||
override Cpp::Location getLocation() { result = store.getLocation() }
|
||||
}
|
||||
|
||||
private class ExplicitDef extends Def, TExplicitDef {
|
||||
ExplicitDef() { this = TExplicitDef(store) }
|
||||
|
||||
override SourceVariable getSourceVariable() {
|
||||
exists(VariableInstruction var |
|
||||
explicitWrite(_, this.getInstruction(), var) and
|
||||
result.(SourceIRVariable).getIRVariable() = var.getIRVariable()
|
||||
)
|
||||
}
|
||||
|
||||
override predicate isCertain() { explicitWrite(true, this.getInstruction(), _) }
|
||||
}
|
||||
|
||||
private class ParameterDef extends Def, TInitializeParam {
|
||||
ParameterDef() { this = TInitializeParam(store) }
|
||||
|
||||
override SourceVariable getSourceVariable() {
|
||||
result.(SourceIRVariable).getIRVariable() =
|
||||
store.(InitializeParameterInstruction).getIRVariable()
|
||||
or
|
||||
result.(SourceIRVariableIndirection).getUnderlyingIRVariable() =
|
||||
store.(InitializeIndirectionInstruction).getIRVariable()
|
||||
}
|
||||
|
||||
override predicate isCertain() { any() }
|
||||
}
|
||||
|
||||
abstract class Use extends DefOrUse {
|
||||
Operand use;
|
||||
|
||||
override Operand asUse() { result = use }
|
||||
|
||||
/** Gets the underlying operand of this use. */
|
||||
Operand getOperand() { result = use }
|
||||
|
||||
override string toString() { result = "Use" }
|
||||
|
||||
/** Gets the variable that is used by this use. */
|
||||
abstract SourceVariable getSourceVariable();
|
||||
|
||||
override IRBlock getBlock() { result = use.getUse().getBlock() }
|
||||
|
||||
override Cpp::Location getLocation() { result = use.getLocation() }
|
||||
}
|
||||
|
||||
private class ExplicitUse extends Use, TExplicitUse {
|
||||
ExplicitUse() { this = TExplicitUse(use) }
|
||||
|
||||
override SourceVariable getSourceVariable() {
|
||||
exists(VariableInstruction var |
|
||||
use.getDef() = var and
|
||||
if use.getUse() instanceof ReadSideEffectInstruction
|
||||
then result.(SourceIRVariableIndirection).getUnderlyingIRVariable() = var.getIRVariable()
|
||||
else result.(SourceIRVariable).getIRVariable() = var.getIRVariable()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private class ReturnParameterIndirection extends Use, TReturnParamIndirection {
|
||||
ReturnParameterIndirection() { this = TReturnParamIndirection(use) }
|
||||
|
||||
override SourceVariable getSourceVariable() {
|
||||
exists(ReturnIndirectionInstruction ret |
|
||||
returnParameterIndirection(use, ret) and
|
||||
result.(SourceIRVariableIndirection).getUnderlyingIRVariable() = ret.getIRVariable()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private predicate isExplicitUse(Operand op) {
|
||||
op.getDef() instanceof VariableAddressInstruction and
|
||||
not exists(LoadInstruction load |
|
||||
load.getSourceAddressOperand() = op and
|
||||
load.getAUse().getUse() instanceof InitializeIndirectionInstruction
|
||||
)
|
||||
}
|
||||
|
||||
private predicate returnParameterIndirection(Operand op, ReturnIndirectionInstruction ret) {
|
||||
ret.getSourceAddressOperand() = op
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `iFrom` computes an address that is used by `iTo`.
|
||||
*/
|
||||
predicate addressFlow(Instruction iFrom, Instruction iTo) {
|
||||
iTo.(CopyValueInstruction).getSourceValue() = iFrom
|
||||
or
|
||||
iTo.(ConvertInstruction).getUnary() = iFrom
|
||||
or
|
||||
iTo.(CheckedConvertOrNullInstruction).getUnary() = iFrom
|
||||
or
|
||||
iTo.(InheritanceConversionInstruction).getUnary() = iFrom
|
||||
or
|
||||
iTo.(PointerArithmeticInstruction).getLeft() = iFrom
|
||||
or
|
||||
iTo.(FieldAddressInstruction).getObjectAddress() = iFrom
|
||||
or
|
||||
// We traverse `LoadInstruction`s since we want to conclude that the
|
||||
// destination of the store operation `*x = source()` is derived from `x`.
|
||||
iTo.(LoadInstruction).getSourceAddress() = iFrom
|
||||
or
|
||||
// We want to include `ReadSideEffectInstruction`s for the same reason that we include
|
||||
// `LoadInstruction`s, but only when a `WriteSideEffectInstruction` for the same index exists as well
|
||||
// (as otherwise we know that the callee won't override the data). However, given an index `i`, the
|
||||
// destination of the `WriteSideEffectInstruction` for `i` is identical to the source address of the
|
||||
// `ReadSideEffectInstruction` for `i`. So we don't have to talk about the `ReadSideEffectInstruction`
|
||||
// at all.
|
||||
exists(WriteSideEffectInstruction write |
|
||||
write.getPrimaryInstruction() = iTo and
|
||||
write.getDestinationAddress() = iFrom
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* The reflexive, transitive closure of `addressFlow` that ends as the address of a
|
||||
* store or read operation.
|
||||
*/
|
||||
cached
|
||||
predicate addressFlowTC(Instruction iFrom, Instruction iTo) {
|
||||
iTo = [getDestinationAddress(_), getSourceAddress(_)] and
|
||||
addressFlow*(iFrom, iTo)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the destination address of `instr` if it is a `StoreInstruction` or
|
||||
* a `WriteSideEffectInstruction`.
|
||||
*/
|
||||
Instruction getDestinationAddress(Instruction instr) {
|
||||
result =
|
||||
[
|
||||
instr.(StoreInstruction).getDestinationAddress(),
|
||||
instr.(WriteSideEffectInstruction).getDestinationAddress()
|
||||
]
|
||||
}
|
||||
|
||||
class ReferenceToInstruction extends CopyValueInstruction {
|
||||
ReferenceToInstruction() {
|
||||
this.getResultType() instanceof Cpp::ReferenceType and
|
||||
not this.getUnary().getResultType() instanceof Cpp::ReferenceType
|
||||
}
|
||||
|
||||
Instruction getSourceAddress() { result = getSourceAddressOperand().getDef() }
|
||||
|
||||
Operand getSourceAddressOperand() { result = this.getUnaryOperand() }
|
||||
}
|
||||
|
||||
/** Gets the source address of `instr` if it is an instruction that behaves like a `LoadInstruction`. */
|
||||
Instruction getSourceAddress(Instruction instr) { result = getSourceAddressOperand(instr).getDef() }
|
||||
|
||||
/**
|
||||
* Gets the operand that represents the source address of `instr` if it is an
|
||||
* instruction that behaves like a `LoadInstruction`.
|
||||
*/
|
||||
Operand getSourceAddressOperand(Instruction instr) {
|
||||
result =
|
||||
[
|
||||
instr.(LoadInstruction).getSourceAddressOperand(),
|
||||
instr.(ReadSideEffectInstruction).getArgumentOperand(),
|
||||
// `ReferenceToInstruction` is really more of an address-of operation,
|
||||
// but by including it in this list we break out of `flowOutOfAddressStep` at an
|
||||
// instruction that, at the source level, looks like a use of a variable.
|
||||
instr.(ReferenceToInstruction).getSourceAddressOperand()
|
||||
]
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the source address of `node` if it's an instruction or operand that
|
||||
* behaves like a `LoadInstruction`.
|
||||
*/
|
||||
Instruction getSourceAddressFromNode(Node node) {
|
||||
result = getSourceAddress(node.asInstruction())
|
||||
or
|
||||
result = getSourceAddress(node.asOperand().(SideEffectOperand).getUse())
|
||||
}
|
||||
|
||||
/** Gets the source value of `instr` if it's an instruction that behaves like a `LoadInstruction`. */
|
||||
Instruction getSourceValue(Instruction instr) { result = getSourceValueOperand(instr).getDef() }
|
||||
|
||||
/**
|
||||
* Gets the operand that represents the source value of `instr` if it's an instruction
|
||||
* that behaves like a `LoadInstruction`.
|
||||
*/
|
||||
Operand getSourceValueOperand(Instruction instr) {
|
||||
result = instr.(LoadInstruction).getSourceValueOperand()
|
||||
or
|
||||
result = instr.(ReadSideEffectInstruction).getSideEffectOperand()
|
||||
or
|
||||
// See the comment on the `ReferenceToInstruction` disjunct in `getSourceAddressOperand` for why
|
||||
// this case is included.
|
||||
result = instr.(ReferenceToInstruction).getSourceValueOperand()
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `instr` is a `StoreInstruction` or a `WriteSideEffectInstruction` that writes to an address.
|
||||
* The addresses is computed using `address`, and `certain` is `true` if the write is guaranteed to overwrite
|
||||
* the entire variable.
|
||||
*/
|
||||
cached
|
||||
predicate explicitWrite(boolean certain, Instruction instr, Instruction address) {
|
||||
exists(StoreInstruction store |
|
||||
store = instr and addressFlowTC(address, store.getDestinationAddress())
|
||||
|
|
||||
// Set `certain = false` if the address is derived from any instructions that prevents us from
|
||||
// concluding that the entire variable is overridden.
|
||||
if
|
||||
addressFlowTC(any(Instruction i |
|
||||
i instanceof FieldAddressInstruction or
|
||||
i instanceof PointerArithmeticInstruction or
|
||||
i instanceof LoadInstruction or
|
||||
i instanceof InheritanceConversionInstruction
|
||||
), store.getDestinationAddress())
|
||||
then certain = false
|
||||
else certain = true
|
||||
)
|
||||
or
|
||||
addressFlowTC(address, instr.(WriteSideEffectInstruction).getDestinationAddress()) and
|
||||
certain = false
|
||||
}
|
||||
|
||||
cached
|
||||
private module Cached {
|
||||
private predicate defUseFlow(Node nodeFrom, Node nodeTo) {
|
||||
exists(IRBlock bb1, int i1, IRBlock bb2, int i2, DefOrUse defOrUse, Use use |
|
||||
defOrUse.hasRankInBlock(bb1, i1) and
|
||||
use.hasRankInBlock(bb2, i2) and
|
||||
adjacentDefRead(_, bb1, i1, bb2, i2) and
|
||||
nodeFrom.asInstruction() = toInstruction(defOrUse) and
|
||||
flowOutOfAddressStep(use.getOperand(), nodeTo)
|
||||
)
|
||||
}
|
||||
|
||||
private predicate fromStoreNode(StoreNodeInstr nodeFrom, Node nodeTo) {
|
||||
// Def-use flow from a `StoreNode`.
|
||||
exists(IRBlock bb1, int i1, IRBlock bb2, int i2, Def def, Use use |
|
||||
nodeFrom.isTerminal() and
|
||||
def.getInstruction() = nodeFrom.getStoreInstruction() and
|
||||
def.hasRankInBlock(bb1, i1) and
|
||||
adjacentDefRead(_, bb1, i1, bb2, i2) and
|
||||
use.hasRankInBlock(bb2, i2) and
|
||||
flowOutOfAddressStep(use.getOperand(), nodeTo)
|
||||
)
|
||||
or
|
||||
// This final case is a bit annoying. The write side effect on an expression like `a = new A;` writes
|
||||
// to a fresh address returned by `operator new`, and there's no easy way to use the shared SSA
|
||||
// library to hook that up to the assignment to `a`. So instead we flow to the _first_ use of the
|
||||
// value computed by `operator new` that occurs after `nodeFrom` (to avoid a loop in the
|
||||
// dataflow graph).
|
||||
exists(WriteSideEffectInstruction write, IRBlock bb, int i1, int i2, Operand op |
|
||||
nodeFrom.getInstruction().(CallInstruction).getStaticCallTarget() instanceof
|
||||
Alloc::OperatorNewAllocationFunction and
|
||||
write = nodeFrom.getStoreInstruction() and
|
||||
bb.getInstruction(i1) = write and
|
||||
bb.getInstruction(i2) = op.getUse() and
|
||||
// Flow to an instruction that occurs later in the block.
|
||||
conversionFlow*(nodeFrom.getInstruction(), op.getDef()) and
|
||||
nodeTo.asOperand() = op and
|
||||
i2 > i1 and
|
||||
// There is no previous instruction that also occurs after `nodeFrom`.
|
||||
not exists(Instruction instr, int i |
|
||||
bb.getInstruction(i) = instr and
|
||||
conversionFlow(instr, op.getDef()) and
|
||||
i1 < i and
|
||||
i < i2
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
private predicate fromReadNode(ReadNode nodeFrom, Node nodeTo) {
|
||||
exists(IRBlock bb1, int i1, IRBlock bb2, int i2, Use use1, Use use2 |
|
||||
use1.hasRankInBlock(bb1, i1) and
|
||||
use2.hasRankInBlock(bb2, i2) and
|
||||
use1.getOperand().getDef() = nodeFrom.getInstruction() and
|
||||
adjacentDefRead(_, bb1, i1, bb2, i2) and
|
||||
flowOutOfAddressStep(use2.getOperand(), nodeTo)
|
||||
)
|
||||
}
|
||||
|
||||
private predicate fromPhiNode(SsaPhiNode nodeFrom, Node nodeTo) {
|
||||
exists(PhiNode phi, Use use, IRBlock block, int rnk |
|
||||
phi = nodeFrom.getPhiNode() and
|
||||
adjacentDefRead(phi, _, _, block, rnk) and
|
||||
use.hasRankInBlock(block, rnk) and
|
||||
flowOutOfAddressStep(use.getOperand(), nodeTo)
|
||||
)
|
||||
}
|
||||
|
||||
private predicate toPhiNode(Node nodeFrom, SsaPhiNode nodeTo) {
|
||||
// Flow to phi nodes
|
||||
exists(Def def, IRBlock block, int rnk |
|
||||
def.hasRankInBlock(block, rnk) and
|
||||
nodeTo.hasInputAtRankInBlock(block, rnk)
|
||||
|
|
||||
exists(StoreNodeInstr storeNode |
|
||||
storeNode = nodeFrom and
|
||||
storeNode.isTerminal() and
|
||||
def.getInstruction() = storeNode.getStoreInstruction()
|
||||
)
|
||||
or
|
||||
def.getInstruction() = nodeFrom.asInstruction()
|
||||
)
|
||||
or
|
||||
// Phi -> phi flow
|
||||
nodeTo.hasInputAtRankInBlock(_, _, nodeFrom.(SsaPhiNode).getPhiNode())
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `nodeFrom` is a read or write, and `nTo` is the next subsequent read of the variable
|
||||
* written (or read) by `storeOrRead`.
|
||||
*/
|
||||
cached
|
||||
predicate ssaFlow(Node nodeFrom, Node nodeTo) {
|
||||
// Def-use/use-use flow from an `InstructionNode`.
|
||||
defUseFlow(nodeFrom, nodeTo)
|
||||
or
|
||||
// Def-use flow from a `StoreNode`.
|
||||
fromStoreNode(nodeFrom, nodeTo)
|
||||
or
|
||||
// Use-use flow from a `ReadNode`.
|
||||
fromReadNode(nodeFrom, nodeTo)
|
||||
or
|
||||
fromPhiNode(nodeFrom, nodeTo)
|
||||
or
|
||||
toPhiNode(nodeFrom, nodeTo)
|
||||
or
|
||||
// When we want to transfer flow out of a `StoreNode` we perform two steps:
|
||||
// 1. Find the next use of the address being stored to
|
||||
// 2. Find the `LoadInstruction` that loads the address
|
||||
// When the address being stored into doesn't have a `LoadInstruction` associated with it because it's
|
||||
// passed into a `CallInstruction` we transfer flow to the `ReadSideEffect`, which will then flow into
|
||||
// the callee. We then pickup the flow from the `InitializeIndirectionInstruction` and use the shared
|
||||
// SSA library to determine where the next use of the address that received the flow is.
|
||||
exists(Node init, Node mid |
|
||||
nodeFrom.asInstruction().(InitializeIndirectionInstruction).getIRVariable() =
|
||||
init.asInstruction().(InitializeParameterInstruction).getIRVariable() and
|
||||
// No need for the flow if the next use is the instruction that returns the flow out of the callee.
|
||||
not mid.asInstruction() instanceof ReturnIndirectionInstruction and
|
||||
// Find the next use of the address
|
||||
ssaFlow(init, mid) and
|
||||
// And flow to the next load of that address
|
||||
flowOutOfAddressStep([mid.asInstruction().getAUse(), mid.asOperand()], nodeTo)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `iTo` is a conversion-like instruction that copies
|
||||
* the value computed by `iFrom`.
|
||||
*
|
||||
* This predicate is used by `fromStoreNode` to find the next use of a pointer that
|
||||
* points to freshly allocated memory.
|
||||
*/
|
||||
private predicate conversionFlow(Instruction iFrom, Instruction iTo) {
|
||||
iTo.(CopyValueInstruction).getSourceValue() = iFrom
|
||||
or
|
||||
iTo.(ConvertInstruction).getUnary() = iFrom
|
||||
or
|
||||
iTo.(CheckedConvertOrNullInstruction).getUnary() = iFrom
|
||||
or
|
||||
iTo.(InheritanceConversionInstruction).getUnary() = iFrom
|
||||
}
|
||||
|
||||
pragma[noinline]
|
||||
private predicate callTargetHasInputOutput(
|
||||
CallInstruction call, DataFlow::FunctionInput input, DataFlow::FunctionOutput output
|
||||
) {
|
||||
exists(DataFlow::DataFlowFunction func |
|
||||
call.getStaticCallTarget() = func and
|
||||
func.hasDataFlow(input, output)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* The role of `flowOutOfAddressStep` is to select the node for which we want dataflow to end up in
|
||||
* after the shared SSA library's `adjacentDefRead` predicate has determined that `operand` is the
|
||||
* next use of some variable.
|
||||
*
|
||||
* More precisely, this predicate holds if `operand` is an operand that represents an address, and:
|
||||
* - `nodeTo` is the next load of that address, or
|
||||
* - `nodeTo` is a `ReadNode` that uses the definition of `operand` to start a sequence of reads, or
|
||||
* - `nodeTo` is the outer-most `StoreNode` that uses the address represented by `operand`. We obtain
|
||||
* use-use flow in this case since `StoreNodeFlow::flowOutOf` will then provide flow to the next of
|
||||
* of `operand`.
|
||||
*
|
||||
* There is one final (slightly annoying) case: When `operand` is a an argument to a modeled function
|
||||
* without any `ReadSideEffect` (such as `std::move`). Here, the address flows from the argument to
|
||||
* the return value, which might then be read later.
|
||||
*/
|
||||
private predicate flowOutOfAddressStep(Operand operand, Node nodeTo) {
|
||||
// Flow into a read node
|
||||
exists(ReadNode readNode | readNode = nodeTo |
|
||||
readNode.isInitial() and
|
||||
operand.getDef() = readNode.getInstruction()
|
||||
)
|
||||
or
|
||||
exists(StoreNodeInstr storeNode, Instruction def |
|
||||
storeNode = nodeTo and
|
||||
def = operand.getDef()
|
||||
|
|
||||
storeNode.isTerminal() and
|
||||
not addressFlow(def, _) and
|
||||
// Only transfer flow to a store node if it doesn't immediately overwrite the address
|
||||
// we've just written to.
|
||||
explicitWrite(false, storeNode.getStoreInstruction(), def)
|
||||
)
|
||||
or
|
||||
operand = getSourceAddressOperand(nodeTo.asInstruction())
|
||||
or
|
||||
exists(ReturnIndirectionInstruction ret |
|
||||
ret.getSourceAddressOperand() = operand and
|
||||
ret = nodeTo.asInstruction()
|
||||
)
|
||||
or
|
||||
exists(ReturnValueInstruction ret |
|
||||
ret.getReturnAddressOperand() = operand and
|
||||
nodeTo.asInstruction() = ret
|
||||
)
|
||||
or
|
||||
exists(CallInstruction call, int index, ReadSideEffectInstruction read |
|
||||
call.getArgumentOperand(index) = operand and
|
||||
read = getSideEffectFor(call, index) and
|
||||
nodeTo.asOperand() = read.getSideEffectOperand()
|
||||
)
|
||||
or
|
||||
exists(CopyInstruction copy |
|
||||
not exists(getSourceAddressOperand(copy)) and
|
||||
copy.getSourceValueOperand() = operand and
|
||||
flowOutOfAddressStep(copy.getAUse(), nodeTo)
|
||||
)
|
||||
or
|
||||
exists(ConvertInstruction convert |
|
||||
convert.getUnaryOperand() = operand and
|
||||
flowOutOfAddressStep(convert.getAUse(), nodeTo)
|
||||
)
|
||||
or
|
||||
exists(CheckedConvertOrNullInstruction convert |
|
||||
convert.getUnaryOperand() = operand and
|
||||
flowOutOfAddressStep(convert.getAUse(), nodeTo)
|
||||
)
|
||||
or
|
||||
exists(InheritanceConversionInstruction convert |
|
||||
convert.getUnaryOperand() = operand and
|
||||
flowOutOfAddressStep(convert.getAUse(), nodeTo)
|
||||
)
|
||||
or
|
||||
exists(PointerArithmeticInstruction arith |
|
||||
arith.getLeftOperand() = operand and
|
||||
flowOutOfAddressStep(arith.getAUse(), nodeTo)
|
||||
)
|
||||
or
|
||||
// Flow through a modeled function that has parameter -> return value flow.
|
||||
exists(
|
||||
CallInstruction call, int index, DataFlow::FunctionInput input,
|
||||
DataFlow::FunctionOutput output
|
||||
|
|
||||
callTargetHasInputOutput(call, input, output) and
|
||||
call.getArgumentOperand(index) = operand and
|
||||
not getSideEffectFor(call, index) instanceof ReadSideEffectInstruction and
|
||||
input.isParameter(index) and
|
||||
output.isReturnValue() and
|
||||
flowOutOfAddressStep(call.getAUse(), nodeTo)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
import Cached
|
||||
|
||||
/**
|
||||
* Holds if the `i`'th write in block `bb` writes to the variable `v`.
|
||||
* `certain` is `true` if the write is guaranteed to overwrite the entire variable.
|
||||
*/
|
||||
predicate variableWrite(IRBlock bb, int i, SourceVariable v, boolean certain) {
|
||||
DataFlowImplCommon::forceCachingInSameStage() and
|
||||
exists(Def def |
|
||||
def.hasRankInBlock(bb, i) and
|
||||
v = def.getSourceVariable() and
|
||||
(if def.isCertain() then certain = true else certain = false)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if the `i`'th read in block `bb` reads to the variable `v`.
|
||||
* `certain` is `true` if the read is guaranteed. For C++, this is always the case.
|
||||
*/
|
||||
predicate variableRead(IRBlock bb, int i, SourceVariable v, boolean certain) {
|
||||
exists(Use use |
|
||||
use.hasRankInBlock(bb, i) and
|
||||
v = use.getSourceVariable() and
|
||||
certain = true
|
||||
)
|
||||
}
|
|
@ -44,8 +44,6 @@ private predicate instructionToOperandTaintStep(Instruction fromInstr, Operand t
|
|||
fromInstr = readInstr.getArgumentDef() and
|
||||
toOperand = readInstr.getSideEffectOperand()
|
||||
)
|
||||
or
|
||||
toOperand.(LoadOperand).getAnyDef() = fromInstr
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -84,8 +82,6 @@ private predicate operandToInstructionTaintStep(Operand opFrom, Instruction inst
|
|||
instrTo.(FieldAddressInstruction).getField().getDeclaringType() instanceof Union
|
||||
)
|
||||
or
|
||||
instrTo.(LoadInstruction).getSourceAddressOperand() = opFrom
|
||||
or
|
||||
// Flow from an element to an array or union that contains it.
|
||||
instrTo.(ChiInstruction).getPartialOperand() = opFrom and
|
||||
not instrTo.isResultConflated() and
|
||||
|
|
|
@ -762,11 +762,21 @@ class ReturnValueInstruction extends ReturnInstruction {
|
|||
*/
|
||||
final LoadOperand getReturnValueOperand() { result = this.getAnOperand() }
|
||||
|
||||
/**
|
||||
* Gets the operand that provides the address of the value being returned by the function.
|
||||
*/
|
||||
final AddressOperand getReturnAddressOperand() { result = this.getAnOperand() }
|
||||
|
||||
/**
|
||||
* Gets the instruction whose result provides the value being returned by the function, if an
|
||||
* exact definition is available.
|
||||
*/
|
||||
final Instruction getReturnValue() { result = this.getReturnValueOperand().getDef() }
|
||||
|
||||
/**
|
||||
* Gets the instruction whose result provides the address of the value being returned by the function.
|
||||
*/
|
||||
final Instruction getReturnAddress() { result = this.getReturnAddressOperand().getDef() }
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -762,11 +762,21 @@ class ReturnValueInstruction extends ReturnInstruction {
|
|||
*/
|
||||
final LoadOperand getReturnValueOperand() { result = this.getAnOperand() }
|
||||
|
||||
/**
|
||||
* Gets the operand that provides the address of the value being returned by the function.
|
||||
*/
|
||||
final AddressOperand getReturnAddressOperand() { result = this.getAnOperand() }
|
||||
|
||||
/**
|
||||
* Gets the instruction whose result provides the value being returned by the function, if an
|
||||
* exact definition is available.
|
||||
*/
|
||||
final Instruction getReturnValue() { result = this.getReturnValueOperand().getDef() }
|
||||
|
||||
/**
|
||||
* Gets the instruction whose result provides the address of the value being returned by the function.
|
||||
*/
|
||||
final Instruction getReturnAddress() { result = this.getReturnAddressOperand().getDef() }
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -762,11 +762,21 @@ class ReturnValueInstruction extends ReturnInstruction {
|
|||
*/
|
||||
final LoadOperand getReturnValueOperand() { result = this.getAnOperand() }
|
||||
|
||||
/**
|
||||
* Gets the operand that provides the address of the value being returned by the function.
|
||||
*/
|
||||
final AddressOperand getReturnAddressOperand() { result = this.getAnOperand() }
|
||||
|
||||
/**
|
||||
* Gets the instruction whose result provides the value being returned by the function, if an
|
||||
* exact definition is available.
|
||||
*/
|
||||
final Instruction getReturnValue() { result = this.getReturnValueOperand().getDef() }
|
||||
|
||||
/**
|
||||
* Gets the instruction whose result provides the address of the value being returned by the function.
|
||||
*/
|
||||
final Instruction getReturnAddress() { result = this.getReturnAddressOperand().getDef() }
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -210,8 +210,8 @@ void test_pointers2()
|
|||
|
||||
sink(buffer); // $ MISSING: ast,ir
|
||||
sink(ptr1); // $ ast MISSING: ir
|
||||
sink(ptr2); // $ SPURIOUS: ast
|
||||
sink(*ptr2); // $ ast MISSING: ir
|
||||
sink(ptr2); // $ SPURIOUS: ast,ir
|
||||
sink(*ptr2); // $ ast,ir
|
||||
sink(ptr3); // $ MISSING: ast,ir
|
||||
sink(ptr4); // clean
|
||||
sink(*ptr4); // $ MISSING: ast,ir
|
||||
|
@ -254,8 +254,8 @@ int test_readv_and_writev(iovec* iovs) {
|
|||
sink(*iovs); // $ast,ir
|
||||
|
||||
char* p = (char*)iovs[1].iov_base;
|
||||
sink(p); // $ ir MISSING: ast
|
||||
sink(*p); // $ ir MISSING: ast
|
||||
sink(p); // $ MISSING: ast,ir
|
||||
sink(*p); // $ MISSING: ast,ir
|
||||
|
||||
writev(0, iovs, 16); // $ remote
|
||||
}
|
||||
|
|
|
@ -89,12 +89,12 @@ void test_stringstream()
|
|||
|
||||
sink(ss1);
|
||||
sink(ss2); // $ ir MISSING: ast
|
||||
sink(ss3); // $ MISSING: ast,ir
|
||||
sink(ss3); // $ ir MISSING: ast
|
||||
sink(ss4); // $ ir MISSING: ast
|
||||
sink(ss5); // $ ir MISSING: ast
|
||||
sink(ss1.str());
|
||||
sink(ss2.str()); // $ ir MISSING: ast
|
||||
sink(ss3.str()); // $ MISSING: ast,ir
|
||||
sink(ss3.str()); // $ ir MISSING: ast
|
||||
sink(ss4.str()); // $ ir MISSING: ast
|
||||
sink(ss5.str()); // $ ir MISSING: ast
|
||||
}
|
||||
|
|
|
@ -26,62 +26,592 @@ unreachableNodeCCtx
|
|||
localCallNodes
|
||||
postIsNotPre
|
||||
postHasUniquePre
|
||||
| test.cpp:373:5:373:20 | Store | PostUpdateNode should have one pre-update node but has 0. |
|
||||
uniquePostUpdate
|
||||
postIsInSameCallable
|
||||
reverseRead
|
||||
argHasPostUpdate
|
||||
postWithInFlow
|
||||
| BarrierGuard.cpp:49:3:49:17 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| BarrierGuard.cpp:60:3:60:18 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| clang.cpp:28:3:28:34 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| clang.cpp:34:22:34:27 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| clang.cpp:34:32:34:37 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| clang.cpp:39:32:39:37 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| clang.cpp:39:42:39:47 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| clang.cpp:43:35:43:40 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| clang.cpp:43:51:43:51 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| clang.cpp:49:25:49:30 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| clang.cpp:49:35:49:40 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| clang.cpp:50:3:50:26 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| example.c:17:19:17:22 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| example.c:17:21:17:21 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| example.c:24:2:24:30 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| example.c:24:13:24:30 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| example.c:26:2:26:25 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| file://:0:0:0:0 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| file://:0:0:0:0 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| file://:0:0:0:0 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| lambdas.cpp:13:12:13:12 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| lambdas.cpp:13:15:13:15 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| lambdas.cpp:28:10:31:2 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| lambdas.cpp:28:10:31:2 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| lambdas.cpp:43:3:43:14 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| ref.cpp:11:5:11:13 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| ref.cpp:20:5:20:13 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| ref.cpp:22:7:22:13 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| ref.cpp:24:7:24:13 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| ref.cpp:29:5:29:18 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| ref.cpp:31:7:31:13 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| ref.cpp:39:7:39:13 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| ref.cpp:44:5:44:18 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| ref.cpp:46:7:46:13 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| ref.cpp:48:7:48:13 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| ref.cpp:75:5:75:17 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| ref.cpp:83:5:83:17 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| ref.cpp:87:7:87:17 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| ref.cpp:89:7:89:17 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| ref.cpp:94:5:94:22 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| ref.cpp:96:7:96:17 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| ref.cpp:104:7:104:17 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| ref.cpp:109:5:109:22 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| ref.cpp:113:7:113:17 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| ref.cpp:115:7:115:17 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:91:3:91:18 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:115:3:115:17 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:120:3:120:10 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:125:3:125:11 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:359:5:359:20 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:373:5:373:20 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:373:5:373:20 | Store | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:465:3:465:15 | Chi | PostUpdateNode should not be the target of local flow. |
|
||||
| BarrierGuard.cpp:49:6:49:6 | x [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| BarrierGuard.cpp:60:3:60:4 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| BarrierGuard.cpp:60:7:60:7 | x [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| clang.cpp:8:20:8:29 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| clang.cpp:22:3:22:6 | & ... [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| clang.cpp:22:8:22:20 | & ... [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| clang.cpp:22:9:22:20 | sourceArray1 [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| clang.cpp:26:8:26:24 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| clang.cpp:26:8:26:24 | sourceStruct1_ptr [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| clang.cpp:26:27:26:34 | sourceStruct1_ptr [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| clang.cpp:28:3:28:19 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| clang.cpp:28:22:28:23 | m1 [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| clang.cpp:30:8:30:24 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| clang.cpp:30:8:30:24 | sourceStruct1_ptr [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| clang.cpp:30:27:30:34 | sourceStruct1_ptr [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| clang.cpp:34:19:34:41 | FieldAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| clang.cpp:34:19:34:41 | FieldAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| clang.cpp:39:16:39:21 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| clang.cpp:39:30:39:51 | FieldAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| clang.cpp:39:30:39:51 | FieldAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| clang.cpp:43:26:43:53 | FieldAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| clang.cpp:43:26:43:53 | FieldAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| clang.cpp:49:7:49:16 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| clang.cpp:49:22:49:44 | PointerAdd [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| clang.cpp:49:22:49:44 | PointerAdd [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| clang.cpp:50:3:50:12 | array to pointer conversion [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| clang.cpp:50:3:50:12 | stackArray [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| clang.cpp:50:3:50:15 | access to array [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:6:29:6:37 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:7:29:7:37 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:9:30:9:45 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:10:30:10:45 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:15:8:15:8 | Argument this [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:15:8:15:8 | ConvertToNonVirtualBase [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:15:8:15:8 | this [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:16:30:16:45 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:17:31:17:39 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:21:8:21:8 | Argument this [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:21:8:21:8 | ConvertToNonVirtualBase [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:21:8:21:8 | this [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:22:30:22:45 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:24:31:24:39 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:29:8:29:13 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:29:29:29:34 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:31:8:31:13 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:31:8:31:13 | topPtr [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:31:16:31:24 | topPtr [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:32:8:32:13 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:32:8:32:13 | topPtr [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:32:16:32:24 | topPtr [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:33:3:33:8 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:33:3:33:8 | topPtr [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:33:11:33:16 | topPtr [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:35:8:35:13 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:35:8:35:13 | topPtr [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:35:16:35:25 | topPtr [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:36:8:36:13 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:36:8:36:13 | topPtr [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:36:16:36:25 | topPtr [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:37:3:37:8 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:37:3:37:8 | topPtr [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:37:11:37:17 | topPtr [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:39:8:39:13 | (reference dereference) [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:39:8:39:13 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:39:8:39:13 | topRef [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:39:15:39:23 | topRef [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:40:8:40:13 | (reference dereference) [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:40:8:40:13 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:40:8:40:13 | topRef [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:40:15:40:23 | topRef [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:41:3:41:8 | (reference dereference) [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:41:3:41:8 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:41:3:41:8 | topRef [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:41:10:41:15 | topRef [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:43:8:43:13 | (reference dereference) [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:43:8:43:13 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:43:8:43:13 | topRef [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:43:15:43:24 | topRef [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:44:8:44:13 | (reference dereference) [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:44:8:44:13 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:44:8:44:13 | topRef [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:44:15:44:24 | topRef [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:45:3:45:8 | (reference dereference) [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:45:3:45:8 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:45:3:45:8 | topRef [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:45:10:45:16 | topRef [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:51:3:51:22 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:55:8:55:19 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:55:8:55:19 | globalBottom [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:55:22:55:30 | globalBottom [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:56:8:56:19 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:56:8:56:19 | globalMiddle [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:56:22:56:30 | globalMiddle [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:58:8:58:23 | call to readGlobalBottom [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:58:28:58:36 | call to readGlobalBottom [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:60:3:60:14 | globalBottom [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:60:18:60:29 | Call [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:60:18:60:29 | new [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:60:18:60:29 | new [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:61:3:61:14 | globalMiddle [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:61:18:61:29 | Call [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:61:18:61:29 | new [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:61:18:61:29 | new [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:65:3:65:22 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:65:10:65:21 | Call [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:65:10:65:21 | new [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:65:10:65:21 | new [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:69:3:69:5 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:69:3:69:5 | top [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:69:8:69:13 | top [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:73:3:73:5 | (reference dereference) [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:73:3:73:5 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:73:3:73:5 | top [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:73:7:73:12 | top [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:77:3:77:19 | call to allocateBottom [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:77:21:77:34 | call to allocateBottom [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:78:3:78:21 | * ... [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:78:23:78:39 | (reference to) [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:78:23:78:39 | * ... [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:78:24:78:37 | call to allocateBottom [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:80:8:80:8 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:81:3:81:3 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:81:3:81:3 | x [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:81:6:81:11 | x [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:85:3:85:13 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:89:3:89:10 | bottom [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:89:3:89:10 | call to identity [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:89:12:89:17 | (Middle *)... [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:89:12:89:17 | (Top *)... [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:89:12:89:17 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:89:12:89:17 | bottom [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:89:21:89:26 | call to identity [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:90:3:90:10 | call to identity [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:90:3:90:10 | top [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:90:12:90:14 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:90:12:90:14 | top [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:90:18:90:23 | call to identity [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:100:3:100:18 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:105:5:105:17 | maybeCallSink [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:113:30:113:38 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:117:31:117:46 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:127:10:127:15 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:127:31:127:36 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:129:10:129:15 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:129:10:129:15 | topPtr [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:129:18:129:25 | topPtr [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:130:10:130:15 | (reference dereference) [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:130:10:130:15 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:130:10:130:15 | topRef [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:130:17:130:24 | topRef [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:148:3:148:3 | u [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:148:5:148:5 | f [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:168:3:168:4 | u2 [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:168:6:168:6 | u [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:168:8:168:8 | f [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| example.c:17:19:17:22 | FieldAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| example.c:17:19:17:22 | FieldAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| example.c:24:9:24:9 | x [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| example.c:24:20:24:20 | y [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| example.c:26:9:26:9 | x [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| example.c:26:13:26:16 | & ... [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| example.c:26:18:26:24 | & ... [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| example.c:26:19:26:24 | coords [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| example.c:28:2:28:12 | & ... [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| example.c:28:14:28:25 | (void *)... [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| example.c:28:22:28:25 | & ... [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| example.c:28:23:28:25 | pos [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| globals.cpp:5:9:5:13 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| globals.cpp:13:5:13:19 | flowTestGlobal1 [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| globals.cpp:23:5:23:19 | flowTestGlobal2 [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| lambdas.cpp:8:6:8:6 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| lambdas.cpp:9:6:9:6 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| lambdas.cpp:10:6:10:6 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| lambdas.cpp:11:6:11:6 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| lambdas.cpp:13:7:13:7 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| lambdas.cpp:13:10:17:2 | FieldAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| lambdas.cpp:13:10:17:2 | FieldAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| lambdas.cpp:16:3:16:11 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| lambdas.cpp:20:7:20:7 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| lambdas.cpp:20:10:24:2 | FieldAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| lambdas.cpp:20:10:24:2 | FieldAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| lambdas.cpp:20:10:24:2 | FieldAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| lambdas.cpp:23:3:23:3 | (reference dereference) [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| lambdas.cpp:23:3:23:14 | FieldAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| lambdas.cpp:23:3:23:14 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| lambdas.cpp:23:3:23:14 | v [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| lambdas.cpp:28:7:28:7 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| lambdas.cpp:28:10:31:2 | FieldAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| lambdas.cpp:28:10:31:2 | FieldAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| lambdas.cpp:34:7:34:7 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| lambdas.cpp:34:13:34:13 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| lambdas.cpp:40:7:40:7 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| lambdas.cpp:40:13:40:13 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| lambdas.cpp:43:3:43:3 | (reference dereference) [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| lambdas.cpp:43:3:43:3 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| lambdas.cpp:43:3:43:3 | c [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| lambdas.cpp:45:3:45:3 | t [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| lambdas.cpp:45:3:45:3 | u [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| lambdas.cpp:45:3:45:3 | w [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| lambdas.cpp:45:4:45:4 | (reference to) [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| lambdas.cpp:45:4:45:4 | t [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| lambdas.cpp:45:7:45:7 | (reference to) [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| lambdas.cpp:45:7:45:7 | u [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| lambdas.cpp:45:10:45:10 | (reference to) [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| lambdas.cpp:45:10:45:10 | w [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ref.cpp:11:5:11:7 | (reference dereference) [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ref.cpp:11:5:11:7 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ref.cpp:11:5:11:7 | lhs [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ref.cpp:16:5:16:10 | lhs [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ref.cpp:16:12:16:14 | (reference dereference) [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ref.cpp:16:12:16:14 | (reference to) [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ref.cpp:16:12:16:14 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ref.cpp:16:12:16:14 | lhs [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ref.cpp:20:5:20:7 | (reference dereference) [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ref.cpp:20:5:20:7 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ref.cpp:20:5:20:7 | lhs [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ref.cpp:22:7:22:9 | (reference dereference) [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ref.cpp:22:7:22:9 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ref.cpp:22:7:22:9 | lhs [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ref.cpp:24:7:24:9 | (reference dereference) [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ref.cpp:24:7:24:9 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ref.cpp:24:7:24:9 | lhs [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ref.cpp:29:5:29:7 | (reference dereference) [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ref.cpp:29:5:29:7 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ref.cpp:29:5:29:7 | out [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ref.cpp:31:7:31:9 | (reference dereference) [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ref.cpp:31:7:31:9 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ref.cpp:31:7:31:9 | out [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ref.cpp:37:7:37:19 | out [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ref.cpp:37:21:37:23 | (reference dereference) [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ref.cpp:37:21:37:23 | (reference to) [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ref.cpp:37:21:37:23 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ref.cpp:37:21:37:23 | out [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ref.cpp:39:7:39:9 | (reference dereference) [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ref.cpp:39:7:39:9 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ref.cpp:39:7:39:9 | out [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ref.cpp:44:5:44:7 | (reference dereference) [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ref.cpp:44:5:44:7 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ref.cpp:44:5:44:7 | out [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ref.cpp:46:7:46:9 | (reference dereference) [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ref.cpp:46:7:46:9 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ref.cpp:46:7:46:9 | out [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ref.cpp:48:7:48:9 | (reference dereference) [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ref.cpp:48:7:48:9 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ref.cpp:48:7:48:9 | out [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ref.cpp:55:5:55:17 | x1 [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ref.cpp:55:19:55:20 | (reference to) [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ref.cpp:55:19:55:20 | x1 [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ref.cpp:58:5:58:13 | x2 [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ref.cpp:58:15:58:16 | (reference to) [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ref.cpp:58:15:58:16 | x2 [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ref.cpp:61:5:61:24 | x3 [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ref.cpp:61:26:61:27 | (reference to) [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ref.cpp:61:26:61:27 | x3 [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ref.cpp:64:5:64:13 | x4 [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ref.cpp:64:15:64:16 | (reference to) [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ref.cpp:64:15:64:16 | x4 [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ref.cpp:75:5:75:7 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ref.cpp:75:5:75:7 | lhs [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ref.cpp:75:9:75:11 | val [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ref.cpp:79:5:79:10 | lhs [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ref.cpp:79:12:79:14 | (reference dereference) [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ref.cpp:79:12:79:14 | (reference to) [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ref.cpp:79:12:79:14 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ref.cpp:79:12:79:14 | lhs [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ref.cpp:83:5:83:7 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ref.cpp:83:5:83:7 | lhs [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ref.cpp:83:9:83:11 | val [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ref.cpp:87:7:87:9 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ref.cpp:87:7:87:9 | lhs [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ref.cpp:87:11:87:13 | val [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ref.cpp:89:7:89:9 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ref.cpp:89:7:89:9 | lhs [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ref.cpp:89:11:89:13 | val [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ref.cpp:94:5:94:7 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ref.cpp:94:5:94:7 | out [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ref.cpp:94:9:94:11 | val [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ref.cpp:96:7:96:9 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ref.cpp:96:7:96:9 | out [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ref.cpp:96:11:96:13 | val [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ref.cpp:102:7:102:19 | out [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ref.cpp:102:21:102:23 | (reference dereference) [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ref.cpp:102:21:102:23 | (reference to) [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ref.cpp:102:21:102:23 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ref.cpp:102:21:102:23 | out [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ref.cpp:104:7:104:9 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ref.cpp:104:7:104:9 | out [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ref.cpp:104:11:104:13 | val [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ref.cpp:109:5:109:7 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ref.cpp:109:5:109:7 | out [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ref.cpp:109:9:109:11 | val [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ref.cpp:113:7:113:9 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ref.cpp:113:7:113:9 | out [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ref.cpp:113:11:113:13 | val [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ref.cpp:115:7:115:9 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ref.cpp:115:7:115:9 | out [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ref.cpp:115:11:115:13 | val [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ref.cpp:122:5:122:17 | x1 [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ref.cpp:122:19:122:20 | (reference to) [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ref.cpp:122:19:122:20 | x1 [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ref.cpp:125:5:125:13 | x2 [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ref.cpp:125:15:125:16 | (reference to) [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ref.cpp:125:15:125:16 | x2 [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ref.cpp:128:5:128:24 | x3 [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ref.cpp:128:26:128:27 | (reference to) [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ref.cpp:128:26:128:27 | x3 [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ref.cpp:131:5:131:13 | x4 [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ref.cpp:131:15:131:16 | (reference to) [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ref.cpp:131:15:131:16 | x4 [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:6:7:6:8 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:8:3:8:4 | t2 [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:12:5:12:6 | t2 [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:17:3:17:4 | t1 [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:23:12:23:12 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:23:27:23:27 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:24:5:24:6 | t1 [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:41:9:41:10 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:41:17:41:18 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:42:9:42:9 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:43:10:43:20 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:43:10:43:20 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:45:5:45:5 | t [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:45:9:45:19 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:45:9:45:19 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:50:9:50:10 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:50:24:50:24 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:52:7:52:7 | t [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:54:7:54:7 | t [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:67:14:67:15 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:68:8:68:9 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:69:8:69:9 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:70:14:70:15 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:77:3:77:4 | u1 [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:80:7:80:8 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:84:8:84:18 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:85:3:85:4 | i1 [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:91:3:91:9 | (reference dereference) [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:91:3:91:9 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:91:3:91:9 | source1 [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:100:9:100:9 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:101:10:101:12 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:102:5:102:5 | t [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:107:9:107:9 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:108:10:108:12 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:109:5:109:5 | t [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:115:3:115:6 | * ... [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:115:4:115:6 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:115:4:115:6 | out [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:116:3:116:11 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:120:3:120:6 | * ... [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:120:4:120:6 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:120:4:120:6 | out [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:121:3:121:11 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:125:3:125:6 | * ... [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:125:4:125:6 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:125:4:125:6 | out [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:126:3:126:11 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:134:3:134:11 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:138:7:138:7 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:139:7:139:7 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:145:3:145:11 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:149:7:149:7 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:151:7:151:7 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:156:7:156:7 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:158:3:158:11 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:162:7:162:7 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:164:7:164:7 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:171:7:171:7 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:172:3:172:11 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:176:7:176:7 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:177:7:177:7 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:190:5:190:13 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:194:9:194:9 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:194:13:194:27 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:194:13:194:27 | this [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:194:13:194:27 | this [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:195:9:195:15 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:196:9:196:9 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:201:9:201:15 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:203:5:203:19 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:207:9:207:9 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:207:13:207:33 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:207:13:207:33 | this [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:207:13:207:33 | this [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:209:9:209:9 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:209:13:209:33 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:209:13:209:33 | this [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:209:13:209:33 | this [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:214:9:214:15 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:215:9:215:9 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:217:5:217:13 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:221:9:221:9 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:221:13:221:34 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:221:13:221:34 | this [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:221:13:221:34 | this [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:223:9:223:9 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:223:13:223:34 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:223:13:223:34 | this [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:223:13:223:34 | this [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:230:9:230:9 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:231:9:231:15 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:232:5:232:19 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:236:9:236:9 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:236:13:236:24 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:236:13:236:24 | this [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:236:13:236:24 | this [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:237:9:237:9 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:245:7:245:12 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:245:7:245:12 | this [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:245:7:245:12 | this [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:246:7:246:16 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:246:7:246:16 | this [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:246:7:246:16 | this [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:250:11:250:11 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:251:7:251:12 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:251:7:251:12 | this [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:251:7:251:12 | this [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:255:11:255:17 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:256:7:256:12 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:256:7:256:12 | this [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:256:7:256:12 | this [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:265:11:265:11 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:265:15:265:20 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:265:15:265:20 | this [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:265:15:265:20 | this [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:267:7:267:7 | x [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:267:11:267:20 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:267:11:267:20 | this [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:267:11:267:20 | this [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:272:11:272:11 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:273:7:273:23 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:273:14:273:19 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:273:14:273:19 | this [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:273:14:273:19 | this [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:277:11:277:17 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:278:7:278:29 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:278:14:278:19 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:278:14:278:19 | this [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:278:14:278:19 | this [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:282:11:282:11 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:283:7:283:15 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:288:13:288:13 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:288:17:288:22 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:288:17:288:22 | this [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:288:17:288:22 | this [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:290:9:290:9 | x [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:290:13:290:22 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:290:13:290:22 | this [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:290:13:290:22 | this [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:295:13:295:13 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:295:17:295:22 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:295:17:295:22 | this [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:295:17:295:22 | this [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:296:9:296:17 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:300:13:300:19 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:300:23:300:28 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:300:23:300:28 | this [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:300:23:300:28 | this [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:301:9:301:23 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:305:13:305:13 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:306:9:306:17 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:314:2:314:2 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:314:2:314:2 | this [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:314:2:314:2 | this [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:317:6:317:6 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:317:10:317:10 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:317:10:317:10 | this [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:317:10:317:10 | this [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:319:6:319:6 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:319:10:319:10 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:319:10:319:10 | this [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:319:10:319:10 | this [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:321:2:321:2 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:321:2:321:2 | this [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:321:2:321:2 | this [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:324:2:324:10 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:333:5:333:13 | globalVar [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:347:5:347:13 | globalVar [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:359:5:359:9 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:359:5:359:9 | field [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:364:5:364:14 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:364:5:364:14 | this [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:364:5:364:14 | this [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:373:5:373:9 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:373:5:373:9 | field [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:374:5:374:20 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:374:5:374:20 | this [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:374:5:374:20 | this [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:383:7:383:9 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:384:3:384:8 | & ... [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:384:10:384:13 | & ... [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:384:10:384:13 | (void *)... [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:384:11:384:13 | tmp [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:389:7:389:9 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:390:8:390:14 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:391:3:391:8 | & ... [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:391:10:391:13 | & ... [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:391:10:391:13 | (void *)... [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:391:11:391:13 | tmp [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:400:3:400:8 | & ... [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:400:10:400:13 | & ... [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:400:10:400:13 | (void *)... [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:400:11:400:13 | tmp [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:406:8:406:14 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:407:3:407:8 | & ... [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:407:10:407:13 | & ... [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:407:10:407:13 | (void *)... [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:407:11:407:13 | tmp [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:417:3:417:14 | local [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:417:16:417:20 | (reference to) [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:417:16:417:20 | local [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:423:3:423:18 | & ... [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:423:20:423:25 | & ... [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:423:21:423:25 | local [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:429:3:429:18 | local [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:429:20:429:24 | array to pointer conversion [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:429:20:429:24 | local [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:436:3:436:16 | & ... [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:436:18:436:23 | & ... [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:436:19:436:23 | local [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:442:3:442:16 | local [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:442:18:442:22 | array to pointer conversion [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:442:18:442:22 | local [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:453:7:453:11 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:456:7:456:9 | tmp [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:458:7:458:9 | tmp [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:465:3:465:4 | * ... [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:465:4:465:4 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:465:4:465:4 | p [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:469:7:469:7 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:470:3:470:19 | & ... [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:470:21:470:22 | & ... [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:470:22:470:22 | x [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:481:3:481:19 | content [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:481:21:481:21 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:481:21:481:30 | (void *)... [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:481:24:481:30 | FieldAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:481:24:481:30 | content [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:482:8:482:16 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| true_upon_entry.cpp:9:7:9:7 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| true_upon_entry.cpp:10:12:10:12 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| true_upon_entry.cpp:10:27:10:27 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| true_upon_entry.cpp:11:5:11:5 | x [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| true_upon_entry.cpp:17:7:17:7 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| true_upon_entry.cpp:18:12:18:12 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| true_upon_entry.cpp:18:35:18:35 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| true_upon_entry.cpp:19:5:19:5 | x [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| true_upon_entry.cpp:25:7:25:7 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| true_upon_entry.cpp:26:12:26:12 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| true_upon_entry.cpp:26:27:26:27 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| true_upon_entry.cpp:27:5:27:5 | x [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| true_upon_entry.cpp:33:7:33:7 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| true_upon_entry.cpp:34:12:34:12 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| true_upon_entry.cpp:34:27:34:27 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| true_upon_entry.cpp:37:5:37:5 | x [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| true_upon_entry.cpp:43:7:43:7 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| true_upon_entry.cpp:44:12:44:12 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| true_upon_entry.cpp:44:27:44:27 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| true_upon_entry.cpp:47:5:47:5 | x [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| true_upon_entry.cpp:54:7:54:7 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| true_upon_entry.cpp:55:12:55:12 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| true_upon_entry.cpp:55:30:55:30 | y [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| true_upon_entry.cpp:55:38:55:38 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| true_upon_entry.cpp:62:7:62:7 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| true_upon_entry.cpp:63:12:63:12 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| true_upon_entry.cpp:63:30:63:30 | y [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| true_upon_entry.cpp:63:38:63:38 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| true_upon_entry.cpp:64:5:64:5 | x [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| true_upon_entry.cpp:70:7:70:7 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| true_upon_entry.cpp:76:12:76:12 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| true_upon_entry.cpp:76:30:76:30 | x [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| true_upon_entry.cpp:76:38:76:38 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| true_upon_entry.cpp:83:7:83:7 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| true_upon_entry.cpp:84:12:84:12 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| true_upon_entry.cpp:84:20:84:20 | y [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| true_upon_entry.cpp:84:38:84:38 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| true_upon_entry.cpp:90:7:90:7 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| true_upon_entry.cpp:91:12:91:12 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| true_upon_entry.cpp:91:20:91:20 | x [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| true_upon_entry.cpp:91:38:91:38 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| true_upon_entry.cpp:97:7:97:7 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| true_upon_entry.cpp:98:7:98:7 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| true_upon_entry.cpp:101:18:101:18 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| true_upon_entry.cpp:102:5:102:5 | x [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
|
|
|
@ -18,7 +18,7 @@ void test_lambdas()
|
|||
sink(a()); // $ ast,ir
|
||||
|
||||
auto b = [&] {
|
||||
sink(t); // $ ast MISSING: ir
|
||||
sink(t); // $ ast,ir
|
||||
sink(u);
|
||||
v = source(); // (v is reference captured)
|
||||
};
|
||||
|
|
|
@ -100,14 +100,14 @@ void local_references(int &source1, int clean1) {
|
|||
int t = source();
|
||||
int &ref = t;
|
||||
t = clean1;
|
||||
sink(ref); // $ SPURIOUS: ast
|
||||
sink(ref); // $ SPURIOUS: ast,ir
|
||||
}
|
||||
|
||||
{
|
||||
int t = clean1;
|
||||
int &ref = t;
|
||||
t = source();
|
||||
sink(ref); // $ ir MISSING: ast
|
||||
sink(ref); // $ MISSING: ast,ir
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -346,7 +346,7 @@ namespace FlowThroughGlobals {
|
|||
int taintAndCall() {
|
||||
globalVar = source();
|
||||
calledAfterTaint();
|
||||
sink(globalVar); // $ ast MISSING: ir
|
||||
sink(globalVar); // $ ast,ir
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -355,21 +355,21 @@ namespace FlowThroughGlobals {
|
|||
class FlowThroughFields {
|
||||
int field = 0;
|
||||
|
||||
int taintField() {
|
||||
void taintField() {
|
||||
field = source();
|
||||
}
|
||||
|
||||
int f() {
|
||||
void f() {
|
||||
sink(field); // tainted or clean? Not sure.
|
||||
taintField();
|
||||
sink(field); // $ ast MISSING: ir
|
||||
}
|
||||
|
||||
int calledAfterTaint() {
|
||||
sink(field); // $ ast,ir
|
||||
}
|
||||
|
||||
int taintAndCall() {
|
||||
void calledAfterTaint() {
|
||||
sink(field); // $ ast,ir
|
||||
}
|
||||
|
||||
void taintAndCall() {
|
||||
field = source();
|
||||
calledAfterTaint();
|
||||
sink(field); // $ ast,ir
|
||||
|
|
|
@ -46,7 +46,7 @@ public:
|
|||
{
|
||||
C *c = new C();
|
||||
B *b = B::make(c);
|
||||
sink(b->c); // $ast MISSING: ir
|
||||
sink(b->c); // $ast,ir
|
||||
}
|
||||
|
||||
void f2()
|
||||
|
@ -54,7 +54,7 @@ public:
|
|||
B *b = new B();
|
||||
b->set(new C1());
|
||||
sink(b->get()); // $ ast ir=55:12
|
||||
sink((new B(new C()))->get()); // $ ast ir
|
||||
sink((new B(new C()))->get()); // $ ast,ir
|
||||
}
|
||||
|
||||
void f3()
|
||||
|
@ -63,7 +63,7 @@ public:
|
|||
B *b2;
|
||||
b2 = setOnB(b1, new C2());
|
||||
sink(b1->c); // no flow
|
||||
sink(b2->c); // $ ast MISSING: ir
|
||||
sink(b2->c); // $ ast ir=64:21
|
||||
}
|
||||
|
||||
void f4()
|
||||
|
@ -72,7 +72,7 @@ public:
|
|||
B *b2;
|
||||
b2 = setOnBWrap(b1, new C2());
|
||||
sink(b1->c); // no flow
|
||||
sink(b2->c); // $ ast MISSING: ir
|
||||
sink(b2->c); // $ ast ir=73:25
|
||||
}
|
||||
|
||||
B *setOnBWrap(B *b1, C *c)
|
||||
|
@ -117,7 +117,7 @@ public:
|
|||
}
|
||||
if (C1 *c1 = dynamic_cast<C1 *>(cc))
|
||||
{
|
||||
sink(c1->a); // $ SPURIOUS: ast
|
||||
sink(c1->a); // $ SPURIOUS: ast,ir
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -150,7 +150,7 @@ public:
|
|||
B *b = new B();
|
||||
D *d = new D(b, r());
|
||||
sink(d->b); // $ ast,ir=143:25 ast,ir=150:12
|
||||
sink(d->b->c); // $ ast MISSING: ir
|
||||
sink(d->b->c); // $ ast,ir
|
||||
sink(b->c); // $ ast,ir
|
||||
}
|
||||
|
||||
|
@ -162,11 +162,11 @@ public:
|
|||
MyList *l3 = new MyList(nullptr, l2);
|
||||
sink(l3->head); // no flow, b is nested beneath at least one ->next
|
||||
sink(l3->next->head); // no flow
|
||||
sink(l3->next->next->head); // $ ast MISSING: ir
|
||||
sink(l3->next->next->head); // $ ast,ir
|
||||
sink(l3->next->next->next->head); // no flow
|
||||
for (MyList *l = l3; l != nullptr; l = l->next)
|
||||
{
|
||||
sink(l->head); // $ ast MISSING: ir
|
||||
sink(l->head); // $ ast,ir
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@ class B
|
|||
Elem *e = new Elem();
|
||||
Box1 *b1 = new Box1(e, nullptr);
|
||||
Box2 *b2 = new Box2(b1);
|
||||
sink(b2->box1->elem1); // $ ast MISSING: ir
|
||||
sink(b2->box1->elem1); // $ ast,ir
|
||||
sink(b2->box1->elem2); // no flow
|
||||
}
|
||||
|
||||
|
@ -16,7 +16,7 @@ class B
|
|||
Box1 *b1 = new B::Box1(nullptr, e);
|
||||
Box2 *b2 = new Box2(b1);
|
||||
sink(b2->box1->elem1); // no flow
|
||||
sink(b2->box1->elem2); // $ ast MISSING: ir
|
||||
sink(b2->box1->elem2); // $ ast,ir
|
||||
}
|
||||
|
||||
static void sink(void *o) {}
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
|
||||
void sink(...);
|
||||
class C
|
||||
{
|
||||
class Elem
|
||||
{
|
||||
};
|
||||
|
||||
private:
|
||||
Elem *s1 = new Elem();
|
||||
const Elem *s2 = new Elem();
|
||||
|
@ -26,12 +26,10 @@ public:
|
|||
|
||||
void func()
|
||||
{
|
||||
sink(s1); // $ast ir
|
||||
sink(s1); // $ast,ir
|
||||
sink(s2); // $ MISSING: ast,ir
|
||||
sink(s3); // $ast ir
|
||||
sink(s3); // $ast MISSING: ir
|
||||
sink(s4); // $ MISSING: ast,ir
|
||||
}
|
||||
|
||||
static void sink(const void *o) {}
|
||||
};
|
||||
const C::Elem *C::s4 = new Elem();
|
||||
|
|
|
@ -19,7 +19,7 @@ public:
|
|||
};
|
||||
|
||||
static void sinkWrap(Box2* b2) {
|
||||
sink(b2->getBox1()->getElem()); // $ast=28:15 ast=35:15 ast=42:15 ast=49:15 MISSING: ir
|
||||
sink(b2->getBox1()->getElem()); // $ast,ir=28:15 ast,ir=35:15 ast,ir=42:15 ast,ir=49:15
|
||||
}
|
||||
|
||||
Box2* boxfield;
|
||||
|
@ -61,6 +61,6 @@ public:
|
|||
|
||||
private:
|
||||
void f5b() {
|
||||
sink(boxfield->box->elem); // $ ast MISSING: ir
|
||||
sink(boxfield->box->elem); // $ ast,ir
|
||||
}
|
||||
};
|
||||
|
|
|
@ -18,7 +18,7 @@ void sink(char *b);
|
|||
|
||||
void handlePacket(packet *p)
|
||||
{
|
||||
sink(p->data.buffer); // $ ast MISSING: ir
|
||||
sink(p->data.buffer); // $ ast,ir
|
||||
}
|
||||
|
||||
void f(buf* b)
|
||||
|
@ -28,7 +28,7 @@ void f(buf* b)
|
|||
argument_source(raw);
|
||||
argument_source(b->buffer);
|
||||
argument_source(p.data.buffer);
|
||||
sink(raw); // $ ast MISSING: ir
|
||||
sink(b->buffer); // $ ast MISSING: ir
|
||||
sink(raw); // $ ast,ir
|
||||
sink(b->buffer); // $ ast,ir
|
||||
handlePacket(&p);
|
||||
}
|
|
@ -18,7 +18,7 @@ class IRConf extends Configuration {
|
|||
override predicate isSink(Node sink) {
|
||||
exists(Call c |
|
||||
c.getTarget().hasName("sink") and
|
||||
c.getAnArgument() = sink.asConvertedExpr()
|
||||
c.getAnArgument() = [sink.asExpr(), sink.asConvertedExpr()]
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
@ -35,12 +35,12 @@ void assignAfterAlias() {
|
|||
S s1 = { 0, 0 };
|
||||
S &ref1 = s1;
|
||||
ref1.m1 = user_input();
|
||||
sink(s1.m1); // $ ir MISSING: ast
|
||||
sink(s1.m1); // $ MISSING: ast,ir
|
||||
|
||||
S s2 = { 0, 0 };
|
||||
S &ref2 = s2;
|
||||
s2.m1 = user_input();
|
||||
sink(ref2.m1); // $ ir MISSING: ast
|
||||
sink(ref2.m1); // $ MISSING: ast,ir
|
||||
}
|
||||
|
||||
void assignAfterCopy() {
|
||||
|
@ -77,14 +77,14 @@ void pointerIntermediate() {
|
|||
Wrapper w = { { 0, 0 } };
|
||||
S *s = &w.s;
|
||||
s->m1 = user_input();
|
||||
sink(w.s.m1); // $ ir MISSING: ast
|
||||
sink(w.s.m1); // $ MISSING: ast,ir
|
||||
}
|
||||
|
||||
void referenceIntermediate() {
|
||||
Wrapper w = { { 0, 0 } };
|
||||
S &s = w.s;
|
||||
s.m1 = user_input();
|
||||
sink(w.s.m1); // $ ir MISSING: ast
|
||||
sink(w.s.m1); // $ MISSING: ast,ir
|
||||
}
|
||||
|
||||
void nestedAssign() {
|
||||
|
@ -99,7 +99,7 @@ void addressOfField() {
|
|||
|
||||
S s_copy = s;
|
||||
int* px = &s_copy.m1;
|
||||
sink(*px); // $ ir MISSING: ast
|
||||
sink(*px); // $ MISSING: ast,ir
|
||||
}
|
||||
|
||||
void taint_a_ptr(int* pa) {
|
||||
|
@ -119,7 +119,7 @@ struct S_with_pointer {
|
|||
|
||||
void pointer_deref(int* xs) {
|
||||
taint_a_ptr(xs);
|
||||
sink(xs[0]); // $ ir MISSING: ast
|
||||
sink(xs[0]); // $ MISSING: ast,ir
|
||||
}
|
||||
|
||||
void pointer_deref_sub(int* xs) {
|
||||
|
@ -129,18 +129,18 @@ void pointer_deref_sub(int* xs) {
|
|||
|
||||
void pointer_many_addrof_and_deref(int* xs) {
|
||||
taint_a_ptr(xs);
|
||||
sink(*&*&*xs); // $ ir MISSING: ast
|
||||
sink(*&*&*xs); // $ MISSING: ast,ir
|
||||
}
|
||||
|
||||
void pointer_unary_plus(int* xs) {
|
||||
taint_a_ptr(+xs);
|
||||
sink(*+xs); // $ ir MISSING: ast
|
||||
sink(*+xs); // $ MISSING: ast,ir
|
||||
}
|
||||
|
||||
void pointer_member_index(S_with_pointer s) {
|
||||
taint_a_ptr(s.data);
|
||||
// `s.data` is points to all-aliased-memory
|
||||
sink(s.data[0]); // $ MISSING: ir,ast
|
||||
sink(s.data[0]); // $ ir MISSING: ast
|
||||
}
|
||||
|
||||
void member_array_different_field(S_with_pointer* s) {
|
||||
|
@ -156,13 +156,13 @@ struct S_with_array {
|
|||
void pointer_member_deref() {
|
||||
S_with_array s;
|
||||
taint_a_ptr(s.data);
|
||||
sink(*s.data); // $ ast MISSING: ir
|
||||
sink(*s.data); // $ ast,ir
|
||||
}
|
||||
|
||||
void array_member_deref() {
|
||||
S_with_array s;
|
||||
taint_a_ptr(s.data);
|
||||
sink(s.data[0]); // $ ast MISSING: ir
|
||||
sink(s.data[0]); // $ ast,ir
|
||||
}
|
||||
|
||||
struct S2 {
|
||||
|
|
|
@ -5,7 +5,7 @@ void local_array() {
|
|||
void *arr[10] = { 0 };
|
||||
arr[0] = user_input();
|
||||
sink(arr[0]); // $ ast,ir
|
||||
sink(arr[1]); // $ SPURIOUS: ast
|
||||
sink(arr[1]); // $ SPURIOUS: ast,ir
|
||||
sink(*arr); // $ ast,ir
|
||||
sink(*&arr[0]); // $ ast,ir
|
||||
}
|
||||
|
@ -14,7 +14,7 @@ void local_array_convoluted_assign() {
|
|||
void *arr[10] = { 0 };
|
||||
*&arr[0] = user_input();
|
||||
sink(arr[0]); // $ ast,ir
|
||||
sink(arr[1]); // $ SPURIOUS: ast
|
||||
sink(arr[1]); // $ SPURIOUS: ast,ir
|
||||
}
|
||||
|
||||
struct inner {
|
||||
|
@ -35,17 +35,17 @@ struct outer {
|
|||
void nested_array_1(outer o) {
|
||||
o.nested.arr[1].data = user_input();
|
||||
sink(o.nested.arr[1].data); // $ ast,ir
|
||||
sink(o.nested.arr[0].data); // $ SPURIOUS: ast
|
||||
sink(o.nested.arr[0].data); // $ SPURIOUS: ast,ir
|
||||
}
|
||||
|
||||
void nested_array_2(outer o) {
|
||||
o.indirect->arr[1].data = user_input();
|
||||
sink(o.indirect->arr[1].data); // $ ast MISSING: ir
|
||||
sink(o.indirect->arr[0].data); // $ SPURIOUS: ast
|
||||
sink(o.indirect->arr[1].data); // $ ast,ir
|
||||
sink(o.indirect->arr[0].data); // $ SPURIOUS: ast,ir
|
||||
}
|
||||
|
||||
void nested_array_3(outer o) {
|
||||
o.indirect->ptr[1].data = user_input();
|
||||
sink(o.indirect->ptr[1].data); // $ MISSING: ir,ast
|
||||
sink(o.indirect->ptr[0].data);
|
||||
sink(o.indirect->ptr[1].data); // $ ir MISSING: ast
|
||||
sink(o.indirect->ptr[0].data); // $ SPURIOUS: ir
|
||||
}
|
||||
|
|
|
@ -108,11 +108,11 @@ void test_outer_with_ptr(Outer *pouter) {
|
|||
taint_a_ptr(&pouter->a);
|
||||
|
||||
sink(outer.inner_nested.a); // $ ast,ir
|
||||
sink(outer.inner_ptr->a); // $ ast MISSING: ir
|
||||
sink(outer.inner_ptr->a); // $ ast,ir
|
||||
sink(outer.a); // $ ast,ir
|
||||
|
||||
sink(pouter->inner_nested.a); // $ ast,ir
|
||||
sink(pouter->inner_ptr->a); // $ast MISSING: ir
|
||||
sink(pouter->inner_ptr->a); // $ast,ir
|
||||
sink(pouter->a); // $ ast,ir
|
||||
}
|
||||
|
||||
|
@ -128,10 +128,10 @@ void test_outer_with_ref(Outer *pouter) {
|
|||
taint_a_ref(pouter->a);
|
||||
|
||||
sink(outer.inner_nested.a); // $ ast,ir
|
||||
sink(outer.inner_ptr->a); // $ ast MISSING: ir
|
||||
sink(outer.inner_ptr->a); // $ ast,ir
|
||||
sink(outer.a); // $ ast,ir
|
||||
|
||||
sink(pouter->inner_nested.a); // $ ast,ir
|
||||
sink(pouter->inner_ptr->a); // $ ast MISSING: ir
|
||||
sink(pouter->inner_ptr->a); // $ ast,ir
|
||||
sink(pouter->a); // $ ast,ir
|
||||
}
|
||||
|
|
|
@ -8,7 +8,7 @@ struct A {
|
|||
|
||||
void pointer_without_allocation(const A& ra) {
|
||||
*ra.p = user_input();
|
||||
sink(*ra.p); // $ MISSING: ast,ir
|
||||
sink(*ra.p); // $ ir MISSING: ast
|
||||
}
|
||||
|
||||
void argument_source(void*);
|
||||
|
@ -17,7 +17,7 @@ void sink(void*);
|
|||
void pointer_without_allocation_2() {
|
||||
char *raw;
|
||||
argument_source(raw);
|
||||
sink(raw); // $ ast MISSING: ir
|
||||
sink(raw); // $ ast,ir
|
||||
}
|
||||
|
||||
A* makeA() {
|
||||
|
@ -27,14 +27,14 @@ A* makeA() {
|
|||
void no_InitializeDynamicAllocation_instruction() {
|
||||
A* pa = makeA();
|
||||
pa->x = user_input();
|
||||
sink(pa->x); // $ ast MISSING: ir
|
||||
sink(pa->x); // $ ast,ir
|
||||
}
|
||||
|
||||
void fresh_or_arg(A* arg, bool unknown) {
|
||||
A* pa;
|
||||
pa = unknown ? arg : new A;
|
||||
pa->x = user_input();
|
||||
sink(pa->x); // $ ast MISSING: ir
|
||||
sink(pa->x); // $ ast,ir
|
||||
}
|
||||
|
||||
struct LinkedList {
|
||||
|
@ -52,11 +52,11 @@ void too_many_indirections() {
|
|||
LinkedList* ll = new LinkedList;
|
||||
ll->next = new LinkedList;
|
||||
ll->next->y = user_input();
|
||||
sink(ll->next->y); // $ ast MISSING: ir
|
||||
sink(ll->next->y); // $ ast,ir
|
||||
}
|
||||
|
||||
void too_many_indirections_2(LinkedList* next) {
|
||||
LinkedList* ll = new LinkedList(next);
|
||||
ll->next->y = user_input();
|
||||
sink(ll->next->y); // $ ast MISSING: ir
|
||||
sink(ll->next->y); // $ ast,ir
|
||||
}
|
||||
|
|
|
@ -3,8 +3,8 @@ uniqueEnclosingCallable
|
|||
| C.cpp:9:14:9:23 | new | Node should have one enclosing callable but has 0. |
|
||||
| C.cpp:10:20:10:29 | 0 | Node should have one enclosing callable but has 0. |
|
||||
| C.cpp:10:20:10:29 | new | Node should have one enclosing callable but has 0. |
|
||||
| C.cpp:37:24:37:33 | 0 | Node should have one enclosing callable but has 0. |
|
||||
| C.cpp:37:24:37:33 | new | Node should have one enclosing callable but has 0. |
|
||||
| C.cpp:35:24:35:33 | 0 | Node should have one enclosing callable but has 0. |
|
||||
| C.cpp:35:24:35:33 | new | Node should have one enclosing callable but has 0. |
|
||||
uniqueType
|
||||
uniqueNodeLocation
|
||||
missingLocation
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -1,152 +1,93 @@
|
|||
| A.cpp:25:13:25:13 | c | AST only |
|
||||
| A.cpp:27:28:27:28 | c | AST only |
|
||||
| A.cpp:31:20:31:20 | c | AST only |
|
||||
| A.cpp:40:5:40:6 | cc | AST only |
|
||||
| A.cpp:41:5:41:6 | ct | AST only |
|
||||
| A.cpp:42:10:42:12 | & ... | AST only |
|
||||
| A.cpp:43:10:43:12 | & ... | AST only |
|
||||
| A.cpp:48:20:48:20 | c | AST only |
|
||||
| A.cpp:49:10:49:10 | b | AST only |
|
||||
| A.cpp:49:13:49:13 | c | AST only |
|
||||
| A.cpp:55:5:55:5 | b | AST only |
|
||||
| A.cpp:56:10:56:10 | b | AST only |
|
||||
| A.cpp:56:13:56:15 | call to get | AST only |
|
||||
| A.cpp:57:28:57:30 | call to get | AST only |
|
||||
| A.cpp:64:10:64:15 | this | AST only |
|
||||
| A.cpp:64:17:64:18 | b1 | AST only |
|
||||
| A.cpp:65:10:65:11 | b1 | AST only |
|
||||
| A.cpp:65:14:65:14 | c | AST only |
|
||||
| A.cpp:66:10:66:11 | b2 | AST only |
|
||||
| A.cpp:66:14:66:14 | c | AST only |
|
||||
| A.cpp:73:10:73:19 | this | AST only |
|
||||
| A.cpp:73:21:73:22 | b1 | AST only |
|
||||
| A.cpp:74:10:74:11 | b1 | AST only |
|
||||
| A.cpp:74:14:74:14 | c | AST only |
|
||||
| A.cpp:75:10:75:11 | b2 | AST only |
|
||||
| A.cpp:75:14:75:14 | c | AST only |
|
||||
| A.cpp:81:10:81:15 | this | AST only |
|
||||
| A.cpp:81:17:81:18 | b1 | AST only |
|
||||
| A.cpp:81:21:81:21 | c | AST only |
|
||||
| A.cpp:82:12:82:12 | this | AST only |
|
||||
| A.cpp:87:9:87:9 | this | AST only |
|
||||
| A.cpp:90:7:90:8 | b2 | AST only |
|
||||
| A.cpp:90:15:90:15 | c | AST only |
|
||||
| A.cpp:31:14:31:21 | new | IR only |
|
||||
| A.cpp:40:8:40:13 | 0 | IR only |
|
||||
| A.cpp:41:8:41:13 | new | IR only |
|
||||
| A.cpp:41:15:41:21 | new | IR only |
|
||||
| A.cpp:47:12:47:18 | new | IR only |
|
||||
| A.cpp:54:12:54:18 | new | IR only |
|
||||
| A.cpp:55:8:55:10 | new | IR only |
|
||||
| A.cpp:55:12:55:19 | new | IR only |
|
||||
| A.cpp:57:11:57:24 | new | IR only |
|
||||
| A.cpp:57:11:57:24 | new | IR only |
|
||||
| A.cpp:57:17:57:23 | new | IR only |
|
||||
| A.cpp:57:28:57:30 | new | IR only |
|
||||
| A.cpp:62:13:62:19 | new | IR only |
|
||||
| A.cpp:64:10:64:15 | new | IR only |
|
||||
| A.cpp:64:21:64:28 | new | IR only |
|
||||
| A.cpp:71:13:71:19 | new | IR only |
|
||||
| A.cpp:73:10:73:19 | new | IR only |
|
||||
| A.cpp:73:25:73:32 | new | IR only |
|
||||
| A.cpp:89:15:89:21 | new | IR only |
|
||||
| A.cpp:99:14:99:21 | new | IR only |
|
||||
| A.cpp:100:9:100:9 | a | AST only |
|
||||
| A.cpp:101:5:101:6 | this | AST only |
|
||||
| A.cpp:101:8:101:9 | c1 | AST only |
|
||||
| A.cpp:107:12:107:13 | c1 | AST only |
|
||||
| A.cpp:107:16:107:16 | a | AST only |
|
||||
| A.cpp:120:12:120:13 | c1 | AST only |
|
||||
| A.cpp:120:16:120:16 | a | AST only |
|
||||
| A.cpp:126:5:126:5 | b | AST only |
|
||||
| A.cpp:131:5:131:6 | this | AST only |
|
||||
| A.cpp:131:8:131:8 | b | AST only |
|
||||
| A.cpp:132:10:132:10 | b | AST only |
|
||||
| A.cpp:132:13:132:13 | c | AST only |
|
||||
| A.cpp:116:12:116:19 | new | IR only |
|
||||
| A.cpp:126:8:126:10 | new | IR only |
|
||||
| A.cpp:126:12:126:18 | new | IR only |
|
||||
| A.cpp:130:12:130:18 | new | IR only |
|
||||
| A.cpp:142:10:142:10 | c | AST only |
|
||||
| A.cpp:142:14:142:20 | new | IR only |
|
||||
| A.cpp:143:13:143:13 | b | AST only |
|
||||
| A.cpp:151:18:151:18 | b | AST only |
|
||||
| A.cpp:151:21:151:21 | this | AST only |
|
||||
| A.cpp:152:10:152:10 | d | AST only |
|
||||
| A.cpp:152:13:152:13 | b | AST only |
|
||||
| A.cpp:153:10:153:10 | d | AST only |
|
||||
| A.cpp:153:13:153:13 | b | AST only |
|
||||
| A.cpp:153:16:153:16 | c | AST only |
|
||||
| A.cpp:154:10:154:10 | b | AST only |
|
||||
| A.cpp:154:13:154:13 | c | AST only |
|
||||
| A.cpp:160:29:160:29 | b | AST only |
|
||||
| A.cpp:161:38:161:39 | l1 | AST only |
|
||||
| A.cpp:162:38:162:39 | l2 | AST only |
|
||||
| A.cpp:163:10:163:11 | l3 | AST only |
|
||||
| A.cpp:163:14:163:17 | head | AST only |
|
||||
| A.cpp:164:10:164:11 | l3 | AST only |
|
||||
| A.cpp:164:14:164:17 | next | AST only |
|
||||
| A.cpp:164:20:164:23 | head | AST only |
|
||||
| A.cpp:165:10:165:11 | l3 | AST only |
|
||||
| A.cpp:165:14:165:17 | next | AST only |
|
||||
| A.cpp:165:20:165:23 | next | AST only |
|
||||
| A.cpp:165:26:165:29 | head | AST only |
|
||||
| A.cpp:166:10:166:11 | l3 | AST only |
|
||||
| A.cpp:166:14:166:17 | next | AST only |
|
||||
| A.cpp:166:20:166:23 | next | AST only |
|
||||
| A.cpp:166:26:166:29 | next | AST only |
|
||||
| A.cpp:166:32:166:35 | head | AST only |
|
||||
| A.cpp:169:12:169:12 | l | AST only |
|
||||
| A.cpp:169:15:169:18 | head | AST only |
|
||||
| A.cpp:143:25:143:31 | new | IR only |
|
||||
| A.cpp:150:12:150:18 | new | IR only |
|
||||
| A.cpp:151:12:151:24 | new | IR only |
|
||||
| A.cpp:159:12:159:18 | new | IR only |
|
||||
| A.cpp:160:18:160:60 | new | IR only |
|
||||
| A.cpp:160:18:160:60 | new | IR only |
|
||||
| A.cpp:160:32:160:59 | 0 | IR only |
|
||||
| A.cpp:160:32:160:59 | 0 | IR only |
|
||||
| A.cpp:160:32:160:59 | new | IR only |
|
||||
| A.cpp:161:18:161:40 | 0 | IR only |
|
||||
| A.cpp:161:18:161:40 | new | IR only |
|
||||
| A.cpp:162:18:162:40 | 0 | IR only |
|
||||
| A.cpp:162:18:162:40 | new | IR only |
|
||||
| A.cpp:183:7:183:10 | head | AST only |
|
||||
| A.cpp:184:13:184:16 | next | AST only |
|
||||
| B.cpp:7:25:7:25 | e | AST only |
|
||||
| B.cpp:8:25:8:26 | b1 | AST only |
|
||||
| B.cpp:9:10:9:11 | b2 | AST only |
|
||||
| B.cpp:9:14:9:17 | box1 | AST only |
|
||||
| B.cpp:9:20:9:24 | elem1 | AST only |
|
||||
| B.cpp:10:10:10:11 | b2 | AST only |
|
||||
| B.cpp:10:14:10:17 | box1 | AST only |
|
||||
| B.cpp:10:20:10:24 | elem2 | AST only |
|
||||
| B.cpp:16:37:16:37 | e | AST only |
|
||||
| B.cpp:17:25:17:26 | b1 | AST only |
|
||||
| B.cpp:18:10:18:11 | b2 | AST only |
|
||||
| B.cpp:18:14:18:17 | box1 | AST only |
|
||||
| B.cpp:18:20:18:24 | elem1 | AST only |
|
||||
| B.cpp:19:10:19:11 | b2 | AST only |
|
||||
| B.cpp:19:14:19:17 | box1 | AST only |
|
||||
| B.cpp:19:20:19:24 | elem2 | AST only |
|
||||
| B.cpp:7:16:7:35 | 0 | IR only |
|
||||
| B.cpp:7:16:7:35 | new | IR only |
|
||||
| B.cpp:8:16:8:27 | new | IR only |
|
||||
| B.cpp:16:16:16:38 | 0 | IR only |
|
||||
| B.cpp:16:16:16:38 | new | IR only |
|
||||
| B.cpp:17:16:17:27 | new | IR only |
|
||||
| B.cpp:35:13:35:17 | elem1 | AST only |
|
||||
| B.cpp:36:13:36:17 | elem2 | AST only |
|
||||
| B.cpp:46:13:46:16 | box1 | AST only |
|
||||
| C.cpp:19:5:19:5 | c | AST only |
|
||||
| C.cpp:18:12:18:18 | new | IR only |
|
||||
| C.cpp:24:11:24:12 | s3 | AST only |
|
||||
| C.cpp:30:5:30:8 | s2 | IR only |
|
||||
| C.cpp:30:10:30:11 | this | IR only |
|
||||
| C.cpp:32:5:32:8 | s4 | IR only |
|
||||
| D.cpp:9:21:9:24 | elem | AST only |
|
||||
| D.cpp:11:29:11:32 | elem | AST only |
|
||||
| D.cpp:16:21:16:23 | box | AST only |
|
||||
| D.cpp:18:29:18:31 | box | AST only |
|
||||
| D.cpp:22:10:22:11 | b2 | AST only |
|
||||
| D.cpp:22:14:22:20 | call to getBox1 | AST only |
|
||||
| D.cpp:22:25:22:31 | call to getElem | AST only |
|
||||
| D.cpp:30:5:30:5 | b | AST only |
|
||||
| D.cpp:30:8:30:10 | box | AST only |
|
||||
| D.cpp:29:15:29:41 | new | IR only |
|
||||
| D.cpp:29:15:29:41 | new | IR only |
|
||||
| D.cpp:29:24:29:40 | 0 | IR only |
|
||||
| D.cpp:29:24:29:40 | new | IR only |
|
||||
| D.cpp:30:13:30:16 | elem | AST only |
|
||||
| D.cpp:31:14:31:14 | b | AST only |
|
||||
| D.cpp:37:5:37:5 | b | AST only |
|
||||
| D.cpp:37:8:37:10 | box | AST only |
|
||||
| D.cpp:37:21:37:21 | e | AST only |
|
||||
| D.cpp:38:14:38:14 | b | AST only |
|
||||
| D.cpp:44:5:44:5 | b | AST only |
|
||||
| D.cpp:44:8:44:14 | call to getBox1 | AST only |
|
||||
| D.cpp:36:15:36:41 | new | IR only |
|
||||
| D.cpp:36:15:36:41 | new | IR only |
|
||||
| D.cpp:36:24:36:40 | 0 | IR only |
|
||||
| D.cpp:36:24:36:40 | new | IR only |
|
||||
| D.cpp:43:15:43:41 | new | IR only |
|
||||
| D.cpp:43:15:43:41 | new | IR only |
|
||||
| D.cpp:43:24:43:40 | 0 | IR only |
|
||||
| D.cpp:43:24:43:40 | new | IR only |
|
||||
| D.cpp:44:19:44:22 | elem | AST only |
|
||||
| D.cpp:45:14:45:14 | b | AST only |
|
||||
| D.cpp:51:5:51:5 | b | AST only |
|
||||
| D.cpp:51:8:51:14 | call to getBox1 | AST only |
|
||||
| D.cpp:51:27:51:27 | e | AST only |
|
||||
| D.cpp:52:14:52:14 | b | AST only |
|
||||
| D.cpp:50:15:50:41 | new | IR only |
|
||||
| D.cpp:50:15:50:41 | new | IR only |
|
||||
| D.cpp:50:24:50:40 | 0 | IR only |
|
||||
| D.cpp:50:24:50:40 | new | IR only |
|
||||
| D.cpp:57:5:57:12 | boxfield | AST only |
|
||||
| D.cpp:58:5:58:12 | boxfield | AST only |
|
||||
| D.cpp:58:5:58:12 | this | AST only |
|
||||
| D.cpp:58:15:58:17 | box | AST only |
|
||||
| D.cpp:57:16:57:42 | new | IR only |
|
||||
| D.cpp:57:16:57:42 | new | IR only |
|
||||
| D.cpp:57:25:57:41 | 0 | IR only |
|
||||
| D.cpp:57:25:57:41 | new | IR only |
|
||||
| D.cpp:58:20:58:23 | elem | AST only |
|
||||
| D.cpp:59:5:59:7 | this | AST only |
|
||||
| D.cpp:64:10:64:17 | boxfield | AST only |
|
||||
| D.cpp:64:10:64:17 | this | AST only |
|
||||
| D.cpp:64:20:64:22 | box | AST only |
|
||||
| D.cpp:64:25:64:28 | elem | AST only |
|
||||
| E.cpp:21:10:21:10 | p | AST only |
|
||||
| E.cpp:21:13:21:16 | data | AST only |
|
||||
| E.cpp:21:18:21:23 | buffer | AST only |
|
||||
| E.cpp:28:21:28:23 | raw | AST only |
|
||||
| E.cpp:29:21:29:21 | b | AST only |
|
||||
| E.cpp:29:24:29:29 | buffer | AST only |
|
||||
| E.cpp:30:21:30:21 | p | AST only |
|
||||
| E.cpp:30:23:30:26 | data | AST only |
|
||||
| E.cpp:30:28:30:33 | buffer | AST only |
|
||||
| E.cpp:31:10:31:12 | raw | AST only |
|
||||
| E.cpp:32:10:32:10 | b | AST only |
|
||||
| E.cpp:32:13:32:18 | buffer | AST only |
|
||||
| E.cpp:33:18:33:19 | & ... | AST only |
|
||||
| aliasing.cpp:9:6:9:7 | m1 | AST only |
|
||||
| aliasing.cpp:13:5:13:6 | m1 | AST only |
|
||||
| aliasing.cpp:17:5:17:6 | m1 | AST only |
|
||||
| aliasing.cpp:25:17:25:19 | & ... | AST only |
|
||||
| aliasing.cpp:26:19:26:20 | s2 | AST only |
|
||||
| aliasing.cpp:37:8:37:9 | m1 | AST only |
|
||||
| aliasing.cpp:42:6:42:7 | m1 | AST only |
|
||||
| aliasing.cpp:49:9:49:10 | m1 | AST only |
|
||||
|
@ -155,291 +96,52 @@
|
|||
| aliasing.cpp:72:5:72:6 | m1 | AST only |
|
||||
| aliasing.cpp:79:6:79:7 | m1 | AST only |
|
||||
| aliasing.cpp:86:5:86:6 | m1 | AST only |
|
||||
| aliasing.cpp:92:3:92:3 | w | AST only |
|
||||
| aliasing.cpp:92:7:92:8 | m1 | AST only |
|
||||
| aliasing.cpp:98:5:98:6 | m1 | AST only |
|
||||
| aliasing.cpp:106:3:106:5 | * ... | AST only |
|
||||
| aliasing.cpp:111:15:111:19 | & ... | AST only |
|
||||
| aliasing.cpp:121:15:121:16 | xs | AST only |
|
||||
| aliasing.cpp:126:15:126:20 | ... - ... | AST only |
|
||||
| aliasing.cpp:131:15:131:16 | xs | AST only |
|
||||
| aliasing.cpp:136:15:136:17 | + ... | AST only |
|
||||
| aliasing.cpp:141:15:141:15 | s | AST only |
|
||||
| aliasing.cpp:141:17:141:20 | data | AST only |
|
||||
| aliasing.cpp:147:15:147:22 | & ... | AST only |
|
||||
| aliasing.cpp:158:15:158:15 | s | AST only |
|
||||
| aliasing.cpp:158:17:158:20 | data | AST only |
|
||||
| aliasing.cpp:164:15:164:15 | s | AST only |
|
||||
| aliasing.cpp:164:17:164:20 | data | AST only |
|
||||
| aliasing.cpp:175:15:175:22 | & ... | AST only |
|
||||
| aliasing.cpp:175:16:175:17 | s2 | AST only |
|
||||
| aliasing.cpp:181:15:181:22 | & ... | AST only |
|
||||
| aliasing.cpp:181:16:181:17 | s2 | AST only |
|
||||
| aliasing.cpp:187:15:187:22 | & ... | AST only |
|
||||
| aliasing.cpp:187:16:187:17 | s2 | AST only |
|
||||
| aliasing.cpp:194:15:194:22 | & ... | AST only |
|
||||
| aliasing.cpp:194:16:194:17 | s2 | AST only |
|
||||
| aliasing.cpp:200:15:200:24 | & ... | AST only |
|
||||
| aliasing.cpp:200:16:200:18 | ps2 | AST only |
|
||||
| aliasing.cpp:205:15:205:24 | & ... | AST only |
|
||||
| aliasing.cpp:205:16:205:18 | ps2 | AST only |
|
||||
| arrays.cpp:6:3:6:8 | access to array | AST only |
|
||||
| arrays.cpp:6:3:6:23 | arr | IR only |
|
||||
| arrays.cpp:7:3:7:6 | access to array | IR only |
|
||||
| arrays.cpp:8:3:8:6 | access to array | IR only |
|
||||
| arrays.cpp:9:3:9:6 | * ... | IR only |
|
||||
| arrays.cpp:10:3:10:6 | * ... | IR only |
|
||||
| arrays.cpp:15:3:15:10 | * ... | AST only |
|
||||
| arrays.cpp:36:3:36:3 | o | AST only |
|
||||
| arrays.cpp:36:5:36:10 | nested | AST only |
|
||||
| arrays.cpp:16:3:16:6 | access to array | IR only |
|
||||
| arrays.cpp:17:3:17:6 | access to array | IR only |
|
||||
| arrays.cpp:36:19:36:22 | data | AST only |
|
||||
| arrays.cpp:37:8:37:8 | o | AST only |
|
||||
| arrays.cpp:37:8:37:22 | access to array | AST only |
|
||||
| arrays.cpp:37:10:37:15 | nested | AST only |
|
||||
| arrays.cpp:37:24:37:27 | data | AST only |
|
||||
| arrays.cpp:38:8:38:8 | o | AST only |
|
||||
| arrays.cpp:38:8:38:22 | access to array | AST only |
|
||||
| arrays.cpp:38:10:38:15 | nested | AST only |
|
||||
| arrays.cpp:38:24:38:27 | data | AST only |
|
||||
| arrays.cpp:42:3:42:3 | o | AST only |
|
||||
| arrays.cpp:42:3:42:20 | access to array | AST only |
|
||||
| arrays.cpp:42:5:42:12 | indirect | AST only |
|
||||
| arrays.cpp:42:22:42:25 | data | AST only |
|
||||
| arrays.cpp:43:8:43:8 | o | AST only |
|
||||
| arrays.cpp:43:8:43:25 | access to array | AST only |
|
||||
| arrays.cpp:43:10:43:17 | indirect | AST only |
|
||||
| arrays.cpp:43:27:43:30 | data | AST only |
|
||||
| arrays.cpp:44:8:44:8 | o | AST only |
|
||||
| arrays.cpp:44:8:44:25 | access to array | AST only |
|
||||
| arrays.cpp:44:10:44:17 | indirect | AST only |
|
||||
| arrays.cpp:44:27:44:30 | data | AST only |
|
||||
| arrays.cpp:48:3:48:3 | o | AST only |
|
||||
| arrays.cpp:48:3:48:20 | access to array | AST only |
|
||||
| arrays.cpp:48:5:48:12 | indirect | AST only |
|
||||
| arrays.cpp:48:22:48:25 | data | AST only |
|
||||
| arrays.cpp:49:8:49:8 | o | AST only |
|
||||
| arrays.cpp:49:8:49:25 | access to array | AST only |
|
||||
| arrays.cpp:49:10:49:17 | indirect | AST only |
|
||||
| arrays.cpp:49:27:49:30 | data | AST only |
|
||||
| arrays.cpp:50:8:50:8 | o | AST only |
|
||||
| arrays.cpp:50:8:50:25 | access to array | AST only |
|
||||
| arrays.cpp:50:10:50:17 | indirect | AST only |
|
||||
| arrays.cpp:50:27:50:30 | data | AST only |
|
||||
| by_reference.cpp:12:8:12:8 | a | AST only |
|
||||
| by_reference.cpp:16:11:16:11 | a | AST only |
|
||||
| by_reference.cpp:20:5:20:8 | this | AST only |
|
||||
| by_reference.cpp:20:23:20:27 | value | AST only |
|
||||
| by_reference.cpp:24:19:24:22 | this | AST only |
|
||||
| by_reference.cpp:24:25:24:29 | value | AST only |
|
||||
| by_reference.cpp:40:12:40:15 | this | AST only |
|
||||
| by_reference.cpp:50:3:50:3 | s | AST only |
|
||||
| by_reference.cpp:50:17:50:26 | call to user_input | AST only |
|
||||
| by_reference.cpp:51:8:51:8 | s | AST only |
|
||||
| by_reference.cpp:51:10:51:20 | call to getDirectly | AST only |
|
||||
| by_reference.cpp:56:3:56:3 | s | AST only |
|
||||
| by_reference.cpp:56:19:56:28 | call to user_input | AST only |
|
||||
| by_reference.cpp:57:8:57:8 | s | AST only |
|
||||
| by_reference.cpp:57:10:57:22 | call to getIndirectly | AST only |
|
||||
| by_reference.cpp:62:3:62:3 | s | AST only |
|
||||
| by_reference.cpp:62:25:62:34 | call to user_input | AST only |
|
||||
| by_reference.cpp:63:8:63:8 | s | AST only |
|
||||
| by_reference.cpp:63:10:63:28 | call to getThroughNonMember | AST only |
|
||||
| by_reference.cpp:68:17:68:18 | & ... | AST only |
|
||||
| by_reference.cpp:68:21:68:30 | call to user_input | AST only |
|
||||
| by_reference.cpp:69:8:69:20 | call to nonMemberGetA | AST only |
|
||||
| by_reference.cpp:84:10:84:10 | a | AST only |
|
||||
| by_reference.cpp:88:9:88:9 | a | AST only |
|
||||
| by_reference.cpp:92:3:92:5 | * ... | AST only |
|
||||
| by_reference.cpp:96:3:96:4 | pa | AST only |
|
||||
| by_reference.cpp:102:21:102:39 | & ... | AST only |
|
||||
| by_reference.cpp:103:21:103:25 | outer | AST only |
|
||||
| by_reference.cpp:103:27:103:35 | inner_ptr | AST only |
|
||||
| by_reference.cpp:104:15:104:22 | & ... | AST only |
|
||||
| by_reference.cpp:106:21:106:41 | & ... | AST only |
|
||||
| by_reference.cpp:107:21:107:26 | pouter | AST only |
|
||||
| by_reference.cpp:107:29:107:37 | inner_ptr | AST only |
|
||||
| by_reference.cpp:108:15:108:24 | & ... | AST only |
|
||||
| by_reference.cpp:110:8:110:12 | outer | AST only |
|
||||
| by_reference.cpp:110:14:110:25 | inner_nested | AST only |
|
||||
| by_reference.cpp:110:27:110:27 | a | AST only |
|
||||
| by_reference.cpp:111:8:111:12 | outer | AST only |
|
||||
| by_reference.cpp:111:14:111:22 | inner_ptr | AST only |
|
||||
| by_reference.cpp:111:25:111:25 | a | AST only |
|
||||
| by_reference.cpp:112:8:112:12 | outer | AST only |
|
||||
| by_reference.cpp:112:14:112:14 | a | AST only |
|
||||
| by_reference.cpp:114:8:114:13 | pouter | AST only |
|
||||
| by_reference.cpp:114:16:114:27 | inner_nested | AST only |
|
||||
| by_reference.cpp:114:29:114:29 | a | AST only |
|
||||
| by_reference.cpp:115:8:115:13 | pouter | AST only |
|
||||
| by_reference.cpp:115:16:115:24 | inner_ptr | AST only |
|
||||
| by_reference.cpp:115:27:115:27 | a | AST only |
|
||||
| by_reference.cpp:116:8:116:13 | pouter | AST only |
|
||||
| by_reference.cpp:116:16:116:16 | a | AST only |
|
||||
| by_reference.cpp:122:27:122:38 | inner_nested | AST only |
|
||||
| by_reference.cpp:123:21:123:36 | * ... | AST only |
|
||||
| by_reference.cpp:123:22:123:26 | outer | AST only |
|
||||
| by_reference.cpp:124:21:124:21 | a | AST only |
|
||||
| by_reference.cpp:126:29:126:40 | inner_nested | AST only |
|
||||
| by_reference.cpp:127:21:127:38 | * ... | AST only |
|
||||
| by_reference.cpp:127:22:127:27 | pouter | AST only |
|
||||
| by_reference.cpp:128:23:128:23 | a | AST only |
|
||||
| by_reference.cpp:130:8:130:12 | outer | AST only |
|
||||
| by_reference.cpp:130:14:130:25 | inner_nested | AST only |
|
||||
| by_reference.cpp:130:27:130:27 | a | AST only |
|
||||
| by_reference.cpp:131:8:131:12 | outer | AST only |
|
||||
| by_reference.cpp:131:14:131:22 | inner_ptr | AST only |
|
||||
| by_reference.cpp:131:25:131:25 | a | AST only |
|
||||
| by_reference.cpp:132:8:132:12 | outer | AST only |
|
||||
| by_reference.cpp:132:14:132:14 | a | AST only |
|
||||
| by_reference.cpp:134:8:134:13 | pouter | AST only |
|
||||
| by_reference.cpp:134:16:134:27 | inner_nested | AST only |
|
||||
| by_reference.cpp:134:29:134:29 | a | AST only |
|
||||
| by_reference.cpp:135:8:135:13 | pouter | AST only |
|
||||
| by_reference.cpp:135:16:135:24 | inner_ptr | AST only |
|
||||
| by_reference.cpp:135:27:135:27 | a | AST only |
|
||||
| by_reference.cpp:136:8:136:13 | pouter | AST only |
|
||||
| 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:42:8:42:8 | b | AST only |
|
||||
| complex.cpp:42:16:42:16 | f | AST only |
|
||||
| complex.cpp:43:8:43:8 | b | AST only |
|
||||
| complex.cpp:43:16:43:16 | f | AST only |
|
||||
| complex.cpp:53:3:53:4 | b1 | AST only |
|
||||
| complex.cpp:53:12:53:12 | f | AST only |
|
||||
| complex.cpp:54:3:54:4 | b2 | AST only |
|
||||
| complex.cpp:54:12:54:12 | f | AST only |
|
||||
| complex.cpp:55:3:55:4 | b3 | AST only |
|
||||
| complex.cpp:55:12:55:12 | f | AST only |
|
||||
| complex.cpp:56:3:56:4 | b3 | 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 |
|
||||
| conflated.cpp:10:3:10:7 | * ... | AST only |
|
||||
| conflated.cpp:10:4:10:5 | ra | AST only |
|
||||
| conflated.cpp:19:19:19:21 | raw | AST only |
|
||||
| conflated.cpp:20:8:20:10 | raw | AST only |
|
||||
| conflated.cpp:29:3:29:4 | pa | AST only |
|
||||
| conflated.cpp:29:7:29:7 | x | AST only |
|
||||
| conflated.cpp:36:3:36:4 | pa | AST only |
|
||||
| conflated.cpp:36:7:36:7 | x | AST only |
|
||||
| conflated.cpp:53:7:53:10 | next | AST only |
|
||||
| conflated.cpp:54:3:54:4 | ll | AST only |
|
||||
| conflated.cpp:54:7:54:10 | next | AST only |
|
||||
| conflated.cpp:54:13:54:13 | y | AST only |
|
||||
| conflated.cpp:59:35:59:38 | next | AST only |
|
||||
| conflated.cpp:60:3:60:4 | ll | AST only |
|
||||
| conflated.cpp:60:7:60:10 | next | AST only |
|
||||
| conflated.cpp:59:20:59:39 | new | IR only |
|
||||
| conflated.cpp:60:13:60:13 | y | 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 |
|
||||
| constructors.cpp:29:10:29:10 | f | AST only |
|
||||
| constructors.cpp:40:9:40:9 | f | AST only |
|
||||
| constructors.cpp:43:9:43:9 | g | AST only |
|
||||
| constructors.cpp:46:9:46:9 | h | AST only |
|
||||
| constructors.cpp:49:9:49:9 | i | AST only |
|
||||
| qualifiers.cpp:9:36:9:36 | a | AST only |
|
||||
| qualifiers.cpp:12:56:12:56 | a | AST only |
|
||||
| qualifiers.cpp:13:57:13:57 | a | AST only |
|
||||
| qualifiers.cpp:22:5:22:9 | outer | AST only |
|
||||
| qualifiers.cpp:22:11:22:18 | call to getInner | AST only |
|
||||
| qualifiers.cpp:22:23:22:23 | a | AST only |
|
||||
| qualifiers.cpp:23:10:23:14 | outer | AST only |
|
||||
| qualifiers.cpp:23:16:23:20 | inner | AST only |
|
||||
| qualifiers.cpp:23:23:23:23 | a | AST only |
|
||||
| qualifiers.cpp:27:5:27:9 | outer | AST only |
|
||||
| qualifiers.cpp:27:11:27:18 | call to getInner | AST only |
|
||||
| qualifiers.cpp:27:28:27:37 | call to user_input | AST only |
|
||||
| qualifiers.cpp:28:10:28:14 | outer | AST only |
|
||||
| qualifiers.cpp:28:16:28:20 | inner | AST only |
|
||||
| qualifiers.cpp:28:23:28:23 | a | AST only |
|
||||
| qualifiers.cpp:32:17:32:21 | outer | AST only |
|
||||
| qualifiers.cpp:32:23:32:30 | call to getInner | AST only |
|
||||
| qualifiers.cpp:32:35:32:44 | call to user_input | AST only |
|
||||
| qualifiers.cpp:33:10:33:14 | outer | AST only |
|
||||
| qualifiers.cpp:33:16:33:20 | inner | AST only |
|
||||
| qualifiers.cpp:33:23:33:23 | a | AST only |
|
||||
| qualifiers.cpp:37:19:37:35 | * ... | AST only |
|
||||
| qualifiers.cpp:37:20:37:24 | outer | AST only |
|
||||
| qualifiers.cpp:37:38:37:47 | call to user_input | AST only |
|
||||
| qualifiers.cpp:38:10:38:14 | outer | AST only |
|
||||
| qualifiers.cpp:38:16:38:20 | inner | AST only |
|
||||
| qualifiers.cpp:38:23:38:23 | a | AST only |
|
||||
| qualifiers.cpp:42:6:42:22 | * ... | AST only |
|
||||
| qualifiers.cpp:42:7:42:11 | outer | AST only |
|
||||
| qualifiers.cpp:42:25:42:25 | a | AST only |
|
||||
| qualifiers.cpp:43:10:43:14 | outer | AST only |
|
||||
| qualifiers.cpp:43:16:43:20 | inner | AST only |
|
||||
| qualifiers.cpp:43:23:43:23 | a | AST only |
|
||||
| qualifiers.cpp:47:6:47:11 | & ... | AST only |
|
||||
| qualifiers.cpp:47:15:47:22 | call to getInner | AST only |
|
||||
| qualifiers.cpp:47:27:47:27 | a | AST only |
|
||||
| qualifiers.cpp:48:10:48:14 | outer | AST only |
|
||||
| qualifiers.cpp:48:16:48:20 | inner | AST only |
|
||||
| qualifiers.cpp:48:23:48:23 | a | AST only |
|
||||
| realistic.cpp:26:5:26:10 | offset | AST only |
|
||||
| realistic.cpp:42:20:42:20 | o | AST only |
|
||||
| realistic.cpp:49:9:49:11 | foo | AST only |
|
||||
| realistic.cpp:49:20:49:22 | baz | AST only |
|
||||
| realistic.cpp:53:9:53:11 | foo | AST only |
|
||||
| realistic.cpp:53:9:53:18 | access to array | AST only |
|
||||
| realistic.cpp:53:20:53:22 | baz | AST only |
|
||||
| realistic.cpp:53:25:53:33 | userInput | AST only |
|
||||
| realistic.cpp:53:35:53:43 | bufferLen | AST only |
|
||||
| realistic.cpp:54:16:54:18 | foo | AST only |
|
||||
| realistic.cpp:54:16:54:25 | access to array | AST only |
|
||||
| realistic.cpp:54:27:54:29 | baz | AST only |
|
||||
| realistic.cpp:54:32:54:40 | userInput | AST only |
|
||||
| realistic.cpp:54:42:54:47 | buffer | AST only |
|
||||
| realistic.cpp:60:16:60:18 | dst | AST only |
|
||||
| realistic.cpp:61:21:61:23 | foo | AST only |
|
||||
| realistic.cpp:61:21:61:30 | access to array | AST only |
|
||||
| realistic.cpp:61:32:61:34 | baz | AST only |
|
||||
| realistic.cpp:61:37:61:45 | userInput | AST only |
|
||||
| realistic.cpp:61:47:61:55 | bufferLen | AST only |
|
||||
| realistic.cpp:65:21:65:23 | foo | AST only |
|
||||
| realistic.cpp:65:21:65:30 | access to array | AST only |
|
||||
| realistic.cpp:65:32:65:34 | baz | AST only |
|
||||
| realistic.cpp:65:37:65:45 | userInput | AST only |
|
||||
| realistic.cpp:65:47:65:52 | buffer | AST only |
|
||||
| realistic.cpp:66:21:66:23 | dst | AST only |
|
||||
| simple.cpp:20:24:20:25 | a_ | AST only |
|
||||
| simple.cpp:21:24:21:25 | b_ | AST only |
|
||||
| simple.cpp:28:10:28:10 | f | AST only |
|
||||
| simple.cpp:29:10:29:10 | f | AST only |
|
||||
| simple.cpp:39:5:39:5 | f | AST only |
|
||||
| simple.cpp:40:5:40:5 | g | AST only |
|
||||
| simple.cpp:41:5:41:5 | h | AST only |
|
||||
| simple.cpp:42:5:42:5 | h | AST only |
|
||||
| simple.cpp:45:9:45:9 | f | AST only |
|
||||
| simple.cpp:48:9:48:9 | g | AST only |
|
||||
| simple.cpp:51:9:51:9 | h | AST only |
|
||||
| simple.cpp:54:9:54:9 | i | AST only |
|
||||
| simple.cpp:65:7:65:7 | i | AST only |
|
||||
| simple.cpp:83:9:83:10 | this | AST only |
|
||||
| simple.cpp:83:12:83:13 | f1 | AST only |
|
||||
| simple.cpp:84:14:84:20 | this | AST only |
|
||||
| simple.cpp:92:7:92:7 | i | AST only |
|
||||
| struct_init.c:15:8:15:9 | ab | AST only |
|
||||
| struct_init.c:15:12:15:12 | a | AST only |
|
||||
| struct_init.c:16:8:16:9 | ab | AST only |
|
||||
| struct_init.c:16:12:16:12 | b | AST only |
|
||||
| struct_init.c:22:8:22:9 | ab | AST only |
|
||||
| struct_init.c:22:11:22:11 | a | AST only |
|
||||
| struct_init.c:23:8:23:9 | ab | AST only |
|
||||
| struct_init.c:23:11:23:11 | b | AST only |
|
||||
| struct_init.c:24:10:24:12 | & ... | AST only |
|
||||
| struct_init.c:31:8:31:12 | outer | AST only |
|
||||
| struct_init.c:31:14:31:21 | nestedAB | AST only |
|
||||
| struct_init.c:31:23:31:23 | a | AST only |
|
||||
| struct_init.c:32:8:32:12 | outer | AST only |
|
||||
| struct_init.c:32:14:32:21 | nestedAB | AST only |
|
||||
| struct_init.c:32:23:32:23 | b | AST only |
|
||||
| struct_init.c:33:8:33:12 | outer | AST only |
|
||||
| struct_init.c:33:14:33:22 | pointerAB | AST only |
|
||||
| struct_init.c:33:25:33:25 | a | AST only |
|
||||
| struct_init.c:34:8:34:12 | outer | AST only |
|
||||
| struct_init.c:34:14:34:22 | pointerAB | AST only |
|
||||
| struct_init.c:34:25:34:25 | b | AST only |
|
||||
| struct_init.c:36:10:36:24 | & ... | AST only |
|
||||
| struct_init.c:46:10:46:14 | outer | AST only |
|
||||
| struct_init.c:46:16:46:24 | pointerAB | AST only |
|
||||
|
|
|
@ -1,22 +1,208 @@
|
|||
| A.cpp:25:7:25:10 | this |
|
||||
| A.cpp:27:22:27:25 | this |
|
||||
| A.cpp:31:14:31:21 | new |
|
||||
| A.cpp:31:20:31:20 | c |
|
||||
| A.cpp:40:5:40:6 | cc |
|
||||
| A.cpp:40:15:40:21 | 0 |
|
||||
| A.cpp:41:5:41:6 | ct |
|
||||
| A.cpp:41:15:41:21 | new |
|
||||
| A.cpp:42:10:42:12 | & ... |
|
||||
| A.cpp:43:10:43:12 | & ... |
|
||||
| A.cpp:47:12:47:18 | new |
|
||||
| A.cpp:48:20:48:20 | c |
|
||||
| A.cpp:49:10:49:10 | b |
|
||||
| A.cpp:49:13:49:13 | c |
|
||||
| A.cpp:54:12:54:18 | new |
|
||||
| A.cpp:55:5:55:5 | b |
|
||||
| A.cpp:55:12:55:19 | new |
|
||||
| A.cpp:56:10:56:10 | b |
|
||||
| A.cpp:56:13:56:15 | call to get |
|
||||
| A.cpp:57:11:57:24 | new |
|
||||
| A.cpp:57:17:57:23 | new |
|
||||
| A.cpp:57:28:57:30 | call to get |
|
||||
| A.cpp:62:13:62:19 | new |
|
||||
| A.cpp:64:10:64:15 | this |
|
||||
| A.cpp:64:17:64:18 | b1 |
|
||||
| A.cpp:64:21:64:28 | new |
|
||||
| A.cpp:65:10:65:11 | b1 |
|
||||
| A.cpp:65:14:65:14 | c |
|
||||
| A.cpp:66:10:66:11 | b2 |
|
||||
| A.cpp:66:14:66:14 | c |
|
||||
| A.cpp:71:13:71:19 | new |
|
||||
| A.cpp:73:10:73:19 | this |
|
||||
| A.cpp:73:21:73:22 | b1 |
|
||||
| A.cpp:73:25:73:32 | new |
|
||||
| A.cpp:74:10:74:11 | b1 |
|
||||
| A.cpp:74:14:74:14 | c |
|
||||
| A.cpp:75:10:75:11 | b2 |
|
||||
| A.cpp:75:14:75:14 | c |
|
||||
| A.cpp:81:10:81:15 | this |
|
||||
| A.cpp:81:17:81:18 | b1 |
|
||||
| A.cpp:81:21:81:21 | c |
|
||||
| A.cpp:82:12:82:12 | this |
|
||||
| A.cpp:87:9:87:9 | this |
|
||||
| A.cpp:89:15:89:21 | new |
|
||||
| A.cpp:90:7:90:8 | b2 |
|
||||
| A.cpp:90:15:90:15 | c |
|
||||
| A.cpp:99:14:99:21 | new |
|
||||
| A.cpp:100:5:100:6 | c1 |
|
||||
| A.cpp:101:5:101:6 | this |
|
||||
| A.cpp:101:8:101:9 | c1 |
|
||||
| A.cpp:107:12:107:13 | c1 |
|
||||
| A.cpp:107:16:107:16 | a |
|
||||
| A.cpp:116:12:116:19 | new |
|
||||
| A.cpp:120:12:120:13 | c1 |
|
||||
| A.cpp:120:16:120:16 | a |
|
||||
| A.cpp:126:5:126:5 | b |
|
||||
| A.cpp:126:12:126:18 | new |
|
||||
| A.cpp:130:12:130:18 | new |
|
||||
| A.cpp:131:5:131:6 | this |
|
||||
| A.cpp:131:8:131:8 | b |
|
||||
| A.cpp:132:10:132:10 | b |
|
||||
| A.cpp:132:13:132:13 | c |
|
||||
| A.cpp:142:7:142:7 | b |
|
||||
| A.cpp:142:14:142:20 | new |
|
||||
| A.cpp:143:7:143:10 | this |
|
||||
| A.cpp:143:25:143:31 | new |
|
||||
| A.cpp:150:12:150:18 | new |
|
||||
| A.cpp:151:12:151:24 | new |
|
||||
| A.cpp:151:18:151:18 | b |
|
||||
| A.cpp:151:21:151:21 | this |
|
||||
| A.cpp:152:10:152:10 | d |
|
||||
| A.cpp:152:13:152:13 | b |
|
||||
| A.cpp:153:10:153:10 | d |
|
||||
| A.cpp:153:13:153:13 | b |
|
||||
| A.cpp:153:16:153:16 | c |
|
||||
| A.cpp:154:10:154:10 | b |
|
||||
| A.cpp:154:13:154:13 | c |
|
||||
| A.cpp:159:12:159:18 | new |
|
||||
| A.cpp:160:18:160:60 | new |
|
||||
| A.cpp:160:29:160:29 | b |
|
||||
| A.cpp:160:32:160:59 | new |
|
||||
| A.cpp:160:43:160:49 | 0 |
|
||||
| A.cpp:160:52:160:58 | 0 |
|
||||
| A.cpp:161:18:161:40 | new |
|
||||
| A.cpp:161:29:161:35 | 0 |
|
||||
| A.cpp:161:38:161:39 | l1 |
|
||||
| A.cpp:162:18:162:40 | new |
|
||||
| A.cpp:162:29:162:35 | 0 |
|
||||
| A.cpp:162:38:162:39 | l2 |
|
||||
| A.cpp:163:10:163:11 | l3 |
|
||||
| A.cpp:163:14:163:17 | head |
|
||||
| A.cpp:164:10:164:11 | l3 |
|
||||
| A.cpp:164:14:164:17 | next |
|
||||
| A.cpp:164:20:164:23 | head |
|
||||
| A.cpp:165:10:165:11 | l3 |
|
||||
| A.cpp:165:14:165:17 | next |
|
||||
| A.cpp:165:20:165:23 | next |
|
||||
| A.cpp:165:26:165:29 | head |
|
||||
| A.cpp:166:10:166:11 | l3 |
|
||||
| A.cpp:166:14:166:17 | next |
|
||||
| A.cpp:166:20:166:23 | next |
|
||||
| A.cpp:166:26:166:29 | next |
|
||||
| A.cpp:166:32:166:35 | head |
|
||||
| A.cpp:169:12:169:12 | l |
|
||||
| A.cpp:169:15:169:18 | head |
|
||||
| A.cpp:183:7:183:10 | this |
|
||||
| A.cpp:184:7:184:10 | this |
|
||||
| B.cpp:7:16:7:35 | new |
|
||||
| B.cpp:7:25:7:25 | e |
|
||||
| B.cpp:7:28:7:34 | 0 |
|
||||
| B.cpp:8:16:8:27 | new |
|
||||
| B.cpp:8:25:8:26 | b1 |
|
||||
| B.cpp:9:10:9:11 | b2 |
|
||||
| B.cpp:9:14:9:17 | box1 |
|
||||
| B.cpp:9:20:9:24 | elem1 |
|
||||
| B.cpp:10:10:10:11 | b2 |
|
||||
| B.cpp:10:14:10:17 | box1 |
|
||||
| B.cpp:10:20:10:24 | elem2 |
|
||||
| B.cpp:16:16:16:38 | new |
|
||||
| B.cpp:16:28:16:34 | 0 |
|
||||
| B.cpp:16:37:16:37 | e |
|
||||
| B.cpp:17:16:17:27 | new |
|
||||
| B.cpp:17:25:17:26 | b1 |
|
||||
| B.cpp:18:10:18:11 | b2 |
|
||||
| B.cpp:18:14:18:17 | box1 |
|
||||
| B.cpp:18:20:18:24 | elem1 |
|
||||
| B.cpp:19:10:19:11 | b2 |
|
||||
| B.cpp:19:14:19:17 | box1 |
|
||||
| B.cpp:19:20:19:24 | elem2 |
|
||||
| B.cpp:35:7:35:10 | this |
|
||||
| B.cpp:36:7:36:10 | this |
|
||||
| B.cpp:46:7:46:10 | this |
|
||||
| C.cpp:18:12:18:18 | new |
|
||||
| C.cpp:19:5:19:5 | c |
|
||||
| C.cpp:24:5:24:8 | this |
|
||||
| C.cpp:29:10:29:11 | s1 |
|
||||
| C.cpp:29:10:29:11 | this |
|
||||
| C.cpp:30:10:30:11 | s2 |
|
||||
| C.cpp:30:10:30:11 | this |
|
||||
| C.cpp:31:10:31:11 | s3 |
|
||||
| C.cpp:31:10:31:11 | this |
|
||||
| C.cpp:32:10:32:11 | s4 |
|
||||
| D.cpp:9:21:9:24 | this |
|
||||
| D.cpp:11:29:11:32 | this |
|
||||
| D.cpp:16:21:16:23 | this |
|
||||
| D.cpp:18:29:18:31 | this |
|
||||
| D.cpp:22:10:22:11 | b2 |
|
||||
| D.cpp:22:14:22:20 | call to getBox1 |
|
||||
| D.cpp:22:25:22:31 | call to getElem |
|
||||
| D.cpp:29:15:29:41 | new |
|
||||
| D.cpp:29:24:29:40 | new |
|
||||
| D.cpp:29:33:29:39 | 0 |
|
||||
| D.cpp:30:5:30:5 | b |
|
||||
| D.cpp:30:8:30:10 | box |
|
||||
| D.cpp:31:14:31:14 | b |
|
||||
| D.cpp:36:15:36:41 | new |
|
||||
| D.cpp:36:24:36:40 | new |
|
||||
| D.cpp:36:33:36:39 | 0 |
|
||||
| D.cpp:37:5:37:5 | b |
|
||||
| D.cpp:37:8:37:10 | box |
|
||||
| D.cpp:37:21:37:21 | e |
|
||||
| D.cpp:38:14:38:14 | b |
|
||||
| D.cpp:43:15:43:41 | new |
|
||||
| D.cpp:43:24:43:40 | new |
|
||||
| D.cpp:43:33:43:39 | 0 |
|
||||
| D.cpp:44:5:44:5 | b |
|
||||
| D.cpp:44:8:44:14 | call to getBox1 |
|
||||
| D.cpp:45:14:45:14 | b |
|
||||
| D.cpp:50:15:50:41 | new |
|
||||
| D.cpp:50:24:50:40 | new |
|
||||
| D.cpp:50:33:50:39 | 0 |
|
||||
| D.cpp:51:5:51:5 | b |
|
||||
| D.cpp:51:8:51:14 | call to getBox1 |
|
||||
| D.cpp:51:27:51:27 | e |
|
||||
| D.cpp:52:14:52:14 | b |
|
||||
| D.cpp:57:5:57:12 | this |
|
||||
| D.cpp:57:16:57:42 | new |
|
||||
| D.cpp:57:25:57:41 | new |
|
||||
| D.cpp:57:34:57:40 | 0 |
|
||||
| D.cpp:58:5:58:12 | boxfield |
|
||||
| D.cpp:58:5:58:12 | this |
|
||||
| D.cpp:58:15:58:17 | box |
|
||||
| D.cpp:59:5:59:7 | this |
|
||||
| D.cpp:64:10:64:17 | boxfield |
|
||||
| D.cpp:64:10:64:17 | this |
|
||||
| D.cpp:64:20:64:22 | box |
|
||||
| D.cpp:64:25:64:28 | elem |
|
||||
| E.cpp:21:10:21:10 | p |
|
||||
| E.cpp:21:13:21:16 | data |
|
||||
| E.cpp:21:18:21:23 | buffer |
|
||||
| E.cpp:28:21:28:23 | raw |
|
||||
| E.cpp:29:21:29:21 | b |
|
||||
| E.cpp:29:24:29:29 | buffer |
|
||||
| E.cpp:30:21:30:21 | p |
|
||||
| E.cpp:30:23:30:26 | data |
|
||||
| E.cpp:30:28:30:33 | buffer |
|
||||
| E.cpp:31:10:31:12 | raw |
|
||||
| E.cpp:32:10:32:10 | b |
|
||||
| E.cpp:32:13:32:18 | buffer |
|
||||
| E.cpp:33:18:33:19 | & ... |
|
||||
| aliasing.cpp:9:3:9:3 | s |
|
||||
| aliasing.cpp:13:3:13:3 | s |
|
||||
| aliasing.cpp:17:3:17:3 | s |
|
||||
| aliasing.cpp:25:17:25:19 | & ... |
|
||||
| aliasing.cpp:26:19:26:20 | s2 |
|
||||
| aliasing.cpp:37:3:37:6 | ref1 |
|
||||
| aliasing.cpp:42:3:42:4 | s2 |
|
||||
| aliasing.cpp:49:3:49:7 | copy1 |
|
||||
|
@ -25,48 +211,299 @@
|
|||
| aliasing.cpp:72:3:72:3 | s |
|
||||
| aliasing.cpp:79:3:79:3 | s |
|
||||
| aliasing.cpp:86:3:86:3 | s |
|
||||
| aliasing.cpp:92:3:92:3 | w |
|
||||
| aliasing.cpp:92:5:92:5 | s |
|
||||
| aliasing.cpp:98:3:98:3 | s |
|
||||
| aliasing.cpp:111:15:111:19 | & ... |
|
||||
| aliasing.cpp:111:16:111:16 | s |
|
||||
| aliasing.cpp:121:15:121:16 | xs |
|
||||
| aliasing.cpp:126:15:126:20 | ... - ... |
|
||||
| aliasing.cpp:131:15:131:16 | xs |
|
||||
| aliasing.cpp:136:15:136:17 | + ... |
|
||||
| aliasing.cpp:141:15:141:15 | s |
|
||||
| aliasing.cpp:141:17:141:20 | data |
|
||||
| aliasing.cpp:147:15:147:22 | & ... |
|
||||
| aliasing.cpp:147:16:147:19 | access to array |
|
||||
| aliasing.cpp:158:15:158:15 | s |
|
||||
| aliasing.cpp:158:17:158:20 | data |
|
||||
| aliasing.cpp:164:15:164:15 | s |
|
||||
| aliasing.cpp:164:17:164:20 | data |
|
||||
| aliasing.cpp:175:15:175:22 | & ... |
|
||||
| aliasing.cpp:175:16:175:17 | s2 |
|
||||
| aliasing.cpp:175:19:175:19 | s |
|
||||
| aliasing.cpp:181:15:181:22 | & ... |
|
||||
| aliasing.cpp:181:16:181:17 | s2 |
|
||||
| aliasing.cpp:181:19:181:19 | s |
|
||||
| aliasing.cpp:187:15:187:22 | & ... |
|
||||
| aliasing.cpp:187:16:187:17 | s2 |
|
||||
| aliasing.cpp:187:19:187:19 | s |
|
||||
| aliasing.cpp:194:15:194:22 | & ... |
|
||||
| aliasing.cpp:194:16:194:17 | s2 |
|
||||
| aliasing.cpp:194:19:194:19 | s |
|
||||
| aliasing.cpp:200:15:200:24 | & ... |
|
||||
| aliasing.cpp:200:16:200:18 | ps2 |
|
||||
| aliasing.cpp:200:21:200:21 | s |
|
||||
| aliasing.cpp:205:15:205:24 | & ... |
|
||||
| aliasing.cpp:205:16:205:18 | ps2 |
|
||||
| aliasing.cpp:205:21:205:21 | s |
|
||||
| arrays.cpp:6:3:6:5 | arr |
|
||||
| arrays.cpp:7:8:7:13 | access to array |
|
||||
| arrays.cpp:8:8:8:13 | access to array |
|
||||
| arrays.cpp:9:8:9:11 | * ... |
|
||||
| arrays.cpp:10:8:10:15 | * ... |
|
||||
| arrays.cpp:16:8:16:13 | access to array |
|
||||
| arrays.cpp:17:8:17:13 | access to array |
|
||||
| arrays.cpp:36:3:36:3 | o |
|
||||
| arrays.cpp:36:3:36:17 | access to array |
|
||||
| arrays.cpp:36:5:36:10 | nested |
|
||||
| arrays.cpp:37:8:37:8 | o |
|
||||
| arrays.cpp:37:8:37:22 | access to array |
|
||||
| arrays.cpp:37:10:37:15 | nested |
|
||||
| arrays.cpp:37:24:37:27 | data |
|
||||
| arrays.cpp:38:8:38:8 | o |
|
||||
| arrays.cpp:38:8:38:22 | access to array |
|
||||
| arrays.cpp:38:10:38:15 | nested |
|
||||
| arrays.cpp:38:24:38:27 | data |
|
||||
| arrays.cpp:42:3:42:3 | o |
|
||||
| arrays.cpp:42:3:42:20 | access to array |
|
||||
| arrays.cpp:42:5:42:12 | indirect |
|
||||
| arrays.cpp:43:8:43:8 | o |
|
||||
| arrays.cpp:43:8:43:25 | access to array |
|
||||
| arrays.cpp:43:10:43:17 | indirect |
|
||||
| arrays.cpp:43:27:43:30 | data |
|
||||
| arrays.cpp:44:8:44:8 | o |
|
||||
| arrays.cpp:44:8:44:25 | access to array |
|
||||
| arrays.cpp:44:10:44:17 | indirect |
|
||||
| arrays.cpp:44:27:44:30 | data |
|
||||
| arrays.cpp:48:3:48:3 | o |
|
||||
| arrays.cpp:48:3:48:20 | access to array |
|
||||
| arrays.cpp:48:5:48:12 | indirect |
|
||||
| arrays.cpp:49:8:49:8 | o |
|
||||
| arrays.cpp:49:8:49:25 | access to array |
|
||||
| arrays.cpp:49:10:49:17 | indirect |
|
||||
| arrays.cpp:49:27:49:30 | data |
|
||||
| arrays.cpp:50:8:50:8 | o |
|
||||
| arrays.cpp:50:8:50:25 | access to array |
|
||||
| arrays.cpp:50:10:50:17 | indirect |
|
||||
| arrays.cpp:50:27:50:30 | data |
|
||||
| by_reference.cpp:12:5:12:5 | s |
|
||||
| by_reference.cpp:16:5:16:8 | this |
|
||||
| by_reference.cpp:20:5:20:8 | this |
|
||||
| by_reference.cpp:20:23:20:27 | value |
|
||||
| by_reference.cpp:24:19:24:22 | this |
|
||||
| by_reference.cpp:24:25:24:29 | value |
|
||||
| by_reference.cpp:50:3:50:3 | s |
|
||||
| by_reference.cpp:50:17:50:26 | call to user_input |
|
||||
| by_reference.cpp:51:10:51:20 | call to getDirectly |
|
||||
| by_reference.cpp:56:3:56:3 | s |
|
||||
| by_reference.cpp:56:19:56:28 | call to user_input |
|
||||
| by_reference.cpp:57:10:57:22 | call to getIndirectly |
|
||||
| by_reference.cpp:62:3:62:3 | s |
|
||||
| by_reference.cpp:62:25:62:34 | call to user_input |
|
||||
| by_reference.cpp:63:10:63:28 | call to getThroughNonMember |
|
||||
| by_reference.cpp:68:17:68:18 | & ... |
|
||||
| by_reference.cpp:68:21:68:30 | call to user_input |
|
||||
| by_reference.cpp:69:8:69:20 | call to nonMemberGetA |
|
||||
| by_reference.cpp:84:3:84:7 | inner |
|
||||
| by_reference.cpp:88:3:88:7 | inner |
|
||||
| by_reference.cpp:102:21:102:39 | & ... |
|
||||
| by_reference.cpp:102:22:102:26 | outer |
|
||||
| by_reference.cpp:103:21:103:25 | outer |
|
||||
| by_reference.cpp:103:27:103:35 | inner_ptr |
|
||||
| by_reference.cpp:104:15:104:22 | & ... |
|
||||
| by_reference.cpp:104:16:104:20 | outer |
|
||||
| by_reference.cpp:106:21:106:41 | & ... |
|
||||
| by_reference.cpp:106:22:106:27 | pouter |
|
||||
| by_reference.cpp:107:21:107:26 | pouter |
|
||||
| by_reference.cpp:107:29:107:37 | inner_ptr |
|
||||
| by_reference.cpp:108:15:108:24 | & ... |
|
||||
| by_reference.cpp:108:16:108:21 | pouter |
|
||||
| by_reference.cpp:110:8:110:12 | outer |
|
||||
| by_reference.cpp:110:14:110:25 | inner_nested |
|
||||
| by_reference.cpp:110:27:110:27 | a |
|
||||
| by_reference.cpp:111:8:111:12 | outer |
|
||||
| by_reference.cpp:111:14:111:22 | inner_ptr |
|
||||
| by_reference.cpp:111:25:111:25 | a |
|
||||
| by_reference.cpp:112:8:112:12 | outer |
|
||||
| by_reference.cpp:112:14:112:14 | a |
|
||||
| by_reference.cpp:114:8:114:13 | pouter |
|
||||
| by_reference.cpp:114:16:114:27 | inner_nested |
|
||||
| by_reference.cpp:114:29:114:29 | a |
|
||||
| by_reference.cpp:115:8:115:13 | pouter |
|
||||
| by_reference.cpp:115:16:115:24 | inner_ptr |
|
||||
| by_reference.cpp:115:27:115:27 | a |
|
||||
| by_reference.cpp:116:8:116:13 | pouter |
|
||||
| by_reference.cpp:116:16:116:16 | a |
|
||||
| by_reference.cpp:122:21:122:25 | outer |
|
||||
| by_reference.cpp:122:27:122:38 | inner_nested |
|
||||
| by_reference.cpp:123:21:123:36 | * ... |
|
||||
| by_reference.cpp:123:22:123:26 | outer |
|
||||
| by_reference.cpp:124:15:124:19 | outer |
|
||||
| by_reference.cpp:124:21:124:21 | a |
|
||||
| by_reference.cpp:126:21:126:26 | pouter |
|
||||
| by_reference.cpp:126:29:126:40 | inner_nested |
|
||||
| by_reference.cpp:127:21:127:38 | * ... |
|
||||
| by_reference.cpp:127:22:127:27 | pouter |
|
||||
| by_reference.cpp:128:15:128:20 | pouter |
|
||||
| by_reference.cpp:128:23:128:23 | a |
|
||||
| by_reference.cpp:130:8:130:12 | outer |
|
||||
| by_reference.cpp:130:14:130:25 | inner_nested |
|
||||
| by_reference.cpp:130:27:130:27 | a |
|
||||
| by_reference.cpp:131:8:131:12 | outer |
|
||||
| by_reference.cpp:131:14:131:22 | inner_ptr |
|
||||
| by_reference.cpp:131:25:131:25 | a |
|
||||
| by_reference.cpp:132:8:132:12 | outer |
|
||||
| by_reference.cpp:132:14:132:14 | a |
|
||||
| by_reference.cpp:134:8:134:13 | pouter |
|
||||
| by_reference.cpp:134:16:134:27 | inner_nested |
|
||||
| by_reference.cpp:134:29:134:29 | a |
|
||||
| by_reference.cpp:135:8:135:13 | pouter |
|
||||
| by_reference.cpp:135:16:135:24 | inner_ptr |
|
||||
| by_reference.cpp:135:27:135:27 | a |
|
||||
| by_reference.cpp:136:8:136:13 | pouter |
|
||||
| by_reference.cpp:136:16:136:16 | a |
|
||||
| complex.cpp:11:22:11:23 | this |
|
||||
| complex.cpp:12:22:12:23 | this |
|
||||
| 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 |
|
||||
| conflated.cpp:10:4:10:5 | ra |
|
||||
| conflated.cpp:19:19:19:21 | raw |
|
||||
| conflated.cpp:20:8:20:10 | raw |
|
||||
| conflated.cpp:29:3:29:4 | pa |
|
||||
| conflated.cpp:36:3:36:4 | pa |
|
||||
| conflated.cpp:53:3:53:4 | ll |
|
||||
| conflated.cpp:54:3:54:4 | ll |
|
||||
| conflated.cpp:54:7:54:10 | next |
|
||||
| conflated.cpp:59:20:59:39 | new |
|
||||
| conflated.cpp:59:35:59:38 | next |
|
||||
| conflated.cpp:60:3:60:4 | ll |
|
||||
| conflated.cpp:60:7:60:10 | next |
|
||||
| constructors.cpp:20:24:20:25 | this |
|
||||
| constructors.cpp:21:24:21:25 | this |
|
||||
| constructors.cpp:28:10:28:10 | f |
|
||||
| constructors.cpp:29:10:29:10 | f |
|
||||
| constructors.cpp:40:9:40:9 | f |
|
||||
| constructors.cpp:43:9:43:9 | g |
|
||||
| constructors.cpp:46:9:46:9 | h |
|
||||
| constructors.cpp:49:9:49:9 | i |
|
||||
| qualifiers.cpp:9:30:9:33 | this |
|
||||
| qualifiers.cpp:12:49:12:53 | inner |
|
||||
| qualifiers.cpp:13:51:13:55 | inner |
|
||||
| qualifiers.cpp:22:5:22:9 | outer |
|
||||
| qualifiers.cpp:22:11:22:18 | call to getInner |
|
||||
| qualifiers.cpp:23:10:23:14 | outer |
|
||||
| qualifiers.cpp:23:16:23:20 | inner |
|
||||
| qualifiers.cpp:23:23:23:23 | a |
|
||||
| qualifiers.cpp:27:5:27:9 | outer |
|
||||
| qualifiers.cpp:27:11:27:18 | call to getInner |
|
||||
| qualifiers.cpp:27:28:27:37 | call to user_input |
|
||||
| qualifiers.cpp:28:10:28:14 | outer |
|
||||
| qualifiers.cpp:28:16:28:20 | inner |
|
||||
| qualifiers.cpp:28:23:28:23 | a |
|
||||
| qualifiers.cpp:32:17:32:21 | outer |
|
||||
| qualifiers.cpp:32:23:32:30 | call to getInner |
|
||||
| qualifiers.cpp:32:35:32:44 | call to user_input |
|
||||
| qualifiers.cpp:33:10:33:14 | outer |
|
||||
| qualifiers.cpp:33:16:33:20 | inner |
|
||||
| qualifiers.cpp:33:23:33:23 | a |
|
||||
| qualifiers.cpp:37:19:37:35 | * ... |
|
||||
| qualifiers.cpp:37:20:37:24 | outer |
|
||||
| qualifiers.cpp:37:38:37:47 | call to user_input |
|
||||
| qualifiers.cpp:38:10:38:14 | outer |
|
||||
| qualifiers.cpp:38:16:38:20 | inner |
|
||||
| qualifiers.cpp:38:23:38:23 | a |
|
||||
| qualifiers.cpp:42:6:42:22 | * ... |
|
||||
| qualifiers.cpp:42:7:42:11 | outer |
|
||||
| qualifiers.cpp:43:10:43:14 | outer |
|
||||
| qualifiers.cpp:43:16:43:20 | inner |
|
||||
| qualifiers.cpp:43:23:43:23 | a |
|
||||
| qualifiers.cpp:47:6:47:11 | & ... |
|
||||
| qualifiers.cpp:47:15:47:22 | call to getInner |
|
||||
| qualifiers.cpp:48:10:48:14 | outer |
|
||||
| qualifiers.cpp:48:16:48:20 | inner |
|
||||
| qualifiers.cpp:48:23:48:23 | a |
|
||||
| realistic.cpp:42:20:42:20 | o |
|
||||
| realistic.cpp:49:9:49:11 | foo |
|
||||
| realistic.cpp:49:9:49:18 | access to array |
|
||||
| realistic.cpp:53:9:53:11 | foo |
|
||||
| realistic.cpp:53:9:53:18 | access to array |
|
||||
| realistic.cpp:53:20:53:22 | baz |
|
||||
| realistic.cpp:53:25:53:33 | userInput |
|
||||
| realistic.cpp:54:16:54:18 | foo |
|
||||
| realistic.cpp:54:16:54:25 | access to array |
|
||||
| realistic.cpp:54:27:54:29 | baz |
|
||||
| realistic.cpp:54:32:54:40 | userInput |
|
||||
| realistic.cpp:54:42:54:47 | buffer |
|
||||
| realistic.cpp:60:16:60:18 | dst |
|
||||
| realistic.cpp:61:21:61:23 | foo |
|
||||
| realistic.cpp:61:21:61:30 | access to array |
|
||||
| realistic.cpp:61:32:61:34 | baz |
|
||||
| realistic.cpp:61:37:61:45 | userInput |
|
||||
| realistic.cpp:61:47:61:55 | bufferLen |
|
||||
| realistic.cpp:65:21:65:23 | foo |
|
||||
| realistic.cpp:65:21:65:30 | access to array |
|
||||
| realistic.cpp:65:32:65:34 | baz |
|
||||
| realistic.cpp:65:37:65:45 | userInput |
|
||||
| realistic.cpp:65:47:65:52 | buffer |
|
||||
| realistic.cpp:66:21:66:23 | dst |
|
||||
| simple.cpp:20:24:20:25 | this |
|
||||
| simple.cpp:21:24:21:25 | this |
|
||||
| simple.cpp:28:10:28:10 | f |
|
||||
| simple.cpp:29:10:29:10 | f |
|
||||
| simple.cpp:39:5:39:5 | f |
|
||||
| simple.cpp:40:5:40:5 | g |
|
||||
| simple.cpp:41:5:41:5 | h |
|
||||
| simple.cpp:42:5:42:5 | h |
|
||||
| simple.cpp:45:9:45:9 | f |
|
||||
| simple.cpp:48:9:48:9 | g |
|
||||
| simple.cpp:51:9:51:9 | h |
|
||||
| simple.cpp:54:9:54:9 | i |
|
||||
| simple.cpp:65:5:65:5 | a |
|
||||
| simple.cpp:83:9:83:10 | f2 |
|
||||
| simple.cpp:83:9:83:10 | this |
|
||||
| simple.cpp:84:14:84:20 | this |
|
||||
| simple.cpp:92:5:92:5 | a |
|
||||
| struct_init.c:15:8:15:9 | ab |
|
||||
| struct_init.c:15:12:15:12 | a |
|
||||
| struct_init.c:16:8:16:9 | ab |
|
||||
| struct_init.c:16:12:16:12 | b |
|
||||
| struct_init.c:22:8:22:9 | ab |
|
||||
| struct_init.c:22:11:22:11 | a |
|
||||
| struct_init.c:23:8:23:9 | ab |
|
||||
| struct_init.c:23:11:23:11 | b |
|
||||
| struct_init.c:24:10:24:12 | & ... |
|
||||
| struct_init.c:31:8:31:12 | outer |
|
||||
| struct_init.c:31:14:31:21 | nestedAB |
|
||||
| struct_init.c:31:23:31:23 | a |
|
||||
| struct_init.c:32:8:32:12 | outer |
|
||||
| struct_init.c:32:14:32:21 | nestedAB |
|
||||
| struct_init.c:32:23:32:23 | b |
|
||||
| struct_init.c:33:8:33:12 | outer |
|
||||
| struct_init.c:33:14:33:22 | pointerAB |
|
||||
| struct_init.c:33:25:33:25 | a |
|
||||
| struct_init.c:34:8:34:12 | outer |
|
||||
| struct_init.c:34:14:34:22 | pointerAB |
|
||||
| struct_init.c:34:25:34:25 | b |
|
||||
| struct_init.c:36:10:36:24 | & ... |
|
||||
| struct_init.c:36:11:36:15 | outer |
|
||||
| struct_init.c:46:10:46:14 | outer |
|
||||
| struct_init.c:46:16:46:24 | pointerAB |
|
||||
|
|
|
@ -107,6 +107,10 @@
|
|||
| C.cpp:19:5:19:5 | c |
|
||||
| C.cpp:24:5:24:8 | this |
|
||||
| C.cpp:24:11:24:12 | s3 |
|
||||
| C.cpp:29:10:29:11 | s1 |
|
||||
| C.cpp:29:10:29:11 | this |
|
||||
| C.cpp:31:10:31:11 | s3 |
|
||||
| C.cpp:31:10:31:11 | this |
|
||||
| D.cpp:9:21:9:24 | elem |
|
||||
| D.cpp:9:21:9:24 | this |
|
||||
| D.cpp:11:29:11:32 | elem |
|
||||
|
|
|
@ -20,31 +20,31 @@ namespace qualifiers {
|
|||
|
||||
void assignToGetter(Outer outer) {
|
||||
outer.getInner()->a = user_input();
|
||||
sink(outer.inner->a); // $ ast MISSING: ir
|
||||
sink(outer.inner->a); // $ ast,ir
|
||||
}
|
||||
|
||||
void getterArgument1(Outer outer) {
|
||||
outer.getInner()->setA(user_input());
|
||||
sink(outer.inner->a); // $ ast MISSING: ir
|
||||
sink(outer.inner->a); // $ ast,ir
|
||||
}
|
||||
|
||||
void getterArgument2(Outer outer) {
|
||||
pointerSetA(outer.getInner(), user_input());
|
||||
sink(outer.inner->a); // $ ast MISSING: ir
|
||||
sink(outer.inner->a); // $ ast,ir
|
||||
}
|
||||
|
||||
void getterArgument2Ref(Outer outer) {
|
||||
referenceSetA(*outer.getInner(), user_input());
|
||||
sink(outer.inner->a); // $ ast MISSING: ir
|
||||
sink(outer.inner->a); // $ ast,ir
|
||||
}
|
||||
|
||||
void assignToGetterStar(Outer outer) {
|
||||
(*outer.getInner()).a = user_input();
|
||||
sink(outer.inner->a); // $ ast MISSING: ir
|
||||
sink(outer.inner->a); // $ ast,ir
|
||||
}
|
||||
|
||||
void assignToGetterAmp(Outer outer) {
|
||||
(&outer)->getInner()->a = user_input();
|
||||
sink(outer.inner->a); // $ ast MISSING: ir
|
||||
sink(outer.inner->a); // $ ast,ir
|
||||
}
|
||||
}
|
|
@ -58,7 +58,7 @@ int main(int argc, char** argv) {
|
|||
return -1;
|
||||
}
|
||||
memcpy(dst, foo.bar[i].baz->userInput.buffer, foo.bar[i].baz->userInput.bufferLen);
|
||||
sink((void*)foo.bar[i].baz->userInput.bufferLen); // $ ast MISSING: ir
|
||||
sink((void*)foo.bar[i].baz->userInput.bufferLen); // $ ast ir=53:47 ir=53:55
|
||||
// There is no flow to the following two `sink` calls because the
|
||||
// source is the _pointer_ returned by `user_input` rather than the
|
||||
// _data_ to which it points.
|
||||
|
|
|
@ -10,6 +10,10 @@
|
|||
| test.cpp:49:23:49:28 | call to getenv | test.cpp:50:29:50:40 | envStrGlobal | AST only |
|
||||
| test.cpp:49:23:49:28 | call to getenv | test.cpp:52:2:52:12 | * ... | AST only |
|
||||
| test.cpp:49:23:49:28 | call to getenv | test.cpp:52:3:52:12 | envStr_ptr | AST only |
|
||||
| test.cpp:49:23:49:28 | call to getenv | test.cpp:54:6:54:35 | ! ... | AST only |
|
||||
| test.cpp:49:23:49:28 | call to getenv | test.cpp:54:7:54:12 | call to strcmp | AST only |
|
||||
| test.cpp:49:23:49:28 | call to getenv | test.cpp:54:7:54:35 | (bool)... | AST only |
|
||||
| test.cpp:49:23:49:28 | call to getenv | test.cpp:54:14:54:25 | envStrGlobal | AST only |
|
||||
| test.cpp:60:29:60:34 | call to getenv | test.cpp:10:27:10:27 | s | AST only |
|
||||
| test.cpp:60:29:60:34 | call to getenv | test.cpp:60:18:60:25 | userName | AST only |
|
||||
| test.cpp:68:28:68:33 | call to getenv | test.cpp:11:20:11:21 | s1 | AST only |
|
||||
|
|
|
@ -14,10 +14,6 @@
|
|||
| test.cpp:49:23:49:28 | call to getenv | test.cpp:49:23:49:28 | call to getenv |
|
||||
| test.cpp:49:23:49:28 | call to getenv | test.cpp:49:23:49:40 | (const char *)... |
|
||||
| test.cpp:49:23:49:28 | call to getenv | test.cpp:52:16:52:21 | envStr |
|
||||
| test.cpp:49:23:49:28 | call to getenv | test.cpp:54:6:54:35 | ! ... |
|
||||
| test.cpp:49:23:49:28 | call to getenv | test.cpp:54:7:54:12 | call to strcmp |
|
||||
| test.cpp:49:23:49:28 | call to getenv | test.cpp:54:7:54:35 | (bool)... |
|
||||
| test.cpp:49:23:49:28 | call to getenv | test.cpp:54:14:54:25 | envStrGlobal |
|
||||
| test.cpp:60:29:60:34 | call to getenv | test.cpp:60:29:60:34 | call to getenv |
|
||||
| test.cpp:60:29:60:34 | call to getenv | test.cpp:60:29:60:47 | (const char *)... |
|
||||
| test.cpp:60:29:60:34 | call to getenv | test.cpp:64:25:64:32 | userName |
|
||||
|
|
|
@ -7,7 +7,7 @@ void test_unique_ptr_int() {
|
|||
std::unique_ptr<int> p1(new int(source()));
|
||||
std::unique_ptr<int> p2 = std::make_unique<int>(source());
|
||||
|
||||
sink(*p1); // $ ir MISSING: ast
|
||||
sink(*p1); // $ MISSING: ast,ir
|
||||
sink(*p2); // $ ast ir=8:50
|
||||
}
|
||||
|
||||
|
@ -23,7 +23,7 @@ void test_unique_ptr_struct() {
|
|||
|
||||
sink(p1->x); // $ ir MISSING: ast
|
||||
sink(p1->y);
|
||||
sink(p2->x); // $ MISSING: ast,ir
|
||||
sink(p2->x); // $ ir=22:46 MISSING: ast
|
||||
sink(p2->y);
|
||||
}
|
||||
|
||||
|
@ -31,7 +31,7 @@ void test_shared_ptr_int() {
|
|||
std::shared_ptr<int> p1(new int(source()));
|
||||
std::shared_ptr<int> p2 = std::make_shared<int>(source());
|
||||
|
||||
sink(*p1); // $ ast ir
|
||||
sink(*p1); // $ ast MISSING: ir
|
||||
sink(*p2); // $ ast ir=32:50
|
||||
}
|
||||
|
||||
|
@ -39,7 +39,7 @@ void test_shared_ptr_struct() {
|
|||
std::shared_ptr<A> p1(new A{source(), 0});
|
||||
std::shared_ptr<A> p2 = std::make_shared<A>(source(), 0);
|
||||
|
||||
sink(p1->x); // $ ir MISSING: ast
|
||||
sink(p1->x); // $ MISSING: ast,ir
|
||||
sink(p1->y);
|
||||
sink(p2->x); // $ MISSING: ast,ir
|
||||
sink(p2->y);
|
||||
|
|
|
@ -13,10 +13,10 @@ void test_pointer_deref_assignment()
|
|||
|
||||
*p_x = source();
|
||||
|
||||
sink(x); // $ ir MISSING: ast
|
||||
sink(x); // $ MISSING: ast,ir
|
||||
sink(*p_x); // $ ast,ir
|
||||
sink(*p2_x); // $ ir MISSING: ast
|
||||
sink(r_x); // $ ir MISSING: ast
|
||||
sink(*p2_x); // $ MISSING: ast,ir
|
||||
sink(r_x); // $ MISSING: ast,ir
|
||||
}
|
||||
|
||||
void test_reference_deref_assignment()
|
||||
|
@ -28,10 +28,10 @@ void test_reference_deref_assignment()
|
|||
|
||||
r_x = source();
|
||||
|
||||
sink(x); // $ ir MISSING: ast
|
||||
sink(*p_x); // $ ir MISSING: ast
|
||||
sink(x); // $ MISSING: ast,ir
|
||||
sink(*p_x); // $ MISSING: ast,ir
|
||||
sink(r_x); // $ ast,ir
|
||||
sink(r2_x); // $ ir MISSING: ast
|
||||
sink(r2_x); // $ MISSING: ast,ir
|
||||
}
|
||||
|
||||
class MyInt
|
||||
|
@ -53,8 +53,8 @@ void test_myint_member_assignment()
|
|||
|
||||
mi.i = source();
|
||||
|
||||
sink(mi); // $ ir MISSING: ast
|
||||
sink(mi.get()); // $ ast,ir
|
||||
sink(mi); // $ MISSING: ast,ir
|
||||
sink(mi.get()); // $ ast MISSING: ir
|
||||
}
|
||||
|
||||
void test_myint_method_assignment()
|
||||
|
@ -64,7 +64,7 @@ void test_myint_method_assignment()
|
|||
mi.get() = source();
|
||||
|
||||
sink(mi); // $ ir MISSING: ast
|
||||
sink(mi.get()); // $ ast,ir
|
||||
sink(mi.get()); // $ ast MISSING: ir
|
||||
}
|
||||
|
||||
void test_myint_overloaded_assignment()
|
||||
|
@ -133,15 +133,15 @@ void test_array_reference_assignment()
|
|||
|
||||
ref1 = source();
|
||||
sink(ref1); // $ ast,ir
|
||||
sink(arr1[5]); // $ ir MISSING: ast
|
||||
sink(arr1[5]); // $ MISSING: ast,ir
|
||||
|
||||
ptr2 = &(arr2[5]);
|
||||
*ptr2 = source();
|
||||
sink(*ptr2); // $ ast,ir
|
||||
sink(arr2[5]); // $ ir MISSING: ast
|
||||
sink(arr2[5]); // $ MISSING: ast,ir
|
||||
|
||||
ptr3 = arr3;
|
||||
ptr3[5] = source();
|
||||
sink(ptr3[5]); // $ ast,ir
|
||||
sink(arr3[5]); // $ ir MISSING: ast
|
||||
sink(arr3[5]); // $ MISSING: ast,ir
|
||||
}
|
||||
|
|
|
@ -28,12 +28,12 @@ void test_pair()
|
|||
b.first = source();
|
||||
sink(b.first); // $ ast,ir
|
||||
sink(b.second);
|
||||
sink(b); // $ MISSING: ast,ir
|
||||
sink(b); // $ ir MISSING: ast
|
||||
|
||||
c.second = source();
|
||||
sink(c.first);
|
||||
sink(c.second); // $ ast,ir
|
||||
sink(c); // $ MISSING: ast,ir
|
||||
sink(c); // $ ir MISSING: ast
|
||||
|
||||
std::pair<char *, char *> d("123", "456");
|
||||
sink(d.first);
|
||||
|
@ -43,21 +43,21 @@ void test_pair()
|
|||
std::pair<char *, char *> e(source(), "456");
|
||||
sink(e.first); // $ ast,ir
|
||||
sink(e.second);
|
||||
sink(e); // $ MISSING: ast,ir
|
||||
sink(e); // $ ir MISSING: ast
|
||||
|
||||
std::pair<char *, char *> f("123", source());
|
||||
sink(f.first); // $ SPURIOUS: ir
|
||||
sink(f.first);
|
||||
sink(f.second); // $ ast,ir
|
||||
sink(f); // $ ast,ir
|
||||
|
||||
std::pair<char *, char *> g(f);
|
||||
sink(g.first); // $ SPURIOUS: ir
|
||||
sink(g.first);
|
||||
sink(g.second); // $ ast,ir
|
||||
sink(g); // $ ast,ir
|
||||
|
||||
std::pair<char *, char *> h;
|
||||
h = f;
|
||||
sink(h.first); // $ SPURIOUS: ir
|
||||
sink(h.first);
|
||||
sink(h.second); // $ ast,ir
|
||||
sink(h); // $ ast,ir
|
||||
|
||||
|
@ -67,17 +67,17 @@ void test_pair()
|
|||
std::pair<char *, char *> l("123", "456");
|
||||
i.swap(j);
|
||||
k.swap(l);
|
||||
sink(i.first); // $ SPURIOUS: ir
|
||||
sink(i.second); // $ ir MISSING: ast
|
||||
sink(i.first);
|
||||
sink(i.second); // $ MISSING: ast,ir
|
||||
sink(i); // $ ast,ir
|
||||
sink(j.first); // $ SPURIOUS: ir
|
||||
sink(j.first);
|
||||
sink(j.second); // $ SPURIOUS: ast,ir
|
||||
sink(j); // $ SPURIOUS: ast,ir
|
||||
sink(k.first); // $ SPURIOUS: ir
|
||||
sink(k.first);
|
||||
sink(k.second); // $ SPURIOUS: ast,ir
|
||||
sink(k); // $ SPURIOUS: ast,ir
|
||||
sink(l.first); // $ SPURIOUS: ir
|
||||
sink(l.second); // $ ir MISSING: ast
|
||||
sink(l.first);
|
||||
sink(l.second); // $ MISSING: ast,ir
|
||||
sink(l); // $ ast,ir
|
||||
|
||||
sink(make_pair("123", "456"));
|
||||
|
@ -87,7 +87,7 @@ void test_pair()
|
|||
sink(make_pair(source(), "456").first); // $ ast,ir
|
||||
sink(make_pair(source(), "456").second);
|
||||
sink(make_pair("123", source())); // $ ast,ir
|
||||
sink(make_pair("123", source()).first); // $ SPURIOUS: ir
|
||||
sink(make_pair("123", source()).first);
|
||||
sink(make_pair("123", source()).second); // $ ast,ir
|
||||
|
||||
std::pair<std::pair<char *, char *>, char *> m;
|
||||
|
@ -105,10 +105,10 @@ void test_map()
|
|||
std::map<char *, char *> m1, m2, m3, m4, m5, m6;
|
||||
|
||||
sink(m1.insert(std::make_pair("abc", "def")).first);
|
||||
sink(m2.insert(std::make_pair("abc", source())).first); // $ SPURIOUS: ir
|
||||
sink(m2.insert(std::make_pair("abc", source())).first);
|
||||
sink(m3.insert(std::make_pair(source(), "def")).first); // $ MISSING: ast,ir
|
||||
sink(m4.insert(m4.begin(), std::pair<char *, char *>("abc", source()))); // $ ast,ir
|
||||
sink(m5.insert_or_assign("abc", source()).first); // $ SPURIOUS: ir
|
||||
sink(m5.insert_or_assign("abc", source()).first);
|
||||
sink(m6.insert_or_assign(m6.begin(), "abc", source())); // $ ast,ir
|
||||
sink(m1);
|
||||
sink(m2); // $ ast,ir
|
||||
|
@ -169,9 +169,9 @@ void test_map()
|
|||
sink(m12.at("abc") = "def");
|
||||
sink(m13.at("abc") = source()); // $ ast,ir
|
||||
sink(m10["abc"]);
|
||||
sink(m11["abc"]); // $ ast MISSING: ir
|
||||
sink(m11["abc"]); // $ ast,ir
|
||||
sink(m12["abc"]);
|
||||
sink(m13["abc"]); // $ ast MISSING: ir
|
||||
sink(m13["abc"]); // $ ast,ir
|
||||
|
||||
// ranges
|
||||
std::map<char *, char *> m14;
|
||||
|
@ -181,10 +181,10 @@ void test_map()
|
|||
m14.insert(std::make_pair("d", "d"));
|
||||
sink(m2.lower_bound("b")); // $ ast,ir
|
||||
sink(m2.upper_bound("b")); // $ ast,ir
|
||||
sink(m2.equal_range("b").first); // $ ir
|
||||
sink(m2.equal_range("b").second); // $ ir MISSING: ast
|
||||
sink(m2.equal_range("b").first); // $ MISSING: ast,ir
|
||||
sink(m2.equal_range("b").second); // $ MISSING: ast,ir
|
||||
sink(m2.upper_bound("c")); // $ SPURIOUS: ast,ir
|
||||
sink(m2.equal_range("c").second); // $ SPURIOUS: ir
|
||||
sink(m2.equal_range("c").second);
|
||||
|
||||
// swap
|
||||
std::map<char *, char *> m15, m16, m17, m18;
|
||||
|
@ -232,7 +232,7 @@ void test_map()
|
|||
std::map<char *, char *> m24, m25;
|
||||
sink(m24.emplace("abc", "def").first);
|
||||
sink(m24);
|
||||
sink(m24.emplace("abc", source()).first); // $ SPURIOUS: ir
|
||||
sink(m24.emplace("abc", source()).first);
|
||||
sink(m24); // $ ast,ir
|
||||
sink(m25.emplace_hint(m25.begin(), "abc", "def"));
|
||||
sink(m25);
|
||||
|
@ -243,7 +243,7 @@ void test_map()
|
|||
std::map<char *, char *> m26, m27;
|
||||
sink(m26.try_emplace("abc", "def").first);
|
||||
sink(m26);
|
||||
sink(m26.try_emplace("abc", source()).first); // $ SPURIOUS: ir
|
||||
sink(m26.try_emplace("abc", source()).first);
|
||||
sink(m26); // $ ast,ir
|
||||
sink(m27.try_emplace(m27.begin(), "abc", "def"));
|
||||
sink(m27);
|
||||
|
@ -257,10 +257,10 @@ void test_unordered_map()
|
|||
std::unordered_map<char *, char *> m1, m2, m3, m4, m5, m6;
|
||||
|
||||
sink(m1.insert(std::make_pair("abc", "def")).first);
|
||||
sink(m2.insert(std::make_pair("abc", source())).first); // $ SPURIOUS: ir
|
||||
sink(m2.insert(std::make_pair("abc", source())).first);
|
||||
sink(m3.insert(std::make_pair(source(), "def")).first); // $ MISSING: ast,ir
|
||||
sink(m4.insert(m4.begin(), std::pair<char *, char *>("abc", source()))); // $ ast,ir
|
||||
sink(m5.insert_or_assign("abc", source()).first); // $ SPURIOUS: ir
|
||||
sink(m5.insert_or_assign("abc", source()).first);
|
||||
sink(m6.insert_or_assign(m6.begin(), "abc", source())); // $ ast,ir
|
||||
sink(m1);
|
||||
sink(m2); // $ ast,ir
|
||||
|
@ -321,9 +321,9 @@ void test_unordered_map()
|
|||
sink(m12.at("abc") = "def");
|
||||
sink(m13.at("abc") = source()); // $ ast,ir
|
||||
sink(m10["abc"]);
|
||||
sink(m11["abc"]); // $ ast MISSING: ir
|
||||
sink(m11["abc"]); // $ ast,ir
|
||||
sink(m12["abc"]);
|
||||
sink(m13["abc"]); // $ ast MISSING: ir
|
||||
sink(m13["abc"]); // $ ast,ir
|
||||
|
||||
// ranges
|
||||
std::unordered_map<char *, char *> m14;
|
||||
|
@ -331,9 +331,9 @@ void test_unordered_map()
|
|||
m14.insert(std::make_pair("b", source()));
|
||||
m14.insert(std::make_pair("c", source()));
|
||||
m14.insert(std::make_pair("d", "d"));
|
||||
sink(m2.equal_range("b").first); // $ ir
|
||||
sink(m2.equal_range("b").second); // $ ir MISSING: ast
|
||||
sink(m2.equal_range("c").second); // $ SPURIOUS: ir
|
||||
sink(m2.equal_range("b").first);
|
||||
sink(m2.equal_range("b").second); // $ MISSING: ast,ir
|
||||
sink(m2.equal_range("c").second);
|
||||
|
||||
// swap
|
||||
std::unordered_map<char *, char *> m15, m16, m17, m18;
|
||||
|
@ -381,7 +381,7 @@ void test_unordered_map()
|
|||
std::unordered_map<char *, char *> m24, m25;
|
||||
sink(m24.emplace("abc", "def").first);
|
||||
sink(m24);
|
||||
sink(m24.emplace("abc", source()).first); // $ SPURIOUS: ir
|
||||
sink(m24.emplace("abc", source()).first);
|
||||
sink(m24); // $ ast,ir
|
||||
sink(m25.emplace_hint(m25.begin(), "abc", "def"));
|
||||
sink(m25);
|
||||
|
@ -393,8 +393,8 @@ void test_unordered_map()
|
|||
sink(m26.try_emplace("abc", "def").first);
|
||||
sink(m26.try_emplace("abc", "def").second);
|
||||
sink(m26);
|
||||
sink(m26.try_emplace("abc", source()).first); // $ SPURIOUS: ir
|
||||
sink(m26.try_emplace("abc", source()).second); // $ ir=396:30 SPURIOUS: ir=397:30 MISSING: ast=396:30
|
||||
sink(m26.try_emplace("abc", source()).first);
|
||||
sink(m26.try_emplace("abc", source()).second); // $ MISSING: ast,ir=396:30
|
||||
sink(m26); // $ ast,ir=396:30 SPURIOUS: ast,ir=397:30
|
||||
sink(m27.try_emplace(m27.begin(), "abc", "def"));
|
||||
sink(m27);
|
||||
|
@ -428,7 +428,7 @@ void test_unordered_map()
|
|||
std::unordered_map<char *, char *> m34, m35;
|
||||
sink(m34.emplace(std::pair<char *, char *>("abc", "def")).first);
|
||||
sink(m34);
|
||||
sink(m34.emplace(std::pair<char *, char *>("abc", source())).first); // $ SPURIOUS: ir
|
||||
sink(m34.emplace(std::pair<char *, char *>("abc", source())).first);
|
||||
sink(m34); // $ ast,ir
|
||||
sink(m34.emplace_hint(m34.begin(), "abc", "def")); // $ ast,ir
|
||||
sink(m35.emplace().first);
|
||||
|
|
|
@ -17,7 +17,7 @@ void test_set()
|
|||
std::set<char *> s1, s2, s3, s4, s5, s6;
|
||||
|
||||
sink(s1.insert("abc").first);
|
||||
sink(s2.insert(source()).first); // $ ir MISSING: ast
|
||||
sink(s2.insert(source()).first); // $ MISSING: ast,ir
|
||||
sink(s3.insert(s3.begin(), "abc"));
|
||||
sink(s4.insert(s4.begin(), source())); // $ ast,ir
|
||||
s5.insert(s1.begin(), s1.end());
|
||||
|
@ -68,8 +68,8 @@ void test_set()
|
|||
s11.insert("c");
|
||||
sink(s11.lower_bound("b")); // $ ast,ir
|
||||
sink(s11.upper_bound("b")); // $ ast,ir
|
||||
sink(s11.equal_range("b").first); // $ ir MISSING: ast
|
||||
sink(s11.equal_range("b").second); // $ ir MISSING: ast
|
||||
sink(s11.equal_range("b").first); // $ MISSING: ast,ir
|
||||
sink(s11.equal_range("b").second); // $ MISSING: ast,ir
|
||||
|
||||
// swap
|
||||
std::set<char *> s12, s13, s14, s15;
|
||||
|
@ -117,7 +117,7 @@ void test_set()
|
|||
std::set<char *> s21, s22;
|
||||
sink(s21.emplace("abc").first);
|
||||
sink(s21);
|
||||
sink(s21.emplace(source()).first); // $ ir MISSING: ast
|
||||
sink(s21.emplace(source()).first); // $ MISSING: ast,ir
|
||||
sink(s21); // $ ast,ir
|
||||
sink(s22.emplace_hint(s22.begin(), "abc"));
|
||||
sink(s22);
|
||||
|
@ -131,7 +131,7 @@ void test_unordered_set()
|
|||
std::unordered_set<char *> s1, s2, s3, s4, s5, s6;
|
||||
|
||||
sink(s1.insert("abc").first);
|
||||
sink(s2.insert(source()).first); // $ ir MISSING: ast
|
||||
sink(s2.insert(source()).first); // $ MISSING: ast,ir
|
||||
sink(s3.insert(s3.begin(), "abc"));
|
||||
sink(s4.insert(s4.begin(), source())); // $ ast,ir
|
||||
s5.insert(s1.begin(), s1.end());
|
||||
|
@ -180,8 +180,8 @@ void test_unordered_set()
|
|||
s11.insert("a");
|
||||
s11.insert(source());
|
||||
s11.insert("c");
|
||||
sink(s11.equal_range("b").first); // $ ir MISSING: ast
|
||||
sink(s11.equal_range("b").second); // $ ir MISSING: ast
|
||||
sink(s11.equal_range("b").first); // $ MISSING: ast,ir
|
||||
sink(s11.equal_range("b").second); // $ MISSING: ast,ir
|
||||
|
||||
// swap
|
||||
std::unordered_set<char *> s12, s13, s14, s15;
|
||||
|
@ -229,7 +229,7 @@ void test_unordered_set()
|
|||
std::unordered_set<char *> s21, s22;
|
||||
sink(s21.emplace("abc").first);
|
||||
sink(s21);
|
||||
sink(s21.emplace(source()).first); // $ ir MISSING: ast
|
||||
sink(s21.emplace(source()).first); // $ MISSING: ast,ir
|
||||
sink(s21); // $ ast,ir
|
||||
sink(s22.emplace_hint(s22.begin(), "abc"));
|
||||
sink(s22);
|
||||
|
|
|
@ -101,7 +101,7 @@ void taint_x(A* pa) {
|
|||
void reverse_taint_smart_pointer() {
|
||||
std::unique_ptr<A> p = std::unique_ptr<A>(new A);
|
||||
taint_x(p.get());
|
||||
sink(p->x); // $ ast,ir
|
||||
sink(p->x); // $ ast MISSING: ir
|
||||
}
|
||||
|
||||
struct C {
|
||||
|
|
|
@ -337,9 +337,9 @@ void test_string_at()
|
|||
b.at(0) = ns_char::source();
|
||||
c[0] = a[0];
|
||||
|
||||
sink(a); // $ ast MISSING: ir
|
||||
sink(b); // $ ast MISSING: ir
|
||||
sink(c); // $ ast MISSING: ir
|
||||
sink(a); // $ ast,ir
|
||||
sink(b); // $ ast,ir
|
||||
sink(c); // $ ast,ir
|
||||
}
|
||||
|
||||
void test_string_data_more()
|
||||
|
@ -347,8 +347,8 @@ void test_string_data_more()
|
|||
std::string str("123");
|
||||
|
||||
str.data()[1] = ns_char::source();
|
||||
sink(str); // $ ast MISSING: ir
|
||||
sink(str.data()); // $ ast MISSING: ir
|
||||
sink(str); // $ ast,ir
|
||||
sink(str.data()); // $ ast,ir
|
||||
}
|
||||
|
||||
void test_string_iterators() {
|
||||
|
@ -540,7 +540,7 @@ void test_string_return_assign() {
|
|||
sink(b);
|
||||
sink(c); // $ ast,ir
|
||||
sink(d); // $ ast,ir
|
||||
sink(e); // $ ast MISSING: ir
|
||||
sink(e); // $ ast,ir
|
||||
sink(f); // $ ast,ir
|
||||
}
|
||||
|
||||
|
@ -560,7 +560,7 @@ void test_string_return_assign() {
|
|||
sink(b);
|
||||
sink(c); // $ ast,ir
|
||||
sink(d); // $ ast,ir
|
||||
sink(e); // $ ast MISSING: ir
|
||||
sink(e); // $ ast,ir
|
||||
sink(f); // $ SPURIOUS: ast,ir
|
||||
}
|
||||
}
|
||||
|
|
|
@ -36,12 +36,12 @@ void test_stringstream_string(int amount)
|
|||
|
||||
sink(ss1);
|
||||
sink(ss2); // $ ast,ir
|
||||
sink(ss3); // $ ast MISSING: ir
|
||||
sink(ss3); // $ ast,ir
|
||||
sink(ss4); // $ ast,ir
|
||||
sink(ss5); // $ ast,ir
|
||||
sink(ss1.str());
|
||||
sink(ss2.str()); // $ ast,ir
|
||||
sink(ss3.str()); // $ ast MISSING: ir
|
||||
sink(ss3.str()); // $ ast,ir
|
||||
sink(ss4.str()); // $ ast,ir
|
||||
sink(ss5.str()); // $ ast,ir
|
||||
|
||||
|
@ -57,14 +57,14 @@ void test_stringstream_string(int amount)
|
|||
sink(ss10.put('a').put(ns_char::source()).put('z')); // $ ast,ir
|
||||
sink(ss8);
|
||||
sink(ss9); // $ ast,ir
|
||||
sink(ss10); // $ ast MISSING: ir
|
||||
sink(ss10); // $ ast,ir
|
||||
|
||||
sink(ss11.write("begin", 5));
|
||||
sink(ss12.write(source(), 5)); // $ ast,ir
|
||||
sink(ss13.write("begin", 5).write(source(), amount).write("end", 3)); // $ ast,ir
|
||||
sink(ss11);
|
||||
sink(ss12); // $ ast,ir
|
||||
sink(ss13); // $ ast MISSING: ir
|
||||
sink(ss13); // $ ast,ir
|
||||
}
|
||||
|
||||
void test_stringstream_int(int source)
|
||||
|
@ -264,5 +264,5 @@ void test_chaining()
|
|||
sink(b2); // $ ast,ir
|
||||
|
||||
sink(ss2.write("abc", 3).flush().write(source(), 3).flush().write("xyz", 3)); // $ ast,ir
|
||||
sink(ss2); // $ ast MISSING: ir
|
||||
sink(ss2); // $ ast,ir
|
||||
}
|
||||
|
|
|
@ -38,9 +38,9 @@ void do_source()
|
|||
global10 = zero(source());
|
||||
|
||||
sink(global6);
|
||||
sink(global7); // $ ast MISSING: ir
|
||||
sink(global8); // $ ast MISSING: ir
|
||||
sink(global9); // $ ast MISSING: ir
|
||||
sink(global7); // $ ast,ir
|
||||
sink(global8); // $ ast,ir
|
||||
sink(global9); // $ ast,ir
|
||||
sink(global10);
|
||||
}
|
||||
|
||||
|
@ -87,11 +87,11 @@ void class_field_test() {
|
|||
|
||||
sink(mc1.a);
|
||||
sink(mc1.b); // $ ast,ir
|
||||
sink(mc1.c); // $ ast,ir
|
||||
sink(mc1.c); // $ ast MISSING: ir
|
||||
sink(mc1.d); // $ ast,ir
|
||||
sink(mc2.a);
|
||||
sink(mc2.b); // $ ast,ir
|
||||
sink(mc2.c); // $ ast,ir
|
||||
sink(mc2.c); // $ ast MISSING: ir
|
||||
sink(mc2.d);
|
||||
}
|
||||
|
||||
|
@ -126,12 +126,12 @@ void pointer_test() {
|
|||
|
||||
*p2 = source();
|
||||
|
||||
sink(*p1); // $ ast,ir
|
||||
sink(*p1); // $ ast MISSING: ir
|
||||
sink(*p2); // $ ast,ir
|
||||
sink(*p3);
|
||||
|
||||
p3 = &t1;
|
||||
sink(*p3); // $ ast,ir
|
||||
sink(*p3); // $ ast MISSING: ir
|
||||
|
||||
*p3 = 0;
|
||||
sink(*p3); // $ SPURIOUS: ast
|
||||
|
@ -233,7 +233,7 @@ void test_lambdas()
|
|||
sink(a()); // $ ast,ir
|
||||
|
||||
auto b = [&] {
|
||||
sink(t); // $ ast MISSING: ir
|
||||
sink(t); // $ ast,ir
|
||||
sink(u); // clean
|
||||
v = source(); // (v is reference captured)
|
||||
};
|
||||
|
@ -448,9 +448,9 @@ void test_qualifiers()
|
|||
sink(b);
|
||||
sink(b.getMember());
|
||||
b.member = source();
|
||||
sink(b); // $ ir MISSING: ast
|
||||
sink(b); // $ MISSING: ast,ir
|
||||
sink(b.member); // $ ast,ir
|
||||
sink(b.getMember()); // $ ir MISSING: ast
|
||||
sink(b.getMember()); // $ MISSING: ast,ir
|
||||
|
||||
c = new MyClass2(0);
|
||||
|
||||
|
@ -665,7 +665,7 @@ public:
|
|||
void test_no_const_member(char* source) {
|
||||
C_no_const_member_function c;
|
||||
memcpy(c.data(), source, 16);
|
||||
sink(c.data()); // $ ast MISSING: ir
|
||||
sink(c.data()); // $ ast,ir
|
||||
}
|
||||
|
||||
class C_const_member_function {
|
||||
|
@ -691,6 +691,6 @@ void test_argument_source_field_to_obj() {
|
|||
argument_source(s.x);
|
||||
|
||||
sink(s); // $ SPURIOUS: ast
|
||||
sink(s.x); // $ ast MISSING: ir
|
||||
sink(s.x); // $ ast,ir
|
||||
sink(s.y); // clean
|
||||
}
|
|
@ -82,7 +82,7 @@ module IRTest {
|
|||
TestAllocationConfig() { this = "TestAllocationConfig" }
|
||||
|
||||
override predicate isSource(DataFlow::Node source) {
|
||||
source.(DataFlow::ExprNode).getConvertedExpr().(FunctionCall).getTarget().getName() = "source"
|
||||
source.asConvertedExpr().(FunctionCall).getTarget().getName() = "source"
|
||||
or
|
||||
source.asParameter().getName().matches("source%")
|
||||
or
|
||||
|
@ -95,11 +95,11 @@ module IRTest {
|
|||
override predicate isSink(DataFlow::Node sink) {
|
||||
exists(FunctionCall call |
|
||||
call.getTarget().getName() = "sink" and
|
||||
sink.(DataFlow::ExprNode).getConvertedExpr() = call.getAnArgument()
|
||||
sink.asConvertedExpr() = call.getAnArgument()
|
||||
or
|
||||
call.getTarget().getName() = "sink" and
|
||||
sink.asExpr() = call.getAnArgument() and
|
||||
sink.(DataFlow::ExprNode).getConvertedExpr() instanceof ReferenceDereferenceExpr
|
||||
sink.asConvertedExpr() instanceof ReferenceDereferenceExpr
|
||||
)
|
||||
or
|
||||
exists(ReadSideEffectInstruction read |
|
||||
|
|
|
@ -49,22 +49,22 @@ void test_element_taint(int x) {
|
|||
sink(v1.back());
|
||||
|
||||
v2[0] = source();
|
||||
sink(v2); // $ ast MISSING: ir
|
||||
sink(v2[0]); // $ ast MISSING: ir
|
||||
sink(v2[1]); // $ SPURIOUS: ast
|
||||
sink(v2[x]); // $ ast MISSING: ir
|
||||
sink(v2); // $ ast,ir
|
||||
sink(v2[0]); // $ ast,ir
|
||||
sink(v2[1]); // $ SPURIOUS: ast,ir
|
||||
sink(v2[x]); // $ ast,ir
|
||||
|
||||
v3 = v2;
|
||||
sink(v3); // $ ast MISSING: ir
|
||||
sink(v3[0]); // $ ast MISSING: ir
|
||||
sink(v3[1]); // $ SPURIOUS: ast
|
||||
sink(v3[x]); // $ ast MISSING: ir
|
||||
sink(v3); // $ ast,ir
|
||||
sink(v3[0]); // $ ast,ir
|
||||
sink(v3[1]); // $ SPURIOUS: ast,ir
|
||||
sink(v3[x]); // $ ast,ir
|
||||
|
||||
v4[x] = source();
|
||||
sink(v4); // $ ast MISSING: ir
|
||||
sink(v4[0]); // $ ast MISSING: ir
|
||||
sink(v4[1]); // $ ast MISSING: ir
|
||||
sink(v4[x]); // $ ast MISSING: ir
|
||||
sink(v4); // $ ast,ir
|
||||
sink(v4[0]); // $ ast,ir
|
||||
sink(v4[1]); // $ ast,ir
|
||||
sink(v4[x]); // $ ast,ir
|
||||
|
||||
v5.push_back(source());
|
||||
sink(v5); // $ ast,ir
|
||||
|
@ -72,8 +72,8 @@ void test_element_taint(int x) {
|
|||
sink(v5.back()); // $ ast,ir
|
||||
|
||||
v6.data()[2] = source();
|
||||
sink(v6); // $ ast MISSING: ir
|
||||
sink(v6.data()[2]); // $ ast MISSING: ir
|
||||
sink(v6); // $ ast,ir
|
||||
sink(v6.data()[2]); // $ ast,ir
|
||||
|
||||
|
||||
{
|
||||
|
@ -94,10 +94,10 @@ void test_element_taint(int x) {
|
|||
sink(v8.back()); // $ MISSING: ast,ir
|
||||
|
||||
v9.at(x) = source();
|
||||
sink(v9); // $ ast MISSING: ir
|
||||
sink(v9.at(0)); // $ ast MISSING: ir
|
||||
sink(v9.at(1)); // $ ast MISSING: ir
|
||||
sink(v9.at(x)); // $ ast MISSING: ir
|
||||
sink(v9); // $ ast,ir
|
||||
sink(v9.at(0)); // $ ast,ir
|
||||
sink(v9.at(1)); // $ ast,ir
|
||||
sink(v9.at(x)); // $ ast,ir
|
||||
}
|
||||
|
||||
void test_vector_swap() {
|
||||
|
@ -168,7 +168,7 @@ void test_nested_vectors()
|
|||
bb[0].push_back(0);
|
||||
sink(bb[0][0]);
|
||||
bb[0][0] = source();
|
||||
sink(bb[0][0]); // $ ast MISSING: ir
|
||||
sink(bb[0][0]); // $ ast,ir
|
||||
}
|
||||
|
||||
{
|
||||
|
@ -177,7 +177,7 @@ void test_nested_vectors()
|
|||
cc[0].push_back(0);
|
||||
sink(cc[0][0]);
|
||||
cc[0][0] = source();
|
||||
sink(cc[0][0]); // $ ast MISSING: ir
|
||||
sink(cc[0][0]); // $ ast,ir
|
||||
}
|
||||
|
||||
{
|
||||
|
@ -188,7 +188,7 @@ void test_nested_vectors()
|
|||
sink(dd[0].a);
|
||||
sink(dd[0].b);
|
||||
dd[0].a = source();
|
||||
sink(dd[0].a); // $ MISSING: ast,ir
|
||||
sink(dd[0].a); // $ ir MISSING: ast
|
||||
sink(dd[0].b);
|
||||
}
|
||||
|
||||
|
@ -198,7 +198,7 @@ void test_nested_vectors()
|
|||
ee.vs.push_back(0);
|
||||
sink(ee.vs[0]);
|
||||
ee.vs[0] = source();
|
||||
sink(ee.vs[0]); // $ ast MISSING: ir
|
||||
sink(ee.vs[0]); // $ ast,ir
|
||||
}
|
||||
|
||||
{
|
||||
|
@ -209,7 +209,7 @@ void test_nested_vectors()
|
|||
ff.push_back(mvc);
|
||||
sink(ff[0].vs[0]);
|
||||
ff[0].vs[0] = source();
|
||||
sink(ff[0].vs[0]); // $ MISSING: ast,ir
|
||||
sink(ff[0].vs[0]); // $ ir MISSING: ast
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -287,9 +287,9 @@ void test_data_more() {
|
|||
sink(v1.data()[2]); // $ ast,ir
|
||||
|
||||
*(v2.data()) = ns_int::source();
|
||||
sink(v2); // $ ast MISSING: ir
|
||||
sink(v2.data()); // $ ast MISSING: ir
|
||||
sink(v2.data()[2]); // $ ast MISSING: ir
|
||||
sink(v2); // $ ast,ir
|
||||
sink(v2.data()); // $ ast,ir
|
||||
sink(v2.data()[2]); // $ ast,ir
|
||||
}
|
||||
|
||||
void sink(std::vector<int>::iterator);
|
||||
|
@ -470,7 +470,7 @@ void test_vector_memcpy()
|
|||
|
||||
sink(v);
|
||||
memcpy(&v[i], &s, sizeof(int));
|
||||
sink(v); // $ ast MISSING: ir
|
||||
sink(v); // $ ast,ir
|
||||
}
|
||||
|
||||
{
|
||||
|
@ -483,7 +483,7 @@ void test_vector_memcpy()
|
|||
sink(cs);
|
||||
memcpy(&cs[offs + 1], src.c_str(), len);
|
||||
sink(src); // $ ast,ir
|
||||
sink(cs); // $ ast MISSING: ir
|
||||
sink(cs); // $ ast,ir
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -1,9 +1,11 @@
|
|||
edges
|
||||
| CWE23_Relative_Path_Traversal__char_console_fopen_11.cpp:55:27:55:38 | ... + ... | CWE23_Relative_Path_Traversal__char_console_fopen_11.cpp:77:23:77:26 | (const char *)... |
|
||||
| CWE23_Relative_Path_Traversal__char_console_fopen_11.cpp:55:27:55:38 | ... + ... | CWE23_Relative_Path_Traversal__char_console_fopen_11.cpp:77:23:77:26 | data |
|
||||
| CWE23_Relative_Path_Traversal__char_console_fopen_11.cpp:55:27:55:38 | ... + ... | CWE23_Relative_Path_Traversal__char_console_fopen_11.cpp:77:23:77:26 | data |
|
||||
| CWE23_Relative_Path_Traversal__char_console_fopen_11.cpp:55:27:55:38 | ... + ... | CWE23_Relative_Path_Traversal__char_console_fopen_11.cpp:77:23:77:26 | data indirection |
|
||||
| CWE23_Relative_Path_Traversal__char_console_fopen_11.cpp:55:27:55:38 | fgets output argument | CWE23_Relative_Path_Traversal__char_console_fopen_11.cpp:77:23:77:26 | (const char *)... |
|
||||
| CWE23_Relative_Path_Traversal__char_console_fopen_11.cpp:55:27:55:38 | fgets output argument | CWE23_Relative_Path_Traversal__char_console_fopen_11.cpp:77:23:77:26 | data |
|
||||
| CWE23_Relative_Path_Traversal__char_console_fopen_11.cpp:55:27:55:38 | fgets output argument | CWE23_Relative_Path_Traversal__char_console_fopen_11.cpp:77:23:77:26 | data |
|
||||
| CWE23_Relative_Path_Traversal__char_console_fopen_11.cpp:55:27:55:38 | fgets output argument | CWE23_Relative_Path_Traversal__char_console_fopen_11.cpp:77:23:77:26 | data indirection |
|
||||
subpaths
|
||||
nodes
|
||||
|
@ -12,6 +14,8 @@ nodes
|
|||
| CWE23_Relative_Path_Traversal__char_console_fopen_11.cpp:77:23:77:26 | (const char *)... | semmle.label | (const char *)... |
|
||||
| CWE23_Relative_Path_Traversal__char_console_fopen_11.cpp:77:23:77:26 | (const char *)... | semmle.label | (const char *)... |
|
||||
| CWE23_Relative_Path_Traversal__char_console_fopen_11.cpp:77:23:77:26 | data | semmle.label | data |
|
||||
| CWE23_Relative_Path_Traversal__char_console_fopen_11.cpp:77:23:77:26 | data | semmle.label | data |
|
||||
| CWE23_Relative_Path_Traversal__char_console_fopen_11.cpp:77:23:77:26 | data | semmle.label | data |
|
||||
| CWE23_Relative_Path_Traversal__char_console_fopen_11.cpp:77:23:77:26 | data indirection | semmle.label | data indirection |
|
||||
| CWE23_Relative_Path_Traversal__char_console_fopen_11.cpp:77:23:77:26 | data indirection | semmle.label | data indirection |
|
||||
#select
|
||||
|
|
|
@ -3,6 +3,8 @@ edges
|
|||
| test.c:9:23:9:26 | argv | test.c:17:11:17:18 | (const char *)... |
|
||||
| test.c:9:23:9:26 | argv | test.c:17:11:17:18 | fileName |
|
||||
| test.c:9:23:9:26 | argv | test.c:17:11:17:18 | fileName |
|
||||
| test.c:9:23:9:26 | argv | test.c:17:11:17:18 | fileName |
|
||||
| test.c:9:23:9:26 | argv | test.c:17:11:17:18 | fileName |
|
||||
| test.c:9:23:9:26 | argv | test.c:17:11:17:18 | fileName indirection |
|
||||
| test.c:9:23:9:26 | argv | test.c:17:11:17:18 | fileName indirection |
|
||||
subpaths
|
||||
|
@ -12,6 +14,8 @@ nodes
|
|||
| test.c:17:11:17:18 | (const char *)... | semmle.label | (const char *)... |
|
||||
| test.c:17:11:17:18 | (const char *)... | semmle.label | (const char *)... |
|
||||
| test.c:17:11:17:18 | fileName | semmle.label | fileName |
|
||||
| test.c:17:11:17:18 | fileName | semmle.label | fileName |
|
||||
| test.c:17:11:17:18 | fileName | semmle.label | fileName |
|
||||
| test.c:17:11:17:18 | fileName indirection | semmle.label | fileName indirection |
|
||||
| test.c:17:11:17:18 | fileName indirection | semmle.label | fileName indirection |
|
||||
#select
|
||||
|
|
|
@ -1,16 +1,16 @@
|
|||
edges
|
||||
| tests.cpp:26:15:26:23 | ReturnValue | tests.cpp:51:12:51:20 | call to badSource |
|
||||
| tests.cpp:33:34:33:39 | call to getenv | tests.cpp:38:39:38:49 | environment indirection |
|
||||
| tests.cpp:38:25:38:36 | strncat output argument | tests.cpp:42:5:42:16 | Phi |
|
||||
| tests.cpp:38:25:38:36 | strncat output argument | tests.cpp:26:15:26:23 | ReturnValue |
|
||||
| tests.cpp:38:39:38:49 | environment indirection | tests.cpp:38:25:38:36 | strncat output argument |
|
||||
| tests.cpp:38:39:38:49 | environment indirection | tests.cpp:38:25:38:36 | strncat output argument |
|
||||
| tests.cpp:42:5:42:16 | Phi | tests.cpp:51:22:51:25 | badSource output argument |
|
||||
| tests.cpp:51:22:51:25 | badSource output argument | tests.cpp:53:16:53:19 | data indirection |
|
||||
| tests.cpp:51:12:51:20 | call to badSource | tests.cpp:53:16:53:19 | data indirection |
|
||||
nodes
|
||||
| tests.cpp:26:15:26:23 | ReturnValue | semmle.label | ReturnValue |
|
||||
| tests.cpp:33:34:33:39 | call to getenv | semmle.label | call to getenv |
|
||||
| tests.cpp:38:25:38:36 | strncat output argument | semmle.label | strncat output argument |
|
||||
| tests.cpp:38:39:38:49 | environment indirection | semmle.label | environment indirection |
|
||||
| tests.cpp:42:5:42:16 | Phi | semmle.label | Phi |
|
||||
| tests.cpp:51:22:51:25 | badSource output argument | semmle.label | badSource output argument |
|
||||
| tests.cpp:51:12:51:20 | call to badSource | semmle.label | call to badSource |
|
||||
| tests.cpp:53:16:53:19 | data indirection | semmle.label | data indirection |
|
||||
subpaths
|
||||
#select
|
||||
|
|
|
@ -31,6 +31,8 @@ edges
|
|||
| tests.c:29:28:29:31 | argv | tests.c:33:21:33:29 | buffer100 indirection |
|
||||
| tests.c:31:15:31:23 | array to pointer conversion | tests.c:31:15:31:23 | buffer100 |
|
||||
| tests.c:31:15:31:23 | array to pointer conversion | tests.c:31:15:31:23 | buffer100 indirection |
|
||||
| tests.c:31:15:31:23 | array to pointer conversion | tests.c:33:21:33:29 | buffer100 |
|
||||
| tests.c:31:15:31:23 | array to pointer conversion | tests.c:33:21:33:29 | buffer100 indirection |
|
||||
| tests.c:31:15:31:23 | buffer100 | tests.c:31:15:31:23 | buffer100 |
|
||||
| tests.c:31:15:31:23 | buffer100 | tests.c:31:15:31:23 | buffer100 indirection |
|
||||
| tests.c:31:15:31:23 | buffer100 | tests.c:33:21:33:29 | buffer100 |
|
||||
|
|
|
@ -7,14 +7,18 @@ edges
|
|||
| char_connect_socket_w32_vsnprintf_01_bad.c:94:55:94:68 | ... + ... | char_connect_socket_w32_vsnprintf_01_bad.c:125:15:125:18 | data indirection |
|
||||
| char_console_fprintf_01_bad.c:30:23:30:35 | ... + ... | char_console_fprintf_01_bad.c:49:21:49:24 | (const char *)... |
|
||||
| char_console_fprintf_01_bad.c:30:23:30:35 | ... + ... | char_console_fprintf_01_bad.c:49:21:49:24 | data |
|
||||
| char_console_fprintf_01_bad.c:30:23:30:35 | ... + ... | char_console_fprintf_01_bad.c:49:21:49:24 | data |
|
||||
| char_console_fprintf_01_bad.c:30:23:30:35 | ... + ... | char_console_fprintf_01_bad.c:49:21:49:24 | data indirection |
|
||||
| char_console_fprintf_01_bad.c:30:23:30:35 | fgets output argument | char_console_fprintf_01_bad.c:49:21:49:24 | (const char *)... |
|
||||
| char_console_fprintf_01_bad.c:30:23:30:35 | fgets output argument | char_console_fprintf_01_bad.c:49:21:49:24 | data |
|
||||
| char_console_fprintf_01_bad.c:30:23:30:35 | fgets output argument | char_console_fprintf_01_bad.c:49:21:49:24 | data |
|
||||
| char_console_fprintf_01_bad.c:30:23:30:35 | fgets output argument | char_console_fprintf_01_bad.c:49:21:49:24 | data indirection |
|
||||
| char_environment_fprintf_01_bad.c:27:30:27:35 | call to getenv | char_environment_fprintf_01_bad.c:36:21:36:24 | (const char *)... |
|
||||
| char_environment_fprintf_01_bad.c:27:30:27:35 | call to getenv | char_environment_fprintf_01_bad.c:36:21:36:24 | (const char *)... |
|
||||
| char_environment_fprintf_01_bad.c:27:30:27:35 | call to getenv | char_environment_fprintf_01_bad.c:36:21:36:24 | data |
|
||||
| char_environment_fprintf_01_bad.c:27:30:27:35 | call to getenv | char_environment_fprintf_01_bad.c:36:21:36:24 | data |
|
||||
| char_environment_fprintf_01_bad.c:27:30:27:35 | call to getenv | char_environment_fprintf_01_bad.c:36:21:36:24 | data |
|
||||
| char_environment_fprintf_01_bad.c:27:30:27:35 | call to getenv | char_environment_fprintf_01_bad.c:36:21:36:24 | data |
|
||||
| char_environment_fprintf_01_bad.c:27:30:27:35 | call to getenv | char_environment_fprintf_01_bad.c:36:21:36:24 | data indirection |
|
||||
| char_environment_fprintf_01_bad.c:27:30:27:35 | call to getenv | char_environment_fprintf_01_bad.c:36:21:36:24 | data indirection |
|
||||
subpaths
|
||||
|
@ -31,6 +35,8 @@ nodes
|
|||
| char_console_fprintf_01_bad.c:49:21:49:24 | (const char *)... | semmle.label | (const char *)... |
|
||||
| char_console_fprintf_01_bad.c:49:21:49:24 | (const char *)... | semmle.label | (const char *)... |
|
||||
| char_console_fprintf_01_bad.c:49:21:49:24 | data | semmle.label | data |
|
||||
| char_console_fprintf_01_bad.c:49:21:49:24 | data | semmle.label | data |
|
||||
| char_console_fprintf_01_bad.c:49:21:49:24 | data | semmle.label | data |
|
||||
| char_console_fprintf_01_bad.c:49:21:49:24 | data indirection | semmle.label | data indirection |
|
||||
| char_console_fprintf_01_bad.c:49:21:49:24 | data indirection | semmle.label | data indirection |
|
||||
| char_environment_fprintf_01_bad.c:27:30:27:35 | call to getenv | semmle.label | call to getenv |
|
||||
|
@ -38,6 +44,8 @@ nodes
|
|||
| char_environment_fprintf_01_bad.c:36:21:36:24 | (const char *)... | semmle.label | (const char *)... |
|
||||
| char_environment_fprintf_01_bad.c:36:21:36:24 | (const char *)... | semmle.label | (const char *)... |
|
||||
| char_environment_fprintf_01_bad.c:36:21:36:24 | data | semmle.label | data |
|
||||
| char_environment_fprintf_01_bad.c:36:21:36:24 | data | semmle.label | data |
|
||||
| char_environment_fprintf_01_bad.c:36:21:36:24 | data | semmle.label | data |
|
||||
| char_environment_fprintf_01_bad.c:36:21:36:24 | data indirection | semmle.label | data indirection |
|
||||
| char_environment_fprintf_01_bad.c:36:21:36:24 | data indirection | semmle.label | data indirection |
|
||||
#select
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
edges
|
||||
| argvLocal.c:9:25:9:31 | correct | argvLocal.c:9:25:9:31 | *correct |
|
||||
| argvLocal.c:9:25:9:31 | *correct | argvLocal.c:9:25:9:31 | ReturnIndirection |
|
||||
| argvLocal.c:95:9:95:12 | argv | argvLocal.c:95:9:95:15 | (const char *)... |
|
||||
| argvLocal.c:95:9:95:12 | argv | argvLocal.c:95:9:95:15 | (const char *)... |
|
||||
| argvLocal.c:95:9:95:12 | argv | argvLocal.c:95:9:95:15 | access to array |
|
||||
|
@ -29,6 +29,8 @@ edges
|
|||
| argvLocal.c:100:7:100:10 | argv | argvLocal.c:102:15:102:16 | i1 |
|
||||
| argvLocal.c:100:7:100:10 | argv | argvLocal.c:102:15:102:16 | i1 indirection |
|
||||
| argvLocal.c:100:7:100:10 | argv | argvLocal.c:102:15:102:16 | i1 indirection |
|
||||
| argvLocal.c:100:7:100:10 | argv | argvLocal.c:102:15:102:16 | i1 indirection |
|
||||
| argvLocal.c:100:7:100:10 | argv | argvLocal.c:102:15:102:16 | i1 indirection |
|
||||
| argvLocal.c:100:7:100:10 | argv | argvLocal.c:144:9:144:10 | (const char *)... |
|
||||
| argvLocal.c:100:7:100:10 | argv | argvLocal.c:144:9:144:10 | (const char *)... |
|
||||
| argvLocal.c:100:7:100:10 | argv | argvLocal.c:144:9:144:10 | i7 |
|
||||
|
@ -44,6 +46,14 @@ edges
|
|||
| argvLocal.c:100:7:100:10 | argv | argvLocal.c:145:15:145:16 | i7 indirection |
|
||||
| argvLocal.c:100:7:100:10 | argv | argvLocal.c:145:15:145:16 | i7 indirection |
|
||||
| argvLocal.c:102:15:102:16 | i1 indirection | argvLocal.c:9:25:9:31 | *correct |
|
||||
| argvLocal.c:102:15:102:16 | i1 indirection | argvLocal.c:102:15:102:16 | printWrapper output argument |
|
||||
| argvLocal.c:102:15:102:16 | printWrapper output argument | argvLocal.c:144:9:144:10 | (const char *)... |
|
||||
| argvLocal.c:102:15:102:16 | printWrapper output argument | argvLocal.c:144:9:144:10 | i7 |
|
||||
| argvLocal.c:102:15:102:16 | printWrapper output argument | argvLocal.c:144:9:144:10 | i7 |
|
||||
| argvLocal.c:102:15:102:16 | printWrapper output argument | argvLocal.c:144:9:144:10 | i7 indirection |
|
||||
| argvLocal.c:102:15:102:16 | printWrapper output argument | argvLocal.c:145:15:145:16 | i7 |
|
||||
| argvLocal.c:102:15:102:16 | printWrapper output argument | argvLocal.c:145:15:145:16 | i7 |
|
||||
| argvLocal.c:102:15:102:16 | printWrapper output argument | argvLocal.c:145:15:145:16 | i7 indirection |
|
||||
| argvLocal.c:105:14:105:17 | argv | argvLocal.c:106:9:106:13 | (const char *)... |
|
||||
| argvLocal.c:105:14:105:17 | argv | argvLocal.c:106:9:106:13 | (const char *)... |
|
||||
| argvLocal.c:105:14:105:17 | argv | argvLocal.c:106:9:106:13 | access to array |
|
||||
|
@ -58,6 +68,8 @@ edges
|
|||
| argvLocal.c:105:14:105:17 | argv | argvLocal.c:107:15:107:19 | access to array |
|
||||
| argvLocal.c:105:14:105:17 | argv | argvLocal.c:107:15:107:19 | access to array indirection |
|
||||
| argvLocal.c:105:14:105:17 | argv | argvLocal.c:107:15:107:19 | access to array indirection |
|
||||
| argvLocal.c:105:14:105:17 | argv | argvLocal.c:107:15:107:19 | access to array indirection |
|
||||
| argvLocal.c:105:14:105:17 | argv | argvLocal.c:107:15:107:19 | access to array indirection |
|
||||
| argvLocal.c:105:14:105:17 | argv | argvLocal.c:110:9:110:11 | (const char *)... |
|
||||
| argvLocal.c:105:14:105:17 | argv | argvLocal.c:110:9:110:11 | (const char *)... |
|
||||
| argvLocal.c:105:14:105:17 | argv | argvLocal.c:110:9:110:11 | * ... |
|
||||
|
@ -73,6 +85,14 @@ edges
|
|||
| argvLocal.c:105:14:105:17 | argv | argvLocal.c:111:15:111:17 | * ... indirection |
|
||||
| argvLocal.c:105:14:105:17 | argv | argvLocal.c:111:15:111:17 | * ... indirection |
|
||||
| argvLocal.c:107:15:107:19 | access to array indirection | argvLocal.c:9:25:9:31 | *correct |
|
||||
| argvLocal.c:107:15:107:19 | access to array indirection | argvLocal.c:107:15:107:19 | printWrapper output argument |
|
||||
| argvLocal.c:107:15:107:19 | printWrapper output argument | argvLocal.c:110:9:110:11 | (const char *)... |
|
||||
| argvLocal.c:107:15:107:19 | printWrapper output argument | argvLocal.c:110:9:110:11 | * ... |
|
||||
| argvLocal.c:107:15:107:19 | printWrapper output argument | argvLocal.c:110:9:110:11 | * ... |
|
||||
| argvLocal.c:107:15:107:19 | printWrapper output argument | argvLocal.c:110:9:110:11 | * ... indirection |
|
||||
| argvLocal.c:107:15:107:19 | printWrapper output argument | argvLocal.c:111:15:111:17 | * ... |
|
||||
| argvLocal.c:107:15:107:19 | printWrapper output argument | argvLocal.c:111:15:111:17 | * ... |
|
||||
| argvLocal.c:107:15:107:19 | printWrapper output argument | argvLocal.c:111:15:111:17 | * ... indirection |
|
||||
| argvLocal.c:111:15:111:17 | * ... indirection | argvLocal.c:9:25:9:31 | *correct |
|
||||
| argvLocal.c:115:13:115:16 | argv | argvLocal.c:116:9:116:10 | (const char *)... |
|
||||
| argvLocal.c:115:13:115:16 | argv | argvLocal.c:116:9:116:10 | (const char *)... |
|
||||
|
@ -80,8 +100,6 @@ edges
|
|||
| argvLocal.c:115:13:115:16 | argv | argvLocal.c:116:9:116:10 | i3 |
|
||||
| argvLocal.c:115:13:115:16 | argv | argvLocal.c:116:9:116:10 | i3 indirection |
|
||||
| argvLocal.c:115:13:115:16 | argv | argvLocal.c:116:9:116:10 | i3 indirection |
|
||||
| argvLocal.c:115:13:115:16 | argv | argvLocal.c:117:2:117:13 | i3 |
|
||||
| argvLocal.c:115:13:115:16 | argv | argvLocal.c:117:2:117:13 | i3 |
|
||||
| argvLocal.c:115:13:115:16 | argv | argvLocal.c:117:15:117:16 | array to pointer conversion |
|
||||
| argvLocal.c:115:13:115:16 | argv | argvLocal.c:117:15:117:16 | array to pointer conversion |
|
||||
| argvLocal.c:115:13:115:16 | argv | argvLocal.c:117:15:117:16 | i3 |
|
||||
|
@ -90,70 +108,41 @@ edges
|
|||
| argvLocal.c:115:13:115:16 | argv | argvLocal.c:117:15:117:16 | i3 indirection |
|
||||
| argvLocal.c:115:13:115:16 | argv | argvLocal.c:117:15:117:16 | i3 indirection |
|
||||
| argvLocal.c:115:13:115:16 | argv | argvLocal.c:117:15:117:16 | i3 indirection |
|
||||
| argvLocal.c:115:13:115:16 | argv | argvLocal.c:121:9:121:10 | (const char *)... |
|
||||
| argvLocal.c:115:13:115:16 | argv | argvLocal.c:121:9:121:10 | (const char *)... |
|
||||
| argvLocal.c:115:13:115:16 | argv | argvLocal.c:121:9:121:10 | i4 |
|
||||
| argvLocal.c:115:13:115:16 | argv | argvLocal.c:121:9:121:10 | i4 |
|
||||
| argvLocal.c:115:13:115:16 | argv | argvLocal.c:121:9:121:10 | i4 indirection |
|
||||
| argvLocal.c:115:13:115:16 | argv | argvLocal.c:121:9:121:10 | i4 indirection |
|
||||
| argvLocal.c:115:13:115:16 | argv | argvLocal.c:122:2:122:13 | i4 |
|
||||
| argvLocal.c:115:13:115:16 | argv | argvLocal.c:122:2:122:13 | i4 |
|
||||
| argvLocal.c:115:13:115:16 | argv | argvLocal.c:122:15:122:16 | i4 |
|
||||
| argvLocal.c:115:13:115:16 | argv | argvLocal.c:122:15:122:16 | i4 |
|
||||
| argvLocal.c:115:13:115:16 | argv | argvLocal.c:122:15:122:16 | i4 |
|
||||
| argvLocal.c:115:13:115:16 | argv | argvLocal.c:122:15:122:16 | i4 |
|
||||
| argvLocal.c:115:13:115:16 | argv | argvLocal.c:122:15:122:16 | i4 indirection |
|
||||
| argvLocal.c:115:13:115:16 | argv | argvLocal.c:122:15:122:16 | i4 indirection |
|
||||
| argvLocal.c:115:13:115:16 | argv | argvLocal.c:122:15:122:16 | i4 indirection |
|
||||
| argvLocal.c:115:13:115:16 | argv | argvLocal.c:122:15:122:16 | i4 indirection |
|
||||
| argvLocal.c:115:13:115:16 | argv | argvLocal.c:135:9:135:12 | (const char *)... |
|
||||
| argvLocal.c:115:13:115:16 | argv | argvLocal.c:135:9:135:12 | (const char *)... |
|
||||
| argvLocal.c:115:13:115:16 | argv | argvLocal.c:135:9:135:12 | ... ++ |
|
||||
| argvLocal.c:115:13:115:16 | argv | argvLocal.c:135:9:135:12 | ... ++ |
|
||||
| argvLocal.c:115:13:115:16 | argv | argvLocal.c:135:9:135:12 | ... ++ indirection |
|
||||
| argvLocal.c:115:13:115:16 | argv | argvLocal.c:135:9:135:12 | ... ++ indirection |
|
||||
| argvLocal.c:115:13:115:16 | argv | argvLocal.c:136:15:136:18 | -- ... |
|
||||
| argvLocal.c:115:13:115:16 | argv | argvLocal.c:136:15:136:18 | -- ... |
|
||||
| argvLocal.c:115:13:115:16 | argv | argvLocal.c:136:15:136:18 | -- ... |
|
||||
| argvLocal.c:115:13:115:16 | argv | argvLocal.c:136:15:136:18 | -- ... |
|
||||
| argvLocal.c:115:13:115:16 | argv | argvLocal.c:136:15:136:18 | -- ... indirection |
|
||||
| argvLocal.c:115:13:115:16 | argv | argvLocal.c:136:15:136:18 | -- ... indirection |
|
||||
| argvLocal.c:117:2:117:13 | i3 | argvLocal.c:9:25:9:31 | correct |
|
||||
| argvLocal.c:117:2:117:13 | i3 | argvLocal.c:117:15:117:16 | printWrapper output argument |
|
||||
| argvLocal.c:117:15:117:16 | i3 indirection | argvLocal.c:9:25:9:31 | *correct |
|
||||
| argvLocal.c:117:15:117:16 | i3 indirection | argvLocal.c:117:15:117:16 | printWrapper output argument |
|
||||
| argvLocal.c:117:15:117:16 | printWrapper output argument | argvLocal.c:121:9:121:10 | (const char *)... |
|
||||
| argvLocal.c:117:15:117:16 | printWrapper output argument | argvLocal.c:121:9:121:10 | i4 |
|
||||
| argvLocal.c:117:15:117:16 | printWrapper output argument | argvLocal.c:121:9:121:10 | i4 indirection |
|
||||
| argvLocal.c:117:15:117:16 | printWrapper output argument | argvLocal.c:122:2:122:13 | i4 |
|
||||
| argvLocal.c:117:15:117:16 | printWrapper output argument | argvLocal.c:122:15:122:16 | i4 |
|
||||
| argvLocal.c:117:15:117:16 | printWrapper output argument | argvLocal.c:122:15:122:16 | i4 |
|
||||
| argvLocal.c:117:15:117:16 | printWrapper output argument | argvLocal.c:122:15:122:16 | i4 indirection |
|
||||
| argvLocal.c:117:15:117:16 | printWrapper output argument | argvLocal.c:122:15:122:16 | i4 indirection |
|
||||
| argvLocal.c:117:15:117:16 | printWrapper output argument | argvLocal.c:135:9:135:10 | i4 |
|
||||
| argvLocal.c:117:15:117:16 | printWrapper output argument | argvLocal.c:135:9:135:12 | (const char *)... |
|
||||
| argvLocal.c:117:15:117:16 | printWrapper output argument | argvLocal.c:135:9:135:12 | ... ++ |
|
||||
| argvLocal.c:117:15:117:16 | printWrapper output argument | argvLocal.c:135:9:135:12 | ... ++ |
|
||||
| argvLocal.c:117:15:117:16 | printWrapper output argument | argvLocal.c:135:9:135:12 | ... ++ indirection |
|
||||
| argvLocal.c:117:15:117:16 | printWrapper output argument | argvLocal.c:136:15:136:18 | -- ... |
|
||||
| argvLocal.c:117:15:117:16 | printWrapper output argument | argvLocal.c:136:15:136:18 | -- ... |
|
||||
| argvLocal.c:117:15:117:16 | printWrapper output argument | argvLocal.c:136:15:136:18 | -- ... indirection |
|
||||
| argvLocal.c:122:2:122:13 | i4 | argvLocal.c:9:25:9:31 | correct |
|
||||
| argvLocal.c:122:2:122:13 | i4 | argvLocal.c:122:15:122:16 | printWrapper output argument |
|
||||
| argvLocal.c:117:15:117:16 | printWrapper output argument | argvLocal.c:136:17:136:18 | i4 |
|
||||
| argvLocal.c:122:15:122:16 | i4 indirection | argvLocal.c:9:25:9:31 | *correct |
|
||||
| argvLocal.c:122:15:122:16 | i4 indirection | argvLocal.c:122:15:122:16 | printWrapper output argument |
|
||||
| argvLocal.c:122:15:122:16 | printWrapper output argument | argvLocal.c:135:9:135:10 | i4 |
|
||||
| argvLocal.c:122:15:122:16 | printWrapper output argument | argvLocal.c:135:9:135:12 | (const char *)... |
|
||||
| argvLocal.c:122:15:122:16 | printWrapper output argument | argvLocal.c:135:9:135:12 | ... ++ |
|
||||
| argvLocal.c:122:15:122:16 | printWrapper output argument | argvLocal.c:135:9:135:12 | ... ++ |
|
||||
| argvLocal.c:122:15:122:16 | printWrapper output argument | argvLocal.c:135:9:135:12 | ... ++ indirection |
|
||||
| argvLocal.c:122:15:122:16 | printWrapper output argument | argvLocal.c:136:15:136:18 | -- ... |
|
||||
| argvLocal.c:122:15:122:16 | printWrapper output argument | argvLocal.c:136:15:136:18 | -- ... |
|
||||
| argvLocal.c:122:15:122:16 | printWrapper output argument | argvLocal.c:136:15:136:18 | -- ... indirection |
|
||||
| argvLocal.c:122:15:122:16 | printWrapper output argument | argvLocal.c:136:17:136:18 | i4 |
|
||||
| argvLocal.c:126:10:126:13 | argv | argvLocal.c:127:9:127:10 | (const char *)... |
|
||||
| argvLocal.c:126:10:126:13 | argv | argvLocal.c:127:9:127:10 | (const char *)... |
|
||||
| argvLocal.c:126:10:126:13 | argv | argvLocal.c:127:9:127:10 | i5 |
|
||||
| argvLocal.c:126:10:126:13 | argv | argvLocal.c:127:9:127:10 | i5 |
|
||||
| argvLocal.c:126:10:126:13 | argv | argvLocal.c:127:9:127:10 | i5 indirection |
|
||||
| argvLocal.c:126:10:126:13 | argv | argvLocal.c:127:9:127:10 | i5 indirection |
|
||||
| argvLocal.c:126:10:126:13 | argv | argvLocal.c:128:2:128:13 | i5 |
|
||||
| argvLocal.c:126:10:126:13 | argv | argvLocal.c:128:2:128:13 | i5 |
|
||||
| argvLocal.c:126:10:126:13 | argv | argvLocal.c:128:15:128:16 | array to pointer conversion |
|
||||
| argvLocal.c:126:10:126:13 | argv | argvLocal.c:128:15:128:16 | array to pointer conversion |
|
||||
| argvLocal.c:126:10:126:13 | argv | argvLocal.c:128:15:128:16 | i5 |
|
||||
|
@ -174,8 +163,6 @@ edges
|
|||
| argvLocal.c:126:10:126:13 | argv | argvLocal.c:132:15:132:20 | ... + ... |
|
||||
| argvLocal.c:126:10:126:13 | argv | argvLocal.c:132:15:132:20 | ... + ... indirection |
|
||||
| argvLocal.c:126:10:126:13 | argv | argvLocal.c:132:15:132:20 | ... + ... indirection |
|
||||
| argvLocal.c:128:2:128:13 | i5 | argvLocal.c:9:25:9:31 | correct |
|
||||
| argvLocal.c:128:2:128:13 | i5 | argvLocal.c:128:15:128:16 | printWrapper output argument |
|
||||
| argvLocal.c:128:15:128:16 | i5 indirection | argvLocal.c:9:25:9:31 | *correct |
|
||||
| argvLocal.c:128:15:128:16 | i5 indirection | argvLocal.c:128:15:128:16 | printWrapper output argument |
|
||||
| argvLocal.c:128:15:128:16 | printWrapper output argument | argvLocal.c:131:9:131:14 | (const char *)... |
|
||||
|
@ -248,16 +235,14 @@ edges
|
|||
| argvLocal.c:168:18:168:21 | argv | argvLocal.c:170:24:170:26 | i10 |
|
||||
| argvLocal.c:170:15:170:26 | i10 indirection | argvLocal.c:9:25:9:31 | *correct |
|
||||
subpaths
|
||||
| argvLocal.c:117:2:117:13 | i3 | argvLocal.c:9:25:9:31 | correct | argvLocal.c:9:25:9:31 | *correct | argvLocal.c:117:15:117:16 | printWrapper output argument |
|
||||
| argvLocal.c:117:15:117:16 | i3 indirection | argvLocal.c:9:25:9:31 | *correct | argvLocal.c:9:25:9:31 | *correct | argvLocal.c:117:15:117:16 | printWrapper output argument |
|
||||
| argvLocal.c:122:2:122:13 | i4 | argvLocal.c:9:25:9:31 | correct | argvLocal.c:9:25:9:31 | *correct | argvLocal.c:122:15:122:16 | printWrapper output argument |
|
||||
| argvLocal.c:122:15:122:16 | i4 indirection | argvLocal.c:9:25:9:31 | *correct | argvLocal.c:9:25:9:31 | *correct | argvLocal.c:122:15:122:16 | printWrapper output argument |
|
||||
| argvLocal.c:128:2:128:13 | i5 | argvLocal.c:9:25:9:31 | correct | argvLocal.c:9:25:9:31 | *correct | argvLocal.c:128:15:128:16 | printWrapper output argument |
|
||||
| argvLocal.c:128:15:128:16 | i5 indirection | argvLocal.c:9:25:9:31 | *correct | argvLocal.c:9:25:9:31 | *correct | argvLocal.c:128:15:128:16 | printWrapper output argument |
|
||||
| argvLocal.c:102:15:102:16 | i1 indirection | argvLocal.c:9:25:9:31 | *correct | argvLocal.c:9:25:9:31 | ReturnIndirection | argvLocal.c:102:15:102:16 | printWrapper output argument |
|
||||
| argvLocal.c:107:15:107:19 | access to array indirection | argvLocal.c:9:25:9:31 | *correct | argvLocal.c:9:25:9:31 | ReturnIndirection | argvLocal.c:107:15:107:19 | printWrapper output argument |
|
||||
| argvLocal.c:117:15:117:16 | i3 indirection | argvLocal.c:9:25:9:31 | *correct | argvLocal.c:9:25:9:31 | ReturnIndirection | argvLocal.c:117:15:117:16 | printWrapper output argument |
|
||||
| argvLocal.c:122:15:122:16 | i4 indirection | argvLocal.c:9:25:9:31 | *correct | argvLocal.c:9:25:9:31 | ReturnIndirection | argvLocal.c:122:15:122:16 | printWrapper output argument |
|
||||
| argvLocal.c:128:15:128:16 | i5 indirection | argvLocal.c:9:25:9:31 | *correct | argvLocal.c:9:25:9:31 | ReturnIndirection | argvLocal.c:128:15:128:16 | printWrapper output argument |
|
||||
nodes
|
||||
| argvLocal.c:9:25:9:31 | *correct | semmle.label | *correct |
|
||||
| argvLocal.c:9:25:9:31 | *correct | semmle.label | *correct |
|
||||
| argvLocal.c:9:25:9:31 | correct | semmle.label | correct |
|
||||
| argvLocal.c:9:25:9:31 | ReturnIndirection | semmle.label | ReturnIndirection |
|
||||
| argvLocal.c:95:9:95:12 | argv | semmle.label | argv |
|
||||
| argvLocal.c:95:9:95:12 | argv | semmle.label | argv |
|
||||
| argvLocal.c:95:9:95:15 | (const char *)... | semmle.label | (const char *)... |
|
||||
|
@ -288,6 +273,7 @@ nodes
|
|||
| argvLocal.c:102:15:102:16 | i1 | semmle.label | i1 |
|
||||
| argvLocal.c:102:15:102:16 | i1 indirection | semmle.label | i1 indirection |
|
||||
| argvLocal.c:102:15:102:16 | i1 indirection | semmle.label | i1 indirection |
|
||||
| argvLocal.c:102:15:102:16 | printWrapper output argument | semmle.label | printWrapper output argument |
|
||||
| argvLocal.c:105:14:105:17 | argv | semmle.label | argv |
|
||||
| argvLocal.c:105:14:105:17 | argv | semmle.label | argv |
|
||||
| argvLocal.c:106:9:106:13 | (const char *)... | semmle.label | (const char *)... |
|
||||
|
@ -302,6 +288,7 @@ nodes
|
|||
| argvLocal.c:107:15:107:19 | access to array | semmle.label | access to array |
|
||||
| argvLocal.c:107:15:107:19 | access to array indirection | semmle.label | access to array indirection |
|
||||
| argvLocal.c:107:15:107:19 | access to array indirection | semmle.label | access to array indirection |
|
||||
| argvLocal.c:107:15:107:19 | printWrapper output argument | semmle.label | printWrapper output argument |
|
||||
| argvLocal.c:110:9:110:11 | (const char *)... | semmle.label | (const char *)... |
|
||||
| argvLocal.c:110:9:110:11 | (const char *)... | semmle.label | (const char *)... |
|
||||
| argvLocal.c:110:9:110:11 | * ... | semmle.label | * ... |
|
||||
|
@ -321,7 +308,6 @@ nodes
|
|||
| argvLocal.c:116:9:116:10 | i3 | semmle.label | i3 |
|
||||
| argvLocal.c:116:9:116:10 | i3 indirection | semmle.label | i3 indirection |
|
||||
| argvLocal.c:116:9:116:10 | i3 indirection | semmle.label | i3 indirection |
|
||||
| argvLocal.c:117:2:117:13 | i3 | semmle.label | i3 |
|
||||
| argvLocal.c:117:15:117:16 | array to pointer conversion | semmle.label | array to pointer conversion |
|
||||
| argvLocal.c:117:15:117:16 | array to pointer conversion | semmle.label | array to pointer conversion |
|
||||
| argvLocal.c:117:15:117:16 | i3 | semmle.label | i3 |
|
||||
|
@ -333,7 +319,6 @@ nodes
|
|||
| argvLocal.c:121:9:121:10 | i4 | semmle.label | i4 |
|
||||
| argvLocal.c:121:9:121:10 | i4 indirection | semmle.label | i4 indirection |
|
||||
| argvLocal.c:121:9:121:10 | i4 indirection | semmle.label | i4 indirection |
|
||||
| argvLocal.c:122:2:122:13 | i4 | semmle.label | i4 |
|
||||
| argvLocal.c:122:15:122:16 | i4 | semmle.label | i4 |
|
||||
| argvLocal.c:122:15:122:16 | i4 | semmle.label | i4 |
|
||||
| argvLocal.c:122:15:122:16 | i4 | semmle.label | i4 |
|
||||
|
@ -347,7 +332,6 @@ nodes
|
|||
| argvLocal.c:127:9:127:10 | i5 | semmle.label | i5 |
|
||||
| argvLocal.c:127:9:127:10 | i5 indirection | semmle.label | i5 indirection |
|
||||
| argvLocal.c:127:9:127:10 | i5 indirection | semmle.label | i5 indirection |
|
||||
| argvLocal.c:128:2:128:13 | i5 | semmle.label | i5 |
|
||||
| argvLocal.c:128:15:128:16 | array to pointer conversion | semmle.label | array to pointer conversion |
|
||||
| argvLocal.c:128:15:128:16 | array to pointer conversion | semmle.label | array to pointer conversion |
|
||||
| argvLocal.c:128:15:128:16 | i5 | semmle.label | i5 |
|
||||
|
@ -364,9 +348,13 @@ nodes
|
|||
| argvLocal.c:132:15:132:20 | ... + ... | semmle.label | ... + ... |
|
||||
| argvLocal.c:132:15:132:20 | ... + ... indirection | semmle.label | ... + ... indirection |
|
||||
| argvLocal.c:132:15:132:20 | ... + ... indirection | semmle.label | ... + ... indirection |
|
||||
| argvLocal.c:135:9:135:10 | i4 | semmle.label | i4 |
|
||||
| argvLocal.c:135:9:135:10 | i4 | semmle.label | i4 |
|
||||
| argvLocal.c:135:9:135:12 | (const char *)... | semmle.label | (const char *)... |
|
||||
| argvLocal.c:135:9:135:12 | (const char *)... | semmle.label | (const char *)... |
|
||||
| argvLocal.c:135:9:135:12 | ... ++ | semmle.label | ... ++ |
|
||||
| argvLocal.c:135:9:135:12 | ... ++ | semmle.label | ... ++ |
|
||||
| argvLocal.c:135:9:135:12 | ... ++ | semmle.label | ... ++ |
|
||||
| argvLocal.c:135:9:135:12 | ... ++ indirection | semmle.label | ... ++ indirection |
|
||||
| argvLocal.c:135:9:135:12 | ... ++ indirection | semmle.label | ... ++ indirection |
|
||||
| argvLocal.c:136:15:136:18 | -- ... | semmle.label | -- ... |
|
||||
|
@ -374,6 +362,8 @@ nodes
|
|||
| argvLocal.c:136:15:136:18 | -- ... | semmle.label | -- ... |
|
||||
| argvLocal.c:136:15:136:18 | -- ... indirection | semmle.label | -- ... indirection |
|
||||
| argvLocal.c:136:15:136:18 | -- ... indirection | semmle.label | -- ... indirection |
|
||||
| argvLocal.c:136:17:136:18 | i4 | semmle.label | i4 |
|
||||
| argvLocal.c:136:17:136:18 | i4 | semmle.label | i4 |
|
||||
| argvLocal.c:144:9:144:10 | (const char *)... | semmle.label | (const char *)... |
|
||||
| argvLocal.c:144:9:144:10 | (const char *)... | semmle.label | (const char *)... |
|
||||
| argvLocal.c:144:9:144:10 | i7 | semmle.label | i7 |
|
||||
|
|
|
@ -1,4 +1,10 @@
|
|||
edges
|
||||
| funcsLocal.c:16:8:16:9 | (void *)... | funcsLocal.c:17:9:17:10 | (const char *)... |
|
||||
| funcsLocal.c:16:8:16:9 | (void *)... | funcsLocal.c:17:9:17:10 | i1 |
|
||||
| funcsLocal.c:16:8:16:9 | (void *)... | funcsLocal.c:17:9:17:10 | i1 indirection |
|
||||
| funcsLocal.c:16:8:16:9 | (void *)... | funcsLocal.c:58:9:58:10 | (const char *)... |
|
||||
| funcsLocal.c:16:8:16:9 | (void *)... | funcsLocal.c:58:9:58:10 | e1 |
|
||||
| funcsLocal.c:16:8:16:9 | (void *)... | funcsLocal.c:58:9:58:10 | e1 indirection |
|
||||
| funcsLocal.c:16:8:16:9 | fread output argument | funcsLocal.c:17:9:17:10 | (const char *)... |
|
||||
| funcsLocal.c:16:8:16:9 | fread output argument | funcsLocal.c:17:9:17:10 | i1 |
|
||||
| funcsLocal.c:16:8:16:9 | fread output argument | funcsLocal.c:17:9:17:10 | i1 indirection |
|
||||
|
@ -51,8 +57,29 @@ edges
|
|||
| funcsLocal.c:41:18:41:20 | i61 | funcsLocal.c:42:9:42:10 | (const char *)... |
|
||||
| funcsLocal.c:41:18:41:20 | i61 | funcsLocal.c:42:9:42:10 | i6 |
|
||||
| funcsLocal.c:41:18:41:20 | i61 | funcsLocal.c:42:9:42:10 | i6 indirection |
|
||||
| funcsLocal.c:46:7:46:9 | * ... | funcsLocal.c:47:9:47:11 | (const char *)... |
|
||||
| funcsLocal.c:46:7:46:9 | * ... | funcsLocal.c:47:9:47:11 | (const char *)... |
|
||||
| funcsLocal.c:46:7:46:9 | * ... | funcsLocal.c:47:9:47:11 | * ... |
|
||||
| funcsLocal.c:46:7:46:9 | * ... | funcsLocal.c:47:9:47:11 | * ... |
|
||||
| funcsLocal.c:46:7:46:9 | * ... | funcsLocal.c:47:9:47:11 | * ... |
|
||||
| funcsLocal.c:46:7:46:9 | * ... | funcsLocal.c:47:9:47:11 | * ... |
|
||||
| funcsLocal.c:46:7:46:9 | * ... | funcsLocal.c:47:9:47:11 | * ... indirection |
|
||||
| funcsLocal.c:46:7:46:9 | * ... | funcsLocal.c:47:9:47:11 | * ... indirection |
|
||||
| funcsLocal.c:46:7:46:9 | gets output argument | funcsLocal.c:47:9:47:11 | (const char *)... |
|
||||
| funcsLocal.c:46:7:46:9 | gets output argument | funcsLocal.c:47:9:47:11 | * ... |
|
||||
| funcsLocal.c:46:7:46:9 | gets output argument | funcsLocal.c:47:9:47:11 | * ... |
|
||||
| funcsLocal.c:46:7:46:9 | gets output argument | funcsLocal.c:47:9:47:11 | * ... indirection |
|
||||
| funcsLocal.c:52:8:52:11 | call to gets | funcsLocal.c:53:9:53:11 | (const char *)... |
|
||||
| funcsLocal.c:52:8:52:11 | call to gets | funcsLocal.c:53:9:53:11 | (const char *)... |
|
||||
| funcsLocal.c:52:8:52:11 | call to gets | funcsLocal.c:53:9:53:11 | * ... |
|
||||
| funcsLocal.c:52:8:52:11 | call to gets | funcsLocal.c:53:9:53:11 | * ... |
|
||||
| funcsLocal.c:52:8:52:11 | call to gets | funcsLocal.c:53:9:53:11 | * ... |
|
||||
| funcsLocal.c:52:8:52:11 | call to gets | funcsLocal.c:53:9:53:11 | * ... |
|
||||
| funcsLocal.c:52:8:52:11 | call to gets | funcsLocal.c:53:9:53:11 | * ... indirection |
|
||||
| funcsLocal.c:52:8:52:11 | call to gets | funcsLocal.c:53:9:53:11 | * ... indirection |
|
||||
subpaths
|
||||
nodes
|
||||
| funcsLocal.c:16:8:16:9 | (void *)... | semmle.label | (void *)... |
|
||||
| funcsLocal.c:16:8:16:9 | fread output argument | semmle.label | fread output argument |
|
||||
| funcsLocal.c:16:8:16:9 | i1 | semmle.label | i1 |
|
||||
| funcsLocal.c:17:9:17:10 | (const char *)... | semmle.label | (const char *)... |
|
||||
|
@ -96,6 +123,25 @@ nodes
|
|||
| funcsLocal.c:42:9:42:10 | i6 | semmle.label | i6 |
|
||||
| funcsLocal.c:42:9:42:10 | i6 indirection | semmle.label | i6 indirection |
|
||||
| funcsLocal.c:42:9:42:10 | i6 indirection | semmle.label | i6 indirection |
|
||||
| funcsLocal.c:46:7:46:9 | * ... | semmle.label | * ... |
|
||||
| funcsLocal.c:46:7:46:9 | * ... | semmle.label | * ... |
|
||||
| funcsLocal.c:46:7:46:9 | gets output argument | semmle.label | gets output argument |
|
||||
| funcsLocal.c:47:9:47:11 | (const char *)... | semmle.label | (const char *)... |
|
||||
| funcsLocal.c:47:9:47:11 | (const char *)... | semmle.label | (const char *)... |
|
||||
| funcsLocal.c:47:9:47:11 | * ... | semmle.label | * ... |
|
||||
| funcsLocal.c:47:9:47:11 | * ... | semmle.label | * ... |
|
||||
| funcsLocal.c:47:9:47:11 | * ... | semmle.label | * ... |
|
||||
| funcsLocal.c:47:9:47:11 | * ... indirection | semmle.label | * ... indirection |
|
||||
| funcsLocal.c:47:9:47:11 | * ... indirection | semmle.label | * ... indirection |
|
||||
| funcsLocal.c:52:8:52:11 | call to gets | semmle.label | call to gets |
|
||||
| funcsLocal.c:52:8:52:11 | call to gets | semmle.label | call to gets |
|
||||
| funcsLocal.c:53:9:53:11 | (const char *)... | semmle.label | (const char *)... |
|
||||
| funcsLocal.c:53:9:53:11 | (const char *)... | semmle.label | (const char *)... |
|
||||
| funcsLocal.c:53:9:53:11 | * ... | semmle.label | * ... |
|
||||
| funcsLocal.c:53:9:53:11 | * ... | semmle.label | * ... |
|
||||
| funcsLocal.c:53:9:53:11 | * ... | semmle.label | * ... |
|
||||
| funcsLocal.c:53:9:53:11 | * ... indirection | semmle.label | * ... indirection |
|
||||
| funcsLocal.c:53:9:53:11 | * ... indirection | semmle.label | * ... indirection |
|
||||
| funcsLocal.c:58:9:58:10 | (const char *)... | semmle.label | (const char *)... |
|
||||
| funcsLocal.c:58:9:58:10 | (const char *)... | semmle.label | (const char *)... |
|
||||
| funcsLocal.c:58:9:58:10 | e1 | semmle.label | e1 |
|
||||
|
@ -109,4 +155,6 @@ nodes
|
|||
| funcsLocal.c:37:9:37:10 | i5 | funcsLocal.c:36:7:36:8 | i5 | funcsLocal.c:37:9:37:10 | i5 | The value of this argument may come from $@ and is being used as a formatting argument to printf(format) | funcsLocal.c:36:7:36:8 | i5 | gets |
|
||||
| funcsLocal.c:42:9:42:10 | i6 | funcsLocal.c:41:13:41:16 | call to gets | funcsLocal.c:42:9:42:10 | i6 | The value of this argument may come from $@ and is being used as a formatting argument to printf(format) | funcsLocal.c:41:13:41:16 | call to gets | gets |
|
||||
| funcsLocal.c:42:9:42:10 | i6 | funcsLocal.c:41:18:41:20 | i61 | funcsLocal.c:42:9:42:10 | i6 | The value of this argument may come from $@ and is being used as a formatting argument to printf(format) | funcsLocal.c:41:18:41:20 | i61 | gets |
|
||||
| funcsLocal.c:47:9:47:11 | * ... | funcsLocal.c:46:7:46:9 | * ... | funcsLocal.c:47:9:47:11 | * ... | The value of this argument may come from $@ and is being used as a formatting argument to printf(format) | funcsLocal.c:46:7:46:9 | * ... | gets |
|
||||
| funcsLocal.c:53:9:53:11 | * ... | funcsLocal.c:52:8:52:11 | call to gets | funcsLocal.c:53:9:53:11 | * ... | The value of this argument may come from $@ and is being used as a formatting argument to printf(format) | funcsLocal.c:52:8:52:11 | call to gets | gets |
|
||||
| funcsLocal.c:58:9:58:10 | e1 | funcsLocal.c:16:8:16:9 | i1 | funcsLocal.c:58:9:58:10 | e1 | The value of this argument may come from $@ and is being used as a formatting argument to printf(format) | funcsLocal.c:16:8:16:9 | i1 | fread |
|
||||
|
|
|
@ -5,6 +5,7 @@ edges
|
|||
| globalVars.c:8:7:8:10 | copy | globalVars.c:30:15:30:18 | copy |
|
||||
| globalVars.c:8:7:8:10 | copy | globalVars.c:30:15:30:18 | copy |
|
||||
| globalVars.c:8:7:8:10 | copy | globalVars.c:30:15:30:18 | copy |
|
||||
| globalVars.c:8:7:8:10 | copy | globalVars.c:33:15:33:18 | copy |
|
||||
| globalVars.c:8:7:8:10 | copy | globalVars.c:35:11:35:14 | copy |
|
||||
| globalVars.c:9:7:9:11 | copy2 | globalVars.c:38:9:38:13 | copy2 |
|
||||
| globalVars.c:9:7:9:11 | copy2 | globalVars.c:38:9:38:13 | copy2 |
|
||||
|
@ -12,15 +13,16 @@ edges
|
|||
| globalVars.c:9:7:9:11 | copy2 | globalVars.c:41:15:41:19 | copy2 |
|
||||
| globalVars.c:9:7:9:11 | copy2 | globalVars.c:41:15:41:19 | copy2 |
|
||||
| globalVars.c:9:7:9:11 | copy2 | globalVars.c:41:15:41:19 | copy2 |
|
||||
| globalVars.c:9:7:9:11 | copy2 | globalVars.c:44:15:44:19 | copy2 |
|
||||
| globalVars.c:9:7:9:11 | copy2 | globalVars.c:50:9:50:13 | copy2 |
|
||||
| globalVars.c:9:7:9:11 | copy2 | globalVars.c:50:9:50:13 | copy2 |
|
||||
| globalVars.c:9:7:9:11 | copy2 | globalVars.c:50:9:50:13 | copy2 |
|
||||
| globalVars.c:11:22:11:25 | *argv | globalVars.c:12:2:12:15 | Store |
|
||||
| globalVars.c:11:22:11:25 | argv | globalVars.c:11:22:11:25 | *argv |
|
||||
| globalVars.c:11:22:11:25 | argv | globalVars.c:12:2:12:15 | Store |
|
||||
| globalVars.c:12:2:12:15 | Store | globalVars.c:8:7:8:10 | copy |
|
||||
| globalVars.c:15:21:15:23 | val | globalVars.c:16:2:16:12 | Store |
|
||||
| globalVars.c:16:2:16:12 | Store | globalVars.c:9:7:9:11 | copy2 |
|
||||
| globalVars.c:19:25:19:27 | *str | globalVars.c:19:25:19:27 | ReturnIndirection |
|
||||
| globalVars.c:24:2:24:9 | argv | globalVars.c:11:22:11:25 | argv |
|
||||
| globalVars.c:24:11:24:14 | argv | globalVars.c:24:2:24:9 | argv |
|
||||
| globalVars.c:24:11:24:14 | argv | globalVars.c:24:2:24:9 | argv |
|
||||
|
@ -34,6 +36,12 @@ edges
|
|||
| globalVars.c:30:15:30:18 | copy | globalVars.c:30:15:30:18 | copy |
|
||||
| globalVars.c:30:15:30:18 | copy | globalVars.c:30:15:30:18 | copy |
|
||||
| globalVars.c:30:15:30:18 | copy | globalVars.c:30:15:30:18 | copy indirection |
|
||||
| globalVars.c:30:15:30:18 | copy | globalVars.c:30:15:30:18 | copy indirection |
|
||||
| globalVars.c:30:15:30:18 | copy | globalVars.c:35:2:35:9 | copy |
|
||||
| globalVars.c:30:15:30:18 | copy indirection | globalVars.c:19:25:19:27 | *str |
|
||||
| globalVars.c:30:15:30:18 | copy indirection | globalVars.c:30:15:30:18 | printWrapper output argument |
|
||||
| globalVars.c:30:15:30:18 | printWrapper output argument | globalVars.c:35:2:35:9 | copy |
|
||||
| globalVars.c:33:15:33:18 | copy | globalVars.c:35:2:35:9 | copy |
|
||||
| globalVars.c:35:2:35:9 | copy | globalVars.c:15:21:15:23 | val |
|
||||
| globalVars.c:35:11:35:14 | copy | globalVars.c:35:2:35:9 | copy |
|
||||
| globalVars.c:38:9:38:13 | copy2 | globalVars.c:38:9:38:13 | (const char *)... |
|
||||
|
@ -43,10 +51,30 @@ edges
|
|||
| globalVars.c:41:15:41:19 | copy2 | globalVars.c:41:15:41:19 | copy2 |
|
||||
| globalVars.c:41:15:41:19 | copy2 | globalVars.c:41:15:41:19 | copy2 |
|
||||
| globalVars.c:41:15:41:19 | copy2 | globalVars.c:41:15:41:19 | copy2 indirection |
|
||||
| globalVars.c:41:15:41:19 | copy2 | globalVars.c:41:15:41:19 | copy2 indirection |
|
||||
| globalVars.c:41:15:41:19 | copy2 | globalVars.c:50:9:50:13 | (const char *)... |
|
||||
| globalVars.c:41:15:41:19 | copy2 | globalVars.c:50:9:50:13 | copy2 |
|
||||
| globalVars.c:41:15:41:19 | copy2 | globalVars.c:50:9:50:13 | copy2 |
|
||||
| globalVars.c:41:15:41:19 | copy2 | globalVars.c:50:9:50:13 | copy2 |
|
||||
| globalVars.c:41:15:41:19 | copy2 | globalVars.c:50:9:50:13 | copy2 indirection |
|
||||
| globalVars.c:41:15:41:19 | copy2 indirection | globalVars.c:19:25:19:27 | *str |
|
||||
| globalVars.c:41:15:41:19 | copy2 indirection | globalVars.c:41:15:41:19 | printWrapper output argument |
|
||||
| globalVars.c:41:15:41:19 | printWrapper output argument | globalVars.c:50:9:50:13 | (const char *)... |
|
||||
| globalVars.c:41:15:41:19 | printWrapper output argument | globalVars.c:50:9:50:13 | copy2 |
|
||||
| globalVars.c:41:15:41:19 | printWrapper output argument | globalVars.c:50:9:50:13 | copy2 |
|
||||
| globalVars.c:41:15:41:19 | printWrapper output argument | globalVars.c:50:9:50:13 | copy2 |
|
||||
| globalVars.c:41:15:41:19 | printWrapper output argument | globalVars.c:50:9:50:13 | copy2 indirection |
|
||||
| globalVars.c:44:15:44:19 | copy2 | globalVars.c:50:9:50:13 | (const char *)... |
|
||||
| globalVars.c:44:15:44:19 | copy2 | globalVars.c:50:9:50:13 | copy2 |
|
||||
| globalVars.c:44:15:44:19 | copy2 | globalVars.c:50:9:50:13 | copy2 |
|
||||
| globalVars.c:44:15:44:19 | copy2 | globalVars.c:50:9:50:13 | copy2 |
|
||||
| globalVars.c:44:15:44:19 | copy2 | globalVars.c:50:9:50:13 | copy2 indirection |
|
||||
| globalVars.c:50:9:50:13 | copy2 | globalVars.c:50:9:50:13 | (const char *)... |
|
||||
| globalVars.c:50:9:50:13 | copy2 | globalVars.c:50:9:50:13 | copy2 |
|
||||
| globalVars.c:50:9:50:13 | copy2 | globalVars.c:50:9:50:13 | copy2 indirection |
|
||||
subpaths
|
||||
| globalVars.c:30:15:30:18 | copy indirection | globalVars.c:19:25:19:27 | *str | globalVars.c:19:25:19:27 | ReturnIndirection | globalVars.c:30:15:30:18 | printWrapper output argument |
|
||||
| globalVars.c:41:15:41:19 | copy2 indirection | globalVars.c:19:25:19:27 | *str | globalVars.c:19:25:19:27 | ReturnIndirection | globalVars.c:41:15:41:19 | printWrapper output argument |
|
||||
nodes
|
||||
| globalVars.c:8:7:8:10 | copy | semmle.label | copy |
|
||||
| globalVars.c:9:7:9:11 | copy2 | semmle.label | copy2 |
|
||||
|
@ -55,6 +83,8 @@ nodes
|
|||
| globalVars.c:12:2:12:15 | Store | semmle.label | Store |
|
||||
| globalVars.c:15:21:15:23 | val | semmle.label | val |
|
||||
| globalVars.c:16:2:16:12 | Store | semmle.label | Store |
|
||||
| globalVars.c:19:25:19:27 | *str | semmle.label | *str |
|
||||
| globalVars.c:19:25:19:27 | ReturnIndirection | semmle.label | ReturnIndirection |
|
||||
| globalVars.c:24:2:24:9 | argv | semmle.label | argv |
|
||||
| globalVars.c:24:11:24:14 | argv | semmle.label | argv |
|
||||
| globalVars.c:24:11:24:14 | argv | semmle.label | argv |
|
||||
|
@ -71,6 +101,8 @@ nodes
|
|||
| globalVars.c:30:15:30:18 | copy | semmle.label | copy |
|
||||
| globalVars.c:30:15:30:18 | copy indirection | semmle.label | copy indirection |
|
||||
| globalVars.c:30:15:30:18 | copy indirection | semmle.label | copy indirection |
|
||||
| globalVars.c:30:15:30:18 | printWrapper output argument | semmle.label | printWrapper output argument |
|
||||
| globalVars.c:33:15:33:18 | copy | semmle.label | copy |
|
||||
| globalVars.c:35:2:35:9 | copy | semmle.label | copy |
|
||||
| globalVars.c:35:11:35:14 | copy | semmle.label | copy |
|
||||
| globalVars.c:38:9:38:13 | (const char *)... | semmle.label | (const char *)... |
|
||||
|
@ -85,6 +117,8 @@ nodes
|
|||
| globalVars.c:41:15:41:19 | copy2 | semmle.label | copy2 |
|
||||
| globalVars.c:41:15:41:19 | copy2 indirection | semmle.label | copy2 indirection |
|
||||
| globalVars.c:41:15:41:19 | copy2 indirection | semmle.label | copy2 indirection |
|
||||
| globalVars.c:41:15:41:19 | printWrapper output argument | semmle.label | printWrapper output argument |
|
||||
| globalVars.c:44:15:44:19 | copy2 | semmle.label | copy2 |
|
||||
| globalVars.c:50:9:50:13 | (const char *)... | semmle.label | (const char *)... |
|
||||
| globalVars.c:50:9:50:13 | (const char *)... | semmle.label | (const char *)... |
|
||||
| globalVars.c:50:9:50:13 | copy2 | semmle.label | copy2 |
|
||||
|
|
|
@ -86,13 +86,13 @@ int main(int argc, char **argv) {
|
|||
i3 = argv[1];
|
||||
printf(i3);
|
||||
|
||||
// BAD [FALSE NEGATIVE]: varOne is 1 so condition is true and it always goes inside the if
|
||||
// BAD: varOne is 1 so condition is true and it always goes inside the if
|
||||
char *i4;
|
||||
if (varOne)
|
||||
i4 = argv[1];
|
||||
printf(i4);
|
||||
|
||||
// BAD [FALSE NEGATIVE]: varZero is 0 so condition is true and it always goes inside the if
|
||||
// BAD: varZero is 0 so condition is true and it always goes inside the if
|
||||
char *i5;
|
||||
if (!varZero)
|
||||
i5 = argv[1];
|
||||
|
|
|
@ -39,6 +39,22 @@ edges
|
|||
| ifs.c:86:8:86:11 | argv | ifs.c:87:9:87:10 | i3 |
|
||||
| ifs.c:86:8:86:11 | argv | ifs.c:87:9:87:10 | i3 indirection |
|
||||
| ifs.c:86:8:86:11 | argv | ifs.c:87:9:87:10 | i3 indirection |
|
||||
| ifs.c:92:8:92:11 | argv | ifs.c:93:9:93:10 | (const char *)... |
|
||||
| ifs.c:92:8:92:11 | argv | ifs.c:93:9:93:10 | (const char *)... |
|
||||
| ifs.c:92:8:92:11 | argv | ifs.c:93:9:93:10 | i4 |
|
||||
| ifs.c:92:8:92:11 | argv | ifs.c:93:9:93:10 | i4 |
|
||||
| ifs.c:92:8:92:11 | argv | ifs.c:93:9:93:10 | i4 |
|
||||
| ifs.c:92:8:92:11 | argv | ifs.c:93:9:93:10 | i4 |
|
||||
| ifs.c:92:8:92:11 | argv | ifs.c:93:9:93:10 | i4 indirection |
|
||||
| ifs.c:92:8:92:11 | argv | ifs.c:93:9:93:10 | i4 indirection |
|
||||
| ifs.c:98:8:98:11 | argv | ifs.c:99:9:99:10 | (const char *)... |
|
||||
| ifs.c:98:8:98:11 | argv | ifs.c:99:9:99:10 | (const char *)... |
|
||||
| ifs.c:98:8:98:11 | argv | ifs.c:99:9:99:10 | i5 |
|
||||
| ifs.c:98:8:98:11 | argv | ifs.c:99:9:99:10 | i5 |
|
||||
| ifs.c:98:8:98:11 | argv | ifs.c:99:9:99:10 | i5 |
|
||||
| ifs.c:98:8:98:11 | argv | ifs.c:99:9:99:10 | i5 |
|
||||
| ifs.c:98:8:98:11 | argv | ifs.c:99:9:99:10 | i5 indirection |
|
||||
| ifs.c:98:8:98:11 | argv | ifs.c:99:9:99:10 | i5 indirection |
|
||||
| ifs.c:105:8:105:11 | argv | ifs.c:106:9:106:10 | (const char *)... |
|
||||
| ifs.c:105:8:105:11 | argv | ifs.c:106:9:106:10 | (const char *)... |
|
||||
| ifs.c:105:8:105:11 | argv | ifs.c:106:9:106:10 | i6 |
|
||||
|
@ -118,6 +134,24 @@ nodes
|
|||
| ifs.c:87:9:87:10 | i3 | semmle.label | i3 |
|
||||
| ifs.c:87:9:87:10 | i3 indirection | semmle.label | i3 indirection |
|
||||
| ifs.c:87:9:87:10 | i3 indirection | semmle.label | i3 indirection |
|
||||
| ifs.c:92:8:92:11 | argv | semmle.label | argv |
|
||||
| ifs.c:92:8:92:11 | argv | semmle.label | argv |
|
||||
| ifs.c:93:9:93:10 | (const char *)... | semmle.label | (const char *)... |
|
||||
| ifs.c:93:9:93:10 | (const char *)... | semmle.label | (const char *)... |
|
||||
| ifs.c:93:9:93:10 | i4 | semmle.label | i4 |
|
||||
| ifs.c:93:9:93:10 | i4 | semmle.label | i4 |
|
||||
| ifs.c:93:9:93:10 | i4 | semmle.label | i4 |
|
||||
| ifs.c:93:9:93:10 | i4 indirection | semmle.label | i4 indirection |
|
||||
| ifs.c:93:9:93:10 | i4 indirection | semmle.label | i4 indirection |
|
||||
| ifs.c:98:8:98:11 | argv | semmle.label | argv |
|
||||
| ifs.c:98:8:98:11 | argv | semmle.label | argv |
|
||||
| ifs.c:99:9:99:10 | (const char *)... | semmle.label | (const char *)... |
|
||||
| ifs.c:99:9:99:10 | (const char *)... | semmle.label | (const char *)... |
|
||||
| ifs.c:99:9:99:10 | i5 | semmle.label | i5 |
|
||||
| ifs.c:99:9:99:10 | i5 | semmle.label | i5 |
|
||||
| ifs.c:99:9:99:10 | i5 | semmle.label | i5 |
|
||||
| ifs.c:99:9:99:10 | i5 indirection | semmle.label | i5 indirection |
|
||||
| ifs.c:99:9:99:10 | i5 indirection | semmle.label | i5 indirection |
|
||||
| ifs.c:105:8:105:11 | argv | semmle.label | argv |
|
||||
| ifs.c:105:8:105:11 | argv | semmle.label | argv |
|
||||
| ifs.c:106:9:106:10 | (const char *)... | semmle.label | (const char *)... |
|
||||
|
@ -160,6 +194,8 @@ nodes
|
|||
| ifs.c:75:9:75:10 | i1 | ifs.c:74:8:74:11 | argv | ifs.c:75:9:75:10 | i1 | The value of this argument may come from $@ and is being used as a formatting argument to printf(format) | ifs.c:74:8:74:11 | argv | argv |
|
||||
| ifs.c:81:9:81:10 | i2 | ifs.c:80:8:80:11 | argv | ifs.c:81:9:81:10 | i2 | The value of this argument may come from $@ and is being used as a formatting argument to printf(format) | ifs.c:80:8:80:11 | argv | argv |
|
||||
| ifs.c:87:9:87:10 | i3 | ifs.c:86:8:86:11 | argv | ifs.c:87:9:87:10 | i3 | The value of this argument may come from $@ and is being used as a formatting argument to printf(format) | ifs.c:86:8:86:11 | argv | argv |
|
||||
| ifs.c:93:9:93:10 | i4 | ifs.c:92:8:92:11 | argv | ifs.c:93:9:93:10 | i4 | The value of this argument may come from $@ and is being used as a formatting argument to printf(format) | ifs.c:92:8:92:11 | argv | argv |
|
||||
| ifs.c:99:9:99:10 | i5 | ifs.c:98:8:98:11 | argv | ifs.c:99:9:99:10 | i5 | The value of this argument may come from $@ and is being used as a formatting argument to printf(format) | ifs.c:98:8:98:11 | argv | argv |
|
||||
| ifs.c:106:9:106:10 | i6 | ifs.c:105:8:105:11 | argv | ifs.c:106:9:106:10 | i6 | The value of this argument may come from $@ and is being used as a formatting argument to printf(format) | ifs.c:105:8:105:11 | argv | argv |
|
||||
| ifs.c:112:9:112:10 | i7 | ifs.c:111:8:111:11 | argv | ifs.c:112:9:112:10 | i7 | The value of this argument may come from $@ and is being used as a formatting argument to printf(format) | ifs.c:111:8:111:11 | argv | argv |
|
||||
| ifs.c:118:9:118:10 | i8 | ifs.c:117:8:117:11 | argv | ifs.c:118:9:118:10 | i8 | The value of this argument may come from $@ and is being used as a formatting argument to printf(format) | ifs.c:117:8:117:11 | argv | argv |
|
||||
|
|
|
@ -6,25 +6,24 @@ edges
|
|||
| test.c:75:13:75:19 | call to rand | test.c:77:9:77:9 | r |
|
||||
| test.c:81:14:81:17 | call to rand | test.c:83:9:83:9 | r |
|
||||
| test.c:81:23:81:26 | call to rand | test.c:83:9:83:9 | r |
|
||||
| test.c:99:14:99:19 | call to rand | test.c:100:5:100:5 | r |
|
||||
| test.c:125:13:125:16 | call to rand | test.c:127:9:127:9 | r |
|
||||
| test.c:131:13:131:16 | call to rand | test.c:133:5:133:5 | r |
|
||||
| test.c:137:13:137:16 | call to rand | test.c:139:10:139:10 | r |
|
||||
| test.c:155:22:155:25 | call to rand | test.c:157:9:157:9 | r |
|
||||
| test.c:155:22:155:27 | (unsigned int)... | test.c:157:9:157:9 | r |
|
||||
| test.cpp:8:9:8:12 | Store | test.cpp:24:11:24:18 | call to get_rand |
|
||||
| test.cpp:8:9:8:12 | call to rand | test.cpp:8:9:8:12 | Store |
|
||||
| test.cpp:13:2:13:15 | Chi [[]] | test.cpp:30:13:30:14 | get_rand2 output argument [[]] |
|
||||
| test.cpp:13:10:13:13 | call to rand | test.cpp:13:2:13:15 | Chi [[]] |
|
||||
| test.cpp:18:2:18:14 | Chi [[]] | test.cpp:36:13:36:13 | get_rand3 output argument [[]] |
|
||||
| test.cpp:18:9:18:12 | call to rand | test.cpp:18:2:18:14 | Chi [[]] |
|
||||
| test.cpp:6:5:6:12 | ReturnValue | test.cpp:24:11:24:18 | call to get_rand |
|
||||
| test.cpp:8:9:8:12 | call to rand | test.cpp:6:5:6:12 | ReturnValue |
|
||||
| test.cpp:13:2:13:6 | * ... [post update] | test.cpp:30:3:30:11 | & ... [post update] |
|
||||
| test.cpp:13:3:13:6 | dest [post update] | test.cpp:30:3:30:11 | & ... [post update] |
|
||||
| test.cpp:13:10:13:13 | call to rand | test.cpp:13:2:13:6 | * ... [post update] |
|
||||
| test.cpp:13:10:13:13 | call to rand | test.cpp:13:3:13:6 | dest [post update] |
|
||||
| test.cpp:18:2:18:5 | (reference dereference) [post update] | test.cpp:36:3:36:11 | r [post update] |
|
||||
| test.cpp:18:2:18:5 | dest [post update] | test.cpp:36:3:36:11 | r [post update] |
|
||||
| test.cpp:18:9:18:12 | call to rand | test.cpp:18:2:18:5 | (reference dereference) [post update] |
|
||||
| test.cpp:18:9:18:12 | call to rand | test.cpp:18:2:18:5 | dest [post update] |
|
||||
| test.cpp:24:11:24:18 | call to get_rand | test.cpp:25:7:25:7 | r |
|
||||
| test.cpp:30:13:30:14 | Chi | test.cpp:31:7:31:7 | r |
|
||||
| test.cpp:30:13:30:14 | get_rand2 output argument [[]] | test.cpp:30:13:30:14 | Chi |
|
||||
| test.cpp:36:13:36:13 | Chi | test.cpp:37:7:37:7 | r |
|
||||
| test.cpp:36:13:36:13 | get_rand3 output argument [[]] | test.cpp:36:13:36:13 | Chi |
|
||||
| test.cpp:62:19:62:22 | call to rand | test.cpp:65:9:65:9 | x |
|
||||
| test.cpp:62:19:62:24 | (unsigned int)... | test.cpp:65:9:65:9 | x |
|
||||
| test.cpp:30:3:30:11 | & ... [post update] | test.cpp:31:7:31:7 | r |
|
||||
| test.cpp:36:3:36:11 | r [post update] | test.cpp:37:7:37:7 | r |
|
||||
| test.cpp:86:10:86:13 | call to rand | test.cpp:90:10:90:10 | x |
|
||||
| test.cpp:98:10:98:13 | call to rand | test.cpp:102:10:102:10 | x |
|
||||
| test.cpp:137:10:137:13 | call to rand | test.cpp:146:9:146:9 | y |
|
||||
|
@ -53,8 +52,6 @@ nodes
|
|||
| test.c:81:14:81:17 | call to rand | semmle.label | call to rand |
|
||||
| test.c:81:23:81:26 | call to rand | semmle.label | call to rand |
|
||||
| test.c:83:9:83:9 | r | semmle.label | r |
|
||||
| test.c:99:14:99:19 | call to rand | semmle.label | call to rand |
|
||||
| test.c:100:5:100:5 | r | semmle.label | r |
|
||||
| test.c:125:13:125:16 | call to rand | semmle.label | call to rand |
|
||||
| test.c:127:9:127:9 | r | semmle.label | r |
|
||||
| test.c:131:13:131:16 | call to rand | semmle.label | call to rand |
|
||||
|
@ -64,23 +61,20 @@ nodes
|
|||
| test.c:155:22:155:25 | call to rand | semmle.label | call to rand |
|
||||
| test.c:155:22:155:27 | (unsigned int)... | semmle.label | (unsigned int)... |
|
||||
| test.c:157:9:157:9 | r | semmle.label | r |
|
||||
| test.cpp:8:9:8:12 | Store | semmle.label | Store |
|
||||
| test.cpp:6:5:6:12 | ReturnValue | semmle.label | ReturnValue |
|
||||
| test.cpp:8:9:8:12 | call to rand | semmle.label | call to rand |
|
||||
| test.cpp:13:2:13:15 | Chi [[]] | semmle.label | Chi [[]] |
|
||||
| test.cpp:13:2:13:6 | * ... [post update] | semmle.label | * ... [post update] |
|
||||
| test.cpp:13:3:13:6 | dest [post update] | semmle.label | dest [post update] |
|
||||
| test.cpp:13:10:13:13 | call to rand | semmle.label | call to rand |
|
||||
| test.cpp:18:2:18:14 | Chi [[]] | semmle.label | Chi [[]] |
|
||||
| test.cpp:18:2:18:5 | (reference dereference) [post update] | semmle.label | (reference dereference) [post update] |
|
||||
| test.cpp:18:2:18:5 | dest [post update] | semmle.label | dest [post update] |
|
||||
| test.cpp:18:9:18:12 | call to rand | semmle.label | call to rand |
|
||||
| test.cpp:24:11:24:18 | call to get_rand | semmle.label | call to get_rand |
|
||||
| test.cpp:25:7:25:7 | r | semmle.label | r |
|
||||
| test.cpp:30:13:30:14 | Chi | semmle.label | Chi |
|
||||
| test.cpp:30:13:30:14 | get_rand2 output argument [[]] | semmle.label | get_rand2 output argument [[]] |
|
||||
| test.cpp:30:3:30:11 | & ... [post update] | semmle.label | & ... [post update] |
|
||||
| test.cpp:31:7:31:7 | r | semmle.label | r |
|
||||
| test.cpp:36:13:36:13 | Chi | semmle.label | Chi |
|
||||
| test.cpp:36:13:36:13 | get_rand3 output argument [[]] | semmle.label | get_rand3 output argument [[]] |
|
||||
| test.cpp:36:3:36:11 | r [post update] | semmle.label | r [post update] |
|
||||
| test.cpp:37:7:37:7 | r | semmle.label | r |
|
||||
| test.cpp:62:19:62:22 | call to rand | semmle.label | call to rand |
|
||||
| test.cpp:62:19:62:24 | (unsigned int)... | semmle.label | (unsigned int)... |
|
||||
| test.cpp:65:9:65:9 | x | semmle.label | x |
|
||||
| test.cpp:86:10:86:13 | call to rand | semmle.label | call to rand |
|
||||
| test.cpp:90:10:90:10 | x | semmle.label | x |
|
||||
| test.cpp:98:10:98:13 | call to rand | semmle.label | call to rand |
|
||||
|
@ -114,7 +108,6 @@ subpaths
|
|||
| test.c:77:9:77:9 | r | test.c:75:13:75:19 | call to rand | test.c:77:9:77:9 | r | $@ flows to here and is used in arithmetic, potentially causing an overflow. | test.c:75:13:75:19 | call to rand | Uncontrolled value |
|
||||
| test.c:83:9:83:9 | r | test.c:81:14:81:17 | call to rand | test.c:83:9:83:9 | r | $@ flows to here and is used in arithmetic, potentially causing an overflow. | test.c:81:14:81:17 | call to rand | Uncontrolled value |
|
||||
| test.c:83:9:83:9 | r | test.c:81:23:81:26 | call to rand | test.c:83:9:83:9 | r | $@ flows to here and is used in arithmetic, potentially causing an overflow. | test.c:81:23:81:26 | call to rand | Uncontrolled value |
|
||||
| test.c:100:5:100:5 | r | test.c:99:14:99:19 | call to rand | test.c:100:5:100:5 | r | $@ flows to here and is used in arithmetic, potentially causing an overflow. | test.c:99:14:99:19 | call to rand | Uncontrolled value |
|
||||
| test.c:127:9:127:9 | r | test.c:125:13:125:16 | call to rand | test.c:127:9:127:9 | r | $@ flows to here and is used in arithmetic, potentially causing an overflow. | test.c:125:13:125:16 | call to rand | Uncontrolled value |
|
||||
| test.c:133:5:133:5 | r | test.c:131:13:131:16 | call to rand | test.c:133:5:133:5 | r | $@ flows to here and is used in arithmetic, potentially causing an overflow. | test.c:131:13:131:16 | call to rand | Uncontrolled value |
|
||||
| test.c:139:10:139:10 | r | test.c:137:13:137:16 | call to rand | test.c:139:10:139:10 | r | $@ flows to here and is used in arithmetic, potentially causing an overflow. | test.c:137:13:137:16 | call to rand | Uncontrolled value |
|
||||
|
@ -123,8 +116,6 @@ subpaths
|
|||
| test.cpp:25:7:25:7 | r | test.cpp:8:9:8:12 | call to rand | test.cpp:25:7:25:7 | r | $@ flows to here and is used in arithmetic, potentially causing an overflow. | test.cpp:8:9:8:12 | call to rand | Uncontrolled value |
|
||||
| test.cpp:31:7:31:7 | r | test.cpp:13:10:13:13 | call to rand | test.cpp:31:7:31:7 | r | $@ flows to here and is used in arithmetic, potentially causing an overflow. | test.cpp:13:10:13:13 | call to rand | Uncontrolled value |
|
||||
| test.cpp:37:7:37:7 | r | test.cpp:18:9:18:12 | call to rand | test.cpp:37:7:37:7 | r | $@ flows to here and is used in arithmetic, potentially causing an overflow. | test.cpp:18:9:18:12 | call to rand | Uncontrolled value |
|
||||
| test.cpp:65:9:65:9 | x | test.cpp:62:19:62:22 | call to rand | test.cpp:65:9:65:9 | x | $@ flows to here and is used in arithmetic, potentially causing an underflow. | test.cpp:62:19:62:22 | call to rand | Uncontrolled value |
|
||||
| test.cpp:65:9:65:9 | x | test.cpp:62:19:62:24 | (unsigned int)... | test.cpp:65:9:65:9 | x | $@ flows to here and is used in arithmetic, potentially causing an underflow. | test.cpp:62:19:62:22 | call to rand | Uncontrolled value |
|
||||
| test.cpp:90:10:90:10 | x | test.cpp:86:10:86:13 | call to rand | test.cpp:90:10:90:10 | x | $@ flows to here and is used in arithmetic, potentially causing an overflow. | test.cpp:86:10:86:13 | call to rand | Uncontrolled value |
|
||||
| test.cpp:102:10:102:10 | x | test.cpp:98:10:98:13 | call to rand | test.cpp:102:10:102:10 | x | $@ flows to here and is used in arithmetic, potentially causing an overflow. | test.cpp:98:10:98:13 | call to rand | Uncontrolled value |
|
||||
| test.cpp:146:9:146:9 | y | test.cpp:137:10:137:13 | call to rand | test.cpp:146:9:146:9 | y | $@ flows to here and is used in arithmetic, potentially causing an overflow. | test.cpp:137:10:137:13 | call to rand | Uncontrolled value |
|
||||
|
|
|
@ -97,7 +97,7 @@ void randomTester() {
|
|||
int r = 0;
|
||||
int *ptr_r = &r;
|
||||
*ptr_r = RAND();
|
||||
r += 100; // BAD
|
||||
r += 100; // BAD [NOT DETECTED]
|
||||
}
|
||||
|
||||
{
|
||||
|
|
|
@ -62,7 +62,7 @@ unsigned int test_remainder_subtract_unsigned()
|
|||
unsigned int x = rand();
|
||||
unsigned int y = x % 100; // y <= x
|
||||
|
||||
return x - y; // GOOD (as y <= x) [FALSE POSITIVE]
|
||||
return x - y; // GOOD (as y <= x)
|
||||
}
|
||||
|
||||
typedef unsigned long size_t;
|
||||
|
|
|
@ -39,10 +39,10 @@ edges
|
|||
| test.cpp:148:20:148:25 | call to getenv | test.cpp:152:11:152:28 | ... * ... |
|
||||
| test.cpp:148:20:148:33 | (const char *)... | test.cpp:152:11:152:28 | ... * ... |
|
||||
| test.cpp:148:20:148:33 | (const char *)... | test.cpp:152:11:152:28 | ... * ... |
|
||||
| test.cpp:211:9:211:42 | Store | test.cpp:241:9:241:24 | call to get_tainted_size |
|
||||
| test.cpp:211:9:211:42 | Store | test.cpp:241:9:241:24 | call to get_tainted_size |
|
||||
| test.cpp:211:14:211:19 | call to getenv | test.cpp:211:9:211:42 | Store |
|
||||
| test.cpp:211:14:211:27 | (const char *)... | test.cpp:211:9:211:42 | Store |
|
||||
| test.cpp:209:8:209:23 | ReturnValue | test.cpp:241:9:241:24 | call to get_tainted_size |
|
||||
| test.cpp:209:8:209:23 | ReturnValue | test.cpp:241:9:241:24 | call to get_tainted_size |
|
||||
| test.cpp:211:14:211:19 | call to getenv | test.cpp:209:8:209:23 | ReturnValue |
|
||||
| test.cpp:211:14:211:27 | (const char *)... | test.cpp:209:8:209:23 | ReturnValue |
|
||||
| test.cpp:224:23:224:23 | s | test.cpp:225:21:225:21 | s |
|
||||
| test.cpp:224:23:224:23 | s | test.cpp:225:21:225:21 | s |
|
||||
| test.cpp:230:21:230:21 | s | test.cpp:231:21:231:21 | s |
|
||||
|
@ -59,20 +59,22 @@ edges
|
|||
| test.cpp:237:24:237:37 | (const char *)... | test.cpp:247:2:247:8 | local_size |
|
||||
| test.cpp:245:2:245:9 | local_size | test.cpp:224:23:224:23 | s |
|
||||
| test.cpp:247:2:247:8 | local_size | test.cpp:230:21:230:21 | s |
|
||||
| test.cpp:251:2:251:32 | Chi [[]] | test.cpp:289:17:289:20 | get_size output argument [[]] |
|
||||
| test.cpp:251:2:251:32 | Chi [[]] | test.cpp:305:18:305:21 | get_size output argument [[]] |
|
||||
| test.cpp:251:18:251:23 | call to getenv | test.cpp:251:2:251:32 | Chi [[]] |
|
||||
| test.cpp:251:18:251:31 | (const char *)... | test.cpp:251:2:251:32 | Chi [[]] |
|
||||
| test.cpp:251:2:251:9 | (reference dereference) [post update] | test.cpp:289:8:289:15 | size [post update] |
|
||||
| test.cpp:251:2:251:9 | (reference dereference) [post update] | test.cpp:305:9:305:16 | size [post update] |
|
||||
| test.cpp:251:2:251:9 | out_size [post update] | test.cpp:289:8:289:15 | size [post update] |
|
||||
| test.cpp:251:2:251:9 | out_size [post update] | test.cpp:305:9:305:16 | size [post update] |
|
||||
| test.cpp:251:18:251:23 | call to getenv | test.cpp:251:2:251:9 | (reference dereference) [post update] |
|
||||
| test.cpp:251:18:251:23 | call to getenv | test.cpp:251:2:251:9 | out_size [post update] |
|
||||
| test.cpp:251:18:251:31 | (const char *)... | test.cpp:251:2:251:9 | (reference dereference) [post update] |
|
||||
| test.cpp:251:18:251:31 | (const char *)... | test.cpp:251:2:251:9 | out_size [post update] |
|
||||
| test.cpp:259:20:259:25 | call to getenv | test.cpp:263:11:263:29 | ... * ... |
|
||||
| test.cpp:259:20:259:25 | call to getenv | test.cpp:263:11:263:29 | ... * ... |
|
||||
| test.cpp:259:20:259:33 | (const char *)... | test.cpp:263:11:263:29 | ... * ... |
|
||||
| test.cpp:259:20:259:33 | (const char *)... | test.cpp:263:11:263:29 | ... * ... |
|
||||
| test.cpp:289:17:289:20 | Chi | test.cpp:291:11:291:28 | ... * ... |
|
||||
| test.cpp:289:17:289:20 | Chi | test.cpp:291:11:291:28 | ... * ... |
|
||||
| test.cpp:289:17:289:20 | get_size output argument [[]] | test.cpp:289:17:289:20 | Chi |
|
||||
| test.cpp:305:18:305:21 | Chi | test.cpp:308:10:308:27 | ... * ... |
|
||||
| test.cpp:305:18:305:21 | Chi | test.cpp:308:10:308:27 | ... * ... |
|
||||
| test.cpp:305:18:305:21 | get_size output argument [[]] | test.cpp:305:18:305:21 | Chi |
|
||||
| test.cpp:289:8:289:15 | size [post update] | test.cpp:291:11:291:28 | ... * ... |
|
||||
| test.cpp:289:8:289:15 | size [post update] | test.cpp:291:11:291:28 | ... * ... |
|
||||
| test.cpp:305:9:305:16 | size [post update] | test.cpp:308:10:308:27 | ... * ... |
|
||||
| test.cpp:305:9:305:16 | size [post update] | test.cpp:308:10:308:27 | ... * ... |
|
||||
subpaths
|
||||
nodes
|
||||
| test.cpp:40:21:40:24 | argv | semmle.label | argv |
|
||||
|
@ -114,7 +116,7 @@ nodes
|
|||
| test.cpp:152:11:152:28 | ... * ... | semmle.label | ... * ... |
|
||||
| test.cpp:152:11:152:28 | ... * ... | semmle.label | ... * ... |
|
||||
| test.cpp:152:11:152:28 | ... * ... | semmle.label | ... * ... |
|
||||
| test.cpp:211:9:211:42 | Store | semmle.label | Store |
|
||||
| test.cpp:209:8:209:23 | ReturnValue | semmle.label | ReturnValue |
|
||||
| test.cpp:211:14:211:19 | call to getenv | semmle.label | call to getenv |
|
||||
| test.cpp:211:14:211:27 | (const char *)... | semmle.label | (const char *)... |
|
||||
| test.cpp:224:23:224:23 | s | semmle.label | s |
|
||||
|
@ -137,8 +139,8 @@ nodes
|
|||
| test.cpp:241:9:241:24 | call to get_tainted_size | semmle.label | call to get_tainted_size |
|
||||
| test.cpp:245:2:245:9 | local_size | semmle.label | local_size |
|
||||
| test.cpp:247:2:247:8 | local_size | semmle.label | local_size |
|
||||
| test.cpp:251:2:251:32 | Chi [[]] | semmle.label | Chi [[]] |
|
||||
| test.cpp:251:2:251:32 | ChiPartial | semmle.label | ChiPartial |
|
||||
| test.cpp:251:2:251:9 | (reference dereference) [post update] | semmle.label | (reference dereference) [post update] |
|
||||
| test.cpp:251:2:251:9 | out_size [post update] | semmle.label | out_size [post update] |
|
||||
| test.cpp:251:18:251:23 | call to getenv | semmle.label | call to getenv |
|
||||
| test.cpp:251:18:251:31 | (const char *)... | semmle.label | (const char *)... |
|
||||
| test.cpp:259:20:259:25 | call to getenv | semmle.label | call to getenv |
|
||||
|
@ -146,13 +148,11 @@ nodes
|
|||
| test.cpp:263:11:263:29 | ... * ... | semmle.label | ... * ... |
|
||||
| test.cpp:263:11:263:29 | ... * ... | semmle.label | ... * ... |
|
||||
| test.cpp:263:11:263:29 | ... * ... | semmle.label | ... * ... |
|
||||
| test.cpp:289:17:289:20 | Chi | semmle.label | Chi |
|
||||
| test.cpp:289:17:289:20 | get_size output argument [[]] | semmle.label | get_size output argument [[]] |
|
||||
| test.cpp:289:8:289:15 | size [post update] | semmle.label | size [post update] |
|
||||
| test.cpp:291:11:291:28 | ... * ... | semmle.label | ... * ... |
|
||||
| test.cpp:291:11:291:28 | ... * ... | semmle.label | ... * ... |
|
||||
| test.cpp:291:11:291:28 | ... * ... | semmle.label | ... * ... |
|
||||
| test.cpp:305:18:305:21 | Chi | semmle.label | Chi |
|
||||
| test.cpp:305:18:305:21 | get_size output argument [[]] | semmle.label | get_size output argument [[]] |
|
||||
| test.cpp:305:9:305:16 | size [post update] | semmle.label | size [post update] |
|
||||
| test.cpp:308:10:308:27 | ... * ... | semmle.label | ... * ... |
|
||||
| test.cpp:308:10:308:27 | ... * ... | semmle.label | ... * ... |
|
||||
| test.cpp:308:10:308:27 | ... * ... | semmle.label | ... * ... |
|
||||
|
|
|
@ -4,11 +4,11 @@ edges
|
|||
| test2.cpp:25:22:25:23 | & ... | test2.cpp:27:2:27:11 | v |
|
||||
| test2.cpp:25:22:25:23 | fscanf output argument | test2.cpp:27:2:27:11 | v |
|
||||
| test2.cpp:27:2:27:11 | v | test2.cpp:12:21:12:21 | v |
|
||||
| test5.cpp:9:7:9:9 | buf | test5.cpp:10:9:10:27 | Store |
|
||||
| test5.cpp:9:7:9:9 | gets output argument | test5.cpp:10:9:10:27 | Store |
|
||||
| test5.cpp:10:9:10:27 | Store | test5.cpp:17:6:17:18 | call to getTaintedInt |
|
||||
| test5.cpp:10:9:10:27 | Store | test5.cpp:17:6:17:18 | call to getTaintedInt |
|
||||
| test5.cpp:10:9:10:27 | Store | test5.cpp:18:6:18:18 | call to getTaintedInt |
|
||||
| test5.cpp:5:5:5:17 | ReturnValue | test5.cpp:17:6:17:18 | call to getTaintedInt |
|
||||
| test5.cpp:5:5:5:17 | ReturnValue | test5.cpp:17:6:17:18 | call to getTaintedInt |
|
||||
| test5.cpp:5:5:5:17 | ReturnValue | test5.cpp:18:6:18:18 | call to getTaintedInt |
|
||||
| test5.cpp:9:7:9:9 | buf | test5.cpp:5:5:5:17 | ReturnValue |
|
||||
| test5.cpp:9:7:9:9 | gets output argument | test5.cpp:5:5:5:17 | ReturnValue |
|
||||
| test5.cpp:18:6:18:18 | call to getTaintedInt | test5.cpp:19:6:19:6 | y |
|
||||
| test5.cpp:18:6:18:18 | call to getTaintedInt | test5.cpp:19:6:19:6 | y |
|
||||
| test.c:11:29:11:32 | argv | test.c:14:15:14:28 | maxConnections |
|
||||
|
@ -32,9 +32,9 @@ nodes
|
|||
| test2.cpp:25:22:25:23 | & ... | semmle.label | & ... |
|
||||
| test2.cpp:25:22:25:23 | fscanf output argument | semmle.label | fscanf output argument |
|
||||
| test2.cpp:27:2:27:11 | v | semmle.label | v |
|
||||
| test5.cpp:5:5:5:17 | ReturnValue | semmle.label | ReturnValue |
|
||||
| test5.cpp:9:7:9:9 | buf | semmle.label | buf |
|
||||
| test5.cpp:9:7:9:9 | gets output argument | semmle.label | gets output argument |
|
||||
| test5.cpp:10:9:10:27 | Store | semmle.label | Store |
|
||||
| test5.cpp:17:6:17:18 | call to getTaintedInt | semmle.label | call to getTaintedInt |
|
||||
| test5.cpp:17:6:17:18 | call to getTaintedInt | semmle.label | call to getTaintedInt |
|
||||
| test5.cpp:17:6:17:18 | call to getTaintedInt | semmle.label | call to getTaintedInt |
|
||||
|
|
|
@ -1,12 +1,8 @@
|
|||
edges
|
||||
| test.cpp:20:29:20:34 | call to getenv | test.cpp:24:10:24:35 | ! ... |
|
||||
| test.cpp:20:29:20:34 | call to getenv | test.cpp:24:11:24:16 | call to strcmp |
|
||||
| test.cpp:20:29:20:34 | call to getenv | test.cpp:41:10:41:38 | ! ... |
|
||||
| test.cpp:20:29:20:34 | call to getenv | test.cpp:41:11:41:16 | call to strcmp |
|
||||
| test.cpp:20:29:20:47 | (const char *)... | test.cpp:24:10:24:35 | ! ... |
|
||||
| test.cpp:20:29:20:47 | (const char *)... | test.cpp:24:11:24:16 | call to strcmp |
|
||||
| test.cpp:20:29:20:47 | (const char *)... | test.cpp:41:10:41:38 | ! ... |
|
||||
| test.cpp:20:29:20:47 | (const char *)... | test.cpp:41:11:41:16 | call to strcmp |
|
||||
subpaths
|
||||
nodes
|
||||
| test.cpp:20:29:20:34 | call to getenv | semmle.label | call to getenv |
|
||||
|
@ -14,9 +10,5 @@ nodes
|
|||
| test.cpp:24:10:24:35 | ! ... | semmle.label | ! ... |
|
||||
| test.cpp:24:11:24:16 | call to strcmp | semmle.label | call to strcmp |
|
||||
| test.cpp:24:11:24:16 | call to strcmp | semmle.label | call to strcmp |
|
||||
| test.cpp:41:10:41:38 | ! ... | semmle.label | ! ... |
|
||||
| test.cpp:41:11:41:16 | call to strcmp | semmle.label | call to strcmp |
|
||||
| test.cpp:41:11:41:16 | call to strcmp | semmle.label | call to strcmp |
|
||||
#select
|
||||
| test.cpp:24:10:24:35 | ! ... | test.cpp:20:29:20:34 | call to getenv | test.cpp:24:10:24:35 | ! ... | Reliance on untrusted input $@ to raise privilege at $@ | test.cpp:20:29:20:34 | call to getenv | call to getenv | test.cpp:25:9:25:27 | ... = ... | ... = ... |
|
||||
| test.cpp:41:10:41:38 | ! ... | test.cpp:20:29:20:34 | call to getenv | test.cpp:41:10:41:38 | ! ... | Reliance on untrusted input $@ to raise privilege at $@ | test.cpp:20:29:20:34 | call to getenv | call to getenv | test.cpp:42:8:42:26 | ... = ... | ... = ... |
|
||||
|
|
|
@ -35,7 +35,7 @@ void processRequest()
|
|||
adminPrivileges = 0; // OK, since it's a 0 and not a 1
|
||||
}
|
||||
|
||||
// BAD (requires pointer analysis to catch)
|
||||
// BAD (requires pointer analysis to catch) [NOT DETECTED]
|
||||
const char** userp = ¤tUser;
|
||||
*userp = userName;
|
||||
if (!strcmp(currentUser, "admin")) {
|
||||
|
|
|
@ -762,11 +762,21 @@ class ReturnValueInstruction extends ReturnInstruction {
|
|||
*/
|
||||
final LoadOperand getReturnValueOperand() { result = this.getAnOperand() }
|
||||
|
||||
/**
|
||||
* Gets the operand that provides the address of the value being returned by the function.
|
||||
*/
|
||||
final AddressOperand getReturnAddressOperand() { result = this.getAnOperand() }
|
||||
|
||||
/**
|
||||
* Gets the instruction whose result provides the value being returned by the function, if an
|
||||
* exact definition is available.
|
||||
*/
|
||||
final Instruction getReturnValue() { result = this.getReturnValueOperand().getDef() }
|
||||
|
||||
/**
|
||||
* Gets the instruction whose result provides the address of the value being returned by the function.
|
||||
*/
|
||||
final Instruction getReturnAddress() { result = this.getReturnAddressOperand().getDef() }
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -762,11 +762,21 @@ class ReturnValueInstruction extends ReturnInstruction {
|
|||
*/
|
||||
final LoadOperand getReturnValueOperand() { result = this.getAnOperand() }
|
||||
|
||||
/**
|
||||
* Gets the operand that provides the address of the value being returned by the function.
|
||||
*/
|
||||
final AddressOperand getReturnAddressOperand() { result = this.getAnOperand() }
|
||||
|
||||
/**
|
||||
* Gets the instruction whose result provides the value being returned by the function, if an
|
||||
* exact definition is available.
|
||||
*/
|
||||
final Instruction getReturnValue() { result = this.getReturnValueOperand().getDef() }
|
||||
|
||||
/**
|
||||
* Gets the instruction whose result provides the address of the value being returned by the function.
|
||||
*/
|
||||
final Instruction getReturnAddress() { result = this.getReturnAddressOperand().getDef() }
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -63,6 +63,11 @@ You can also specify:
|
|||
language to the GitHub code scanning API. For more information about this use case,
|
||||
see `Configuring CodeQL CLI in your CI system <https://docs.github.com/en/code-security/secure-coding/using-codeql-code-scanning-with-your-existing-ci-system/configuring-codeql-cli-in-your-ci-system>`__ in the GitHub documentation.
|
||||
|
||||
- ``--sarif-add-query-help``: (supported in version 2.7.1 onwards) adds any custom query help written
|
||||
in markdown to SARIF files (v2.1.0 or later) generated by the analysis. Query help stored in ``.qhelp`` files must be
|
||||
converted to ``.md`` before running the analysis. For further information,
|
||||
see ":ref:`Including query help for custom CodeQL queries in SARIF files <including-query-help-for-custom-codeql-queries-in-sarif-files>`."
|
||||
|
||||
- .. include:: ../reusables/threads-query-execution.rst
|
||||
|
||||
|
||||
|
@ -201,6 +206,29 @@ A SARIF results file is generated. Specifying ``--format=sarif-latest`` ensures
|
|||
that the results are formatted according to the most recent SARIF specification
|
||||
supported by CodeQL.
|
||||
|
||||
.. _including-query-help-for-custom-codeql-queries-in-sarif-files:
|
||||
|
||||
Including query help for custom CodeQL queries in SARIF files
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
If you use the CodeQL CLI to to run code scanning analyses on third party CI/CD systems,
|
||||
you can include the query help for your custom queries in SARIF files generated during an analysis.
|
||||
After uploading the SARIF file to GitHub, the query help is shown in the code scanning UI for any
|
||||
alerts generated by the custom queries.
|
||||
|
||||
From CodeQL CLI 2.7.1 onwards, you can include markdown-rendered query help in SARIF files
|
||||
by providing the ``--sarif-add-query-help`` option when running
|
||||
``codeql database analyze``.
|
||||
For more information, see `Configuring CodeQL CLI in your CI system <https://docs.github.com/en/code-security/code-scanning/using-codeql-code-scanning-with-your-existing-ci-system/configuring-codeql-cli-in-your-ci-system#analyzing-a-codeql-database>`
|
||||
in the GitHub documentation.
|
||||
|
||||
You can write query help for custom queries directly in a markdown file and save it alongside the
|
||||
corresponding query. Alternatively, for consistency with the standard CodeQL queries,
|
||||
you can write query help in the ``.qhelp`` format. Query help written in ``.qhelp``
|
||||
files can't be included in SARIF files, and they can't be processed by code
|
||||
scanning so must be converted to markdown before running
|
||||
the analysis. For more information, see ":ref:`Query help files <query-help-files>`"
|
||||
and ":doc:`Testing query help files <testing-query-help-files>`."
|
||||
|
||||
Results
|
||||
-------
|
||||
|
|
|
@ -15,6 +15,10 @@ in the CodeQL repository.
|
|||
The CodeQL CLI includes a command to test query help and render the content as
|
||||
markdown, so that you can easily preview the content in your IDE. Use the command to validate
|
||||
query help files before uploading them to the CodeQL repository or sharing them with other users.
|
||||
From CodeQL CLI 2.7.1 onwards, you can also include the markdown-rendered query help in SARIF files
|
||||
generated during CodeQL analyses so that the query help can be displayed in the code scanning UI.
|
||||
For more information, see
|
||||
":ref:`Analyzing databases with the CodeQL CLI <including-query-help-for-custom-codeql-queries-in-sarif-files>`."
|
||||
|
||||
Prerequisites
|
||||
-------------
|
||||
|
|
|
@ -184,6 +184,7 @@ Python built-in support
|
|||
yarl, Utility library
|
||||
aioch, Database
|
||||
aiomysql, Database
|
||||
aiopg, Database
|
||||
asyncpg, Database
|
||||
clickhouse-driver, Database
|
||||
mysql-connector-python, Database
|
||||
|
|
|
@ -10,7 +10,6 @@ A typical data-flow query looks like this:
|
|||
|
||||
.. code-block:: ql
|
||||
|
||||
::
|
||||
|
||||
class MyConfig extends TaintTracking::Configuration {
|
||||
MyConfig() { this = "MyConfig" }
|
||||
|
@ -79,7 +78,8 @@ To avoid these problems, a data-flow ``Configuration`` comes with a mechanism fo
|
|||
*/
|
||||
final predicate hasPartialFlow(PartialPathNode source, PartialPathNode node, int dist) {
|
||||
|
||||
As noted in the documentation for ``hasPartialFlow`` (for example, in the `CodeQL for Java documentation <https://codeql.github.com/codeql-standard-libraries/java/semmle/code/java/dataflow/internal/DataFlowImpl2.qll/predicate.DataFlowImpl2$Configuration$hasPartialFlow.3.html>__`) you must first enable this by adding an override of ``explorationLimit``. For example:
|
||||
As noted in the documentation for ``hasPartialFlow`` (for example, in the
|
||||
`CodeQL for Java documentation <https://codeql.github.com/codeql-standard-libraries/java/semmle/code/java/dataflow/internal/DataFlowImpl2.qll/predicate.DataFlowImpl2$Configuration$hasPartialFlow.3.html>`__) you must first enable this by adding an override of ``explorationLimit``. For example:
|
||||
|
||||
.. code-block:: ql
|
||||
|
||||
|
|
|
@ -40,6 +40,13 @@ Query help files are written using a custom XML format, and stored in a file wit
|
|||
The header and single top-level ``qhelp`` element are both mandatory.
|
||||
The following sections explain additional elements that you may include in your query help files.
|
||||
|
||||
.. pull-quote::
|
||||
|
||||
Code scanning does not process ``.qhelp`` files for custom CodeQL queries, so to show
|
||||
query help for custom queries in the code scanning UI you must convert the ``.qhelp`` files to markdown
|
||||
and then include the markdown-rendered query help in SARIF files generated during an analysis.
|
||||
For more information, see
|
||||
":ref:`Analyzing databases with the CodeQL CLI <including-query-help-for-custom-codeql-queries-in-sarif-files>`."
|
||||
|
||||
Section-level elements
|
||||
======================
|
||||
|
|
|
@ -26,7 +26,7 @@ jakarta.ws.rs.client,1,,,,,,,,,,,,,,1,,,,,,,,,,,
|
|||
jakarta.ws.rs.container,,9,,,,,,,,,,,,,,,,,,,,,,9,,
|
||||
jakarta.ws.rs.core,2,,149,,,,,,,,,,,,,,,,2,,,,,,94,55
|
||||
java.beans,,,1,,,,,,,,,,,,,,,,,,,,,,1,
|
||||
java.io,3,,27,,3,,,,,,,,,,,,,,,,,,,,26,1
|
||||
java.io,3,,31,,3,,,,,,,,,,,,,,,,,,,,30,1
|
||||
java.lang,,,51,,,,,,,,,,,,,,,,,,,,,,41,10
|
||||
java.net,10,3,7,,,,,,,,,,,,10,,,,,,,,,3,7,
|
||||
java.nio,10,,4,,10,,,,,,,,,,,,,,,,,,,,4,
|
||||
|
|
|
|
@ -15,9 +15,9 @@ Java framework & library support
|
|||
`Apache HttpComponents <https://hc.apache.org/>`_,"``org.apache.hc.core5.*``, ``org.apache.http``",5,136,28,,,3,,,,25
|
||||
`Google Guava <https://guava.dev/>`_,``com.google.common.*``,,728,6,,6,,,,,
|
||||
`JSON-java <https://github.com/stleary/JSON-java>`_,``org.json``,,236,,,,,,,,
|
||||
Java Standard Library,``java.*``,3,519,30,13,,,7,,,10
|
||||
Java Standard Library,``java.*``,3,523,30,13,,,7,,,10
|
||||
Java extensions,"``javax.*``, ``jakarta.*``",54,552,32,,,4,,1,1,2
|
||||
`Spring <https://spring.io/>`_,``org.springframework.*``,29,469,91,,,,19,14,,29
|
||||
Others,"``cn.hutool.core.codec``, ``com.esotericsoftware.kryo.io``, ``com.esotericsoftware.kryo5.io``, ``com.fasterxml.jackson.core``, ``com.fasterxml.jackson.databind``, ``com.opensymphony.xwork2.ognl``, ``com.unboundid.ldap.sdk``, ``flexjson``, ``groovy.lang``, ``groovy.util``, ``jodd.json``, ``net.sf.saxon.s9api``, ``ognl``, ``org.apache.commons.codec``, ``org.apache.commons.jexl2``, ``org.apache.commons.jexl3``, ``org.apache.commons.ognl``, ``org.apache.directory.ldap.client.api``, ``org.apache.ibatis.jdbc``, ``org.apache.shiro.codec``, ``org.apache.shiro.jndi``, ``org.codehaus.groovy.control``, ``org.dom4j``, ``org.hibernate``, ``org.jooq``, ``org.mvel2``, ``org.xml.sax``, ``org.xmlpull.v1``, ``play.mvc``, ``ratpack.core.form``, ``ratpack.core.handling``, ``ratpack.core.http``, ``ratpack.exec``, ``ratpack.form``, ``ratpack.func``, ``ratpack.handling``, ``ratpack.http``, ``ratpack.util``",39,99,151,,,,14,18,,
|
||||
Totals,,175,5364,431,13,6,10,107,33,1,66
|
||||
Totals,,175,5368,431,13,6,10,107,33,1,66
|
||||
|
||||
|
|
|
@ -83,6 +83,7 @@ private module Frameworks {
|
|||
private import semmle.code.java.frameworks.android.XssSinks
|
||||
private import semmle.code.java.frameworks.ApacheHttp
|
||||
private import semmle.code.java.frameworks.apache.Collections
|
||||
private import semmle.code.java.frameworks.apache.IO
|
||||
private import semmle.code.java.frameworks.apache.Lang
|
||||
private import semmle.code.java.frameworks.Flexjson
|
||||
private import semmle.code.java.frameworks.guava.Guava
|
||||
|
@ -322,33 +323,11 @@ private predicate summaryModelCsv(string row) {
|
|||
"org.apache.commons.codec;BinaryDecoder;true;decode;(byte[]);;Argument[0];ReturnValue;taint",
|
||||
"org.apache.commons.codec;StringEncoder;true;encode;(String);;Argument[0];ReturnValue;taint",
|
||||
"org.apache.commons.codec;StringDecoder;true;decode;(String);;Argument[0];ReturnValue;taint",
|
||||
"org.apache.commons.io;IOUtils;false;buffer;;;Argument[0];ReturnValue;taint",
|
||||
"org.apache.commons.io;IOUtils;false;readLines;;;Argument[0];ReturnValue;taint",
|
||||
"org.apache.commons.io;IOUtils;false;readFully;(InputStream,int);;Argument[0];ReturnValue;taint",
|
||||
"org.apache.commons.io;IOUtils;false;toBufferedInputStream;;;Argument[0];ReturnValue;taint",
|
||||
"org.apache.commons.io;IOUtils;false;toBufferedReader;;;Argument[0];ReturnValue;taint",
|
||||
"org.apache.commons.io;IOUtils;false;toByteArray;;;Argument[0];ReturnValue;taint",
|
||||
"org.apache.commons.io;IOUtils;false;toCharArray;;;Argument[0];ReturnValue;taint",
|
||||
"org.apache.commons.io;IOUtils;false;toInputStream;;;Argument[0];ReturnValue;taint",
|
||||
"org.apache.commons.io;IOUtils;false;toString;;;Argument[0];ReturnValue;taint",
|
||||
"java.net;URLDecoder;false;decode;;;Argument[0];ReturnValue;taint",
|
||||
"java.net;URI;false;create;;;Argument[0];ReturnValue;taint",
|
||||
"javax.xml.transform.sax;SAXSource;false;sourceToInputSource;;;Argument[0];ReturnValue;taint",
|
||||
// arg to arg
|
||||
"java.lang;System;false;arraycopy;;;Argument[0];Argument[2];taint",
|
||||
"org.apache.commons.io;IOUtils;false;copy;;;Argument[0];Argument[1];taint",
|
||||
"org.apache.commons.io;IOUtils;false;copyLarge;;;Argument[0];Argument[1];taint",
|
||||
"org.apache.commons.io;IOUtils;false;read;;;Argument[0];Argument[1];taint",
|
||||
"org.apache.commons.io;IOUtils;false;readFully;(InputStream,byte[]);;Argument[0];Argument[1];taint",
|
||||
"org.apache.commons.io;IOUtils;false;readFully;(InputStream,byte[],int,int);;Argument[0];Argument[1];taint",
|
||||
"org.apache.commons.io;IOUtils;false;readFully;(InputStream,ByteBuffer);;Argument[0];Argument[1];taint",
|
||||
"org.apache.commons.io;IOUtils;false;readFully;(ReadableByteChannel,ByteBuffer);;Argument[0];Argument[1];taint",
|
||||
"org.apache.commons.io;IOUtils;false;readFully;(Reader,char[]);;Argument[0];Argument[1];taint",
|
||||
"org.apache.commons.io;IOUtils;false;readFully;(Reader,char[],int,int);;Argument[0];Argument[1];taint",
|
||||
"org.apache.commons.io;IOUtils;false;write;;;Argument[0];Argument[1];taint",
|
||||
"org.apache.commons.io;IOUtils;false;writeChunked;;;Argument[0];Argument[1];taint",
|
||||
"org.apache.commons.io;IOUtils;false;writeLines;;;Argument[0];Argument[2];taint",
|
||||
"org.apache.commons.io;IOUtils;false;writeLines;;;Argument[1];Argument[2];taint",
|
||||
// constructor flow
|
||||
"java.io;File;false;File;;;Argument[0];Argument[-1];taint",
|
||||
"java.io;File;false;File;;;Argument[1];Argument[-1];taint",
|
||||
|
@ -373,7 +352,11 @@ private predicate summaryModelCsv(string row) {
|
|||
"java.io;StringReader;false;StringReader;;;Argument[0];Argument[-1];taint",
|
||||
"java.io;CharArrayReader;false;CharArrayReader;;;Argument[0];Argument[-1];taint",
|
||||
"java.io;BufferedReader;false;BufferedReader;;;Argument[0];Argument[-1];taint",
|
||||
"java.io;InputStreamReader;false;InputStreamReader;;;Argument[0];Argument[-1];taint"
|
||||
"java.io;InputStreamReader;false;InputStreamReader;;;Argument[0];Argument[-1];taint",
|
||||
"java.io;OutputStream;true;write;(byte[]);;Argument[0];Argument[-1];taint",
|
||||
"java.io;OutputStream;true;write;(byte[],int,int);;Argument[0];Argument[-1];taint",
|
||||
"java.io;OutputStream;true;write;(int);;Argument[0];Argument[-1];taint",
|
||||
"java.io;FilterOutputStream;true;FilterOutputStream;(OutputStream);;Argument[0];Argument[-1];taint"
|
||||
]
|
||||
}
|
||||
|
||||
|
|
|
@ -376,13 +376,6 @@ private predicate argToQualifierStep(Expr tracked, Expr sink) {
|
|||
* `arg` is the index of the argument.
|
||||
*/
|
||||
private predicate taintPreservingArgumentToQualifier(Method method, int arg) {
|
||||
exists(Method write |
|
||||
method.overrides*(write) and
|
||||
write.hasName("write") and
|
||||
arg = 0 and
|
||||
write.getDeclaringType().hasQualifiedName("java.io", "OutputStream")
|
||||
)
|
||||
or
|
||||
method.(TaintPreservingCallable).transfersTaint(arg, -1)
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,34 @@
|
|||
/** Definitions related to the Apache Commons IO library. */
|
||||
|
||||
import java
|
||||
private import semmle.code.java.dataflow.ExternalFlow
|
||||
|
||||
private class CommonsIOSummaryCsv extends SummaryModelCsv {
|
||||
override predicate row(string row) {
|
||||
row =
|
||||
[
|
||||
"org.apache.commons.io;IOUtils;false;buffer;;;Argument[0];ReturnValue;taint",
|
||||
"org.apache.commons.io;IOUtils;false;copy;;;Argument[0];Argument[1];taint",
|
||||
"org.apache.commons.io;IOUtils;false;copyLarge;;;Argument[0];Argument[1];taint",
|
||||
"org.apache.commons.io;IOUtils;false;read;;;Argument[0];Argument[1];taint",
|
||||
"org.apache.commons.io;IOUtils;false;readFully;(InputStream,byte[],int,int);;Argument[0];Argument[1];taint",
|
||||
"org.apache.commons.io;IOUtils;false;readFully;(InputStream,byte[]);;Argument[0];Argument[1];taint",
|
||||
"org.apache.commons.io;IOUtils;false;readFully;(InputStream,ByteBuffer);;Argument[0];Argument[1];taint",
|
||||
"org.apache.commons.io;IOUtils;false;readFully;(InputStream,int);;Argument[0];ReturnValue;taint",
|
||||
"org.apache.commons.io;IOUtils;false;readFully;(ReadableByteChannel,ByteBuffer);;Argument[0];Argument[1];taint",
|
||||
"org.apache.commons.io;IOUtils;false;readFully;(Reader,char[],int,int);;Argument[0];Argument[1];taint",
|
||||
"org.apache.commons.io;IOUtils;false;readFully;(Reader,char[]);;Argument[0];Argument[1];taint",
|
||||
"org.apache.commons.io;IOUtils;false;readLines;;;Argument[0];ReturnValue;taint",
|
||||
"org.apache.commons.io;IOUtils;false;toBufferedInputStream;;;Argument[0];ReturnValue;taint",
|
||||
"org.apache.commons.io;IOUtils;false;toBufferedReader;;;Argument[0];ReturnValue;taint",
|
||||
"org.apache.commons.io;IOUtils;false;toByteArray;;;Argument[0];ReturnValue;taint",
|
||||
"org.apache.commons.io;IOUtils;false;toCharArray;;;Argument[0];ReturnValue;taint",
|
||||
"org.apache.commons.io;IOUtils;false;toInputStream;;;Argument[0];ReturnValue;taint",
|
||||
"org.apache.commons.io;IOUtils;false;toString;;;Argument[0];ReturnValue;taint",
|
||||
"org.apache.commons.io;IOUtils;false;write;;;Argument[0];Argument[1];taint",
|
||||
"org.apache.commons.io;IOUtils;false;writeChunked;;;Argument[0];Argument[1];taint",
|
||||
"org.apache.commons.io;IOUtils;false;writeLines;;;Argument[0];Argument[2];taint",
|
||||
"org.apache.commons.io;IOUtils;false;writeLines;;;Argument[1];Argument[2];taint"
|
||||
]
|
||||
}
|
||||
}
|
|
@ -72,4 +72,13 @@ public class A {
|
|||
arrayWrite(taint(), b);
|
||||
sink(b);
|
||||
}
|
||||
|
||||
void testFilterOutputStream() throws IOException {
|
||||
ByteArrayOutputStream bOutput = new ByteArrayOutputStream();
|
||||
bOutput.write(taint());
|
||||
FilterOutputStream filterOutput = new FilterOutputStream(bOutput) {
|
||||
};
|
||||
sink(filterOutput);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
| A.java:33:23:33:29 | taint(...) | A.java:34:10:34:27 | toByteArray(...) |
|
||||
| A.java:46:27:46:33 | taint(...) | A.java:47:10:47:30 | toByteArray(...) |
|
||||
| A.java:55:58:55:64 | taint(...) | A.java:61:10:61:16 | dh.data |
|
||||
| A.java:78:19:78:25 | taint(...) | A.java:81:10:81:21 | filterOutput |
|
||||
| B.java:15:21:15:27 | taint(...) | B.java:18:10:18:16 | aaaargs |
|
||||
| B.java:15:21:15:27 | taint(...) | B.java:21:10:21:10 | s |
|
||||
| B.java:15:21:15:27 | taint(...) | B.java:24:10:24:15 | concat |
|
||||
|
|
|
@ -5,7 +5,7 @@ import java.io.File;
|
|||
import java.io.FileInputStream;
|
||||
import java.io.FileReader;
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.CharacterCodingException;
|
||||
import java.nio.charset.Charset;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Path;
|
||||
import java.util.LinkedHashSet;
|
||||
|
@ -17,7 +17,6 @@ import com.semmle.js.extractor.trapcache.CachingTrapWriter;
|
|||
import com.semmle.js.extractor.trapcache.ITrapCache;
|
||||
import com.semmle.util.data.StringUtil;
|
||||
import com.semmle.util.exception.Exceptions;
|
||||
import com.semmle.util.exception.ResourceError;
|
||||
import com.semmle.util.extraction.ExtractorOutputConfig;
|
||||
import com.semmle.util.files.FileUtil;
|
||||
import com.semmle.util.io.WholeIO;
|
||||
|
@ -439,16 +438,7 @@ public class FileExtractor {
|
|||
}
|
||||
|
||||
// populate source archive
|
||||
WholeIO wholeIO = new WholeIO(config.getDefaultEncoding(), true);
|
||||
String source = wholeIO.read(f);
|
||||
if (source == null) {
|
||||
if (wholeIO.getLastException() instanceof CharacterCodingException) {
|
||||
System.err.println("Skipped due to unsupported character encoding: " + f);
|
||||
return 0;
|
||||
} else {
|
||||
throw new ResourceError("Failed to read file " + f, wholeIO.getLastException());
|
||||
}
|
||||
}
|
||||
String source = new WholeIO(config.getDefaultEncoding()).strictread(f);
|
||||
outputConfig.getSourceArchive().add(f, source);
|
||||
|
||||
// extract language-independent bits
|
||||
|
|
|
@ -459,7 +459,7 @@ module TaintedPath {
|
|||
* An expression of form `x.matches(/\.\./)` or similar.
|
||||
*/
|
||||
class ContainsDotDotRegExpSanitizer extends BarrierGuardNode instanceof StringOps::RegExpTest {
|
||||
ContainsDotDotRegExpSanitizer() { super.getRegExp().getConstantValue() = [".", "..", "../"] }
|
||||
ContainsDotDotRegExpSanitizer() { super.getRegExp().getAMatchedString() = [".", "..", "../"] }
|
||||
|
||||
override predicate blocks(boolean outcome, Expr e, DataFlow::FlowLabel label) {
|
||||
e = super.getStringOperand().asExpr() and
|
||||
|
|
|
@ -398,4 +398,7 @@ app.get('/dotdot-regexp', (req, res) => {
|
|||
if (!path.match(/\.\.\/foo/)) {
|
||||
fs.readFileSync(path); // NOT OK
|
||||
}
|
||||
if (!path.match(/(\.\.\/|\.\.\\)/)) {
|
||||
fs.readFileSync(path); // OK
|
||||
}
|
||||
});
|
||||
|
|
|
@ -0,0 +1,2 @@
|
|||
lgtm,codescanning
|
||||
* Added modeling of `aiopg` for sinks executing SQL.
|
|
@ -7,6 +7,7 @@
|
|||
private import semmle.python.frameworks.Aioch
|
||||
private import semmle.python.frameworks.Aiohttp
|
||||
private import semmle.python.frameworks.Aiomysql
|
||||
private import semmle.python.frameworks.Aiopg
|
||||
private import semmle.python.frameworks.Asyncpg
|
||||
private import semmle.python.frameworks.ClickhouseDriver
|
||||
private import semmle.python.frameworks.Cryptodome
|
||||
|
|
|
@ -53,6 +53,8 @@ private module Cached {
|
|||
DataFlowPrivate::iterableUnpackingStoreStep(nodeFrom, _, nodeTo)
|
||||
or
|
||||
awaitStep(nodeFrom, nodeTo)
|
||||
or
|
||||
asyncWithStep(nodeFrom, nodeTo)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -211,3 +213,24 @@ predicate copyStep(DataFlow::CfgNode nodeFrom, DataFlow::CfgNode nodeTo) {
|
|||
predicate awaitStep(DataFlow::Node nodeFrom, DataFlow::Node nodeTo) {
|
||||
nodeTo.asExpr().(Await).getValue() = nodeFrom.asExpr()
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if taint can flow from `nodeFrom` to `nodeTo` inside an `async with` statement.
|
||||
*
|
||||
* For example in
|
||||
* ```python
|
||||
* async with open("foo") as f:
|
||||
* ```
|
||||
* the variable `f` is tainted if the result of `open("foo")` is tainted.
|
||||
*/
|
||||
predicate asyncWithStep(DataFlow::Node nodeFrom, DataFlow::Node nodeTo) {
|
||||
exists(With with, ControlFlowNode contextManager, ControlFlowNode var |
|
||||
nodeFrom.(DataFlow::CfgNode).getNode() = contextManager and
|
||||
nodeTo.(DataFlow::EssaNode).getVar().getDefinition().(WithDefinition).getDefiningNode() = var and
|
||||
// see `with_flow` in `python/ql/src/semmle/python/dataflow/Implementation.qll`
|
||||
with.getContextExpr() = contextManager.getNode() and
|
||||
with.getOptionalVars() = var.getNode() and
|
||||
with.isAsync() and
|
||||
contextManager.strictlyDominates(var)
|
||||
)
|
||||
}
|
||||
|
|
|
@ -0,0 +1,141 @@
|
|||
/**
|
||||
* Provides classes modeling security-relevant aspects of the `aiopg` PyPI package.
|
||||
* See
|
||||
* - https://aiopg.readthedocs.io/en/stable/index.html
|
||||
* - https://pypi.org/project/aiopg/
|
||||
*/
|
||||
|
||||
private import python
|
||||
private import semmle.python.dataflow.new.DataFlow
|
||||
private import semmle.python.Concepts
|
||||
private import semmle.python.ApiGraphs
|
||||
|
||||
/** Provides models for the `aiopg` PyPI package. */
|
||||
private module Aiopg {
|
||||
private import semmle.python.internal.Awaited
|
||||
|
||||
/**
|
||||
* A `ConectionPool` is created when the result of `aiopg.create_pool()` is awaited.
|
||||
* See https://aiopg.readthedocs.io/en/stable/core.html#pool
|
||||
*/
|
||||
API::Node connectionPool() {
|
||||
result = API::moduleImport("aiopg").getMember("create_pool").getReturn().getAwaited()
|
||||
}
|
||||
|
||||
/**
|
||||
* A `Connection` is created when
|
||||
* - the result of `aiopg.connect()` is awaited.
|
||||
* - the result of calling `aquire` on a `ConnectionPool` is awaited.
|
||||
* See https://aiopg.readthedocs.io/en/stable/core.html#connection
|
||||
*/
|
||||
API::Node connection() {
|
||||
result = API::moduleImport("aiopg").getMember("connect").getReturn().getAwaited()
|
||||
or
|
||||
result = connectionPool().getMember("acquire").getReturn().getAwaited()
|
||||
}
|
||||
|
||||
/**
|
||||
* A `Cursor` is created when
|
||||
* - the result of calling `cursor` on a `ConnectionPool` is awaited.
|
||||
* - the result of calling `cursor` on a `Connection` is awaited.
|
||||
* See https://aiopg.readthedocs.io/en/stable/core.html#cursor
|
||||
*/
|
||||
API::Node cursor() {
|
||||
result = connectionPool().getMember("cursor").getReturn().getAwaited()
|
||||
or
|
||||
result = connection().getMember("cursor").getReturn().getAwaited()
|
||||
}
|
||||
|
||||
/**
|
||||
* Calling `execute` on a `Cursor` constructs a query.
|
||||
* See https://aiopg.readthedocs.io/en/stable/core.html#aiopg.Cursor.execute
|
||||
*/
|
||||
class CursorExecuteCall extends SqlConstruction::Range, DataFlow::CallCfgNode {
|
||||
CursorExecuteCall() { this = cursor().getMember("execute").getACall() }
|
||||
|
||||
override DataFlow::Node getSql() { result in [this.getArg(0), this.getArgByName("operation")] }
|
||||
}
|
||||
|
||||
/**
|
||||
* This is only needed to connect the argument to the execute call with the subsequnt awaiting.
|
||||
* It should be obsolete once we have `API::CallNode` available.
|
||||
*/
|
||||
private DataFlow::TypeTrackingNode cursorExecuteCall(DataFlow::TypeTracker t, DataFlow::Node sql) {
|
||||
// cursor created from connection
|
||||
t.start() and
|
||||
sql = result.(CursorExecuteCall).getSql()
|
||||
or
|
||||
exists(DataFlow::TypeTracker t2 | result = cursorExecuteCall(t2, sql).track(t2, t))
|
||||
}
|
||||
|
||||
DataFlow::Node cursorExecuteCall(DataFlow::Node sql) {
|
||||
cursorExecuteCall(DataFlow::TypeTracker::end(), sql).flowsTo(result)
|
||||
}
|
||||
|
||||
/**
|
||||
* Awaiting the result of calling `execute` executes the query.
|
||||
* See https://aiopg.readthedocs.io/en/stable/core.html#aiopg.Cursor.execute
|
||||
*/
|
||||
class AwaitedCursorExecuteCall extends SqlExecution::Range {
|
||||
DataFlow::Node sql;
|
||||
|
||||
AwaitedCursorExecuteCall() { this = awaited(cursorExecuteCall(sql)) }
|
||||
|
||||
override DataFlow::Node getSql() { result = sql }
|
||||
}
|
||||
|
||||
/**
|
||||
* An `Engine` is created when the result of calling `aiopg.sa.create_engine` is awaited.
|
||||
* See https://aiopg.readthedocs.io/en/stable/sa.html#engine
|
||||
*/
|
||||
API::Node engine() {
|
||||
result =
|
||||
API::moduleImport("aiopg").getMember("sa").getMember("create_engine").getReturn().getAwaited()
|
||||
}
|
||||
|
||||
/**
|
||||
* A `SAConnection` is created when the result of calling `aquire` on an `Engine` is awaited.
|
||||
* See https://aiopg.readthedocs.io/en/stable/sa.html#connection
|
||||
*/
|
||||
API::Node saConnection() { result = engine().getMember("acquire").getReturn().getAwaited() }
|
||||
|
||||
/**
|
||||
* Calling `execute` on a `SAConnection` constructs a query.
|
||||
* See https://aiopg.readthedocs.io/en/stable/sa.html#aiopg.sa.SAConnection.execute
|
||||
*/
|
||||
class SAConnectionExecuteCall extends SqlConstruction::Range, DataFlow::CallCfgNode {
|
||||
SAConnectionExecuteCall() { this = saConnection().getMember("execute").getACall() }
|
||||
|
||||
override DataFlow::Node getSql() { result in [this.getArg(0), this.getArgByName("query")] }
|
||||
}
|
||||
|
||||
/**
|
||||
* This is only needed to connect the argument to the execute call with the subsequnt awaiting.
|
||||
* It should be obsolete once we have `API::CallNode` available.
|
||||
*/
|
||||
private DataFlow::TypeTrackingNode saConnectionExecuteCall(
|
||||
DataFlow::TypeTracker t, DataFlow::Node sql
|
||||
) {
|
||||
// saConnection created from engine
|
||||
t.start() and
|
||||
sql = result.(SAConnectionExecuteCall).getSql()
|
||||
or
|
||||
exists(DataFlow::TypeTracker t2 | result = saConnectionExecuteCall(t2, sql).track(t2, t))
|
||||
}
|
||||
|
||||
DataFlow::Node saConnectionExecuteCall(DataFlow::Node sql) {
|
||||
saConnectionExecuteCall(DataFlow::TypeTracker::end(), sql).flowsTo(result)
|
||||
}
|
||||
|
||||
/**
|
||||
* Awaiting the result of calling `execute` executes the query.
|
||||
* See https://aiopg.readthedocs.io/en/stable/sa.html#aiopg.sa.SAConnection.execute
|
||||
*/
|
||||
class AwaitedSAConnectionExecuteCall extends SqlExecution::Range {
|
||||
DataFlow::Node sql;
|
||||
|
||||
AwaitedSAConnectionExecuteCall() { this = awaited(saConnectionExecuteCall(sql)) }
|
||||
|
||||
override DataFlow::Node getSql() { result = sql }
|
||||
}
|
||||
}
|
|
@ -31,7 +31,7 @@ async def test_async_with():
|
|||
ctx = AsyncContext()
|
||||
taint(ctx)
|
||||
async with ctx as tainted:
|
||||
ensure_tainted(tainted) # $ MISSING: tainted
|
||||
ensure_tainted(tainted) # $ tainted
|
||||
|
||||
|
||||
class AsyncIter:
|
||||
|
@ -45,7 +45,7 @@ async def test_async_for():
|
|||
iter = AsyncIter()
|
||||
taint(iter)
|
||||
async for tainted in iter:
|
||||
ensure_tainted(tainted) # $ MISSING: tainted
|
||||
ensure_tainted(tainted) # $ tainted
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -0,0 +1,30 @@
|
|||
# Add taintlib to PATH so it can be imported during runtime without any hassle
|
||||
import sys; import os; sys.path.append(os.path.dirname(os.path.dirname((__file__))))
|
||||
from taintlib import *
|
||||
|
||||
# This has no runtime impact, but allows autocomplete to work
|
||||
from typing import TYPE_CHECKING
|
||||
if TYPE_CHECKING:
|
||||
from ..taintlib import *
|
||||
|
||||
|
||||
# Actual tests
|
||||
|
||||
class Iter:
|
||||
def __iter__(self):
|
||||
return self
|
||||
|
||||
def __next__(self):
|
||||
raise StopIteration
|
||||
|
||||
def test_for():
|
||||
iter = Iter()
|
||||
taint(iter)
|
||||
for tainted in iter:
|
||||
ensure_tainted(tainted) # $ tainted
|
||||
|
||||
|
||||
|
||||
# Make tests runable
|
||||
|
||||
test_for()
|
|
@ -0,0 +1,60 @@
|
|||
# Add taintlib to PATH so it can be imported during runtime without any hassle
|
||||
import sys; import os; sys.path.append(os.path.dirname(os.path.dirname((__file__))))
|
||||
from taintlib import *
|
||||
|
||||
# This has no runtime impact, but allows autocomplete to work
|
||||
from typing import TYPE_CHECKING
|
||||
if TYPE_CHECKING:
|
||||
from ..taintlib import *
|
||||
|
||||
|
||||
# Actual tests
|
||||
|
||||
class Context:
|
||||
def __enter__(self):
|
||||
return ""
|
||||
|
||||
def __exit__(self, exc_type, exc, tb):
|
||||
pass
|
||||
|
||||
def test_with():
|
||||
ctx = Context()
|
||||
taint(ctx)
|
||||
with ctx as tainted:
|
||||
ensure_tainted(tainted) # $ tainted
|
||||
|
||||
class Context_taint:
|
||||
def __enter__(self):
|
||||
return TAINTED_STRING
|
||||
|
||||
def __exit__(self, exc_type, exc, tb):
|
||||
pass
|
||||
|
||||
def test_with_taint():
|
||||
ctx = Context_taint()
|
||||
with ctx as tainted:
|
||||
ensure_tainted(tainted) # $ MISSING: tainted
|
||||
|
||||
|
||||
class Context_arg:
|
||||
def __init__(self, arg):
|
||||
self.arg = arg
|
||||
|
||||
def __enter__(self):
|
||||
return self.arg
|
||||
|
||||
def __exit__(self, exc_type, exc, tb):
|
||||
pass
|
||||
|
||||
def test_with_arg():
|
||||
ctx = Context_arg(TAINTED_STRING)
|
||||
with ctx as tainted:
|
||||
ensure_tainted(tainted) # $ tainted
|
||||
|
||||
|
||||
|
||||
# Make tests runable
|
||||
|
||||
test_with()
|
||||
test_with_taint()
|
||||
test_with_arg()
|
|
@ -30,24 +30,36 @@ DataFlow::Node shouldNotBeTainted() {
|
|||
)
|
||||
}
|
||||
|
||||
class TestTaintTrackingConfiguration extends TaintTracking::Configuration {
|
||||
TestTaintTrackingConfiguration() { this = "TestTaintTrackingConfiguration" }
|
||||
// this module allows the configuration to be imported in other `.ql` files without the
|
||||
// top level query predicates of this file coming into scope.
|
||||
module Conf {
|
||||
class TestTaintTrackingConfiguration extends TaintTracking::Configuration {
|
||||
TestTaintTrackingConfiguration() { this = "TestTaintTrackingConfiguration" }
|
||||
|
||||
override predicate isSource(DataFlow::Node source) {
|
||||
source.asCfgNode().(NameNode).getId() in [
|
||||
"TAINTED_STRING", "TAINTED_BYTES", "TAINTED_LIST", "TAINTED_DICT"
|
||||
]
|
||||
or
|
||||
source instanceof RemoteFlowSource
|
||||
}
|
||||
override predicate isSource(DataFlow::Node source) {
|
||||
source.asCfgNode().(NameNode).getId() in [
|
||||
"TAINTED_STRING", "TAINTED_BYTES", "TAINTED_LIST", "TAINTED_DICT"
|
||||
]
|
||||
or
|
||||
// User defined sources
|
||||
exists(CallNode call |
|
||||
call.getFunction().(NameNode).getId() = "taint" and
|
||||
source.(DataFlow::CfgNode).getNode() = call.getAnArg()
|
||||
)
|
||||
or
|
||||
source instanceof RemoteFlowSource
|
||||
}
|
||||
|
||||
override predicate isSink(DataFlow::Node sink) {
|
||||
sink = shouldBeTainted()
|
||||
or
|
||||
sink = shouldNotBeTainted()
|
||||
override predicate isSink(DataFlow::Node sink) {
|
||||
sink = shouldBeTainted()
|
||||
or
|
||||
sink = shouldNotBeTainted()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
import Conf
|
||||
|
||||
class InlineTaintTest extends InlineExpectationsTest {
|
||||
InlineTaintTest() { this = "InlineTaintTest" }
|
||||
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
edges
|
||||
nodes
|
||||
subpaths
|
||||
#select
|
|
@ -0,0 +1,25 @@
|
|||
/**
|
||||
* @kind path-problem
|
||||
*/
|
||||
|
||||
// This query is for debugging InlineTaintTestFailures.
|
||||
// The intended usage is
|
||||
// 1. load the database of the failing test
|
||||
// 2. run this query to see actual paths
|
||||
// 3. if necessary, look at partial paths by (un)commenting appropriate lines
|
||||
import python
|
||||
import semmle.python.dataflow.new.DataFlow
|
||||
import experimental.meta.InlineTaintTest::Conf
|
||||
// import DataFlow::PartialPathGraph
|
||||
import DataFlow::PathGraph
|
||||
|
||||
class Conf extends TestTaintTrackingConfiguration {
|
||||
override int explorationLimit() { result = 5 }
|
||||
}
|
||||
|
||||
// from Conf config, DataFlow::PartialPathNode source, DataFlow::PartialPathNode sink
|
||||
// where config.hasPartialFlow(source, sink, _)
|
||||
from Conf config, DataFlow::PathNode source, DataFlow::PathNode sink
|
||||
where config.hasFlowPath(source, sink)
|
||||
select sink.getNode(), source, sink, "This node receives taint from $@.", source.getNode(),
|
||||
"this source"
|
|
@ -0,0 +1,2 @@
|
|||
import python
|
||||
import experimental.meta.ConceptsTest
|
|
@ -0,0 +1,33 @@
|
|||
import aiopg
|
||||
|
||||
# Only a cursor can execute sql.
|
||||
async def test_cursor():
|
||||
# Create connection directly
|
||||
conn = await aiopg.connect()
|
||||
cur = await conn.cursor()
|
||||
await cur.execute("sql") # $ getSql="sql" constructedSql="sql"
|
||||
|
||||
# Create connection via pool
|
||||
async with aiopg.create_pool() as pool:
|
||||
# Create Cursor via Connection
|
||||
async with pool.acquire() as conn:
|
||||
async with conn.cursor() as cur:
|
||||
await cur.execute("sql") # $ getSql="sql" constructedSql="sql"
|
||||
|
||||
# Create Cursor directly
|
||||
async with pool.cursor() as cur:
|
||||
await cur.execute("sql") # $ getSql="sql" constructedSql="sql"
|
||||
|
||||
# variants using as few `async with` as possible
|
||||
pool = await aiopg.create_pool()
|
||||
conn = await pool.acquire()
|
||||
cur = await conn.cursor()
|
||||
await cur.execute("sql") # $ getSql="sql" constructedSql="sql"
|
||||
|
||||
# Test SQLAlchemy integration
|
||||
from aiopg.sa import create_engine
|
||||
|
||||
async def test_engine():
|
||||
engine = await create_engine()
|
||||
conn = await engine.acquire()
|
||||
await conn.execute("sql") # $ getSql="sql" constructedSql="sql"
|
|
@ -0,0 +1,2 @@
|
|||
lgtm,codescanning
|
||||
* The precision of "Hard-coded credentials" (`rb/hardcoded-credentials`) has been decreased from "high" to "medium". This query will no longer be run and displayed by default on Code Scanning and LGTM.
|
|
@ -99,11 +99,11 @@ predicate returnStep(Node nodeFrom, Node nodeTo) {
|
|||
* to `z` inside `bar`, even though this content write happens _after_ `bar` is
|
||||
* called.
|
||||
*/
|
||||
predicate basicStoreStep(Node nodeFrom, DataFlowPublic::LocalSourceNode nodeTo, string content) {
|
||||
predicate basicStoreStep(Node nodeFrom, Node nodeTo, string content) {
|
||||
// TODO: support SetterMethodCall inside TuplePattern
|
||||
exists(ExprNodes::MethodCallCfgNode call |
|
||||
content = getSetterCallAttributeName(call.getExpr()) and
|
||||
nodeTo.(DataFlowPublic::ExprNode).getExprNode() = call.getReceiver() and
|
||||
nodeTo.(DataFlowPrivate::PostUpdateNode).getPreUpdateNode().asExpr() = call.getReceiver() and
|
||||
call.getExpr() instanceof AST::SetterMethodCall and
|
||||
call.getArgument(call.getNumberOfArguments() - 1) =
|
||||
nodeFrom.(DataFlowPublic::ExprNode).getExprNode()
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
* @kind path-problem
|
||||
* @problem.severity error
|
||||
* @security-severity 9.8
|
||||
* @precision high
|
||||
* @precision medium
|
||||
* @id rb/hardcoded-credentials
|
||||
* @tags security
|
||||
* external/cwe/cwe-259
|
||||
|
|
|
@ -0,0 +1,134 @@
|
|||
track
|
||||
| type_tracker.rb:2:5:5:7 | &block | type tracker without call steps | type_tracker.rb:2:5:5:7 | &block |
|
||||
| type_tracker.rb:2:5:5:7 | field= | type tracker without call steps | type_tracker.rb:2:5:5:7 | field= |
|
||||
| type_tracker.rb:2:5:5:7 | return return in field= | type tracker without call steps | type_tracker.rb:2:5:5:7 | return return in field= |
|
||||
| type_tracker.rb:2:5:5:7 | return return in field= | type tracker without call steps | type_tracker.rb:14:5:14:13 | call to field= |
|
||||
| type_tracker.rb:2:5:5:7 | self (field=) | type tracker with call steps | type_tracker.rb:7:5:9:7 | self in field |
|
||||
| type_tracker.rb:2:5:5:7 | self (field=) | type tracker without call steps | type_tracker.rb:2:5:5:7 | self (field=) |
|
||||
| type_tracker.rb:2:5:5:7 | self in field= | type tracker with call steps | type_tracker.rb:7:5:9:7 | self in field |
|
||||
| type_tracker.rb:2:5:5:7 | self in field= | type tracker without call steps | type_tracker.rb:2:5:5:7 | self in field= |
|
||||
| type_tracker.rb:2:16:2:18 | val | type tracker with call steps | type_tracker.rb:2:16:2:18 | val |
|
||||
| type_tracker.rb:2:16:2:18 | val | type tracker without call steps | type_tracker.rb:2:5:5:7 | return return in field= |
|
||||
| type_tracker.rb:2:16:2:18 | val | type tracker without call steps | type_tracker.rb:2:16:2:18 | val |
|
||||
| type_tracker.rb:2:16:2:18 | val | type tracker without call steps | type_tracker.rb:2:16:2:18 | val |
|
||||
| type_tracker.rb:2:16:2:18 | val | type tracker without call steps | type_tracker.rb:2:16:2:18 | val |
|
||||
| type_tracker.rb:2:16:2:18 | val | type tracker without call steps | type_tracker.rb:14:5:14:13 | call to field= |
|
||||
| type_tracker.rb:3:9:3:23 | [post] self | type tracker with call steps | type_tracker.rb:7:5:9:7 | self in field |
|
||||
| type_tracker.rb:3:9:3:23 | [post] self | type tracker without call steps | type_tracker.rb:3:9:3:23 | [post] self |
|
||||
| type_tracker.rb:3:9:3:23 | call to puts | type tracker without call steps | type_tracker.rb:3:9:3:23 | call to puts |
|
||||
| type_tracker.rb:3:9:3:23 | self | type tracker with call steps | type_tracker.rb:7:5:9:7 | self in field |
|
||||
| type_tracker.rb:3:9:3:23 | self | type tracker without call steps | type_tracker.rb:3:9:3:23 | self |
|
||||
| type_tracker.rb:3:14:3:17 | [post] self | type tracker without call steps | type_tracker.rb:3:14:3:17 | [post] self |
|
||||
| type_tracker.rb:3:14:3:17 | self | type tracker with call steps | type_tracker.rb:7:5:9:7 | self in field |
|
||||
| type_tracker.rb:3:14:3:17 | self | type tracker without call steps | type_tracker.rb:3:14:3:17 | self |
|
||||
| type_tracker.rb:3:14:3:23 | [post] call to field | type tracker without call steps | type_tracker.rb:3:14:3:23 | [post] call to field |
|
||||
| type_tracker.rb:3:14:3:23 | call to field | type tracker without call steps | type_tracker.rb:3:14:3:23 | call to field |
|
||||
| type_tracker.rb:4:9:4:14 | @field | type tracker without call steps | type_tracker.rb:4:9:4:14 | @field |
|
||||
| type_tracker.rb:4:18:4:20 | val | type tracker without call steps | type_tracker.rb:2:5:5:7 | return return in field= |
|
||||
| type_tracker.rb:4:18:4:20 | val | type tracker without call steps | type_tracker.rb:4:18:4:20 | val |
|
||||
| type_tracker.rb:4:18:4:20 | val | type tracker without call steps | type_tracker.rb:14:5:14:13 | call to field= |
|
||||
| type_tracker.rb:7:5:9:7 | &block | type tracker without call steps | type_tracker.rb:7:5:9:7 | &block |
|
||||
| type_tracker.rb:7:5:9:7 | field | type tracker without call steps | type_tracker.rb:7:5:9:7 | field |
|
||||
| type_tracker.rb:7:5:9:7 | return return in field | type tracker without call steps | type_tracker.rb:3:14:3:23 | call to field |
|
||||
| type_tracker.rb:7:5:9:7 | return return in field | type tracker without call steps | type_tracker.rb:7:5:9:7 | return return in field |
|
||||
| type_tracker.rb:7:5:9:7 | return return in field | type tracker without call steps | type_tracker.rb:15:10:15:18 | call to field |
|
||||
| type_tracker.rb:7:5:9:7 | self in field | type tracker without call steps | type_tracker.rb:7:5:9:7 | self in field |
|
||||
| type_tracker.rb:8:9:8:14 | @field | type tracker without call steps | type_tracker.rb:3:14:3:23 | call to field |
|
||||
| type_tracker.rb:8:9:8:14 | @field | type tracker without call steps | type_tracker.rb:7:5:9:7 | return return in field |
|
||||
| type_tracker.rb:8:9:8:14 | @field | type tracker without call steps | type_tracker.rb:8:9:8:14 | @field |
|
||||
| type_tracker.rb:8:9:8:14 | @field | type tracker without call steps | type_tracker.rb:15:10:15:18 | call to field |
|
||||
| type_tracker.rb:12:1:16:3 | &block | type tracker without call steps | type_tracker.rb:12:1:16:3 | &block |
|
||||
| type_tracker.rb:12:1:16:3 | m | type tracker without call steps | type_tracker.rb:12:1:16:3 | m |
|
||||
| type_tracker.rb:12:1:16:3 | return return in m | type tracker without call steps | type_tracker.rb:12:1:16:3 | return return in m |
|
||||
| type_tracker.rb:12:1:16:3 | self (m) | type tracker without call steps | type_tracker.rb:12:1:16:3 | self (m) |
|
||||
| type_tracker.rb:12:1:16:3 | self in m | type tracker without call steps | type_tracker.rb:12:1:16:3 | self in m |
|
||||
| type_tracker.rb:13:5:13:7 | var | type tracker without call steps | type_tracker.rb:13:5:13:7 | var |
|
||||
| type_tracker.rb:13:11:13:19 | Container | type tracker without call steps | type_tracker.rb:13:11:13:19 | Container |
|
||||
| type_tracker.rb:13:11:13:19 | [post] Container | type tracker without call steps | type_tracker.rb:13:11:13:19 | [post] Container |
|
||||
| type_tracker.rb:13:11:13:23 | call to new | type tracker with call steps | type_tracker.rb:2:5:5:7 | self in field= |
|
||||
| type_tracker.rb:13:11:13:23 | call to new | type tracker with call steps | type_tracker.rb:7:5:9:7 | self in field |
|
||||
| type_tracker.rb:13:11:13:23 | call to new | type tracker without call steps | type_tracker.rb:13:11:13:23 | call to new |
|
||||
| type_tracker.rb:14:5:14:7 | [post] var | type tracker with call steps | type_tracker.rb:7:5:9:7 | self in field |
|
||||
| type_tracker.rb:14:5:14:7 | [post] var | type tracker without call steps | type_tracker.rb:14:5:14:7 | [post] var |
|
||||
| type_tracker.rb:14:5:14:13 | [post] ... = ... | type tracker without call steps | type_tracker.rb:14:5:14:13 | [post] ... = ... |
|
||||
| type_tracker.rb:14:5:14:13 | __synth__0 | type tracker without call steps | type_tracker.rb:14:5:14:13 | __synth__0 |
|
||||
| type_tracker.rb:14:5:14:13 | call to field= | type tracker without call steps | type_tracker.rb:14:5:14:13 | call to field= |
|
||||
| type_tracker.rb:14:17:14:23 | "hello" | type tracker with call steps | type_tracker.rb:2:16:2:18 | val |
|
||||
| type_tracker.rb:14:17:14:23 | "hello" | type tracker with call steps | type_tracker.rb:2:16:2:18 | val |
|
||||
| type_tracker.rb:14:17:14:23 | "hello" | type tracker with call steps with content field | type_tracker.rb:7:5:9:7 | self in field |
|
||||
| type_tracker.rb:14:17:14:23 | "hello" | type tracker without call steps | type_tracker.rb:14:17:14:23 | "hello" |
|
||||
| type_tracker.rb:14:17:14:23 | "hello" | type tracker without call steps | type_tracker.rb:15:10:15:18 | call to field |
|
||||
| type_tracker.rb:14:17:14:23 | "hello" | type tracker without call steps with content field | type_tracker.rb:14:5:14:7 | [post] var |
|
||||
| type_tracker.rb:15:5:15:18 | [post] self | type tracker without call steps | type_tracker.rb:15:5:15:18 | [post] self |
|
||||
| type_tracker.rb:15:5:15:18 | call to puts | type tracker without call steps | type_tracker.rb:12:1:16:3 | return return in m |
|
||||
| type_tracker.rb:15:5:15:18 | call to puts | type tracker without call steps | type_tracker.rb:15:5:15:18 | call to puts |
|
||||
| type_tracker.rb:15:5:15:18 | self | type tracker without call steps | type_tracker.rb:15:5:15:18 | self |
|
||||
| type_tracker.rb:15:10:15:12 | [post] var | type tracker without call steps | type_tracker.rb:15:10:15:12 | [post] var |
|
||||
| type_tracker.rb:15:10:15:18 | [post] call to field | type tracker without call steps | type_tracker.rb:15:10:15:18 | [post] call to field |
|
||||
| type_tracker.rb:15:10:15:18 | call to field | type tracker without call steps | type_tracker.rb:15:10:15:18 | call to field |
|
||||
trackEnd
|
||||
| type_tracker.rb:2:5:5:7 | &block | type_tracker.rb:2:5:5:7 | &block |
|
||||
| type_tracker.rb:2:5:5:7 | field= | type_tracker.rb:2:5:5:7 | field= |
|
||||
| type_tracker.rb:2:5:5:7 | return return in field= | type_tracker.rb:2:5:5:7 | return return in field= |
|
||||
| type_tracker.rb:2:5:5:7 | return return in field= | type_tracker.rb:14:5:14:13 | call to field= |
|
||||
| type_tracker.rb:2:5:5:7 | self (field=) | type_tracker.rb:2:5:5:7 | self (field=) |
|
||||
| type_tracker.rb:2:5:5:7 | self (field=) | type_tracker.rb:7:5:9:7 | self in field |
|
||||
| type_tracker.rb:2:5:5:7 | self in field= | type_tracker.rb:2:5:5:7 | self in field= |
|
||||
| type_tracker.rb:2:5:5:7 | self in field= | type_tracker.rb:7:5:9:7 | self in field |
|
||||
| type_tracker.rb:2:16:2:18 | val | type_tracker.rb:2:5:5:7 | return return in field= |
|
||||
| type_tracker.rb:2:16:2:18 | val | type_tracker.rb:2:16:2:18 | val |
|
||||
| type_tracker.rb:2:16:2:18 | val | type_tracker.rb:2:16:2:18 | val |
|
||||
| type_tracker.rb:2:16:2:18 | val | type_tracker.rb:2:16:2:18 | val |
|
||||
| type_tracker.rb:2:16:2:18 | val | type_tracker.rb:2:16:2:18 | val |
|
||||
| type_tracker.rb:2:16:2:18 | val | type_tracker.rb:14:5:14:13 | call to field= |
|
||||
| type_tracker.rb:3:9:3:23 | [post] self | type_tracker.rb:3:9:3:23 | [post] self |
|
||||
| type_tracker.rb:3:9:3:23 | [post] self | type_tracker.rb:7:5:9:7 | self in field |
|
||||
| type_tracker.rb:3:9:3:23 | call to puts | type_tracker.rb:3:9:3:23 | call to puts |
|
||||
| type_tracker.rb:3:9:3:23 | self | type_tracker.rb:3:9:3:23 | self |
|
||||
| type_tracker.rb:3:9:3:23 | self | type_tracker.rb:7:5:9:7 | self in field |
|
||||
| type_tracker.rb:3:14:3:17 | [post] self | type_tracker.rb:3:14:3:17 | [post] self |
|
||||
| type_tracker.rb:3:14:3:17 | self | type_tracker.rb:3:14:3:17 | self |
|
||||
| type_tracker.rb:3:14:3:17 | self | type_tracker.rb:7:5:9:7 | self in field |
|
||||
| type_tracker.rb:3:14:3:23 | [post] call to field | type_tracker.rb:3:14:3:23 | [post] call to field |
|
||||
| type_tracker.rb:3:14:3:23 | call to field | type_tracker.rb:3:14:3:23 | call to field |
|
||||
| type_tracker.rb:4:9:4:14 | @field | type_tracker.rb:4:9:4:14 | @field |
|
||||
| type_tracker.rb:4:18:4:20 | val | type_tracker.rb:2:5:5:7 | return return in field= |
|
||||
| type_tracker.rb:4:18:4:20 | val | type_tracker.rb:4:18:4:20 | val |
|
||||
| type_tracker.rb:4:18:4:20 | val | type_tracker.rb:14:5:14:13 | call to field= |
|
||||
| type_tracker.rb:7:5:9:7 | &block | type_tracker.rb:7:5:9:7 | &block |
|
||||
| type_tracker.rb:7:5:9:7 | field | type_tracker.rb:7:5:9:7 | field |
|
||||
| type_tracker.rb:7:5:9:7 | return return in field | type_tracker.rb:3:14:3:23 | call to field |
|
||||
| type_tracker.rb:7:5:9:7 | return return in field | type_tracker.rb:7:5:9:7 | return return in field |
|
||||
| type_tracker.rb:7:5:9:7 | return return in field | type_tracker.rb:15:10:15:18 | call to field |
|
||||
| type_tracker.rb:7:5:9:7 | self in field | type_tracker.rb:7:5:9:7 | self in field |
|
||||
| type_tracker.rb:8:9:8:14 | @field | type_tracker.rb:3:14:3:23 | call to field |
|
||||
| type_tracker.rb:8:9:8:14 | @field | type_tracker.rb:7:5:9:7 | return return in field |
|
||||
| type_tracker.rb:8:9:8:14 | @field | type_tracker.rb:8:9:8:14 | @field |
|
||||
| type_tracker.rb:8:9:8:14 | @field | type_tracker.rb:15:10:15:18 | call to field |
|
||||
| type_tracker.rb:12:1:16:3 | &block | type_tracker.rb:12:1:16:3 | &block |
|
||||
| type_tracker.rb:12:1:16:3 | m | type_tracker.rb:12:1:16:3 | m |
|
||||
| type_tracker.rb:12:1:16:3 | return return in m | type_tracker.rb:12:1:16:3 | return return in m |
|
||||
| type_tracker.rb:12:1:16:3 | self (m) | type_tracker.rb:12:1:16:3 | self (m) |
|
||||
| type_tracker.rb:12:1:16:3 | self in m | type_tracker.rb:12:1:16:3 | self in m |
|
||||
| type_tracker.rb:13:5:13:7 | var | type_tracker.rb:13:5:13:7 | var |
|
||||
| type_tracker.rb:13:11:13:19 | Container | type_tracker.rb:13:11:13:19 | Container |
|
||||
| type_tracker.rb:13:11:13:19 | [post] Container | type_tracker.rb:13:11:13:19 | [post] Container |
|
||||
| type_tracker.rb:13:11:13:23 | call to new | type_tracker.rb:2:5:5:7 | self in field= |
|
||||
| type_tracker.rb:13:11:13:23 | call to new | type_tracker.rb:7:5:9:7 | self in field |
|
||||
| type_tracker.rb:13:11:13:23 | call to new | type_tracker.rb:13:11:13:23 | call to new |
|
||||
| type_tracker.rb:14:5:14:7 | [post] var | type_tracker.rb:7:5:9:7 | self in field |
|
||||
| type_tracker.rb:14:5:14:7 | [post] var | type_tracker.rb:14:5:14:7 | [post] var |
|
||||
| type_tracker.rb:14:5:14:13 | [post] ... = ... | type_tracker.rb:14:5:14:13 | [post] ... = ... |
|
||||
| type_tracker.rb:14:5:14:13 | __synth__0 | type_tracker.rb:14:5:14:13 | __synth__0 |
|
||||
| type_tracker.rb:14:5:14:13 | call to field= | type_tracker.rb:14:5:14:13 | call to field= |
|
||||
| type_tracker.rb:14:17:14:23 | "hello" | type_tracker.rb:2:16:2:18 | val |
|
||||
| type_tracker.rb:14:17:14:23 | "hello" | type_tracker.rb:2:16:2:18 | val |
|
||||
| type_tracker.rb:14:17:14:23 | "hello" | type_tracker.rb:14:17:14:23 | "hello" |
|
||||
| type_tracker.rb:14:17:14:23 | "hello" | type_tracker.rb:15:10:15:18 | call to field |
|
||||
| type_tracker.rb:15:5:15:18 | [post] self | type_tracker.rb:15:5:15:18 | [post] self |
|
||||
| type_tracker.rb:15:5:15:18 | call to puts | type_tracker.rb:12:1:16:3 | return return in m |
|
||||
| type_tracker.rb:15:5:15:18 | call to puts | type_tracker.rb:15:5:15:18 | call to puts |
|
||||
| type_tracker.rb:15:5:15:18 | self | type_tracker.rb:15:5:15:18 | self |
|
||||
| type_tracker.rb:15:10:15:12 | [post] var | type_tracker.rb:15:10:15:12 | [post] var |
|
||||
| type_tracker.rb:15:10:15:18 | [post] call to field | type_tracker.rb:15:10:15:18 | [post] call to field |
|
||||
| type_tracker.rb:15:10:15:18 | call to field | type_tracker.rb:15:10:15:18 | call to field |
|
|
@ -0,0 +1,18 @@
|
|||
import ruby
|
||||
import codeql.ruby.DataFlow
|
||||
import codeql.ruby.typetracking.TypeTracker
|
||||
|
||||
class LocalSourceNode extends DataFlow::LocalSourceNode {
|
||||
LocalSourceNode() { this.getLocation().getFile().getExtension() = "rb" }
|
||||
}
|
||||
|
||||
query predicate track(LocalSourceNode src, TypeTracker t, LocalSourceNode dst) {
|
||||
t.start() and
|
||||
dst = src
|
||||
or
|
||||
exists(TypeTracker t2, LocalSourceNode mid | track(src, t2, mid) and dst = mid.track(t2, t))
|
||||
}
|
||||
|
||||
query predicate trackEnd(LocalSourceNode src, LocalSourceNode dst) {
|
||||
track(src, TypeTracker::end(), dst)
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
class Container
|
||||
def field=(val)
|
||||
puts self.field
|
||||
@field = val
|
||||
end
|
||||
|
||||
def field
|
||||
@field
|
||||
end
|
||||
end
|
||||
|
||||
def m()
|
||||
var = Container.new
|
||||
var.field = "hello"
|
||||
puts var.field
|
||||
end
|
Загрузка…
Ссылка в новой задаче