Merge branch 'main' into extractBigReg

This commit is contained in:
Erik Krogh Kristensen
2021-11-12 11:45:49 +01:00
286 changed files with 13089 additions and 4444 deletions

View File

@@ -8,7 +8,7 @@ runs:
run: | run: |
LATEST=$(gh release list --repo https://github.com/github/codeql-cli-binaries | cut -f 1 | grep -v beta | sort --version-sort | tail -1) LATEST=$(gh release list --repo https://github.com/github/codeql-cli-binaries | cut -f 1 | grep -v beta | sort --version-sort | tail -1)
gh release download --repo https://github.com/github/codeql-cli-binaries --pattern codeql-linux64.zip "$LATEST" gh release download --repo https://github.com/github/codeql-cli-binaries --pattern codeql-linux64.zip "$LATEST"
unzip -q codeql-linux64.zip unzip -q -d "${RUNNER_TEMP}" codeql-linux64.zip
echo "${{ github.workspace }}/codeql" >> $GITHUB_PATH echo "${RUNNER_TEMP}/codeql" >> "${GITHUB_PATH}"
env: env:
GITHUB_TOKEN: ${{ github.token }} GITHUB_TOKEN: ${{ github.token }}

31
.github/workflows/post-pr-comment.yml vendored Normal file
View File

@@ -0,0 +1,31 @@
name: Post pull-request comment
on:
workflow_run:
workflows: ["Query help preview"]
types:
- completed
permissions:
pull-requests: write
jobs:
post_comment:
runs-on: ubuntu-latest
steps:
- name: Download artifact
run: gh run download "${WORKFLOW_RUN_ID}" --repo "${GITHUB_REPOSITORY}" --name "comment"
env:
GITHUB_TOKEN: ${{ github.token }}
WORKFLOW_RUN_ID: ${{ github.event.workflow_run.id }}
- run: |
PR="$(grep -o '^[0-9]\+$' pr.txt)"
PR_HEAD_SHA="$(gh api "/repos/${GITHUB_REPOSITORY}/pulls/${PR}" --jq .head.sha)"
# Check that the pull-request head SHA matches the head SHA of the workflow run
if [ "${WORKFLOW_RUN_HEAD_SHA}" != "${PR_HEAD_SHA}" ]; then
echo "PR head SHA ${PR_HEAD_SHA} does not match workflow_run event SHA ${WORKFLOW_RUN_HEAD_SHA}. Stopping." 1>&2
exit 1
fi
gh pr comment "${PR}" --repo "${GITHUB_REPOSITORY}" -F comment.txt
env:
GITHUB_TOKEN: ${{ github.token }}
WORKFLOW_RUN_HEAD_SHA: ${{ github.event.workflow_run.head_commit.id }}

View File

@@ -1,10 +1,13 @@
name: Query help preview name: Query help preview
permissions:
contents: read
on: on:
pull_request: pull_request:
branches: branches:
- main - main
- 'rc/*' - "rc/*"
paths: paths:
- "ruby/**/*.qhelp" - "ruby/**/*.qhelp"
@@ -12,28 +15,49 @@ jobs:
qhelp: qhelp:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- run: echo "${{ github.event.number }}" > pr.txt
- uses: actions/upload-artifact@v2
with:
name: comment
path: pr.txt
retention-days: 1
- uses: actions/checkout@v2 - uses: actions/checkout@v2
with: with:
fetch-depth: 2 fetch-depth: 2
persist-credentials: false
- uses: ./.github/actions/fetch-codeql
- name: Determine changed files - name: Determine changed files
id: changes id: changes
run: | run: |
echo -n "::set-output name=qhelp_files::" (git diff -z --name-only --diff-filter=ACMRT HEAD~1 HEAD | grep -z '.qhelp$' | grep -z -v '.inc.qhelp';
(git diff --name-only --diff-filter=ACMRT HEAD~1 HEAD | grep .qhelp$ | grep -v .inc.qhelp; git diff -z --name-only --diff-filter=ACMRT HEAD~1 HEAD | grep -z '.inc.qhelp$' | xargs --null -rn1 basename | xargs --null -rn1 git grep -z -l) |
git diff --name-only --diff-filter=ACMRT HEAD~1 HEAD | grep .inc.qhelp$ | xargs -d '\n' -rn1 basename | xargs -d '\n' -rn1 git grep -l) | grep -z '.qhelp$' | grep -z -v '^-' | sort -z -u > "${RUNNER_TEMP}/paths.txt"
sort -u | xargs -d '\n' -n1 printf "'%s' "
- uses: ./.github/actions/fetch-codeql
- name: QHelp preview - name: QHelp preview
if: ${{ steps.changes.outputs.qhelp_files }}
run: | run: |
( echo "QHelp previews:"; EXIT_CODE=0
for path in ${{ steps.changes.outputs.qhelp_files }} ; do echo "QHelp previews:" > comment.txt
while read -r -d $'\0' path; do
if [ ! -f "${path}" ]; then
exit 1
fi
echo "<details> <summary>${path}</summary>" echo "<details> <summary>${path}</summary>"
echo echo
codeql generate query-help --format=markdown ${path} codeql generate query-help --format=markdown -- "./${path}" 2> errors.txt || EXIT_CODE="$?"
if [ -s errors.txt ]; then
echo "# errors/warnings:"
echo '```'
cat errors.txt
cat errors.txt 1>&2
echo '```'
fi
echo "</details>" echo "</details>"
done) | gh pr comment "${{ github.event.pull_request.number }}" -F - done < "${RUNNER_TEMP}/paths.txt" >> comment.txt
env: exit "${EXIT_CODE}"
GITHUB_TOKEN: ${{ github.token }}
- if: always()
uses: actions/upload-artifact@v2
with:
name: comment
path: comment.txt
retention-days: 1

View File

@@ -3,16 +3,18 @@ name: "Ruby: Build"
on: on:
push: push:
paths: paths:
- 'ruby/**' - "ruby/**"
- .github/workflows/ruby-build.yml
branches: branches:
- main - main
- 'rc/*' - "rc/*"
pull_request: pull_request:
paths: paths:
- 'ruby/**' - "ruby/**"
- .github/workflows/ruby-build.yml
branches: branches:
- main - main
- 'rc/*' - "rc/*"
workflow_dispatch: workflow_dispatch:
inputs: inputs:
tag: tag:

View File

@@ -4,15 +4,17 @@ on:
push: push:
branches: branches:
- main - main
- 'rc/*' - "rc/*"
paths: paths:
- ruby/ql/lib/ruby.dbscheme - ruby/ql/lib/ruby.dbscheme
- .github/workflows/ruby-dataset-measure.yml
pull_request: pull_request:
branches: branches:
- main - main
- 'rc/*' - "rc/*"
paths: paths:
- ruby/ql/lib/ruby.dbscheme - ruby/ql/lib/ruby.dbscheme
- .github/workflows/ruby-dataset-measure.yml
workflow_dispatch: workflow_dispatch:
jobs: jobs:

View File

@@ -3,16 +3,18 @@ name: "Ruby: Run QL Tests"
on: on:
push: push:
paths: paths:
- 'ruby/**' - "ruby/**"
- .github/workflows/ruby-qltest.yml
branches: branches:
- main - main
- 'rc/*' - "rc/*"
pull_request: pull_request:
paths: paths:
- 'ruby/**' - "ruby/**"
- .github/workflows/ruby-qltest.yml
branches: branches:
- main - main
- 'rc/*' - "rc/*"
env: env:
CARGO_TERM_COLOR: always CARGO_TERM_COLOR: always
@@ -44,5 +46,5 @@ jobs:
run: | run: |
echo >empty.trap echo >empty.trap
codeql dataset import -S ql/lib/upgrades/initial/ruby.dbscheme testdb empty.trap codeql dataset import -S ql/lib/upgrades/initial/ruby.dbscheme testdb empty.trap
codeql dataset upgrade testdb --additional-packs ql/lib/upgrades codeql dataset upgrade testdb --additional-packs ql/lib
diff -q testdb/ruby.dbscheme ql/lib/ruby.dbscheme diff -q testdb/ruby.dbscheme ql/lib/ruby.dbscheme

View File

@@ -449,7 +449,8 @@
"csharp/ql/lib/semmle/code/csharp/controlflow/internal/pressa/SsaImplCommon.qll", "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/csharp/dataflow/internal/basessa/SsaImplCommon.qll",
"csharp/ql/lib/semmle/code/cil/internal/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": [ "CryptoAlgorithms Python/JS": [
"javascript/ql/lib/semmle/javascript/security/CryptoAlgorithms.qll", "javascript/ql/lib/semmle/javascript/security/CryptoAlgorithms.qll",

View File

@@ -3,11 +3,14 @@ private import semmle.code.cpp.models.interfaces.ArrayFunction
private import semmle.code.cpp.models.implementations.Strcat private import semmle.code.cpp.models.implementations.Strcat
import semmle.code.cpp.dataflow.DataFlow import semmle.code.cpp.dataflow.DataFlow
private predicate mayAddNullTerminatorHelper(Expr e, VariableAccess va, Expr e0) { /**
exists(StackVariable v0, Expr val | * Holds if the expression `e` assigns something including `va` to a
exprDefinition(v0, e, val) and * stack variable `v0`.
val.getAChild*() = va and */
mayAddNullTerminator(e0, v0.getAnAccess()) private predicate mayAddNullTerminatorHelper(Expr e, VariableAccess va, StackVariable v0) {
exists(Expr val |
exprDefinition(v0, e, val) and // `e` is `v0 := val`
val.getAChild*() = va
) )
} }
@@ -25,8 +28,8 @@ private predicate controlFlowNodeSuccessorTransitive(ControlFlowNode n1, Control
} }
/** /**
* Holds if the expression `e` may add a null terminator to the string in * Holds if the expression `e` may add a null terminator to the string
* variable `v`. * accessed by `va`.
*/ */
predicate mayAddNullTerminator(Expr e, VariableAccess va) { predicate mayAddNullTerminator(Expr e, VariableAccess va) {
// Assignment: dereferencing or array access // Assignment: dereferencing or array access
@@ -43,8 +46,9 @@ predicate mayAddNullTerminator(Expr e, VariableAccess va) {
) )
or or
// Assignment to another stack variable // Assignment to another stack variable
exists(Expr e0 | exists(StackVariable v0, Expr e0 |
mayAddNullTerminatorHelper(pragma[only_bind_into](e), va, pragma[only_bind_into](e0)) and mayAddNullTerminatorHelper(e, va, v0) and
mayAddNullTerminator(pragma[only_bind_into](e0), pragma[only_bind_into](v0.getAnAccess())) and
controlFlowNodeSuccessorTransitive(e, e0) controlFlowNodeSuccessorTransitive(e, e0)
) )
or or

View File

@@ -474,6 +474,24 @@ module TaintedWithPath {
} }
} }
/**
* INTERNAL: Do not use.
*/
module Private {
/** Gets a predecessor `PathNode` of `pathNode`, if any. */
PathNode getAPredecessor(PathNode pathNode) { edges(result, pathNode) }
/** Gets the element that `pathNode` wraps, if any. */
Element getElementFromPathNode(PathNode pathNode) {
exists(DataFlow::Node node | node = pathNode.(WrapPathNode).inner().getNode() |
result = node.asExpr() or
result = node.asParameter()
)
or
result = pathNode.(EndpointPathNode).inner()
}
}
private class WrapPathNode extends PathNode, TWrapPathNode { private class WrapPathNode extends PathNode, TWrapPathNode {
DataFlow3::PathNode inner() { this = TWrapPathNode(result) } DataFlow3::PathNode inner() { this = TWrapPathNode(result) }

View File

@@ -63,8 +63,10 @@ private module VirtualDispatch {
| |
// Call argument // Call argument
exists(DataFlowCall call, int i | exists(DataFlowCall call, int i |
other.(DataFlow::ParameterNode).isParameterOf(call.getStaticCallTarget(), i) and other
src.(ArgumentNode).argumentOf(call, i) .(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 ) and
allowOtherFromArg = true and allowOtherFromArg = true and
allowFromArg = true allowFromArg = true
@@ -128,6 +130,7 @@ private module VirtualDispatch {
* *
* Used to fix a join ordering issue in flowsFrom. * Used to fix a join ordering issue in flowsFrom.
*/ */
pragma[noinline]
private predicate returnNodeWithKindAndEnclosingCallable( private predicate returnNodeWithKindAndEnclosingCallable(
ReturnNode node, ReturnKind kind, DataFlowCallable callable ReturnNode node, ReturnKind kind, DataFlowCallable callable
) { ) {

View File

@@ -112,11 +112,9 @@ class ReturnNode extends InstructionNode {
Instruction primary; Instruction primary;
ReturnNode() { ReturnNode() {
exists(ReturnValueInstruction ret | instr = ret.getReturnValue() and primary = ret) exists(ReturnValueInstruction ret | instr = ret and primary = ret)
or or
exists(ReturnIndirectionInstruction rii | exists(ReturnIndirectionInstruction rii | instr = rii and primary = rii)
instr = rii.getSideEffectOperand().getAnyDef() and primary = rii
)
} }
/** Gets the kind of this returned value. */ /** Gets the kind of this returned value. */
@@ -190,108 +188,16 @@ OutNode getAnOutNode(DataFlowCall call, ReturnKind kind) {
*/ */
predicate jumpStep(Node n1, Node n2) { none() } 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`. * 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 * Thus, `node2` references an object with a field `f` that contains the
* value of `node1`. * value of `node1`.
*/ */
predicate storeStep(Node node1, Content f, PostUpdateNode node2) { predicate storeStep(StoreNodeInstr node1, FieldContent f, StoreNodeInstr node2) {
fieldStoreStepNoChi(node1, f, node2) or exists(FieldAddressInstruction fai |
fieldStoreStepChi(node1, f, node2) or node1.getInstruction() = fai and
arrayStoreStepChi(node1, f, node2) or node2.getInstruction() = fai.getObjectAddress() and
fieldStoreStepAfterArraySuppression(node1, f, node2) f.getField() = fai.getField()
}
// 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()
) )
} }
@@ -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 * Thus, `node1` references an object with a field `f` whose value ends up in
* `node2`. * `node2`.
*/ */
private predicate fieldReadStep(Node node1, FieldContent f, Node node2) { predicate readStep(ReadNode node1, FieldContent f, ReadNode node2) {
exists(LoadOperand operand | exists(FieldAddressInstruction fai |
node2.asOperand() = operand and node1.getInstruction() = fai.getObjectAddress() and
node1.asInstruction() = operand.getAnyDef() and node2.getInstruction() = fai and
exists(Class c | f.getField() = fai.getField()
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, _, _)
)
) )
} }
/**
* 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`. * 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 // Java QL library compatibility wrappers
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////
/** A node that performs a type cast. */ /** A node that performs a type cast. */
class CastNode extends InstructionNode { class CastNode extends Node {
CastNode() { none() } // stub implementation CastNode() { none() } // stub implementation
} }

View File

@@ -10,19 +10,78 @@ private import semmle.code.cpp.ir.ValueNumbering
private import semmle.code.cpp.ir.IR private import semmle.code.cpp.ir.IR
private import semmle.code.cpp.controlflow.IRGuards private import semmle.code.cpp.controlflow.IRGuards
private import semmle.code.cpp.models.interfaces.DataFlow private import semmle.code.cpp.models.interfaces.DataFlow
private import DataFlowPrivate
private import SsaInternals as Ssa
cached cached
private module 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 cached
newtype TIRDataFlowNode = newtype TIRDataFlowNode =
TInstructionNode(Instruction i) or TInstructionNode(Instruction i) or
TOperandNode(Operand op) 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 cached
predicate localFlowStepCached(Node nodeFrom, Node nodeTo) { predicate localFlowStepCached(Node nodeFrom, Node nodeTo) {
simpleLocalFlowStep(nodeFrom, 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 private import Cached
@@ -180,6 +239,234 @@ class OperandNode extends Node, TOperandNode {
override string toString() { result = this.getOperand().toString() } 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. * 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 * Nodes corresponding to AST elements, for example `ExprNode`, usually refer
* to the value before the update with the exception of `ClassInstanceExpr`, * to the value before the update with the exception of `ClassInstanceExpr`,
* which represents the value after the constructor has run. * 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. * Gets the node before the state update.
*/ */
abstract Node getPreUpdateNode(); 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: * value, but does not necessarily replace it entirely. For example:
* ``` * ```
* x.y = 1; // a partial definition of the object `x`. * 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`. * x.setY(1); // a partial definition of the object `x`.
* setY(&x); // 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(); abstract Expr getDefinedExpr();
} }
private class ExplicitFieldStoreQualifierNode extends PartialDefinitionNode { private class FieldPartialDefinitionNode extends PartialDefinitionNode, StoreNodeInstr {
override ChiInstruction instr; FieldPartialDefinitionNode() {
StoreInstruction store; this.getInstruction() = any(FieldAddressInstruction fai).getObjectAddress()
ExplicitFieldStoreQualifierNode() {
not instr.isResultConflated() and
instr.getPartial() = store and
(
instr.getUpdatedInterval(_, _) or
store.getDestinationAddress() instanceof FieldAddressInstruction
)
} }
// By using an operand as the result of this predicate we avoid the dataflow inconsistency errors override Node getPreUpdateNode() { result.asInstruction() = this.getInstruction() }
// 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 override Expr getDefinedExpr() { result = this.getInstruction().getUnconvertedResultExpression() }
// into a big step.
override Node getPreUpdateNode() { result.asOperand() = instr.getTotalOperand() } 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() { override Expr getDefinedExpr() {
result = result = this.getOperand().getDef().getUnconvertedResultExpression()
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
} }
override Node getPreUpdateNode() { none() } override string toString() { result = PartialDefinitionNode.super.toString() }
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() }
} }
/** /**
@@ -548,6 +733,11 @@ class VariableNode extends Node, TVariableNode {
*/ */
InstructionNode instructionNode(Instruction instr) { result.getInstruction() = instr } InstructionNode instructionNode(Instruction instr) { result.getInstruction() = instr }
/**
* Gets the node corresponding to `operand`.
*/
OperandNode operandNode(Operand operand) { result.getOperand() = operand }
/** /**
* DEPRECATED: use `definitionByReferenceNodeFromArgument` instead. * DEPRECATED: use `definitionByReferenceNodeFromArgument` instead.
* *
@@ -614,61 +804,167 @@ predicate simpleLocalFlowStep(Node nodeFrom, Node nodeTo) {
or or
// Instruction -> Operand flow // Instruction -> Operand flow
simpleOperandLocalFlowStep(nodeFrom.asInstruction(), nodeTo.asOperand()) 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 adjacentDefUseFlow(Node nodeFrom, Node nodeTo) {
private predicate getFieldSizeOfClass(Class c, Type type, int size) { // Flow that isn't already covered by field flow out of store/read nodes.
exists(Field f | not nodeFrom.asInstruction() = any(StoreNode pun).getStoreInstruction() and
f.getDeclaringType() = c and not nodeFrom.asInstruction() = any(ReadNode pun).getALoadInstruction() and
f.getUnderlyingType() = type and (
type.getSize() = size //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) { private module ReadNodeFlow {
exists(int size, Class c | /** Holds if the read node `nodeTo` should receive flow from `nodeFrom`. */
c = op.getType().getUnderlyingType() and predicate flowInto(Node nodeFrom, ReadNode nodeTo) {
c.getSize() = size and nodeTo.isInitial() and
getFieldSizeOfClass(c, type, size) (
) // 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) { private predicate simpleOperandLocalFlowStep(Instruction iFrom, Operand opTo) {
// Propagate flow from an instruction to its exact uses. // 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 opTo.getDef() = iFrom
or }
opTo = any(ReadSideEffectInstruction read).getSideEffectOperand() and
not iFrom.isResultConflated() and pragma[noinline]
iFrom = opTo.getAnyDef() private predicate getAddressType(LoadInstruction load, Type t) {
or exists(Instruction address |
// Loading a single `int` from an `int *` parameter is not an exact load since address = load.getSourceAddress() and
// the parameter may point to an entire array rather than a single `int`. The t = address.getResultType()
// 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)
) )
} }
/**
* 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) { private predicate simpleInstructionLocalFlowStep(Operand opFrom, Instruction iTo) {
iTo.(CopyInstruction).getSourceValueOperand() = opFrom iTo.(CopyInstruction).getSourceValueOperand() = opFrom
or or
@@ -681,40 +977,8 @@ private predicate simpleInstructionLocalFlowStep(Operand opFrom, Instruction iTo
or or
iTo.(InheritanceConversionInstruction).getUnaryOperand() = opFrom iTo.(InheritanceConversionInstruction).getUnaryOperand() = opFrom
or or
// A chi instruction represents a point where a new value (the _partial_ // Conflate references and values like in AST dataflow.
// operand) may overwrite an old value (the _total_ operand), but the alias iTo.(ReferenceDereferenceInstruction).getSourceAddressOperand() = opFrom
// 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()
)
or or
// Flow through modeled functions // Flow through modeled functions
modelFlow(opFrom, iTo) modelFlow(opFrom, iTo)
@@ -788,25 +1052,14 @@ predicate localInstructionFlow(Instruction e1, Instruction e2) {
*/ */
predicate localExprFlow(Expr e1, Expr e2) { localFlow(exprNode(e1), exprNode(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 = private newtype TContent =
TFieldContent(Class c, int startBit, int endBit) { exists(getAField(c, startBit, endBit)) } or TFieldContent(Field f) {
TCollectionContent() or // As reads and writes to union fields can create flow even though the reads and writes
TArrayContent() // 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 * 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. */ /** A reference through an instance field. */
class FieldContent extends Content, TFieldContent { class FieldContent extends Content, TFieldContent {
Class c; Field f;
int startBit;
int endBit;
FieldContent() { this = TFieldContent(c, startBit, endBit) } FieldContent() { this = TFieldContent(f) }
// Ensure that there's just 1 result for `toString`. override string toString() { result = f.toString() }
override string toString() { result = min(Field f | f = this.getAField() | f.toString()) }
predicate hasOffset(Class cl, int start, int end) { cl = c and start = startBit and end = endBit } Field getField() { result = f }
Field getAField() { result = getAField(c, startBit, endBit) }
} }
/** A reference through an array. */ /** A reference through an array. */

View File

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

View File

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

View File

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

View File

@@ -44,8 +44,6 @@ private predicate instructionToOperandTaintStep(Instruction fromInstr, Operand t
fromInstr = readInstr.getArgumentDef() and fromInstr = readInstr.getArgumentDef() and
toOperand = readInstr.getSideEffectOperand() 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 instrTo.(FieldAddressInstruction).getField().getDeclaringType() instanceof Union
) )
or or
instrTo.(LoadInstruction).getSourceAddressOperand() = opFrom
or
// Flow from an element to an array or union that contains it. // Flow from an element to an array or union that contains it.
instrTo.(ChiInstruction).getPartialOperand() = opFrom and instrTo.(ChiInstruction).getPartialOperand() = opFrom and
not instrTo.isResultConflated() and not instrTo.isResultConflated() and

View File

@@ -762,11 +762,21 @@ class ReturnValueInstruction extends ReturnInstruction {
*/ */
final LoadOperand getReturnValueOperand() { result = this.getAnOperand() } 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 * Gets the instruction whose result provides the value being returned by the function, if an
* exact definition is available. * exact definition is available.
*/ */
final Instruction getReturnValue() { result = this.getReturnValueOperand().getDef() } 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() }
} }
/** /**

View File

@@ -762,11 +762,21 @@ class ReturnValueInstruction extends ReturnInstruction {
*/ */
final LoadOperand getReturnValueOperand() { result = this.getAnOperand() } 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 * Gets the instruction whose result provides the value being returned by the function, if an
* exact definition is available. * exact definition is available.
*/ */
final Instruction getReturnValue() { result = this.getReturnValueOperand().getDef() } 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() }
} }
/** /**

View File

@@ -762,11 +762,21 @@ class ReturnValueInstruction extends ReturnInstruction {
*/ */
final LoadOperand getReturnValueOperand() { result = this.getAnOperand() } 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 * Gets the instruction whose result provides the value being returned by the function, if an
* exact definition is available. * exact definition is available.
*/ */
final Instruction getReturnValue() { result = this.getReturnValueOperand().getDef() } 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() }
} }
/** /**

View File

@@ -0,0 +1,24 @@
...
chroot("/myFold/myTmp"); // BAD
...
chdir("/myFold/myTmp"); // BAD
...
int fd = open("/myFold/myTmp", O_RDONLY | O_DIRECTORY);
fchdir(fd); // BAD
...
if (chdir("/myFold/myTmp") == -1) {
exit(-1);
}
if (chroot("/myFold/myTmp") == -1) { // GOOD
exit(-1);
}
...
if (chdir("/myFold/myTmp") == -1) { // GOOD
exit(-1);
}
...
int fd = open("/myFold/myTmp", O_RDONLY | O_DIRECTORY);
if(fchdir(fd) == -1) { // GOOD
exit(-1);
}
...

View File

@@ -0,0 +1,23 @@
<!DOCTYPE qhelp PUBLIC
"-//Semmle//qhelp//EN"
"qhelp.dtd">
<qhelp>
<overview>
<p>Working with changing directories, without checking the return value or pinning the directory, may not be safe. Requires the attention of developers.</p>
</overview>
<example>
<p>The following example demonstrates erroneous and corrected work with changing working directories.</p>
<sample src="IncorrectChangingWorkingDirectory.cpp" />
</example>
<references>
<li>
CERT C Coding Standard:
<a href="https://wiki.sei.cmu.edu/confluence/display/c/POS05-C.+Limit+access+to+files+by+creating+a+jail">POS05-C. Limit access to files by creating a jail.</a>
</li>
</references>
</qhelp>

View File

@@ -0,0 +1,69 @@
/**
* @name Find work with changing working directories, with security errors.
* @description Not validating the return value or pinning the directory can be unsafe.
* @kind problem
* @id cpp/work-with-changing-working-directories
* @problem.severity warning
* @precision medium
* @tags correctness
* security
* external/cwe/cwe-243
* external/cwe/cwe-252
*/
import cpp
import semmle.code.cpp.commons.Exclusions
/** Holds if a `fc` function call is available before or after a `chdir` function call. */
predicate inExistsChdir(FunctionCall fcp) {
exists(FunctionCall fctmp |
(
fctmp.getTarget().hasGlobalOrStdName("chdir") or
fctmp.getTarget().hasGlobalOrStdName("fchdir")
) and
(
fcp.getBasicBlock().getASuccessor*() = fctmp.getBasicBlock() or
fctmp.getBasicBlock().getASuccessor*() = fcp.getBasicBlock()
)
)
}
/** Holds if a `fc` function call is available before or after a function call containing a `chdir` call. */
predicate outExistsChdir(FunctionCall fcp) {
exists(FunctionCall fctmp |
exists(FunctionCall fctmp2 |
(
fctmp2.getTarget().hasGlobalOrStdName("chdir") or
fctmp2.getTarget().hasGlobalOrStdName("fchdir")
) and
// we are looking for a call containing calls chdir and fchdir
fctmp2.getEnclosingStmt().getParentStmt*() = fctmp.getTarget().getEntryPoint().getChildStmt*()
) and
(
fcp.getBasicBlock().getASuccessor*() = fctmp.getBasicBlock() or
fctmp.getBasicBlock().getASuccessor*() = fcp.getBasicBlock()
)
)
}
from FunctionCall fc, string msg
where
fc.getTarget().hasGlobalOrStdName("chroot") and
not inExistsChdir(fc) and
not outExistsChdir(fc) and
// in this section I want to exclude calls to functions containing chroot that have a direct path to chdir, or to a function containing chdir
exists(FunctionCall fctmp |
fc.getEnclosingStmt().getParentStmt*() = fctmp.getTarget().getEntryPoint().getChildStmt*() and
not inExistsChdir(fctmp) and
not outExistsChdir(fctmp)
) and
msg = "Creation of 'chroot' jail without changing the working directory"
or
(
fc.getTarget().hasGlobalOrStdName("chdir") or
fc.getTarget().hasGlobalOrStdName("fchdir")
) and
fc instanceof ExprInVoidContext and
not isFromMacroDefinition(fc) and
msg = "Unchecked return value for call to '" + fc.getTarget().getName() + "'."
select fc, msg

View File

@@ -0,0 +1,14 @@
...
fp = fopen("/tmp/name.tmp","w"); // BAD
...
char filename = tmpnam(NULL);
fp = fopen(filename,"w"); // BAD
...
strcat (filename, "/tmp/name.XXXXXX");
fd = mkstemp(filename);
if ( fd < 0 ) {
return error;
}
fp = fdopen(fd,"w") // GOOD
...

View File

@@ -0,0 +1,23 @@
<!DOCTYPE qhelp PUBLIC
"-//Semmle//qhelp//EN"
"qhelp.dtd">
<qhelp>
<overview>
<p>Working with a file, without checking its existence and its rights, as well as working with names that can be predicted, may not be safe. Requires the attention of developers.</p>
</overview>
<example>
<p>The following example demonstrates erroneous and corrected work with file.</p>
<sample src="InsecureTemporaryFile.cpp" />
</example>
<references>
<li>
CERT C Coding Standard:
<a href="https://wiki.sei.cmu.edu/confluence/display/c/CON33-C.+Avoid+race+conditions+when+using+library+functions">CON33-C. Avoid race conditions when using library functions</a>.
</li>
</references>
</qhelp>

View File

@@ -0,0 +1,112 @@
/**
* @name Insecure generation of filenames.
* @description Using a predictable filename when creating a temporary file can lead to an attacker-controlled input.
* @kind problem
* @id cpp/insecure-generation-of-filename
* @problem.severity warning
* @precision medium
* @tags correctness
* security
* external/cwe/cwe-377
*/
import cpp
import semmle.code.cpp.valuenumbering.GlobalValueNumbering
/** Holds for a function `f` that has an argument at index `apos` used to read the file. */
predicate numberArgumentRead(Function f, int apos) {
f.hasGlobalOrStdName("fgets") and apos = 2
or
f.hasGlobalOrStdName("fread") and apos = 3
or
f.hasGlobalOrStdName("read") and apos = 0
or
f.hasGlobalOrStdName("fscanf") and apos = 0
}
/** Holds for a function `f` that has an argument at index `apos` used to write to file */
predicate numberArgumentWrite(Function f, int apos) {
f.hasGlobalOrStdName("fprintf") and apos = 0
or
f.hasGlobalOrStdName("fputs") and apos = 1
or
f.hasGlobalOrStdName("write") and apos = 0
or
f.hasGlobalOrStdName("fwrite") and apos = 3
or
f.hasGlobalOrStdName("fflush") and apos = 0
}
from FunctionCall fc, string msg
where
// search for functions for generating a name, without a guarantee of the absence of a file during the period of work with it.
(
fc.getTarget().hasGlobalOrStdName("tmpnam") or
fc.getTarget().hasGlobalOrStdName("tmpnam_s") or
fc.getTarget().hasGlobalOrStdName("tmpnam_r")
) and
not exists(FunctionCall fctmp |
(
fctmp.getTarget().hasGlobalOrStdName("mktemp") or
fctmp.getTarget().hasGlobalOrStdName("mkstemp") or
fctmp.getTarget().hasGlobalOrStdName("mkstemps") or
fctmp.getTarget().hasGlobalOrStdName("mkdtemp")
) and
(
fc.getBasicBlock().getASuccessor*() = fctmp.getBasicBlock() or
fctmp.getBasicBlock().getASuccessor*() = fc.getBasicBlock()
)
) and
msg =
"Finding the name of a file that does not exist does not mean that it will not be exist at the next operation."
or
// finding places to work with a file without setting permissions, but with predictable names.
(
fc.getTarget().hasGlobalOrStdName("fopen") or
fc.getTarget().hasGlobalOrStdName("open")
) and
fc.getNumberOfArguments() = 2 and
exists(FunctionCall fctmp, int i |
numberArgumentWrite(fctmp.getTarget(), i) and
globalValueNumber(fc) = globalValueNumber(fctmp.getArgument(i))
) and
not exists(FunctionCall fctmp, int i |
numberArgumentRead(fctmp.getTarget(), i) and
globalValueNumber(fc) = globalValueNumber(fctmp.getArgument(i))
) and
exists(FunctionCall fctmp |
(
fctmp.getTarget().hasGlobalOrStdName("strcat") or
fctmp.getTarget().hasGlobalOrStdName("strcpy")
) and
globalValueNumber(fc.getArgument(0)) = globalValueNumber(fctmp.getAnArgument())
or
fctmp.getTarget().hasGlobalOrStdName("getenv") and
globalValueNumber(fc.getArgument(0)) = globalValueNumber(fctmp)
or
(
fctmp.getTarget().hasGlobalOrStdName("asprintf") or
fctmp.getTarget().hasGlobalOrStdName("vasprintf") or
fctmp.getTarget().hasGlobalOrStdName("xasprintf") or
fctmp.getTarget().hasGlobalOrStdName("xvasprintf ")
) and
exists(Variable vrtmp |
vrtmp = fc.getArgument(0).(VariableAccess).getTarget() and
vrtmp = fctmp.getArgument(0).(AddressOfExpr).getAddressable().(Variable) and
not vrtmp instanceof Field
)
) and
not exists(FunctionCall fctmp |
(
fctmp.getTarget().hasGlobalOrStdName("umask") or
fctmp.getTarget().hasGlobalOrStdName("fchmod") or
fctmp.getTarget().hasGlobalOrStdName("chmod")
) and
(
fc.getBasicBlock().getASuccessor*() = fctmp.getBasicBlock() or
fctmp.getBasicBlock().getASuccessor*() = fc.getBasicBlock()
)
) and
msg =
"Creating a file for writing without evaluating its existence and setting permissions can be unsafe."
select fc, msg

View File

@@ -0,0 +1,2 @@
| test.cpp:12:7:12:12 | call to chroot | Creation of 'chroot' jail without changing the working directory |
| test.cpp:29:3:29:7 | call to chdir | Unchecked return value for call to 'chdir'. |

View File

@@ -0,0 +1 @@
experimental/Security/CWE/CWE-243/IncorrectChangingWorkingDirectory.ql

View File

@@ -0,0 +1,46 @@
typedef int FILE;
#define size_t int
size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream);
FILE *fopen(const char *filename, const char *mode);
int fread(char *buf, int size, int count, FILE *fp);
int fclose(FILE *fp);
int chroot(char *path);
int chdir(char *path);
void exit(int status);
int funTest1(){
if (chroot("/myFold/myTmp") == -1) { // BAD
exit(-1);
}
return 0;
}
int funTest2(){
if (chdir("/myFold/myTmp") == -1) { // GOOD
exit(-1);
}
if (chroot("/myFold/myTmp") == -1) { // GOOD
exit(-1);
}
return 0;
}
int funTest3(){
chdir("/myFold/myTmp"); // BAD
return 0;
}
int main(int argc, char *argv[])
{
if(argc = 0) {
funTest3();
return 2;
}
if(argc = 1)
funTest1();
else
funTest2();
FILE *fp = fopen(argv[1], "w");
fwrite("12345", 5, 1, fp);
fclose(fp);
return 0;
}

View File

@@ -0,0 +1,2 @@
| test.cpp:16:20:16:25 | call to tmpnam | Finding the name of a file that does not exist does not mean that it will not be exist at the next operation. |
| test.cpp:42:8:42:12 | call to fopen | Creating a file for writing without evaluating its existence and setting permissions can be unsafe. |

View File

@@ -0,0 +1 @@
experimental/Security/CWE/CWE-377/InsecureTemporaryFile.ql

View File

@@ -0,0 +1,68 @@
typedef int FILE;
#define NULL (0)
FILE *fopen(char *filename, const char *mode);
FILE *fdopen(int handle, char *mode);
char * tmpnam(char * name);
int mkstemp(char * name);
char * strcat(char *str1, const char *str2);
int umask(int pmode);
int chmod(char * filename,int pmode);
int fprintf(FILE *fp,const char *fmt, ...);
int fclose(FILE *stream);
int funcTest1()
{
FILE *fp;
char *filename = tmpnam(NULL); // BAD
fp = fopen(filename,"w");
fprintf(fp,"%s\n","data to file");
fclose(fp);
return 0;
}
int funcTest2()
{
FILE *fp;
int fd;
char filename[80];
strcat (filename, "/tmp/name.XXXXXX");
fd = mkstemp(filename);
if ( fd < 0 ) {
return 1;
}
fp = fdopen(fd,"w"); // GOOD
return 0;
}
int funcTest3()
{
FILE *fp;
char filename[80];
strcat(filename, "/tmp/tmp.name");
fp = fopen(filename,"w"); // BAD
fprintf(fp,"%s\n","data to file");
fclose(fp);
return 0;
}
int funcTest4()
{
FILE *fp;
char filename[80];
umask(0022);
strcat(filename, "/tmp/tmp.name");
fp = fopen(filename,"w"); // GOOD
chmod(filename,0666);
fprintf(fp,"%s\n","data to file");
fclose(fp);
return 0;
}
int main(int argc, char *argv[])
{
funcTest1();
funcTest2();
funcTest3();
funcTest4();
return 0;
}

View File

@@ -4,8 +4,8 @@ using SinkFunction = void (*)(int);
void notSink(int notSinkParam); void notSink(int notSinkParam);
void callsSink(int sinkParam) { void callsSink(int sinkParam) { // $ ir-path=31:28 ir-path=32:31 ir-path=34:22
sink(sinkParam); // $ ast,ir=31:28 ast,ir=32:31 ast,ir=34:22 MISSING: ast,ir=28 sink(sinkParam); // $ ir-sink=31:28 ir-sink=32:31 ir-sink=34:22 ast=31:28 ast=32:31 ast=34:22 MISSING: ast,ir=28
} }
struct { struct {
@@ -25,13 +25,13 @@ void assignGlobals() {
}; };
void testStruct() { void testStruct() {
globalStruct.sinkPtr(atoi(getenv("TAINTED"))); // $ MISSING: ast,ir globalStruct.sinkPtr(atoi(getenv("TAINTED"))); // $ ir MISSING: ast
globalStruct.notSinkPtr(atoi(getenv("TAINTED"))); // clean globalStruct.notSinkPtr(atoi(getenv("TAINTED"))); // clean
globalUnion.sinkPtr(atoi(getenv("TAINTED"))); // $ ast,ir globalUnion.sinkPtr(atoi(getenv("TAINTED"))); // $ ast ir-path
globalUnion.notSinkPtr(atoi(getenv("TAINTED"))); // $ ast,ir globalUnion.notSinkPtr(atoi(getenv("TAINTED"))); // $ ast ir-path
globalSinkPtr(atoi(getenv("TAINTED"))); // $ ast,ir globalSinkPtr(atoi(getenv("TAINTED"))); // $ ast ir-path
} }
class B { class B {
@@ -48,19 +48,19 @@ class D2 : public D1 {
class D3 : public D2 { class D3 : public D2 {
public: public:
void f(const char* p) override { void f(const char* p) override { // $ ir-path=58:10 ir-path=60:17 ir-path=61:28 ir-path=62:29 ir-path=63:33 ir-path=73:30
sink(p); // $ ast,ir=58:10 ast,ir=60:17 ast,ir=61:28 ast,ir=62:29 ast,ir=63:33 SPURIOUS: ast,ir=73:30 sink(p); // $ ir-sink=58:10 ir-sink=60:17 ir-sink=61:28 ir-sink=62:29 ir-sink=63:33 ast=58:10 ast=60:17 ast=61:28 ast=62:29 ast=63:33 SPURIOUS: ast=73:30 ir-sink=73:30
} }
}; };
void test_dynamic_cast() { void test_dynamic_cast() {
B* b = new D3(); B* b = new D3();
b->f(getenv("VAR")); // $ ast,ir b->f(getenv("VAR")); // $ ast ir-path
((D2*)b)->f(getenv("VAR")); // $ ast,ir ((D2*)b)->f(getenv("VAR")); // $ ast ir-path
static_cast<D2*>(b)->f(getenv("VAR")); // $ ast,ir static_cast<D2*>(b)->f(getenv("VAR")); // $ ast ir-path
dynamic_cast<D2*>(b)->f(getenv("VAR")); // $ ast,ir dynamic_cast<D2*>(b)->f(getenv("VAR")); // $ ast ir-path
reinterpret_cast<D2*>(b)->f(getenv("VAR")); // $ ast,ir reinterpret_cast<D2*>(b)->f(getenv("VAR")); // $ ast ir-path
B* b2 = new D2(); B* b2 = new D2();
b2->f(getenv("VAR")); b2->f(getenv("VAR"));
@@ -70,5 +70,5 @@ void test_dynamic_cast() {
dynamic_cast<D2*>(b2)->f(getenv("VAR")); dynamic_cast<D2*>(b2)->f(getenv("VAR"));
reinterpret_cast<D2*>(b2)->f(getenv("VAR")); reinterpret_cast<D2*>(b2)->f(getenv("VAR"));
dynamic_cast<D3*>(b2)->f(getenv("VAR")); // $ SPURIOUS: ast,ir dynamic_cast<D3*>(b2)->f(getenv("VAR")); // $ SPURIOUS: ast ir-path
} }

View File

@@ -7,9 +7,10 @@ import cpp
import semmle.code.cpp.security.TaintTrackingImpl as ASTTaintTracking import semmle.code.cpp.security.TaintTrackingImpl as ASTTaintTracking
import semmle.code.cpp.ir.dataflow.DefaultTaintTracking as IRDefaultTaintTracking import semmle.code.cpp.ir.dataflow.DefaultTaintTracking as IRDefaultTaintTracking
import IRDefaultTaintTracking::TaintedWithPath as TaintedWithPath import IRDefaultTaintTracking::TaintedWithPath as TaintedWithPath
import TaintedWithPath::Private
import TestUtilities.InlineExpectationsTest import TestUtilities.InlineExpectationsTest
predicate isSink(Element sink) { predicate isSinkArgument(Element sink) {
exists(FunctionCall call | exists(FunctionCall call |
call.getTarget().getName() = "sink" and call.getTarget().getName() = "sink" and
sink = call.getAnArgument() sink = call.getAnArgument()
@@ -19,31 +20,34 @@ predicate isSink(Element sink) {
predicate astTaint(Expr source, Element sink) { ASTTaintTracking::tainted(source, sink) } predicate astTaint(Expr source, Element sink) { ASTTaintTracking::tainted(source, sink) }
class SourceConfiguration extends TaintedWithPath::TaintTrackingConfiguration { class SourceConfiguration extends TaintedWithPath::TaintTrackingConfiguration {
override predicate isSink(Element e) { any() } override predicate isSink(Element e) { isSinkArgument(e) }
} }
predicate irTaint(Expr source, Element sink) { predicate irTaint(Element source, Element sink, string tag) {
TaintedWithPath::taintedWithPath(source, sink, _, _) exists(TaintedWithPath::PathNode sinkNode, TaintedWithPath::PathNode predNode |
TaintedWithPath::taintedWithPath(source, _, _, sinkNode) and
predNode = getAPredecessor*(sinkNode) and
sink = getElementFromPathNode(predNode) and
// Make sure the path is actually reachable from this predecessor.
// Otherwise, we could pick `predNode` to be b when `source` is
// `source1` in this dataflow graph:
// source1 ---> a ---> c ---> sinkNode
// ^
// source2 ---> b --/
source = getElementFromPathNode(getAPredecessor*(predNode)) and
if sinkNode = predNode then tag = "ir-sink" else tag = "ir-path"
)
} }
class IRDefaultTaintTrackingTest extends InlineExpectationsTest { class IRDefaultTaintTrackingTest extends InlineExpectationsTest {
IRDefaultTaintTrackingTest() { this = "IRDefaultTaintTrackingTest" } IRDefaultTaintTrackingTest() { this = "IRDefaultTaintTrackingTest" }
override string getARelevantTag() { result = "ir" } override string getARelevantTag() { result = ["ir-path", "ir-sink"] }
override predicate hasActualResult(Location location, string element, string tag, string value) { override predicate hasActualResult(Location location, string element, string tag, string value) {
exists(Expr source, Element tainted, int n | exists(Element source, Element tainted, int n |
tag = "ir" and irTaint(source, tainted, tag) and
irTaint(source, tainted) and n = strictcount(Element otherSource | irTaint(otherSource, tainted, _)) and
(
isSink(tainted)
or
exists(Element sink |
isSink(sink) and
irTaint(tainted, sink)
)
) and
n = strictcount(Expr otherSource | irTaint(otherSource, tainted)) and
( (
n = 1 and value = "" n = 1 and value = ""
or or
@@ -70,10 +74,10 @@ class ASTTaintTrackingTest extends InlineExpectationsTest {
tag = "ast" and tag = "ast" and
astTaint(source, tainted) and astTaint(source, tainted) and
( (
isSink(tainted) isSinkArgument(tainted)
or or
exists(Element sink | exists(Element sink |
isSink(sink) and isSinkArgument(sink) and
astTaint(tainted, sink) astTaint(tainted, sink)
) )
) and ) and

View File

@@ -13,8 +13,8 @@ struct S {
} }
}; };
void calls_sink_with_argv(const char* a) { void calls_sink_with_argv(const char* a) { // $ ir-path=96:26 ir-path=98:18
sink(a); // $ ast,ir=96:26 ast,ir=98:18 sink(a); // $ ast=96:26 ast=98:18 ir-sink=96:26 ir-sink=98:18
} }
extern int i; extern int i;
@@ -26,8 +26,8 @@ public:
class DerivedCallsSink : public BaseWithPureVirtual { class DerivedCallsSink : public BaseWithPureVirtual {
public: public:
void f(const char* p) override { void f(const char* p) override { // $ ir-path
sink(p); // $ ir ast=108:10 SPURIOUS: ast=111:10 sink(p); // $ ir-sink ast=108:10 SPURIOUS: ast=111:10
} }
}; };
@@ -38,8 +38,8 @@ public:
class DerivedCallsSinkDiamond1 : virtual public BaseWithPureVirtual { class DerivedCallsSinkDiamond1 : virtual public BaseWithPureVirtual {
public: public:
void f(const char* p) override { void f(const char* p) override { // $ ir-path
sink(p); // $ ast,ir sink(p); // $ ast ir-sink
} }
}; };
@@ -49,7 +49,7 @@ public:
}; };
class DerivesMultiple : public DerivedCallsSinkDiamond1, public DerivedDoesNotCallSinkDiamond2 { class DerivesMultiple : public DerivedCallsSinkDiamond1, public DerivedDoesNotCallSinkDiamond2 {
void f(const char* p) override { void f(const char* p) override { // $ ir-path
DerivedCallsSinkDiamond1::f(p); DerivedCallsSinkDiamond1::f(p);
} }
}; };
@@ -57,15 +57,15 @@ class DerivesMultiple : public DerivedCallsSinkDiamond1, public DerivedDoesNotCa
template<typename T> template<typename T>
class CRTP { class CRTP {
public: public:
void f(const char* p) { void f(const char* p) { // $ ir-path
static_cast<T*>(this)->g(p); static_cast<T*>(this)->g(p);
} }
}; };
class CRTPCallsSink : public CRTP<CRTPCallsSink> { class CRTPCallsSink : public CRTP<CRTPCallsSink> {
public: public:
void g(const char* p) { void g(const char* p) { // $ ir-path
sink(p); // $ ast,ir sink(p); // $ ast ir-sink
} }
}; };
@@ -78,8 +78,8 @@ class Derived2 : public Derived1 {
class Derived3 : public Derived2 { class Derived3 : public Derived2 {
public: public:
void f(const char* p) override { void f(const char* p) override { // $ ir-path=124:19 ir-path=126:43 ir-path=128:44
sink(p); // $ ast,ir=124:19 ast,ir=126:43 ast,ir=128:44 sink(p); // $ ast,ir-sink=124:19 ast,ir-sink=126:43 ast,ir-sink=128:44
} }
}; };
@@ -89,41 +89,41 @@ class CRTPDoesNotCallSink : public CRTP<CRTPDoesNotCallSink> {
}; };
int main(int argc, char *argv[]) { int main(int argc, char *argv[]) {
sink(argv[0]); // $ ast,ir sink(argv[0]); // $ ast,ir-path,ir-sink
sink(reinterpret_cast<int>(argv)); // $ ast,ir sink(reinterpret_cast<int>(argv)); // $ ast,ir-sink
calls_sink_with_argv(argv[1]); // $ ast,ir calls_sink_with_argv(argv[1]); // $ ast,ir-path
char*** p = &argv; // $ ast,ir char*** p = &argv; // $ ast,ir-path
sink(*p[0]); // $ ast,ir sink(*p[0]); // $ ast,ir-sink
calls_sink_with_argv(*p[i]); // $ MISSING: ast,ir calls_sink_with_argv(*p[i]); // $ MISSING: ast,ir-path
sink(*(argv + 1)); // $ ast,ir sink(*(argv + 1)); // $ ast,ir-path ir-sink
BaseWithPureVirtual* b = new DerivedCallsSink; BaseWithPureVirtual* b = new DerivedCallsSink;
b->f(argv[1]); // $ ast,ir b->f(argv[1]); // $ ast,ir-path
b = new DerivedDoesNotCallSink; b = new DerivedDoesNotCallSink;
b->f(argv[0]); // $ SPURIOUS: ast b->f(argv[0]); // $ SPURIOUS: ast
BaseWithPureVirtual* b2 = new DerivesMultiple; BaseWithPureVirtual* b2 = new DerivesMultiple;
b2->f(argv[i]); // $ ast,ir b2->f(argv[i]); // $ ast,ir-path
CRTP<CRTPDoesNotCallSink> crtp_not_call_sink; CRTP<CRTPDoesNotCallSink> crtp_not_call_sink;
crtp_not_call_sink.f(argv[0]); // clean crtp_not_call_sink.f(argv[0]); // clean
CRTP<CRTPCallsSink> crtp_calls_sink; CRTP<CRTPCallsSink> crtp_calls_sink;
crtp_calls_sink.f(argv[0]); // $ ast,ir crtp_calls_sink.f(argv[0]); // $ ast,ir-path
Derived1* calls_sink = new Derived3; Derived1* calls_sink = new Derived3;
calls_sink->f(argv[1]); // $ ast,ir calls_sink->f(argv[1]); // $ ast,ir-path
static_cast<Derived2*>(calls_sink)->f(argv[1]); // $ ast,ir static_cast<Derived2*>(calls_sink)->f(argv[1]); // $ ast,ir-path
dynamic_cast<Derived2*>(calls_sink)->f(argv[1]); // $ ast,ir dynamic_cast<Derived2*>(calls_sink)->f(argv[1]); // $ ast,ir-path
} }

View File

@@ -210,8 +210,8 @@ void test_pointers2()
sink(buffer); // $ MISSING: ast,ir sink(buffer); // $ MISSING: ast,ir
sink(ptr1); // $ ast MISSING: ir sink(ptr1); // $ ast MISSING: ir
sink(ptr2); // $ SPURIOUS: ast sink(ptr2); // $ SPURIOUS: ast,ir
sink(*ptr2); // $ ast MISSING: ir sink(*ptr2); // $ ast,ir
sink(ptr3); // $ MISSING: ast,ir sink(ptr3); // $ MISSING: ast,ir
sink(ptr4); // clean sink(ptr4); // clean
sink(*ptr4); // $ MISSING: ast,ir sink(*ptr4); // $ MISSING: ast,ir
@@ -254,8 +254,8 @@ int test_readv_and_writev(iovec* iovs) {
sink(*iovs); // $ast,ir sink(*iovs); // $ast,ir
char* p = (char*)iovs[1].iov_base; char* p = (char*)iovs[1].iov_base;
sink(p); // $ ir MISSING: ast sink(p); // $ MISSING: ast,ir
sink(*p); // $ ir MISSING: ast sink(*p); // $ MISSING: ast,ir
writev(0, iovs, 16); // $ remote writev(0, iovs, 16); // $ remote
} }

View File

@@ -89,12 +89,12 @@ void test_stringstream()
sink(ss1); sink(ss1);
sink(ss2); // $ ir MISSING: ast sink(ss2); // $ ir MISSING: ast
sink(ss3); // $ MISSING: ast,ir sink(ss3); // $ ir MISSING: ast
sink(ss4); // $ ir MISSING: ast sink(ss4); // $ ir MISSING: ast
sink(ss5); // $ ir MISSING: ast sink(ss5); // $ ir MISSING: ast
sink(ss1.str()); sink(ss1.str());
sink(ss2.str()); // $ ir MISSING: ast 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(ss4.str()); // $ ir MISSING: ast
sink(ss5.str()); // $ ir MISSING: ast sink(ss5.str()); // $ ir MISSING: ast
} }

View File

@@ -26,62 +26,592 @@ unreachableNodeCCtx
localCallNodes localCallNodes
postIsNotPre postIsNotPre
postHasUniquePre postHasUniquePre
| test.cpp:373:5:373:20 | Store | PostUpdateNode should have one pre-update node but has 0. |
uniquePostUpdate uniquePostUpdate
postIsInSameCallable postIsInSameCallable
reverseRead reverseRead
argHasPostUpdate argHasPostUpdate
postWithInFlow postWithInFlow
| BarrierGuard.cpp:49:3:49:17 | 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:18 | Chi | 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. |
| clang.cpp:28:3:28:34 | Chi | 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:34:22:34:27 | Chi | 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:34:32:34:37 | Chi | 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:39:32:39:37 | Chi | 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:39:42:39:47 | Chi | 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:43:35:43:40 | Chi | 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:43:51:43:51 | Chi | 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:49:25:49:30 | Chi | 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:49:35:49:40 | Chi | 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:50:3:50:26 | Chi | 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. |
| example.c:17:19:17:22 | Chi | 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. |
| example.c:17:21:17:21 | Chi | 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. |
| example.c:24:2:24:30 | Chi | 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. |
| example.c:24:13:24:30 | Chi | 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. |
| example.c:26:2:26:25 | Chi | 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. |
| file://:0:0:0:0 | Chi | 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. |
| file://:0:0:0:0 | Chi | 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. |
| file://:0:0:0:0 | Chi | 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. |
| lambdas.cpp:13:12:13:12 | Chi | 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. |
| lambdas.cpp:13:15:13:15 | Chi | 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. |
| lambdas.cpp:28:10:31:2 | Chi | 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. |
| lambdas.cpp:28:10:31:2 | Chi | 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. |
| lambdas.cpp:43:3:43:14 | Chi | 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. |
| ref.cpp:11:5:11:13 | Chi | 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. |
| ref.cpp:20:5:20:13 | Chi | 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. |
| ref.cpp:22:7:22:13 | Chi | 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. |
| ref.cpp:24:7:24:13 | Chi | 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. |
| ref.cpp:29:5:29:18 | Chi | 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. |
| ref.cpp:31:7:31:13 | Chi | 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. |
| ref.cpp:39:7:39:13 | Chi | 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. |
| ref.cpp:44:5:44:18 | Chi | 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. |
| ref.cpp:46:7:46:13 | Chi | 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. |
| ref.cpp:48:7:48:13 | Chi | 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. |
| ref.cpp:75:5:75:17 | Chi | 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. |
| ref.cpp:83:5:83:17 | Chi | 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. |
| ref.cpp:87:7:87:17 | Chi | 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. |
| ref.cpp:89:7:89:17 | Chi | 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. |
| ref.cpp:94:5:94:22 | Chi | 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. |
| ref.cpp:96:7:96:17 | Chi | 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. |
| ref.cpp:104:7:104:17 | Chi | 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. |
| ref.cpp:109:5:109:22 | Chi | 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. |
| ref.cpp:113:7:113:17 | Chi | 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. |
| ref.cpp:115:7:115:17 | Chi | 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. |
| test.cpp:91:3:91:18 | Chi | 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. |
| test.cpp:115:3:115:17 | Chi | 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. |
| test.cpp:120:3:120:10 | Chi | 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. |
| test.cpp:125:3:125:11 | Chi | 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. |
| test.cpp:359:5:359:20 | Chi | 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. |
| test.cpp:373:5:373:20 | Chi | 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. |
| test.cpp:373:5:373:20 | Store | 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. |
| test.cpp:465:3:465:15 | Chi | 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. |

View File

@@ -18,7 +18,7 @@ void test_lambdas()
sink(a()); // $ ast,ir sink(a()); // $ ast,ir
auto b = [&] { auto b = [&] {
sink(t); // $ ast MISSING: ir sink(t); // $ ast,ir
sink(u); sink(u);
v = source(); // (v is reference captured) v = source(); // (v is reference captured)
}; };

View File

@@ -100,14 +100,14 @@ void local_references(int &source1, int clean1) {
int t = source(); int t = source();
int &ref = t; int &ref = t;
t = clean1; t = clean1;
sink(ref); // $ SPURIOUS: ast sink(ref); // $ SPURIOUS: ast,ir
} }
{ {
int t = clean1; int t = clean1;
int &ref = t; int &ref = t;
t = source(); t = source();
sink(ref); // $ ir MISSING: ast sink(ref); // $ MISSING: ast,ir
} }
} }
@@ -346,7 +346,7 @@ namespace FlowThroughGlobals {
int taintAndCall() { int taintAndCall() {
globalVar = source(); globalVar = source();
calledAfterTaint(); calledAfterTaint();
sink(globalVar); // $ ast MISSING: ir sink(globalVar); // $ ast,ir
} }
} }
@@ -355,21 +355,21 @@ namespace FlowThroughGlobals {
class FlowThroughFields { class FlowThroughFields {
int field = 0; int field = 0;
int taintField() { void taintField() {
field = source(); field = source();
} }
int f() { void f() {
sink(field); // tainted or clean? Not sure. sink(field); // tainted or clean? Not sure.
taintField(); taintField();
sink(field); // $ ast MISSING: ir
}
int calledAfterTaint() {
sink(field); // $ ast,ir sink(field); // $ ast,ir
} }
int taintAndCall() { void calledAfterTaint() {
sink(field); // $ ast,ir
}
void taintAndCall() {
field = source(); field = source();
calledAfterTaint(); calledAfterTaint();
sink(field); // $ ast,ir sink(field); // $ ast,ir

View File

@@ -46,7 +46,7 @@ public:
{ {
C *c = new C(); C *c = new C();
B *b = B::make(c); B *b = B::make(c);
sink(b->c); // $ast MISSING: ir sink(b->c); // $ast,ir
} }
void f2() void f2()
@@ -54,7 +54,7 @@ public:
B *b = new B(); B *b = new B();
b->set(new C1()); b->set(new C1());
sink(b->get()); // $ ast ir=55:12 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() void f3()
@@ -63,7 +63,7 @@ public:
B *b2; B *b2;
b2 = setOnB(b1, new C2()); b2 = setOnB(b1, new C2());
sink(b1->c); // no flow sink(b1->c); // no flow
sink(b2->c); // $ ast MISSING: ir sink(b2->c); // $ ast ir=64:21
} }
void f4() void f4()
@@ -72,7 +72,7 @@ public:
B *b2; B *b2;
b2 = setOnBWrap(b1, new C2()); b2 = setOnBWrap(b1, new C2());
sink(b1->c); // no flow sink(b1->c); // no flow
sink(b2->c); // $ ast MISSING: ir sink(b2->c); // $ ast ir=73:25
} }
B *setOnBWrap(B *b1, C *c) B *setOnBWrap(B *b1, C *c)
@@ -117,7 +117,7 @@ public:
} }
if (C1 *c1 = dynamic_cast<C1 *>(cc)) 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(); B *b = new B();
D *d = new D(b, r()); D *d = new D(b, r());
sink(d->b); // $ ast,ir=143:25 ast,ir=150:12 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 sink(b->c); // $ ast,ir
} }
@@ -162,11 +162,11 @@ public:
MyList *l3 = new MyList(nullptr, l2); MyList *l3 = new MyList(nullptr, l2);
sink(l3->head); // no flow, b is nested beneath at least one ->next sink(l3->head); // no flow, b is nested beneath at least one ->next
sink(l3->next->head); // no flow 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 sink(l3->next->next->next->head); // no flow
for (MyList *l = l3; l != nullptr; l = l->next) for (MyList *l = l3; l != nullptr; l = l->next)
{ {
sink(l->head); // $ ast MISSING: ir sink(l->head); // $ ast,ir
} }
} }

View File

@@ -6,7 +6,7 @@ class B
Elem *e = new Elem(); Elem *e = new Elem();
Box1 *b1 = new Box1(e, nullptr); Box1 *b1 = new Box1(e, nullptr);
Box2 *b2 = new Box2(b1); Box2 *b2 = new Box2(b1);
sink(b2->box1->elem1); // $ ast MISSING: ir sink(b2->box1->elem1); // $ ast,ir
sink(b2->box1->elem2); // no flow sink(b2->box1->elem2); // no flow
} }
@@ -16,7 +16,7 @@ class B
Box1 *b1 = new B::Box1(nullptr, e); Box1 *b1 = new B::Box1(nullptr, e);
Box2 *b2 = new Box2(b1); Box2 *b2 = new Box2(b1);
sink(b2->box1->elem1); // no flow sink(b2->box1->elem1); // no flow
sink(b2->box1->elem2); // $ ast MISSING: ir sink(b2->box1->elem2); // $ ast,ir
} }
static void sink(void *o) {} static void sink(void *o) {}

View File

@@ -1,10 +1,10 @@
void sink(...);
class C class C
{ {
class Elem class Elem
{ {
}; };
private: private:
Elem *s1 = new Elem(); Elem *s1 = new Elem();
const Elem *s2 = new Elem(); const Elem *s2 = new Elem();
@@ -26,12 +26,10 @@ public:
void func() void func()
{ {
sink(s1); // $ast ir sink(s1); // $ast,ir
sink(s2); // $ MISSING: ast,ir sink(s2); // $ MISSING: ast,ir
sink(s3); // $ast ir sink(s3); // $ast MISSING: ir
sink(s4); // $ MISSING: ast,ir sink(s4); // $ MISSING: ast,ir
} }
static void sink(const void *o) {}
}; };
const C::Elem *C::s4 = new Elem(); const C::Elem *C::s4 = new Elem();

View File

@@ -19,7 +19,7 @@ public:
}; };
static void sinkWrap(Box2* b2) { 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; Box2* boxfield;
@@ -61,6 +61,6 @@ public:
private: private:
void f5b() { void f5b() {
sink(boxfield->box->elem); // $ ast MISSING: ir sink(boxfield->box->elem); // $ ast,ir
} }
}; };

View File

@@ -18,7 +18,7 @@ void sink(char *b);
void handlePacket(packet *p) void handlePacket(packet *p)
{ {
sink(p->data.buffer); // $ ast MISSING: ir sink(p->data.buffer); // $ ast,ir
} }
void f(buf* b) void f(buf* b)
@@ -28,7 +28,7 @@ void f(buf* b)
argument_source(raw); argument_source(raw);
argument_source(b->buffer); argument_source(b->buffer);
argument_source(p.data.buffer); argument_source(p.data.buffer);
sink(raw); // $ ast MISSING: ir sink(raw); // $ ast,ir
sink(b->buffer); // $ ast MISSING: ir sink(b->buffer); // $ ast,ir
handlePacket(&p); handlePacket(&p);
} }

View File

@@ -18,7 +18,7 @@ class IRConf extends Configuration {
override predicate isSink(Node sink) { override predicate isSink(Node sink) {
exists(Call c | exists(Call c |
c.getTarget().hasName("sink") and c.getTarget().hasName("sink") and
c.getAnArgument() = sink.asConvertedExpr() c.getAnArgument() = [sink.asExpr(), sink.asConvertedExpr()]
) )
} }

View File

@@ -35,12 +35,12 @@ void assignAfterAlias() {
S s1 = { 0, 0 }; S s1 = { 0, 0 };
S &ref1 = s1; S &ref1 = s1;
ref1.m1 = user_input(); ref1.m1 = user_input();
sink(s1.m1); // $ ir MISSING: ast sink(s1.m1); // $ MISSING: ast,ir
S s2 = { 0, 0 }; S s2 = { 0, 0 };
S &ref2 = s2; S &ref2 = s2;
s2.m1 = user_input(); s2.m1 = user_input();
sink(ref2.m1); // $ ir MISSING: ast sink(ref2.m1); // $ MISSING: ast,ir
} }
void assignAfterCopy() { void assignAfterCopy() {
@@ -77,14 +77,14 @@ void pointerIntermediate() {
Wrapper w = { { 0, 0 } }; Wrapper w = { { 0, 0 } };
S *s = &w.s; S *s = &w.s;
s->m1 = user_input(); s->m1 = user_input();
sink(w.s.m1); // $ ir MISSING: ast sink(w.s.m1); // $ MISSING: ast,ir
} }
void referenceIntermediate() { void referenceIntermediate() {
Wrapper w = { { 0, 0 } }; Wrapper w = { { 0, 0 } };
S &s = w.s; S &s = w.s;
s.m1 = user_input(); s.m1 = user_input();
sink(w.s.m1); // $ ir MISSING: ast sink(w.s.m1); // $ MISSING: ast,ir
} }
void nestedAssign() { void nestedAssign() {
@@ -99,7 +99,7 @@ void addressOfField() {
S s_copy = s; S s_copy = s;
int* px = &s_copy.m1; int* px = &s_copy.m1;
sink(*px); // $ ir MISSING: ast sink(*px); // $ MISSING: ast,ir
} }
void taint_a_ptr(int* pa) { void taint_a_ptr(int* pa) {
@@ -119,7 +119,7 @@ struct S_with_pointer {
void pointer_deref(int* xs) { void pointer_deref(int* xs) {
taint_a_ptr(xs); taint_a_ptr(xs);
sink(xs[0]); // $ ir MISSING: ast sink(xs[0]); // $ MISSING: ast,ir
} }
void pointer_deref_sub(int* xs) { void pointer_deref_sub(int* xs) {
@@ -129,18 +129,18 @@ void pointer_deref_sub(int* xs) {
void pointer_many_addrof_and_deref(int* xs) { void pointer_many_addrof_and_deref(int* xs) {
taint_a_ptr(xs); taint_a_ptr(xs);
sink(*&*&*xs); // $ ir MISSING: ast sink(*&*&*xs); // $ MISSING: ast,ir
} }
void pointer_unary_plus(int* xs) { void pointer_unary_plus(int* xs) {
taint_a_ptr(+xs); taint_a_ptr(+xs);
sink(*+xs); // $ ir MISSING: ast sink(*+xs); // $ MISSING: ast,ir
} }
void pointer_member_index(S_with_pointer s) { void pointer_member_index(S_with_pointer s) {
taint_a_ptr(s.data); taint_a_ptr(s.data);
// `s.data` is points to all-aliased-memory // `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) { void member_array_different_field(S_with_pointer* s) {
@@ -156,13 +156,13 @@ struct S_with_array {
void pointer_member_deref() { void pointer_member_deref() {
S_with_array s; S_with_array s;
taint_a_ptr(s.data); taint_a_ptr(s.data);
sink(*s.data); // $ ast MISSING: ir sink(*s.data); // $ ast,ir
} }
void array_member_deref() { void array_member_deref() {
S_with_array s; S_with_array s;
taint_a_ptr(s.data); taint_a_ptr(s.data);
sink(s.data[0]); // $ ast MISSING: ir sink(s.data[0]); // $ ast,ir
} }
struct S2 { struct S2 {

View File

@@ -5,7 +5,7 @@ void local_array() {
void *arr[10] = { 0 }; void *arr[10] = { 0 };
arr[0] = user_input(); arr[0] = user_input();
sink(arr[0]); // $ ast,ir sink(arr[0]); // $ ast,ir
sink(arr[1]); // $ SPURIOUS: ast sink(arr[1]); // $ SPURIOUS: ast,ir
sink(*arr); // $ ast,ir sink(*arr); // $ ast,ir
sink(*&arr[0]); // $ ast,ir sink(*&arr[0]); // $ ast,ir
} }
@@ -14,7 +14,7 @@ void local_array_convoluted_assign() {
void *arr[10] = { 0 }; void *arr[10] = { 0 };
*&arr[0] = user_input(); *&arr[0] = user_input();
sink(arr[0]); // $ ast,ir sink(arr[0]); // $ ast,ir
sink(arr[1]); // $ SPURIOUS: ast sink(arr[1]); // $ SPURIOUS: ast,ir
} }
struct inner { struct inner {
@@ -35,17 +35,17 @@ struct outer {
void nested_array_1(outer o) { void nested_array_1(outer o) {
o.nested.arr[1].data = user_input(); o.nested.arr[1].data = user_input();
sink(o.nested.arr[1].data); // $ ast,ir 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) { void nested_array_2(outer o) {
o.indirect->arr[1].data = user_input(); o.indirect->arr[1].data = user_input();
sink(o.indirect->arr[1].data); // $ ast MISSING: ir sink(o.indirect->arr[1].data); // $ ast,ir
sink(o.indirect->arr[0].data); // $ SPURIOUS: ast sink(o.indirect->arr[0].data); // $ SPURIOUS: ast,ir
} }
void nested_array_3(outer o) { void nested_array_3(outer o) {
o.indirect->ptr[1].data = user_input(); o.indirect->ptr[1].data = user_input();
sink(o.indirect->ptr[1].data); // $ MISSING: ir,ast sink(o.indirect->ptr[1].data); // $ ir MISSING: ast
sink(o.indirect->ptr[0].data); sink(o.indirect->ptr[0].data); // $ SPURIOUS: ir
} }

View File

@@ -108,11 +108,11 @@ void test_outer_with_ptr(Outer *pouter) {
taint_a_ptr(&pouter->a); taint_a_ptr(&pouter->a);
sink(outer.inner_nested.a); // $ ast,ir 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(outer.a); // $ ast,ir
sink(pouter->inner_nested.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 sink(pouter->a); // $ ast,ir
} }
@@ -128,10 +128,10 @@ void test_outer_with_ref(Outer *pouter) {
taint_a_ref(pouter->a); taint_a_ref(pouter->a);
sink(outer.inner_nested.a); // $ ast,ir 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(outer.a); // $ ast,ir
sink(pouter->inner_nested.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 sink(pouter->a); // $ ast,ir
} }

View File

@@ -8,7 +8,7 @@ struct A {
void pointer_without_allocation(const A& ra) { void pointer_without_allocation(const A& ra) {
*ra.p = user_input(); *ra.p = user_input();
sink(*ra.p); // $ MISSING: ast,ir sink(*ra.p); // $ ir MISSING: ast
} }
void argument_source(void*); void argument_source(void*);
@@ -17,7 +17,7 @@ void sink(void*);
void pointer_without_allocation_2() { void pointer_without_allocation_2() {
char *raw; char *raw;
argument_source(raw); argument_source(raw);
sink(raw); // $ ast MISSING: ir sink(raw); // $ ast,ir
} }
A* makeA() { A* makeA() {
@@ -27,14 +27,14 @@ A* makeA() {
void no_InitializeDynamicAllocation_instruction() { void no_InitializeDynamicAllocation_instruction() {
A* pa = makeA(); A* pa = makeA();
pa->x = user_input(); pa->x = user_input();
sink(pa->x); // $ ast MISSING: ir sink(pa->x); // $ ast,ir
} }
void fresh_or_arg(A* arg, bool unknown) { void fresh_or_arg(A* arg, bool unknown) {
A* pa; A* pa;
pa = unknown ? arg : new A; pa = unknown ? arg : new A;
pa->x = user_input(); pa->x = user_input();
sink(pa->x); // $ ast MISSING: ir sink(pa->x); // $ ast,ir
} }
struct LinkedList { struct LinkedList {
@@ -52,11 +52,11 @@ void too_many_indirections() {
LinkedList* ll = new LinkedList; LinkedList* ll = new LinkedList;
ll->next = new LinkedList; ll->next = new LinkedList;
ll->next->y = user_input(); 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) { void too_many_indirections_2(LinkedList* next) {
LinkedList* ll = new LinkedList(next); LinkedList* ll = new LinkedList(next);
ll->next->y = user_input(); ll->next->y = user_input();
sink(ll->next->y); // $ ast MISSING: ir sink(ll->next->y); // $ ast,ir
} }

View File

@@ -3,8 +3,8 @@ uniqueEnclosingCallable
| C.cpp:9:14:9:23 | new | Node should have one enclosing callable but has 0. | | 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 | 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: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:35:24:35: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 | new | Node should have one enclosing callable but has 0. |
uniqueType uniqueType
uniqueNodeLocation uniqueNodeLocation
missingLocation missingLocation

File diff suppressed because it is too large Load Diff

View File

@@ -1,152 +1,93 @@
| A.cpp:25:13:25:13 | c | AST only | | A.cpp:25:13:25:13 | c | AST only |
| A.cpp:27:28:27:28 | c | AST only | | A.cpp:27:28:27:28 | c | AST only |
| A.cpp:31:20:31:20 | c | AST only | | A.cpp:31:14:31:21 | new | IR only |
| A.cpp:40:5:40:6 | cc | AST only | | A.cpp:40:8:40:13 | 0 | IR only |
| A.cpp:41:5:41:6 | ct | AST only | | A.cpp:41:8:41:13 | new | IR only |
| A.cpp:42:10:42:12 | & ... | AST only | | A.cpp:41:15:41:21 | new | IR only |
| A.cpp:43:10:43:12 | & ... | AST only | | A.cpp:47:12:47:18 | new | IR only |
| A.cpp:48:20:48:20 | c | AST only | | A.cpp:54:12:54:18 | new | IR only |
| A.cpp:49:10:49:10 | b | AST only | | A.cpp:55:8:55:10 | new | IR only |
| A.cpp:49:13:49:13 | c | AST only | | A.cpp:55:12:55:19 | new | IR only |
| A.cpp:55:5:55:5 | b | AST only | | A.cpp:57:11:57:24 | new | IR only |
| A.cpp:56:10:56:10 | b | AST only | | A.cpp:57:11:57:24 | new | IR only |
| A.cpp:56:13:56:15 | call to get | AST only | | A.cpp:57:17:57:23 | new | IR only |
| A.cpp:57:28:57:30 | call to get | AST only | | A.cpp:57:28:57:30 | new | IR only |
| A.cpp:64:10:64:15 | this | AST only | | A.cpp:62:13:62:19 | new | IR only |
| A.cpp:64:17:64:18 | b1 | AST only | | A.cpp:64:10:64:15 | new | IR only |
| A.cpp:65:10:65:11 | b1 | AST only | | A.cpp:64:21:64:28 | new | IR only |
| A.cpp:65:14:65:14 | c | AST only | | A.cpp:71:13:71:19 | new | IR only |
| A.cpp:66:10:66:11 | b2 | AST only | | A.cpp:73:10:73:19 | new | IR only |
| A.cpp:66:14:66:14 | c | AST only | | A.cpp:73:25:73:32 | new | IR only |
| A.cpp:73:10:73:19 | this | AST only | | A.cpp:89:15:89:21 | new | IR only |
| A.cpp:73:21:73:22 | b1 | AST only | | A.cpp:99:14:99:21 | new | IR 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:100:9:100:9 | a | AST only | | A.cpp:100:9:100:9 | a | AST only |
| A.cpp:101:5:101:6 | this | AST only | | A.cpp:116:12:116:19 | new | IR only |
| A.cpp:101:8:101:9 | c1 | AST only | | A.cpp:126:8:126:10 | new | IR only |
| A.cpp:107:12:107:13 | c1 | AST only | | A.cpp:126:12:126:18 | new | IR only |
| A.cpp:107:16:107:16 | a | AST only | | A.cpp:130:12:130:18 | new | IR 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:142:10:142:10 | c | AST 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:143:13:143:13 | b | AST only |
| A.cpp:151:18:151:18 | b | AST only | | A.cpp:143:25:143:31 | new | IR only |
| A.cpp:151:21:151:21 | this | AST only | | A.cpp:150:12:150:18 | new | IR only |
| A.cpp:152:10:152:10 | d | AST only | | A.cpp:151:12:151:24 | new | IR only |
| A.cpp:152:13:152:13 | b | AST only | | A.cpp:159:12:159:18 | new | IR only |
| A.cpp:153:10:153:10 | d | AST only | | A.cpp:160:18:160:60 | new | IR only |
| A.cpp:153:13:153:13 | b | AST only | | A.cpp:160:18:160:60 | new | IR only |
| A.cpp:153:16:153:16 | c | AST only | | A.cpp:160:32:160:59 | 0 | IR only |
| A.cpp:154:10:154:10 | b | AST only | | A.cpp:160:32:160:59 | 0 | IR only |
| A.cpp:154:13:154:13 | c | AST only | | A.cpp:160:32:160:59 | new | IR only |
| A.cpp:160:29:160:29 | b | AST only | | A.cpp:161:18:161:40 | 0 | IR only |
| A.cpp:161:38:161:39 | l1 | AST only | | A.cpp:161:18:161:40 | new | IR only |
| A.cpp:162:38:162:39 | l2 | AST only | | A.cpp:162:18:162:40 | 0 | IR only |
| A.cpp:163:10:163:11 | l3 | AST only | | A.cpp:162:18:162:40 | new | IR 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:183:7:183:10 | head | AST only | | A.cpp:183:7:183:10 | head | AST only |
| A.cpp:184:13:184:16 | next | AST only | | A.cpp:184:13:184:16 | next | AST only |
| B.cpp:7:25:7:25 | e | AST only | | B.cpp:7:16:7:35 | 0 | IR only |
| B.cpp:8:25:8:26 | b1 | AST only | | B.cpp:7:16:7:35 | new | IR only |
| B.cpp:9:10:9:11 | b2 | AST only | | B.cpp:8:16:8:27 | new | IR only |
| B.cpp:9:14:9:17 | box1 | AST only | | B.cpp:16:16:16:38 | 0 | IR only |
| B.cpp:9:20:9:24 | elem1 | AST only | | B.cpp:16:16:16:38 | new | IR only |
| B.cpp:10:10:10:11 | b2 | AST only | | B.cpp:17:16:17:27 | new | IR 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:35:13:35:17 | elem1 | AST only | | B.cpp:35:13:35:17 | elem1 | AST only |
| B.cpp:36:13:36:17 | elem2 | AST only | | B.cpp:36:13:36:17 | elem2 | AST only |
| B.cpp:46:13:46:16 | box1 | 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: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:9:21:9:24 | elem | AST only |
| D.cpp:11:29:11:32 | elem | AST only | | D.cpp:11:29:11:32 | elem | AST only |
| D.cpp:16:21:16:23 | box | AST only | | D.cpp:16:21:16:23 | box | AST only |
| D.cpp:18:29:18:31 | box | AST only | | D.cpp:18:29:18:31 | box | AST only |
| D.cpp:22:10:22:11 | b2 | AST only | | D.cpp:29:15:29:41 | new | IR only |
| D.cpp:22:14:22:20 | call to getBox1 | AST only | | D.cpp:29:15:29:41 | new | IR only |
| D.cpp:22:25:22:31 | call to getElem | AST only | | D.cpp:29:24:29:40 | 0 | IR only |
| D.cpp:30:5:30:5 | b | AST only | | D.cpp:29:24:29:40 | new | IR only |
| D.cpp:30:8:30:10 | box | AST only |
| D.cpp:30:13:30:16 | elem | AST only | | D.cpp:30:13:30:16 | elem | AST only |
| D.cpp:31:14:31:14 | b | AST only | | D.cpp:36:15:36:41 | new | IR only |
| D.cpp:37:5:37:5 | b | AST only | | D.cpp:36:15:36:41 | new | IR only |
| D.cpp:37:8:37:10 | box | AST only | | D.cpp:36:24:36:40 | 0 | IR only |
| D.cpp:37:21:37:21 | e | AST only | | D.cpp:36:24:36:40 | new | IR only |
| D.cpp:38:14:38:14 | b | AST only | | D.cpp:43:15:43:41 | new | IR only |
| D.cpp:44:5:44:5 | b | AST only | | D.cpp:43:15:43:41 | new | IR only |
| D.cpp:44:8:44:14 | call to getBox1 | AST 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:44:19:44:22 | elem | AST only |
| D.cpp:45:14:45:14 | b | AST only | | D.cpp:50:15:50:41 | new | IR only |
| D.cpp:51:5:51:5 | b | AST only | | D.cpp:50:15:50:41 | new | IR only |
| D.cpp:51:8:51:14 | call to getBox1 | AST only | | D.cpp:50:24:50:40 | 0 | IR only |
| D.cpp:51:27:51:27 | e | AST only | | D.cpp:50:24:50:40 | new | IR only |
| D.cpp:52:14:52:14 | b | AST only |
| D.cpp:57:5:57:12 | boxfield | AST only | | D.cpp:57:5:57:12 | boxfield | AST only |
| D.cpp:58:5:58:12 | boxfield | AST only | | D.cpp:57:16:57:42 | new | IR only |
| D.cpp:58:5:58:12 | this | AST only | | D.cpp:57:16:57:42 | new | IR only |
| D.cpp:58:15:58:17 | box | AST 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: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:9:6:9:7 | m1 | AST only |
| aliasing.cpp:13:5:13:6 | m1 | AST only | | aliasing.cpp:13:5:13:6 | m1 | AST only |
| aliasing.cpp:17:5:17: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:37:8:37:9 | m1 | AST only |
| aliasing.cpp:42:6:42:7 | m1 | AST only | | aliasing.cpp:42:6:42:7 | m1 | AST only |
| aliasing.cpp:49:9:49:10 | 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:72:5:72:6 | m1 | AST only |
| aliasing.cpp:79:6:79:7 | m1 | AST only | | aliasing.cpp:79:6:79:7 | m1 | AST only |
| aliasing.cpp:86:5:86:6 | 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:92:7:92:8 | m1 | AST only |
| aliasing.cpp:98:5:98:6 | m1 | AST only | | aliasing.cpp:98:5:98:6 | m1 | AST only |
| aliasing.cpp:106:3:106:5 | * ... | 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: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:15:3:15:10 | * ... | AST only |
| arrays.cpp:36:3:36:3 | o | AST only | | arrays.cpp:16:3:16:6 | access to array | IR only |
| arrays.cpp:36:5:36:10 | nested | AST only | | arrays.cpp:17:3:17:6 | access to array | IR only |
| arrays.cpp:36:19:36:22 | data | AST 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: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: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:12:8:12:8 | a | AST only |
| by_reference.cpp:16:11:16:11 | 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: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: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: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: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:84:10:84:10 | a | AST only |
| by_reference.cpp:88:9:88:9 | 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:92:3:92:5 | * ... | AST only |
| by_reference.cpp:96:3:96:4 | pa | 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:11:22:11:23 | a_ | AST only |
| complex.cpp:12:22:12:23 | b_ | AST only | | complex.cpp:12:22:12:23 | b_ | AST only |
| complex.cpp: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: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: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:36:7:36:7 | x | AST only |
| conflated.cpp:53:7:53:10 | next | 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:54:13:54:13 | y | AST only |
| conflated.cpp:59:35:59:38 | next | AST only | | conflated.cpp:59:20:59:39 | new | IR only |
| conflated.cpp:60:3:60:4 | ll | AST only |
| conflated.cpp:60:7:60:10 | next | AST only |
| conflated.cpp:60:13:60:13 | y | AST only | | conflated.cpp:60:13:60:13 | y | AST only |
| constructors.cpp:20:24:20:25 | a_ | AST only | | constructors.cpp:20:24:20:25 | a_ | AST only |
| constructors.cpp:21:24:21:25 | b_ | AST only | | constructors.cpp:21:24:21:25 | b_ | AST only |
| constructors.cpp:28:10:28:10 | f | AST only |
| constructors.cpp: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:9:36:9:36 | a | AST only |
| qualifiers.cpp:12:56:12:56 | a | AST only | | qualifiers.cpp:12:56:12:56 | a | AST only |
| qualifiers.cpp:13:57:13:57 | 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: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: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: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: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: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: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:20:24:20:25 | a_ | AST only |
| simple.cpp:21:24:21:25 | b_ | 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: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: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 | | 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 |

View File

@@ -1,22 +1,208 @@
| A.cpp:25:7:25:10 | this | | A.cpp:25:7:25:10 | this |
| A.cpp:27:22:27:25 | 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: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:7:142:7 | b |
| A.cpp:142:14:142:20 | new |
| A.cpp:143:7:143:10 | this | | 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:183:7:183:10 | this |
| A.cpp:184:7:184: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:35:7:35:10 | this |
| B.cpp:36:7:36:10 | this | | B.cpp:36:7:36:10 | this |
| B.cpp:46:7:46: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: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:9:21:9:24 | this |
| D.cpp:11:29:11:32 | this | | D.cpp:11:29:11:32 | this |
| D.cpp:16:21:16:23 | this | | D.cpp:16:21:16:23 | this |
| D.cpp:18:29:18:31 | 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: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:9:3:9:3 | s |
| aliasing.cpp:13:3:13:3 | s | | aliasing.cpp:13:3:13:3 | s |
| aliasing.cpp:17:3:17: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:37:3:37:6 | ref1 |
| aliasing.cpp:42:3:42:4 | s2 | | aliasing.cpp:42:3:42:4 | s2 |
| aliasing.cpp:49:3:49:7 | copy1 | | aliasing.cpp:49:3:49:7 | copy1 |
@@ -25,48 +211,299 @@
| aliasing.cpp:72:3:72:3 | s | | aliasing.cpp:72:3:72:3 | s |
| aliasing.cpp:79:3:79:3 | s | | aliasing.cpp:79:3:79:3 | s |
| aliasing.cpp:86:3:86: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:92:5:92:5 | s |
| aliasing.cpp:98:3:98:3 | s | | aliasing.cpp:98:3:98:3 | s |
| aliasing.cpp:111:15:111:19 | & ... |
| aliasing.cpp:111:16:111:16 | s | | 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: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: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: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: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: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: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 | | 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: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:12:5:12:5 | s |
| by_reference.cpp:16:5:16:8 | this | | 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:84:3:84:7 | inner |
| by_reference.cpp:88:3:88: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: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:104:16:104:20 | outer |
| by_reference.cpp:106:21:106:41 | & ... |
| by_reference.cpp:106:22:106:27 | pouter | | 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: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: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:15:124:19 | outer |
| by_reference.cpp:124:21:124:21 | a |
| by_reference.cpp:126:21:126:26 | pouter | | 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: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:11:22:11:23 | this |
| complex.cpp:12:22:12: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: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: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: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: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: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: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: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:20:24:20:25 | this |
| constructors.cpp:21:24:21: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:9:30:9:33 | this |
| qualifiers.cpp:12:49:12:53 | inner | | qualifiers.cpp:12:49:12:53 | inner |
| qualifiers.cpp:13:51:13:55 | 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: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:20:24:20:25 | this |
| simple.cpp:21:24:21: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:65:5:65:5 | a |
| simple.cpp:83:9:83:10 | f2 | | 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 | | 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:36:11:36:15 | outer |
| struct_init.c:46:10:46:14 | outer |
| struct_init.c:46:16:46:24 | pointerAB |

View File

@@ -107,6 +107,10 @@
| C.cpp:19:5:19:5 | c | | C.cpp:19:5:19:5 | c |
| C.cpp:24:5:24:8 | this | | C.cpp:24:5:24:8 | this |
| C.cpp:24:11:24:12 | s3 | | 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 | elem |
| D.cpp:9:21:9:24 | this | | D.cpp:9:21:9:24 | this |
| D.cpp:11:29:11:32 | elem | | D.cpp:11:29:11:32 | elem |

View File

@@ -20,31 +20,31 @@ namespace qualifiers {
void assignToGetter(Outer outer) { void assignToGetter(Outer outer) {
outer.getInner()->a = user_input(); outer.getInner()->a = user_input();
sink(outer.inner->a); // $ ast MISSING: ir sink(outer.inner->a); // $ ast,ir
} }
void getterArgument1(Outer outer) { void getterArgument1(Outer outer) {
outer.getInner()->setA(user_input()); outer.getInner()->setA(user_input());
sink(outer.inner->a); // $ ast MISSING: ir sink(outer.inner->a); // $ ast,ir
} }
void getterArgument2(Outer outer) { void getterArgument2(Outer outer) {
pointerSetA(outer.getInner(), user_input()); pointerSetA(outer.getInner(), user_input());
sink(outer.inner->a); // $ ast MISSING: ir sink(outer.inner->a); // $ ast,ir
} }
void getterArgument2Ref(Outer outer) { void getterArgument2Ref(Outer outer) {
referenceSetA(*outer.getInner(), user_input()); referenceSetA(*outer.getInner(), user_input());
sink(outer.inner->a); // $ ast MISSING: ir sink(outer.inner->a); // $ ast,ir
} }
void assignToGetterStar(Outer outer) { void assignToGetterStar(Outer outer) {
(*outer.getInner()).a = user_input(); (*outer.getInner()).a = user_input();
sink(outer.inner->a); // $ ast MISSING: ir sink(outer.inner->a); // $ ast,ir
} }
void assignToGetterAmp(Outer outer) { void assignToGetterAmp(Outer outer) {
(&outer)->getInner()->a = user_input(); (&outer)->getInner()->a = user_input();
sink(outer.inner->a); // $ ast MISSING: ir sink(outer.inner->a); // $ ast,ir
} }
} }

View File

@@ -58,7 +58,7 @@ int main(int argc, char** argv) {
return -1; return -1;
} }
memcpy(dst, foo.bar[i].baz->userInput.buffer, foo.bar[i].baz->userInput.bufferLen); 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 // There is no flow to the following two `sink` calls because the
// source is the _pointer_ returned by `user_input` rather than the // source is the _pointer_ returned by `user_input` rather than the
// _data_ to which it points. // _data_ to which it points.

View File

@@ -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: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: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: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: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: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 | | test.cpp:68:28:68:33 | call to getenv | test.cpp:11:20:11:21 | s1 | AST only |

View File

@@ -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: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: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: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: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:60:29:60:47 | (const char *)... |
| test.cpp:60:29:60:34 | call to getenv | test.cpp:64:25:64:32 | userName | | test.cpp:60:29:60:34 | call to getenv | test.cpp:64:25:64:32 | userName |

View File

@@ -7,7 +7,7 @@ void test_unique_ptr_int() {
std::unique_ptr<int> p1(new int(source())); std::unique_ptr<int> p1(new int(source()));
std::unique_ptr<int> p2 = std::make_unique<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 sink(*p2); // $ ast ir=8:50
} }
@@ -23,7 +23,7 @@ void test_unique_ptr_struct() {
sink(p1->x); // $ ir MISSING: ast sink(p1->x); // $ ir MISSING: ast
sink(p1->y); sink(p1->y);
sink(p2->x); // $ MISSING: ast,ir sink(p2->x); // $ ir=22:46 MISSING: ast
sink(p2->y); sink(p2->y);
} }
@@ -31,7 +31,7 @@ void test_shared_ptr_int() {
std::shared_ptr<int> p1(new int(source())); std::shared_ptr<int> p1(new int(source()));
std::shared_ptr<int> p2 = std::make_shared<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 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> p1(new A{source(), 0});
std::shared_ptr<A> p2 = std::make_shared<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(p1->y);
sink(p2->x); // $ MISSING: ast,ir sink(p2->x); // $ MISSING: ast,ir
sink(p2->y); sink(p2->y);

View File

@@ -13,10 +13,10 @@ void test_pointer_deref_assignment()
*p_x = source(); *p_x = source();
sink(x); // $ ir MISSING: ast sink(x); // $ MISSING: ast,ir
sink(*p_x); // $ ast,ir sink(*p_x); // $ ast,ir
sink(*p2_x); // $ ir MISSING: ast sink(*p2_x); // $ MISSING: ast,ir
sink(r_x); // $ ir MISSING: ast sink(r_x); // $ MISSING: ast,ir
} }
void test_reference_deref_assignment() void test_reference_deref_assignment()
@@ -28,10 +28,10 @@ void test_reference_deref_assignment()
r_x = source(); r_x = source();
sink(x); // $ ir MISSING: ast sink(x); // $ MISSING: ast,ir
sink(*p_x); // $ ir MISSING: ast sink(*p_x); // $ MISSING: ast,ir
sink(r_x); // $ ast,ir sink(r_x); // $ ast,ir
sink(r2_x); // $ ir MISSING: ast sink(r2_x); // $ MISSING: ast,ir
} }
class MyInt class MyInt
@@ -53,8 +53,8 @@ void test_myint_member_assignment()
mi.i = source(); mi.i = source();
sink(mi); // $ ir MISSING: ast sink(mi); // $ MISSING: ast,ir
sink(mi.get()); // $ ast,ir sink(mi.get()); // $ ast MISSING: ir
} }
void test_myint_method_assignment() void test_myint_method_assignment()
@@ -64,7 +64,7 @@ void test_myint_method_assignment()
mi.get() = source(); mi.get() = source();
sink(mi); // $ ir MISSING: ast sink(mi); // $ ir MISSING: ast
sink(mi.get()); // $ ast,ir sink(mi.get()); // $ ast MISSING: ir
} }
void test_myint_overloaded_assignment() void test_myint_overloaded_assignment()
@@ -133,15 +133,15 @@ void test_array_reference_assignment()
ref1 = source(); ref1 = source();
sink(ref1); // $ ast,ir sink(ref1); // $ ast,ir
sink(arr1[5]); // $ ir MISSING: ast sink(arr1[5]); // $ MISSING: ast,ir
ptr2 = &(arr2[5]); ptr2 = &(arr2[5]);
*ptr2 = source(); *ptr2 = source();
sink(*ptr2); // $ ast,ir sink(*ptr2); // $ ast,ir
sink(arr2[5]); // $ ir MISSING: ast sink(arr2[5]); // $ MISSING: ast,ir
ptr3 = arr3; ptr3 = arr3;
ptr3[5] = source(); ptr3[5] = source();
sink(ptr3[5]); // $ ast,ir sink(ptr3[5]); // $ ast,ir
sink(arr3[5]); // $ ir MISSING: ast sink(arr3[5]); // $ MISSING: ast,ir
} }

View File

@@ -594,12 +594,6 @@
| map.cpp:105:31:105:32 | call to map | map.cpp:136:7:136:8 | m2 | | | map.cpp:105:31:105:32 | call to map | map.cpp:136:7:136:8 | m2 | |
| map.cpp:105:31:105:32 | call to map | map.cpp:152:12:152:13 | m2 | | | map.cpp:105:31:105:32 | call to map | map.cpp:152:12:152:13 | m2 | |
| map.cpp:105:31:105:32 | call to map | map.cpp:152:30:152:31 | m2 | | | map.cpp:105:31:105:32 | call to map | map.cpp:152:30:152:31 | m2 | |
| map.cpp:105:31:105:32 | call to map | map.cpp:182:7:182:8 | m2 | |
| map.cpp:105:31:105:32 | call to map | map.cpp:183:7:183:8 | m2 | |
| map.cpp:105:31:105:32 | call to map | map.cpp:184:7:184:8 | m2 | |
| map.cpp:105:31:105:32 | call to map | map.cpp:185:7:185:8 | m2 | |
| map.cpp:105:31:105:32 | call to map | map.cpp:186:7:186:8 | m2 | |
| map.cpp:105:31:105:32 | call to map | map.cpp:187:7:187:8 | m2 | |
| map.cpp:105:31:105:32 | call to map | map.cpp:252:1:252:1 | m2 | | | map.cpp:105:31:105:32 | call to map | map.cpp:252:1:252:1 | m2 | |
| map.cpp:105:35:105:36 | call to map | map.cpp:109:7:109:8 | m3 | | | map.cpp:105:35:105:36 | call to map | map.cpp:109:7:109:8 | m3 | |
| map.cpp:105:35:105:36 | call to map | map.cpp:115:7:115:8 | m3 | | | map.cpp:105:35:105:36 | call to map | map.cpp:115:7:115:8 | m3 | |
@@ -643,12 +637,6 @@
| map.cpp:108:7:108:8 | ref arg m2 | map.cpp:136:7:136:8 | m2 | | | map.cpp:108:7:108:8 | ref arg m2 | map.cpp:136:7:136:8 | m2 | |
| map.cpp:108:7:108:8 | ref arg m2 | map.cpp:152:12:152:13 | m2 | | | map.cpp:108:7:108:8 | ref arg m2 | map.cpp:152:12:152:13 | m2 | |
| map.cpp:108:7:108:8 | ref arg m2 | map.cpp:152:30:152:31 | m2 | | | map.cpp:108:7:108:8 | ref arg m2 | map.cpp:152:30:152:31 | m2 | |
| map.cpp:108:7:108:8 | ref arg m2 | map.cpp:182:7:182:8 | m2 | |
| map.cpp:108:7:108:8 | ref arg m2 | map.cpp:183:7:183:8 | m2 | |
| map.cpp:108:7:108:8 | ref arg m2 | map.cpp:184:7:184:8 | m2 | |
| map.cpp:108:7:108:8 | ref arg m2 | map.cpp:185:7:185:8 | m2 | |
| map.cpp:108:7:108:8 | ref arg m2 | map.cpp:186:7:186:8 | m2 | |
| map.cpp:108:7:108:8 | ref arg m2 | map.cpp:187:7:187:8 | m2 | |
| map.cpp:108:7:108:8 | ref arg m2 | map.cpp:252:1:252:1 | m2 | | | map.cpp:108:7:108:8 | ref arg m2 | map.cpp:252:1:252:1 | m2 | |
| map.cpp:108:17:108:30 | call to make_pair | map.cpp:108:17:108:47 | call to pair | TAINT | | map.cpp:108:17:108:30 | call to make_pair | map.cpp:108:17:108:47 | call to pair | TAINT |
| map.cpp:108:17:108:47 | call to pair | map.cpp:108:7:108:8 | ref arg m2 | TAINT | | map.cpp:108:17:108:47 | call to pair | map.cpp:108:7:108:8 | ref arg m2 | TAINT |
@@ -717,12 +705,6 @@
| map.cpp:120:7:120:8 | ref arg m2 | map.cpp:136:7:136:8 | m2 | | | map.cpp:120:7:120:8 | ref arg m2 | map.cpp:136:7:136:8 | m2 | |
| map.cpp:120:7:120:8 | ref arg m2 | map.cpp:152:12:152:13 | m2 | | | map.cpp:120:7:120:8 | ref arg m2 | map.cpp:152:12:152:13 | m2 | |
| map.cpp:120:7:120:8 | ref arg m2 | map.cpp:152:30:152:31 | m2 | | | map.cpp:120:7:120:8 | ref arg m2 | map.cpp:152:30:152:31 | m2 | |
| map.cpp:120:7:120:8 | ref arg m2 | map.cpp:182:7:182:8 | m2 | |
| map.cpp:120:7:120:8 | ref arg m2 | map.cpp:183:7:183:8 | m2 | |
| map.cpp:120:7:120:8 | ref arg m2 | map.cpp:184:7:184:8 | m2 | |
| map.cpp:120:7:120:8 | ref arg m2 | map.cpp:185:7:185:8 | m2 | |
| map.cpp:120:7:120:8 | ref arg m2 | map.cpp:186:7:186:8 | m2 | |
| map.cpp:120:7:120:8 | ref arg m2 | map.cpp:187:7:187:8 | m2 | |
| map.cpp:120:7:120:8 | ref arg m2 | map.cpp:252:1:252:1 | m2 | | | map.cpp:120:7:120:8 | ref arg m2 | map.cpp:252:1:252:1 | m2 | |
| map.cpp:121:7:121:8 | m3 | map.cpp:121:10:121:13 | call to find | TAINT | | map.cpp:121:7:121:8 | m3 | map.cpp:121:10:121:13 | call to find | TAINT |
| map.cpp:121:7:121:8 | ref arg m3 | map.cpp:127:7:127:8 | m3 | | | map.cpp:121:7:121:8 | ref arg m3 | map.cpp:127:7:127:8 | m3 | |
@@ -748,12 +730,6 @@
| map.cpp:126:7:126:8 | ref arg m2 | map.cpp:136:7:136:8 | m2 | | | map.cpp:126:7:126:8 | ref arg m2 | map.cpp:136:7:136:8 | m2 | |
| map.cpp:126:7:126:8 | ref arg m2 | map.cpp:152:12:152:13 | m2 | | | map.cpp:126:7:126:8 | ref arg m2 | map.cpp:152:12:152:13 | m2 | |
| map.cpp:126:7:126:8 | ref arg m2 | map.cpp:152:30:152:31 | m2 | | | map.cpp:126:7:126:8 | ref arg m2 | map.cpp:152:30:152:31 | m2 | |
| map.cpp:126:7:126:8 | ref arg m2 | map.cpp:182:7:182:8 | m2 | |
| map.cpp:126:7:126:8 | ref arg m2 | map.cpp:183:7:183:8 | m2 | |
| map.cpp:126:7:126:8 | ref arg m2 | map.cpp:184:7:184:8 | m2 | |
| map.cpp:126:7:126:8 | ref arg m2 | map.cpp:185:7:185:8 | m2 | |
| map.cpp:126:7:126:8 | ref arg m2 | map.cpp:186:7:186:8 | m2 | |
| map.cpp:126:7:126:8 | ref arg m2 | map.cpp:187:7:187:8 | m2 | |
| map.cpp:126:7:126:8 | ref arg m2 | map.cpp:252:1:252:1 | m2 | | | map.cpp:126:7:126:8 | ref arg m2 | map.cpp:252:1:252:1 | m2 | |
| map.cpp:127:7:127:8 | m3 | map.cpp:127:10:127:13 | call to find | TAINT | | map.cpp:127:7:127:8 | m3 | map.cpp:127:10:127:13 | call to find | TAINT |
| map.cpp:127:7:127:8 | ref arg m3 | map.cpp:158:12:158:13 | m3 | | | map.cpp:127:7:127:8 | ref arg m3 | map.cpp:158:12:158:13 | m3 | |
@@ -830,12 +806,6 @@
| map.cpp:150:8:150:9 | ref arg i1 | map.cpp:150:8:150:9 | i1 | | | map.cpp:150:8:150:9 | ref arg i1 | map.cpp:150:8:150:9 | i1 | |
| map.cpp:152:12:152:13 | m2 | map.cpp:152:15:152:19 | call to begin | TAINT | | map.cpp:152:12:152:13 | m2 | map.cpp:152:15:152:19 | call to begin | TAINT |
| map.cpp:152:12:152:13 | ref arg m2 | map.cpp:152:30:152:31 | m2 | | | map.cpp:152:12:152:13 | ref arg m2 | map.cpp:152:30:152:31 | m2 | |
| map.cpp:152:12:152:13 | ref arg m2 | map.cpp:182:7:182:8 | m2 | |
| map.cpp:152:12:152:13 | ref arg m2 | map.cpp:183:7:183:8 | m2 | |
| map.cpp:152:12:152:13 | ref arg m2 | map.cpp:184:7:184:8 | m2 | |
| map.cpp:152:12:152:13 | ref arg m2 | map.cpp:185:7:185:8 | m2 | |
| map.cpp:152:12:152:13 | ref arg m2 | map.cpp:186:7:186:8 | m2 | |
| map.cpp:152:12:152:13 | ref arg m2 | map.cpp:187:7:187:8 | m2 | |
| map.cpp:152:12:152:13 | ref arg m2 | map.cpp:252:1:252:1 | m2 | | | map.cpp:152:12:152:13 | ref arg m2 | map.cpp:252:1:252:1 | m2 | |
| map.cpp:152:15:152:19 | call to begin | map.cpp:152:7:152:21 | ... = ... | | | map.cpp:152:15:152:19 | call to begin | map.cpp:152:7:152:21 | ... = ... | |
| map.cpp:152:15:152:19 | call to begin | map.cpp:152:24:152:25 | i2 | | | map.cpp:152:15:152:19 | call to begin | map.cpp:152:24:152:25 | i2 | |
@@ -845,12 +815,6 @@
| map.cpp:152:15:152:19 | call to begin | map.cpp:156:8:156:9 | i2 | | | map.cpp:152:15:152:19 | call to begin | map.cpp:156:8:156:9 | i2 | |
| map.cpp:152:30:152:31 | m2 | map.cpp:152:33:152:35 | call to end | TAINT | | map.cpp:152:30:152:31 | m2 | map.cpp:152:33:152:35 | call to end | TAINT |
| map.cpp:152:30:152:31 | ref arg m2 | map.cpp:152:30:152:31 | m2 | | | map.cpp:152:30:152:31 | ref arg m2 | map.cpp:152:30:152:31 | m2 | |
| map.cpp:152:30:152:31 | ref arg m2 | map.cpp:182:7:182:8 | m2 | |
| map.cpp:152:30:152:31 | ref arg m2 | map.cpp:183:7:183:8 | m2 | |
| map.cpp:152:30:152:31 | ref arg m2 | map.cpp:184:7:184:8 | m2 | |
| map.cpp:152:30:152:31 | ref arg m2 | map.cpp:185:7:185:8 | m2 | |
| map.cpp:152:30:152:31 | ref arg m2 | map.cpp:186:7:186:8 | m2 | |
| map.cpp:152:30:152:31 | ref arg m2 | map.cpp:187:7:187:8 | m2 | |
| map.cpp:152:30:152:31 | ref arg m2 | map.cpp:252:1:252:1 | m2 | | | map.cpp:152:30:152:31 | ref arg m2 | map.cpp:252:1:252:1 | m2 | |
| map.cpp:152:40:152:41 | i2 | map.cpp:152:42:152:42 | call to operator++ | | | map.cpp:152:40:152:41 | i2 | map.cpp:152:42:152:42 | call to operator++ | |
| map.cpp:152:40:152:41 | ref arg i2 | map.cpp:152:24:152:25 | i2 | | | map.cpp:152:40:152:41 | ref arg i2 | map.cpp:152:24:152:25 | i2 | |
@@ -962,59 +926,89 @@
| map.cpp:177:27:177:29 | call to map | map.cpp:179:2:179:4 | m14 | | | map.cpp:177:27:177:29 | call to map | map.cpp:179:2:179:4 | m14 | |
| map.cpp:177:27:177:29 | call to map | map.cpp:180:2:180:4 | m14 | | | map.cpp:177:27:177:29 | call to map | map.cpp:180:2:180:4 | m14 | |
| map.cpp:177:27:177:29 | call to map | map.cpp:181:2:181:4 | m14 | | | map.cpp:177:27:177:29 | call to map | map.cpp:181:2:181:4 | m14 | |
| map.cpp:177:27:177:29 | call to map | map.cpp:182:7:182:9 | m14 | |
| map.cpp:177:27:177:29 | call to map | map.cpp:183:7:183:9 | m14 | |
| map.cpp:177:27:177:29 | call to map | map.cpp:184:7:184:9 | m14 | |
| map.cpp:177:27:177:29 | call to map | map.cpp:185:7:185:9 | m14 | |
| map.cpp:177:27:177:29 | call to map | map.cpp:186:7:186:9 | m14 | |
| map.cpp:177:27:177:29 | call to map | map.cpp:187:7:187:9 | m14 | |
| map.cpp:177:27:177:29 | call to map | map.cpp:252:1:252:1 | m14 | | | map.cpp:177:27:177:29 | call to map | map.cpp:252:1:252:1 | m14 | |
| map.cpp:178:2:178:4 | ref arg m14 | map.cpp:179:2:179:4 | m14 | | | map.cpp:178:2:178:4 | ref arg m14 | map.cpp:179:2:179:4 | m14 | |
| map.cpp:178:2:178:4 | ref arg m14 | map.cpp:180:2:180:4 | m14 | | | map.cpp:178:2:178:4 | ref arg m14 | map.cpp:180:2:180:4 | m14 | |
| map.cpp:178:2:178:4 | ref arg m14 | map.cpp:181:2:181:4 | m14 | | | map.cpp:178:2:178:4 | ref arg m14 | map.cpp:181:2:181:4 | m14 | |
| map.cpp:178:2:178:4 | ref arg m14 | map.cpp:182:7:182:9 | m14 | |
| map.cpp:178:2:178:4 | ref arg m14 | map.cpp:183:7:183:9 | m14 | |
| map.cpp:178:2:178:4 | ref arg m14 | map.cpp:184:7:184:9 | m14 | |
| map.cpp:178:2:178:4 | ref arg m14 | map.cpp:185:7:185:9 | m14 | |
| map.cpp:178:2:178:4 | ref arg m14 | map.cpp:186:7:186:9 | m14 | |
| map.cpp:178:2:178:4 | ref arg m14 | map.cpp:187:7:187:9 | m14 | |
| map.cpp:178:2:178:4 | ref arg m14 | map.cpp:252:1:252:1 | m14 | | | map.cpp:178:2:178:4 | ref arg m14 | map.cpp:252:1:252:1 | m14 | |
| map.cpp:178:13:178:26 | call to make_pair | map.cpp:178:13:178:36 | call to pair | TAINT | | map.cpp:178:13:178:26 | call to make_pair | map.cpp:178:13:178:36 | call to pair | TAINT |
| map.cpp:178:13:178:36 | call to pair | map.cpp:178:2:178:4 | ref arg m14 | TAINT | | map.cpp:178:13:178:36 | call to pair | map.cpp:178:2:178:4 | ref arg m14 | TAINT |
| map.cpp:178:13:178:36 | call to pair | map.cpp:178:6:178:11 | call to insert | TAINT | | map.cpp:178:13:178:36 | call to pair | map.cpp:178:6:178:11 | call to insert | TAINT |
| map.cpp:179:2:179:4 | ref arg m14 | map.cpp:180:2:180:4 | m14 | | | map.cpp:179:2:179:4 | ref arg m14 | map.cpp:180:2:180:4 | m14 | |
| map.cpp:179:2:179:4 | ref arg m14 | map.cpp:181:2:181:4 | m14 | | | map.cpp:179:2:179:4 | ref arg m14 | map.cpp:181:2:181:4 | m14 | |
| map.cpp:179:2:179:4 | ref arg m14 | map.cpp:182:7:182:9 | m14 | |
| map.cpp:179:2:179:4 | ref arg m14 | map.cpp:183:7:183:9 | m14 | |
| map.cpp:179:2:179:4 | ref arg m14 | map.cpp:184:7:184:9 | m14 | |
| map.cpp:179:2:179:4 | ref arg m14 | map.cpp:185:7:185:9 | m14 | |
| map.cpp:179:2:179:4 | ref arg m14 | map.cpp:186:7:186:9 | m14 | |
| map.cpp:179:2:179:4 | ref arg m14 | map.cpp:187:7:187:9 | m14 | |
| map.cpp:179:2:179:4 | ref arg m14 | map.cpp:252:1:252:1 | m14 | | | map.cpp:179:2:179:4 | ref arg m14 | map.cpp:252:1:252:1 | m14 | |
| map.cpp:179:13:179:26 | call to make_pair | map.cpp:179:13:179:41 | call to pair | TAINT | | map.cpp:179:13:179:26 | call to make_pair | map.cpp:179:13:179:41 | call to pair | TAINT |
| map.cpp:179:13:179:41 | call to pair | map.cpp:179:2:179:4 | ref arg m14 | TAINT | | map.cpp:179:13:179:41 | call to pair | map.cpp:179:2:179:4 | ref arg m14 | TAINT |
| map.cpp:179:13:179:41 | call to pair | map.cpp:179:6:179:11 | call to insert | TAINT | | map.cpp:179:13:179:41 | call to pair | map.cpp:179:6:179:11 | call to insert | TAINT |
| map.cpp:180:2:180:4 | ref arg m14 | map.cpp:181:2:181:4 | m14 | | | map.cpp:180:2:180:4 | ref arg m14 | map.cpp:181:2:181:4 | m14 | |
| map.cpp:180:2:180:4 | ref arg m14 | map.cpp:182:7:182:9 | m14 | |
| map.cpp:180:2:180:4 | ref arg m14 | map.cpp:183:7:183:9 | m14 | |
| map.cpp:180:2:180:4 | ref arg m14 | map.cpp:184:7:184:9 | m14 | |
| map.cpp:180:2:180:4 | ref arg m14 | map.cpp:185:7:185:9 | m14 | |
| map.cpp:180:2:180:4 | ref arg m14 | map.cpp:186:7:186:9 | m14 | |
| map.cpp:180:2:180:4 | ref arg m14 | map.cpp:187:7:187:9 | m14 | |
| map.cpp:180:2:180:4 | ref arg m14 | map.cpp:252:1:252:1 | m14 | | | map.cpp:180:2:180:4 | ref arg m14 | map.cpp:252:1:252:1 | m14 | |
| map.cpp:180:13:180:26 | call to make_pair | map.cpp:180:13:180:41 | call to pair | TAINT | | map.cpp:180:13:180:26 | call to make_pair | map.cpp:180:13:180:41 | call to pair | TAINT |
| map.cpp:180:13:180:41 | call to pair | map.cpp:180:2:180:4 | ref arg m14 | TAINT | | map.cpp:180:13:180:41 | call to pair | map.cpp:180:2:180:4 | ref arg m14 | TAINT |
| map.cpp:180:13:180:41 | call to pair | map.cpp:180:6:180:11 | call to insert | TAINT | | map.cpp:180:13:180:41 | call to pair | map.cpp:180:6:180:11 | call to insert | TAINT |
| map.cpp:181:2:181:4 | ref arg m14 | map.cpp:182:7:182:9 | m14 | |
| map.cpp:181:2:181:4 | ref arg m14 | map.cpp:183:7:183:9 | m14 | |
| map.cpp:181:2:181:4 | ref arg m14 | map.cpp:184:7:184:9 | m14 | |
| map.cpp:181:2:181:4 | ref arg m14 | map.cpp:185:7:185:9 | m14 | |
| map.cpp:181:2:181:4 | ref arg m14 | map.cpp:186:7:186:9 | m14 | |
| map.cpp:181:2:181:4 | ref arg m14 | map.cpp:187:7:187:9 | m14 | |
| map.cpp:181:2:181:4 | ref arg m14 | map.cpp:252:1:252:1 | m14 | | | map.cpp:181:2:181:4 | ref arg m14 | map.cpp:252:1:252:1 | m14 | |
| map.cpp:181:13:181:26 | call to make_pair | map.cpp:181:13:181:36 | call to pair | TAINT | | map.cpp:181:13:181:26 | call to make_pair | map.cpp:181:13:181:36 | call to pair | TAINT |
| map.cpp:181:13:181:36 | call to pair | map.cpp:181:2:181:4 | ref arg m14 | TAINT | | map.cpp:181:13:181:36 | call to pair | map.cpp:181:2:181:4 | ref arg m14 | TAINT |
| map.cpp:181:13:181:36 | call to pair | map.cpp:181:6:181:11 | call to insert | TAINT | | map.cpp:181:13:181:36 | call to pair | map.cpp:181:6:181:11 | call to insert | TAINT |
| map.cpp:182:7:182:8 | m2 | map.cpp:182:10:182:20 | call to lower_bound | TAINT | | map.cpp:182:7:182:9 | m14 | map.cpp:182:11:182:21 | call to lower_bound | TAINT |
| map.cpp:182:7:182:8 | ref arg m2 | map.cpp:183:7:183:8 | m2 | | | map.cpp:182:7:182:9 | ref arg m14 | map.cpp:183:7:183:9 | m14 | |
| map.cpp:182:7:182:8 | ref arg m2 | map.cpp:184:7:184:8 | m2 | | | map.cpp:182:7:182:9 | ref arg m14 | map.cpp:184:7:184:9 | m14 | |
| map.cpp:182:7:182:8 | ref arg m2 | map.cpp:185:7:185:8 | m2 | | | map.cpp:182:7:182:9 | ref arg m14 | map.cpp:185:7:185:9 | m14 | |
| map.cpp:182:7:182:8 | ref arg m2 | map.cpp:186:7:186:8 | m2 | | | map.cpp:182:7:182:9 | ref arg m14 | map.cpp:186:7:186:9 | m14 | |
| map.cpp:182:7:182:8 | ref arg m2 | map.cpp:187:7:187:8 | m2 | | | map.cpp:182:7:182:9 | ref arg m14 | map.cpp:187:7:187:9 | m14 | |
| map.cpp:182:7:182:8 | ref arg m2 | map.cpp:252:1:252:1 | m2 | | | map.cpp:182:7:182:9 | ref arg m14 | map.cpp:252:1:252:1 | m14 | |
| map.cpp:183:7:183:8 | m2 | map.cpp:183:10:183:20 | call to upper_bound | TAINT | | map.cpp:183:7:183:9 | m14 | map.cpp:183:11:183:21 | call to upper_bound | TAINT |
| map.cpp:183:7:183:8 | ref arg m2 | map.cpp:184:7:184:8 | m2 | | | map.cpp:183:7:183:9 | ref arg m14 | map.cpp:184:7:184:9 | m14 | |
| map.cpp:183:7:183:8 | ref arg m2 | map.cpp:185:7:185:8 | m2 | | | map.cpp:183:7:183:9 | ref arg m14 | map.cpp:185:7:185:9 | m14 | |
| map.cpp:183:7:183:8 | ref arg m2 | map.cpp:186:7:186:8 | m2 | | | map.cpp:183:7:183:9 | ref arg m14 | map.cpp:186:7:186:9 | m14 | |
| map.cpp:183:7:183:8 | ref arg m2 | map.cpp:187:7:187:8 | m2 | | | map.cpp:183:7:183:9 | ref arg m14 | map.cpp:187:7:187:9 | m14 | |
| map.cpp:183:7:183:8 | ref arg m2 | map.cpp:252:1:252:1 | m2 | | | map.cpp:183:7:183:9 | ref arg m14 | map.cpp:252:1:252:1 | m14 | |
| map.cpp:184:7:184:8 | m2 | map.cpp:184:10:184:20 | call to equal_range | TAINT | | map.cpp:184:7:184:9 | m14 | map.cpp:184:11:184:21 | call to equal_range | TAINT |
| map.cpp:184:7:184:8 | ref arg m2 | map.cpp:185:7:185:8 | m2 | | | map.cpp:184:7:184:9 | ref arg m14 | map.cpp:185:7:185:9 | m14 | |
| map.cpp:184:7:184:8 | ref arg m2 | map.cpp:186:7:186:8 | m2 | | | map.cpp:184:7:184:9 | ref arg m14 | map.cpp:186:7:186:9 | m14 | |
| map.cpp:184:7:184:8 | ref arg m2 | map.cpp:187:7:187:8 | m2 | | | map.cpp:184:7:184:9 | ref arg m14 | map.cpp:187:7:187:9 | m14 | |
| map.cpp:184:7:184:8 | ref arg m2 | map.cpp:252:1:252:1 | m2 | | | map.cpp:184:7:184:9 | ref arg m14 | map.cpp:252:1:252:1 | m14 | |
| map.cpp:184:27:184:31 | first | map.cpp:184:7:184:31 | call to iterator | | | map.cpp:184:28:184:32 | first | map.cpp:184:7:184:32 | call to iterator | |
| map.cpp:185:7:185:8 | m2 | map.cpp:185:10:185:20 | call to equal_range | TAINT | | map.cpp:185:7:185:9 | m14 | map.cpp:185:11:185:21 | call to equal_range | TAINT |
| map.cpp:185:7:185:8 | ref arg m2 | map.cpp:186:7:186:8 | m2 | | | map.cpp:185:7:185:9 | ref arg m14 | map.cpp:186:7:186:9 | m14 | |
| map.cpp:185:7:185:8 | ref arg m2 | map.cpp:187:7:187:8 | m2 | | | map.cpp:185:7:185:9 | ref arg m14 | map.cpp:187:7:187:9 | m14 | |
| map.cpp:185:7:185:8 | ref arg m2 | map.cpp:252:1:252:1 | m2 | | | map.cpp:185:7:185:9 | ref arg m14 | map.cpp:252:1:252:1 | m14 | |
| map.cpp:185:27:185:32 | second | map.cpp:185:7:185:32 | call to iterator | | | map.cpp:185:28:185:33 | second | map.cpp:185:7:185:33 | call to iterator | |
| map.cpp:186:7:186:8 | m2 | map.cpp:186:10:186:20 | call to upper_bound | TAINT | | map.cpp:186:7:186:9 | m14 | map.cpp:186:11:186:21 | call to upper_bound | TAINT |
| map.cpp:186:7:186:8 | ref arg m2 | map.cpp:187:7:187:8 | m2 | | | map.cpp:186:7:186:9 | ref arg m14 | map.cpp:187:7:187:9 | m14 | |
| map.cpp:186:7:186:8 | ref arg m2 | map.cpp:252:1:252:1 | m2 | | | map.cpp:186:7:186:9 | ref arg m14 | map.cpp:252:1:252:1 | m14 | |
| map.cpp:187:7:187:8 | m2 | map.cpp:187:10:187:20 | call to equal_range | TAINT | | map.cpp:187:7:187:9 | m14 | map.cpp:187:11:187:21 | call to equal_range | TAINT |
| map.cpp:187:7:187:8 | ref arg m2 | map.cpp:252:1:252:1 | m2 | | | map.cpp:187:7:187:9 | ref arg m14 | map.cpp:252:1:252:1 | m14 | |
| map.cpp:187:27:187:32 | second | map.cpp:187:7:187:32 | call to iterator | | | map.cpp:187:28:187:33 | second | map.cpp:187:7:187:33 | call to iterator | |
| map.cpp:190:27:190:29 | call to map | map.cpp:191:2:191:4 | m15 | | | map.cpp:190:27:190:29 | call to map | map.cpp:191:2:191:4 | m15 | |
| map.cpp:190:27:190:29 | call to map | map.cpp:193:7:193:9 | m15 | | | map.cpp:190:27:190:29 | call to map | map.cpp:193:7:193:9 | m15 | |
| map.cpp:190:27:190:29 | call to map | map.cpp:197:2:197:4 | m15 | | | map.cpp:190:27:190:29 | call to map | map.cpp:197:2:197:4 | m15 | |
@@ -1315,9 +1309,6 @@
| map.cpp:257:41:257:42 | call to unordered_map | map.cpp:288:7:288:8 | m2 | | | map.cpp:257:41:257:42 | call to unordered_map | map.cpp:288:7:288:8 | m2 | |
| map.cpp:257:41:257:42 | call to unordered_map | map.cpp:304:12:304:13 | m2 | | | map.cpp:257:41:257:42 | call to unordered_map | map.cpp:304:12:304:13 | m2 | |
| map.cpp:257:41:257:42 | call to unordered_map | map.cpp:304:30:304:31 | m2 | | | map.cpp:257:41:257:42 | call to unordered_map | map.cpp:304:30:304:31 | m2 | |
| map.cpp:257:41:257:42 | call to unordered_map | map.cpp:334:7:334:8 | m2 | |
| map.cpp:257:41:257:42 | call to unordered_map | map.cpp:335:7:335:8 | m2 | |
| map.cpp:257:41:257:42 | call to unordered_map | map.cpp:336:7:336:8 | m2 | |
| map.cpp:257:41:257:42 | call to unordered_map | map.cpp:438:1:438:1 | m2 | | | map.cpp:257:41:257:42 | call to unordered_map | map.cpp:438:1:438:1 | m2 | |
| map.cpp:257:45:257:46 | call to unordered_map | map.cpp:261:7:261:8 | m3 | | | map.cpp:257:45:257:46 | call to unordered_map | map.cpp:261:7:261:8 | m3 | |
| map.cpp:257:45:257:46 | call to unordered_map | map.cpp:267:7:267:8 | m3 | | | map.cpp:257:45:257:46 | call to unordered_map | map.cpp:267:7:267:8 | m3 | |
@@ -1361,9 +1352,6 @@
| map.cpp:260:7:260:8 | ref arg m2 | map.cpp:288:7:288:8 | m2 | | | map.cpp:260:7:260:8 | ref arg m2 | map.cpp:288:7:288:8 | m2 | |
| map.cpp:260:7:260:8 | ref arg m2 | map.cpp:304:12:304:13 | m2 | | | map.cpp:260:7:260:8 | ref arg m2 | map.cpp:304:12:304:13 | m2 | |
| map.cpp:260:7:260:8 | ref arg m2 | map.cpp:304:30:304:31 | m2 | | | map.cpp:260:7:260:8 | ref arg m2 | map.cpp:304:30:304:31 | m2 | |
| map.cpp:260:7:260:8 | ref arg m2 | map.cpp:334:7:334:8 | m2 | |
| map.cpp:260:7:260:8 | ref arg m2 | map.cpp:335:7:335:8 | m2 | |
| map.cpp:260:7:260:8 | ref arg m2 | map.cpp:336:7:336:8 | m2 | |
| map.cpp:260:7:260:8 | ref arg m2 | map.cpp:438:1:438:1 | m2 | | | map.cpp:260:7:260:8 | ref arg m2 | map.cpp:438:1:438:1 | m2 | |
| map.cpp:260:17:260:30 | call to make_pair | map.cpp:260:17:260:47 | call to pair | TAINT | | map.cpp:260:17:260:30 | call to make_pair | map.cpp:260:17:260:47 | call to pair | TAINT |
| map.cpp:260:17:260:47 | call to pair | map.cpp:260:7:260:8 | ref arg m2 | TAINT | | map.cpp:260:17:260:47 | call to pair | map.cpp:260:7:260:8 | ref arg m2 | TAINT |
@@ -1432,9 +1420,6 @@
| map.cpp:272:7:272:8 | ref arg m2 | map.cpp:288:7:288:8 | m2 | | | map.cpp:272:7:272:8 | ref arg m2 | map.cpp:288:7:288:8 | m2 | |
| map.cpp:272:7:272:8 | ref arg m2 | map.cpp:304:12:304:13 | m2 | | | map.cpp:272:7:272:8 | ref arg m2 | map.cpp:304:12:304:13 | m2 | |
| map.cpp:272:7:272:8 | ref arg m2 | map.cpp:304:30:304:31 | m2 | | | map.cpp:272:7:272:8 | ref arg m2 | map.cpp:304:30:304:31 | m2 | |
| map.cpp:272:7:272:8 | ref arg m2 | map.cpp:334:7:334:8 | m2 | |
| map.cpp:272:7:272:8 | ref arg m2 | map.cpp:335:7:335:8 | m2 | |
| map.cpp:272:7:272:8 | ref arg m2 | map.cpp:336:7:336:8 | m2 | |
| map.cpp:272:7:272:8 | ref arg m2 | map.cpp:438:1:438:1 | m2 | | | map.cpp:272:7:272:8 | ref arg m2 | map.cpp:438:1:438:1 | m2 | |
| map.cpp:273:7:273:8 | m3 | map.cpp:273:10:273:13 | call to find | TAINT | | map.cpp:273:7:273:8 | m3 | map.cpp:273:10:273:13 | call to find | TAINT |
| map.cpp:273:7:273:8 | ref arg m3 | map.cpp:279:7:279:8 | m3 | | | map.cpp:273:7:273:8 | ref arg m3 | map.cpp:279:7:279:8 | m3 | |
@@ -1460,9 +1445,6 @@
| map.cpp:278:7:278:8 | ref arg m2 | map.cpp:288:7:288:8 | m2 | | | map.cpp:278:7:278:8 | ref arg m2 | map.cpp:288:7:288:8 | m2 | |
| map.cpp:278:7:278:8 | ref arg m2 | map.cpp:304:12:304:13 | m2 | | | map.cpp:278:7:278:8 | ref arg m2 | map.cpp:304:12:304:13 | m2 | |
| map.cpp:278:7:278:8 | ref arg m2 | map.cpp:304:30:304:31 | m2 | | | map.cpp:278:7:278:8 | ref arg m2 | map.cpp:304:30:304:31 | m2 | |
| map.cpp:278:7:278:8 | ref arg m2 | map.cpp:334:7:334:8 | m2 | |
| map.cpp:278:7:278:8 | ref arg m2 | map.cpp:335:7:335:8 | m2 | |
| map.cpp:278:7:278:8 | ref arg m2 | map.cpp:336:7:336:8 | m2 | |
| map.cpp:278:7:278:8 | ref arg m2 | map.cpp:438:1:438:1 | m2 | | | map.cpp:278:7:278:8 | ref arg m2 | map.cpp:438:1:438:1 | m2 | |
| map.cpp:279:7:279:8 | m3 | map.cpp:279:10:279:13 | call to find | TAINT | | map.cpp:279:7:279:8 | m3 | map.cpp:279:10:279:13 | call to find | TAINT |
| map.cpp:279:7:279:8 | ref arg m3 | map.cpp:310:12:310:13 | m3 | | | map.cpp:279:7:279:8 | ref arg m3 | map.cpp:310:12:310:13 | m3 | |
@@ -1539,9 +1521,6 @@
| map.cpp:302:8:302:9 | ref arg i1 | map.cpp:302:8:302:9 | i1 | | | map.cpp:302:8:302:9 | ref arg i1 | map.cpp:302:8:302:9 | i1 | |
| map.cpp:304:12:304:13 | m2 | map.cpp:304:15:304:19 | call to begin | TAINT | | map.cpp:304:12:304:13 | m2 | map.cpp:304:15:304:19 | call to begin | TAINT |
| map.cpp:304:12:304:13 | ref arg m2 | map.cpp:304:30:304:31 | m2 | | | map.cpp:304:12:304:13 | ref arg m2 | map.cpp:304:30:304:31 | m2 | |
| map.cpp:304:12:304:13 | ref arg m2 | map.cpp:334:7:334:8 | m2 | |
| map.cpp:304:12:304:13 | ref arg m2 | map.cpp:335:7:335:8 | m2 | |
| map.cpp:304:12:304:13 | ref arg m2 | map.cpp:336:7:336:8 | m2 | |
| map.cpp:304:12:304:13 | ref arg m2 | map.cpp:438:1:438:1 | m2 | | | map.cpp:304:12:304:13 | ref arg m2 | map.cpp:438:1:438:1 | m2 | |
| map.cpp:304:15:304:19 | call to begin | map.cpp:304:7:304:21 | ... = ... | | | map.cpp:304:15:304:19 | call to begin | map.cpp:304:7:304:21 | ... = ... | |
| map.cpp:304:15:304:19 | call to begin | map.cpp:304:24:304:25 | i2 | | | map.cpp:304:15:304:19 | call to begin | map.cpp:304:24:304:25 | i2 | |
@@ -1551,9 +1530,6 @@
| map.cpp:304:15:304:19 | call to begin | map.cpp:308:8:308:9 | i2 | | | map.cpp:304:15:304:19 | call to begin | map.cpp:308:8:308:9 | i2 | |
| map.cpp:304:30:304:31 | m2 | map.cpp:304:33:304:35 | call to end | TAINT | | map.cpp:304:30:304:31 | m2 | map.cpp:304:33:304:35 | call to end | TAINT |
| map.cpp:304:30:304:31 | ref arg m2 | map.cpp:304:30:304:31 | m2 | | | map.cpp:304:30:304:31 | ref arg m2 | map.cpp:304:30:304:31 | m2 | |
| map.cpp:304:30:304:31 | ref arg m2 | map.cpp:334:7:334:8 | m2 | |
| map.cpp:304:30:304:31 | ref arg m2 | map.cpp:335:7:335:8 | m2 | |
| map.cpp:304:30:304:31 | ref arg m2 | map.cpp:336:7:336:8 | m2 | |
| map.cpp:304:30:304:31 | ref arg m2 | map.cpp:438:1:438:1 | m2 | | | map.cpp:304:30:304:31 | ref arg m2 | map.cpp:438:1:438:1 | m2 | |
| map.cpp:304:40:304:41 | i2 | map.cpp:304:42:304:42 | call to operator++ | | | map.cpp:304:40:304:41 | i2 | map.cpp:304:42:304:42 | call to operator++ | |
| map.cpp:304:40:304:41 | ref arg i2 | map.cpp:304:24:304:25 | i2 | | | map.cpp:304:40:304:41 | ref arg i2 | map.cpp:304:24:304:25 | i2 | |
@@ -1665,41 +1641,56 @@
| map.cpp:329:37:329:39 | call to unordered_map | map.cpp:331:2:331:4 | m14 | | | map.cpp:329:37:329:39 | call to unordered_map | map.cpp:331:2:331:4 | m14 | |
| map.cpp:329:37:329:39 | call to unordered_map | map.cpp:332:2:332:4 | m14 | | | map.cpp:329:37:329:39 | call to unordered_map | map.cpp:332:2:332:4 | m14 | |
| map.cpp:329:37:329:39 | call to unordered_map | map.cpp:333:2:333:4 | m14 | | | map.cpp:329:37:329:39 | call to unordered_map | map.cpp:333:2:333:4 | m14 | |
| map.cpp:329:37:329:39 | call to unordered_map | map.cpp:334:7:334:9 | m14 | |
| map.cpp:329:37:329:39 | call to unordered_map | map.cpp:335:7:335:9 | m14 | |
| map.cpp:329:37:329:39 | call to unordered_map | map.cpp:336:7:336:9 | m14 | |
| map.cpp:329:37:329:39 | call to unordered_map | map.cpp:438:1:438:1 | m14 | | | map.cpp:329:37:329:39 | call to unordered_map | map.cpp:438:1:438:1 | m14 | |
| map.cpp:330:2:330:4 | ref arg m14 | map.cpp:331:2:331:4 | m14 | | | map.cpp:330:2:330:4 | ref arg m14 | map.cpp:331:2:331:4 | m14 | |
| map.cpp:330:2:330:4 | ref arg m14 | map.cpp:332:2:332:4 | m14 | | | map.cpp:330:2:330:4 | ref arg m14 | map.cpp:332:2:332:4 | m14 | |
| map.cpp:330:2:330:4 | ref arg m14 | map.cpp:333:2:333:4 | m14 | | | map.cpp:330:2:330:4 | ref arg m14 | map.cpp:333:2:333:4 | m14 | |
| map.cpp:330:2:330:4 | ref arg m14 | map.cpp:334:7:334:9 | m14 | |
| map.cpp:330:2:330:4 | ref arg m14 | map.cpp:335:7:335:9 | m14 | |
| map.cpp:330:2:330:4 | ref arg m14 | map.cpp:336:7:336:9 | m14 | |
| map.cpp:330:2:330:4 | ref arg m14 | map.cpp:438:1:438:1 | m14 | | | map.cpp:330:2:330:4 | ref arg m14 | map.cpp:438:1:438:1 | m14 | |
| map.cpp:330:13:330:26 | call to make_pair | map.cpp:330:13:330:36 | call to pair | TAINT | | map.cpp:330:13:330:26 | call to make_pair | map.cpp:330:13:330:36 | call to pair | TAINT |
| map.cpp:330:13:330:36 | call to pair | map.cpp:330:2:330:4 | ref arg m14 | TAINT | | map.cpp:330:13:330:36 | call to pair | map.cpp:330:2:330:4 | ref arg m14 | TAINT |
| map.cpp:330:13:330:36 | call to pair | map.cpp:330:6:330:11 | call to insert | TAINT | | map.cpp:330:13:330:36 | call to pair | map.cpp:330:6:330:11 | call to insert | TAINT |
| map.cpp:331:2:331:4 | ref arg m14 | map.cpp:332:2:332:4 | m14 | | | map.cpp:331:2:331:4 | ref arg m14 | map.cpp:332:2:332:4 | m14 | |
| map.cpp:331:2:331:4 | ref arg m14 | map.cpp:333:2:333:4 | m14 | | | map.cpp:331:2:331:4 | ref arg m14 | map.cpp:333:2:333:4 | m14 | |
| map.cpp:331:2:331:4 | ref arg m14 | map.cpp:334:7:334:9 | m14 | |
| map.cpp:331:2:331:4 | ref arg m14 | map.cpp:335:7:335:9 | m14 | |
| map.cpp:331:2:331:4 | ref arg m14 | map.cpp:336:7:336:9 | m14 | |
| map.cpp:331:2:331:4 | ref arg m14 | map.cpp:438:1:438:1 | m14 | | | map.cpp:331:2:331:4 | ref arg m14 | map.cpp:438:1:438:1 | m14 | |
| map.cpp:331:13:331:26 | call to make_pair | map.cpp:331:13:331:41 | call to pair | TAINT | | map.cpp:331:13:331:26 | call to make_pair | map.cpp:331:13:331:41 | call to pair | TAINT |
| map.cpp:331:13:331:41 | call to pair | map.cpp:331:2:331:4 | ref arg m14 | TAINT | | map.cpp:331:13:331:41 | call to pair | map.cpp:331:2:331:4 | ref arg m14 | TAINT |
| map.cpp:331:13:331:41 | call to pair | map.cpp:331:6:331:11 | call to insert | TAINT | | map.cpp:331:13:331:41 | call to pair | map.cpp:331:6:331:11 | call to insert | TAINT |
| map.cpp:332:2:332:4 | ref arg m14 | map.cpp:333:2:333:4 | m14 | | | map.cpp:332:2:332:4 | ref arg m14 | map.cpp:333:2:333:4 | m14 | |
| map.cpp:332:2:332:4 | ref arg m14 | map.cpp:334:7:334:9 | m14 | |
| map.cpp:332:2:332:4 | ref arg m14 | map.cpp:335:7:335:9 | m14 | |
| map.cpp:332:2:332:4 | ref arg m14 | map.cpp:336:7:336:9 | m14 | |
| map.cpp:332:2:332:4 | ref arg m14 | map.cpp:438:1:438:1 | m14 | | | map.cpp:332:2:332:4 | ref arg m14 | map.cpp:438:1:438:1 | m14 | |
| map.cpp:332:13:332:26 | call to make_pair | map.cpp:332:13:332:41 | call to pair | TAINT | | map.cpp:332:13:332:26 | call to make_pair | map.cpp:332:13:332:41 | call to pair | TAINT |
| map.cpp:332:13:332:41 | call to pair | map.cpp:332:2:332:4 | ref arg m14 | TAINT | | map.cpp:332:13:332:41 | call to pair | map.cpp:332:2:332:4 | ref arg m14 | TAINT |
| map.cpp:332:13:332:41 | call to pair | map.cpp:332:6:332:11 | call to insert | TAINT | | map.cpp:332:13:332:41 | call to pair | map.cpp:332:6:332:11 | call to insert | TAINT |
| map.cpp:333:2:333:4 | ref arg m14 | map.cpp:334:7:334:9 | m14 | |
| map.cpp:333:2:333:4 | ref arg m14 | map.cpp:335:7:335:9 | m14 | |
| map.cpp:333:2:333:4 | ref arg m14 | map.cpp:336:7:336:9 | m14 | |
| map.cpp:333:2:333:4 | ref arg m14 | map.cpp:438:1:438:1 | m14 | | | map.cpp:333:2:333:4 | ref arg m14 | map.cpp:438:1:438:1 | m14 | |
| map.cpp:333:13:333:26 | call to make_pair | map.cpp:333:13:333:36 | call to pair | TAINT | | map.cpp:333:13:333:26 | call to make_pair | map.cpp:333:13:333:36 | call to pair | TAINT |
| map.cpp:333:13:333:36 | call to pair | map.cpp:333:2:333:4 | ref arg m14 | TAINT | | map.cpp:333:13:333:36 | call to pair | map.cpp:333:2:333:4 | ref arg m14 | TAINT |
| map.cpp:333:13:333:36 | call to pair | map.cpp:333:6:333:11 | call to insert | TAINT | | map.cpp:333:13:333:36 | call to pair | map.cpp:333:6:333:11 | call to insert | TAINT |
| map.cpp:334:7:334:8 | m2 | map.cpp:334:10:334:20 | call to equal_range | TAINT | | map.cpp:334:7:334:9 | m14 | map.cpp:334:11:334:21 | call to equal_range | TAINT |
| map.cpp:334:7:334:8 | ref arg m2 | map.cpp:335:7:335:8 | m2 | | | map.cpp:334:7:334:9 | ref arg m14 | map.cpp:335:7:335:9 | m14 | |
| map.cpp:334:7:334:8 | ref arg m2 | map.cpp:336:7:336:8 | m2 | | | map.cpp:334:7:334:9 | ref arg m14 | map.cpp:336:7:336:9 | m14 | |
| map.cpp:334:7:334:8 | ref arg m2 | map.cpp:438:1:438:1 | m2 | | | map.cpp:334:7:334:9 | ref arg m14 | map.cpp:438:1:438:1 | m14 | |
| map.cpp:334:27:334:31 | first | map.cpp:334:7:334:31 | call to iterator | | | map.cpp:334:28:334:32 | first | map.cpp:334:7:334:32 | call to iterator | |
| map.cpp:335:7:335:8 | m2 | map.cpp:335:10:335:20 | call to equal_range | TAINT | | map.cpp:335:7:335:9 | m14 | map.cpp:335:11:335:21 | call to equal_range | TAINT |
| map.cpp:335:7:335:8 | ref arg m2 | map.cpp:336:7:336:8 | m2 | | | map.cpp:335:7:335:9 | ref arg m14 | map.cpp:336:7:336:9 | m14 | |
| map.cpp:335:7:335:8 | ref arg m2 | map.cpp:438:1:438:1 | m2 | | | map.cpp:335:7:335:9 | ref arg m14 | map.cpp:438:1:438:1 | m14 | |
| map.cpp:335:27:335:32 | second | map.cpp:335:7:335:32 | call to iterator | | | map.cpp:335:28:335:33 | second | map.cpp:335:7:335:33 | call to iterator | |
| map.cpp:336:7:336:8 | m2 | map.cpp:336:10:336:20 | call to equal_range | TAINT | | map.cpp:336:7:336:9 | m14 | map.cpp:336:11:336:21 | call to equal_range | TAINT |
| map.cpp:336:7:336:8 | ref arg m2 | map.cpp:438:1:438:1 | m2 | | | map.cpp:336:7:336:9 | ref arg m14 | map.cpp:438:1:438:1 | m14 | |
| map.cpp:336:27:336:32 | second | map.cpp:336:7:336:32 | call to iterator | | | map.cpp:336:28:336:33 | second | map.cpp:336:7:336:33 | call to iterator | |
| map.cpp:339:37:339:39 | call to unordered_map | map.cpp:340:2:340:4 | m15 | | | map.cpp:339:37:339:39 | call to unordered_map | map.cpp:340:2:340:4 | m15 | |
| map.cpp:339:37:339:39 | call to unordered_map | map.cpp:342:7:342:9 | m15 | | | map.cpp:339:37:339:39 | call to unordered_map | map.cpp:342:7:342:9 | m15 | |
| map.cpp:339:37:339:39 | call to unordered_map | map.cpp:346:2:346:4 | m15 | | | map.cpp:339:37:339:39 | call to unordered_map | map.cpp:346:2:346:4 | m15 | |

View File

@@ -28,12 +28,12 @@ void test_pair()
b.first = source(); b.first = source();
sink(b.first); // $ ast,ir sink(b.first); // $ ast,ir
sink(b.second); sink(b.second);
sink(b); // $ MISSING: ast,ir sink(b); // $ ir MISSING: ast
c.second = source(); c.second = source();
sink(c.first); sink(c.first);
sink(c.second); // $ ast,ir sink(c.second); // $ ast,ir
sink(c); // $ MISSING: ast,ir sink(c); // $ ir MISSING: ast
std::pair<char *, char *> d("123", "456"); std::pair<char *, char *> d("123", "456");
sink(d.first); sink(d.first);
@@ -43,21 +43,21 @@ void test_pair()
std::pair<char *, char *> e(source(), "456"); std::pair<char *, char *> e(source(), "456");
sink(e.first); // $ ast,ir sink(e.first); // $ ast,ir
sink(e.second); sink(e.second);
sink(e); // $ MISSING: ast,ir sink(e); // $ ir MISSING: ast
std::pair<char *, char *> f("123", source()); std::pair<char *, char *> f("123", source());
sink(f.first); // $ SPURIOUS: ir sink(f.first);
sink(f.second); // $ ast,ir sink(f.second); // $ ast,ir
sink(f); // $ ast,ir sink(f); // $ ast,ir
std::pair<char *, char *> g(f); std::pair<char *, char *> g(f);
sink(g.first); // $ SPURIOUS: ir sink(g.first);
sink(g.second); // $ ast,ir sink(g.second); // $ ast,ir
sink(g); // $ ast,ir sink(g); // $ ast,ir
std::pair<char *, char *> h; std::pair<char *, char *> h;
h = f; h = f;
sink(h.first); // $ SPURIOUS: ir sink(h.first);
sink(h.second); // $ ast,ir sink(h.second); // $ ast,ir
sink(h); // $ ast,ir sink(h); // $ ast,ir
@@ -67,17 +67,17 @@ void test_pair()
std::pair<char *, char *> l("123", "456"); std::pair<char *, char *> l("123", "456");
i.swap(j); i.swap(j);
k.swap(l); k.swap(l);
sink(i.first); // $ SPURIOUS: ir sink(i.first);
sink(i.second); // $ ir MISSING: ast sink(i.second); // $ MISSING: ast,ir
sink(i); // $ ast,ir sink(i); // $ ast,ir
sink(j.first); // $ SPURIOUS: ir sink(j.first);
sink(j.second); // $ SPURIOUS: ast,ir sink(j.second); // $ SPURIOUS: ast,ir
sink(j); // $ SPURIOUS: ast,ir sink(j); // $ SPURIOUS: ast,ir
sink(k.first); // $ SPURIOUS: ir sink(k.first);
sink(k.second); // $ SPURIOUS: ast,ir sink(k.second); // $ SPURIOUS: ast,ir
sink(k); // $ SPURIOUS: ast,ir sink(k); // $ SPURIOUS: ast,ir
sink(l.first); // $ SPURIOUS: ir sink(l.first);
sink(l.second); // $ ir MISSING: ast sink(l.second); // $ MISSING: ast,ir
sink(l); // $ ast,ir sink(l); // $ ast,ir
sink(make_pair("123", "456")); 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").first); // $ ast,ir
sink(make_pair(source(), "456").second); sink(make_pair(source(), "456").second);
sink(make_pair("123", source())); // $ ast,ir 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 sink(make_pair("123", source()).second); // $ ast,ir
std::pair<std::pair<char *, char *>, char *> m; 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; std::map<char *, char *> m1, m2, m3, m4, m5, m6;
sink(m1.insert(std::make_pair("abc", "def")).first); 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(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(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(m6.insert_or_assign(m6.begin(), "abc", source())); // $ ast,ir
sink(m1); sink(m1);
sink(m2); // $ ast,ir sink(m2); // $ ast,ir
@@ -169,9 +169,9 @@ void test_map()
sink(m12.at("abc") = "def"); sink(m12.at("abc") = "def");
sink(m13.at("abc") = source()); // $ ast,ir sink(m13.at("abc") = source()); // $ ast,ir
sink(m10["abc"]); sink(m10["abc"]);
sink(m11["abc"]); // $ ast MISSING: ir sink(m11["abc"]); // $ ast,ir
sink(m12["abc"]); sink(m12["abc"]);
sink(m13["abc"]); // $ ast MISSING: ir sink(m13["abc"]); // $ ast,ir
// ranges // ranges
std::map<char *, char *> m14; std::map<char *, char *> m14;
@@ -179,12 +179,12 @@ void test_map()
m14.insert(std::make_pair("b", source())); m14.insert(std::make_pair("b", source()));
m14.insert(std::make_pair("c", source())); m14.insert(std::make_pair("c", source()));
m14.insert(std::make_pair("d", "d")); m14.insert(std::make_pair("d", "d"));
sink(m2.lower_bound("b")); // $ ast,ir sink(m14.lower_bound("b")); // $ ast,ir=179:33 ast,ir=180:33
sink(m2.upper_bound("b")); // $ ast,ir sink(m14.upper_bound("b")); // $ ast,ir=179:33 ast,ir=180:33
sink(m2.equal_range("b").first); // $ ir sink(m14.equal_range("b").first); // $ MISSING: ast,ir
sink(m2.equal_range("b").second); // $ ir MISSING: ast sink(m14.equal_range("b").second); // $ MISSING: ast,ir
sink(m2.upper_bound("c")); // $ SPURIOUS: ast,ir sink(m14.upper_bound("c")); // $ SPURIOUS: ast,ir=179:33 ast,ir=180:33
sink(m2.equal_range("c").second); // $ SPURIOUS: ir sink(m14.equal_range("c").second);
// swap // swap
std::map<char *, char *> m15, m16, m17, m18; std::map<char *, char *> m15, m16, m17, m18;
@@ -232,7 +232,7 @@ void test_map()
std::map<char *, char *> m24, m25; std::map<char *, char *> m24, m25;
sink(m24.emplace("abc", "def").first); sink(m24.emplace("abc", "def").first);
sink(m24); sink(m24);
sink(m24.emplace("abc", source()).first); // $ SPURIOUS: ir sink(m24.emplace("abc", source()).first);
sink(m24); // $ ast,ir sink(m24); // $ ast,ir
sink(m25.emplace_hint(m25.begin(), "abc", "def")); sink(m25.emplace_hint(m25.begin(), "abc", "def"));
sink(m25); sink(m25);
@@ -243,7 +243,7 @@ void test_map()
std::map<char *, char *> m26, m27; std::map<char *, char *> m26, m27;
sink(m26.try_emplace("abc", "def").first); sink(m26.try_emplace("abc", "def").first);
sink(m26); sink(m26);
sink(m26.try_emplace("abc", source()).first); // $ SPURIOUS: ir sink(m26.try_emplace("abc", source()).first);
sink(m26); // $ ast,ir sink(m26); // $ ast,ir
sink(m27.try_emplace(m27.begin(), "abc", "def")); sink(m27.try_emplace(m27.begin(), "abc", "def"));
sink(m27); sink(m27);
@@ -257,10 +257,10 @@ void test_unordered_map()
std::unordered_map<char *, char *> m1, m2, m3, m4, m5, m6; std::unordered_map<char *, char *> m1, m2, m3, m4, m5, m6;
sink(m1.insert(std::make_pair("abc", "def")).first); 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(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(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(m6.insert_or_assign(m6.begin(), "abc", source())); // $ ast,ir
sink(m1); sink(m1);
sink(m2); // $ ast,ir sink(m2); // $ ast,ir
@@ -321,9 +321,9 @@ void test_unordered_map()
sink(m12.at("abc") = "def"); sink(m12.at("abc") = "def");
sink(m13.at("abc") = source()); // $ ast,ir sink(m13.at("abc") = source()); // $ ast,ir
sink(m10["abc"]); sink(m10["abc"]);
sink(m11["abc"]); // $ ast MISSING: ir sink(m11["abc"]); // $ ast,ir
sink(m12["abc"]); sink(m12["abc"]);
sink(m13["abc"]); // $ ast MISSING: ir sink(m13["abc"]); // $ ast,ir
// ranges // ranges
std::unordered_map<char *, char *> m14; 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("b", source()));
m14.insert(std::make_pair("c", source())); m14.insert(std::make_pair("c", source()));
m14.insert(std::make_pair("d", "d")); m14.insert(std::make_pair("d", "d"));
sink(m2.equal_range("b").first); // $ ir sink(m14.equal_range("b").first);
sink(m2.equal_range("b").second); // $ ir MISSING: ast sink(m14.equal_range("b").second); // $ MISSING: ast,ir
sink(m2.equal_range("c").second); // $ SPURIOUS: ir sink(m14.equal_range("c").second);
// swap // swap
std::unordered_map<char *, char *> m15, m16, m17, m18; std::unordered_map<char *, char *> m15, m16, m17, m18;
@@ -381,7 +381,7 @@ void test_unordered_map()
std::unordered_map<char *, char *> m24, m25; std::unordered_map<char *, char *> m24, m25;
sink(m24.emplace("abc", "def").first); sink(m24.emplace("abc", "def").first);
sink(m24); sink(m24);
sink(m24.emplace("abc", source()).first); // $ SPURIOUS: ir sink(m24.emplace("abc", source()).first);
sink(m24); // $ ast,ir sink(m24); // $ ast,ir
sink(m25.emplace_hint(m25.begin(), "abc", "def")); sink(m25.emplace_hint(m25.begin(), "abc", "def"));
sink(m25); sink(m25);
@@ -393,8 +393,8 @@ void test_unordered_map()
sink(m26.try_emplace("abc", "def").first); sink(m26.try_emplace("abc", "def").first);
sink(m26.try_emplace("abc", "def").second); sink(m26.try_emplace("abc", "def").second);
sink(m26); sink(m26);
sink(m26.try_emplace("abc", source()).first); // $ SPURIOUS: ir sink(m26.try_emplace("abc", source()).first);
sink(m26.try_emplace("abc", source()).second); // $ ir=396:30 SPURIOUS: ir=397:30 MISSING: ast=396:30 sink(m26.try_emplace("abc", source()).second); // $ MISSING: ast,ir=396:30
sink(m26); // $ ast,ir=396:30 SPURIOUS: ast,ir=397:30 sink(m26); // $ ast,ir=396:30 SPURIOUS: ast,ir=397:30
sink(m27.try_emplace(m27.begin(), "abc", "def")); sink(m27.try_emplace(m27.begin(), "abc", "def"));
sink(m27); sink(m27);
@@ -428,7 +428,7 @@ void test_unordered_map()
std::unordered_map<char *, char *> m34, m35; std::unordered_map<char *, char *> m34, m35;
sink(m34.emplace(std::pair<char *, char *>("abc", "def")).first); sink(m34.emplace(std::pair<char *, char *>("abc", "def")).first);
sink(m34); 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); // $ ast,ir
sink(m34.emplace_hint(m34.begin(), "abc", "def")); // $ ast,ir sink(m34.emplace_hint(m34.begin(), "abc", "def")); // $ ast,ir
sink(m35.emplace().first); sink(m35.emplace().first);

View File

@@ -17,7 +17,7 @@ void test_set()
std::set<char *> s1, s2, s3, s4, s5, s6; std::set<char *> s1, s2, s3, s4, s5, s6;
sink(s1.insert("abc").first); 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(s3.insert(s3.begin(), "abc"));
sink(s4.insert(s4.begin(), source())); // $ ast,ir sink(s4.insert(s4.begin(), source())); // $ ast,ir
s5.insert(s1.begin(), s1.end()); s5.insert(s1.begin(), s1.end());
@@ -68,8 +68,8 @@ void test_set()
s11.insert("c"); s11.insert("c");
sink(s11.lower_bound("b")); // $ ast,ir sink(s11.lower_bound("b")); // $ ast,ir
sink(s11.upper_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").first); // $ MISSING: ast,ir
sink(s11.equal_range("b").second); // $ ir MISSING: ast sink(s11.equal_range("b").second); // $ MISSING: ast,ir
// swap // swap
std::set<char *> s12, s13, s14, s15; std::set<char *> s12, s13, s14, s15;
@@ -117,7 +117,7 @@ void test_set()
std::set<char *> s21, s22; std::set<char *> s21, s22;
sink(s21.emplace("abc").first); sink(s21.emplace("abc").first);
sink(s21); sink(s21);
sink(s21.emplace(source()).first); // $ ir MISSING: ast sink(s21.emplace(source()).first); // $ MISSING: ast,ir
sink(s21); // $ ast,ir sink(s21); // $ ast,ir
sink(s22.emplace_hint(s22.begin(), "abc")); sink(s22.emplace_hint(s22.begin(), "abc"));
sink(s22); sink(s22);
@@ -131,7 +131,7 @@ void test_unordered_set()
std::unordered_set<char *> s1, s2, s3, s4, s5, s6; std::unordered_set<char *> s1, s2, s3, s4, s5, s6;
sink(s1.insert("abc").first); 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(s3.insert(s3.begin(), "abc"));
sink(s4.insert(s4.begin(), source())); // $ ast,ir sink(s4.insert(s4.begin(), source())); // $ ast,ir
s5.insert(s1.begin(), s1.end()); s5.insert(s1.begin(), s1.end());
@@ -180,8 +180,8 @@ void test_unordered_set()
s11.insert("a"); s11.insert("a");
s11.insert(source()); s11.insert(source());
s11.insert("c"); s11.insert("c");
sink(s11.equal_range("b").first); // $ ir MISSING: ast sink(s11.equal_range("b").first); // $ MISSING: ast,ir
sink(s11.equal_range("b").second); // $ ir MISSING: ast sink(s11.equal_range("b").second); // $ MISSING: ast,ir
// swap // swap
std::unordered_set<char *> s12, s13, s14, s15; std::unordered_set<char *> s12, s13, s14, s15;
@@ -229,7 +229,7 @@ void test_unordered_set()
std::unordered_set<char *> s21, s22; std::unordered_set<char *> s21, s22;
sink(s21.emplace("abc").first); sink(s21.emplace("abc").first);
sink(s21); sink(s21);
sink(s21.emplace(source()).first); // $ ir MISSING: ast sink(s21.emplace(source()).first); // $ MISSING: ast,ir
sink(s21); // $ ast,ir sink(s21); // $ ast,ir
sink(s22.emplace_hint(s22.begin(), "abc")); sink(s22.emplace_hint(s22.begin(), "abc"));
sink(s22); sink(s22);

View File

@@ -101,7 +101,7 @@ void taint_x(A* pa) {
void reverse_taint_smart_pointer() { void reverse_taint_smart_pointer() {
std::unique_ptr<A> p = std::unique_ptr<A>(new A); std::unique_ptr<A> p = std::unique_ptr<A>(new A);
taint_x(p.get()); taint_x(p.get());
sink(p->x); // $ ast,ir sink(p->x); // $ ast MISSING: ir
} }
struct C { struct C {

View File

@@ -337,9 +337,9 @@ void test_string_at()
b.at(0) = ns_char::source(); b.at(0) = ns_char::source();
c[0] = a[0]; c[0] = a[0];
sink(a); // $ ast MISSING: ir sink(a); // $ ast,ir
sink(b); // $ ast MISSING: ir sink(b); // $ ast,ir
sink(c); // $ ast MISSING: ir sink(c); // $ ast,ir
} }
void test_string_data_more() void test_string_data_more()
@@ -347,8 +347,8 @@ void test_string_data_more()
std::string str("123"); std::string str("123");
str.data()[1] = ns_char::source(); str.data()[1] = ns_char::source();
sink(str); // $ ast MISSING: ir sink(str); // $ ast,ir
sink(str.data()); // $ ast MISSING: ir sink(str.data()); // $ ast,ir
} }
void test_string_iterators() { void test_string_iterators() {
@@ -540,7 +540,7 @@ void test_string_return_assign() {
sink(b); sink(b);
sink(c); // $ ast,ir sink(c); // $ ast,ir
sink(d); // $ ast,ir sink(d); // $ ast,ir
sink(e); // $ ast MISSING: ir sink(e); // $ ast,ir
sink(f); // $ ast,ir sink(f); // $ ast,ir
} }
@@ -560,7 +560,7 @@ void test_string_return_assign() {
sink(b); sink(b);
sink(c); // $ ast,ir sink(c); // $ ast,ir
sink(d); // $ ast,ir sink(d); // $ ast,ir
sink(e); // $ ast MISSING: ir sink(e); // $ ast,ir
sink(f); // $ SPURIOUS: ast,ir sink(f); // $ SPURIOUS: ast,ir
} }
} }

View File

@@ -36,12 +36,12 @@ void test_stringstream_string(int amount)
sink(ss1); sink(ss1);
sink(ss2); // $ ast,ir sink(ss2); // $ ast,ir
sink(ss3); // $ ast MISSING: ir sink(ss3); // $ ast,ir
sink(ss4); // $ ast,ir sink(ss4); // $ ast,ir
sink(ss5); // $ ast,ir sink(ss5); // $ ast,ir
sink(ss1.str()); sink(ss1.str());
sink(ss2.str()); // $ ast,ir sink(ss2.str()); // $ ast,ir
sink(ss3.str()); // $ ast MISSING: ir sink(ss3.str()); // $ ast,ir
sink(ss4.str()); // $ ast,ir sink(ss4.str()); // $ ast,ir
sink(ss5.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(ss10.put('a').put(ns_char::source()).put('z')); // $ ast,ir
sink(ss8); sink(ss8);
sink(ss9); // $ ast,ir sink(ss9); // $ ast,ir
sink(ss10); // $ ast MISSING: ir sink(ss10); // $ ast,ir
sink(ss11.write("begin", 5)); sink(ss11.write("begin", 5));
sink(ss12.write(source(), 5)); // $ ast,ir sink(ss12.write(source(), 5)); // $ ast,ir
sink(ss13.write("begin", 5).write(source(), amount).write("end", 3)); // $ ast,ir sink(ss13.write("begin", 5).write(source(), amount).write("end", 3)); // $ ast,ir
sink(ss11); sink(ss11);
sink(ss12); // $ ast,ir sink(ss12); // $ ast,ir
sink(ss13); // $ ast MISSING: ir sink(ss13); // $ ast,ir
} }
void test_stringstream_int(int source) void test_stringstream_int(int source)
@@ -264,5 +264,5 @@ void test_chaining()
sink(b2); // $ ast,ir sink(b2); // $ ast,ir
sink(ss2.write("abc", 3).flush().write(source(), 3).flush().write("xyz", 3)); // $ 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
} }

View File

@@ -38,9 +38,9 @@ void do_source()
global10 = zero(source()); global10 = zero(source());
sink(global6); sink(global6);
sink(global7); // $ ast MISSING: ir sink(global7); // $ ast,ir
sink(global8); // $ ast MISSING: ir sink(global8); // $ ast,ir
sink(global9); // $ ast MISSING: ir sink(global9); // $ ast,ir
sink(global10); sink(global10);
} }
@@ -87,11 +87,11 @@ void class_field_test() {
sink(mc1.a); sink(mc1.a);
sink(mc1.b); // $ ast,ir sink(mc1.b); // $ ast,ir
sink(mc1.c); // $ ast,ir sink(mc1.c); // $ ast MISSING: ir
sink(mc1.d); // $ ast,ir sink(mc1.d); // $ ast,ir
sink(mc2.a); sink(mc2.a);
sink(mc2.b); // $ ast,ir sink(mc2.b); // $ ast,ir
sink(mc2.c); // $ ast,ir sink(mc2.c); // $ ast MISSING: ir
sink(mc2.d); sink(mc2.d);
} }
@@ -126,12 +126,12 @@ void pointer_test() {
*p2 = source(); *p2 = source();
sink(*p1); // $ ast,ir sink(*p1); // $ ast MISSING: ir
sink(*p2); // $ ast,ir sink(*p2); // $ ast,ir
sink(*p3); sink(*p3);
p3 = &t1; p3 = &t1;
sink(*p3); // $ ast,ir sink(*p3); // $ ast MISSING: ir
*p3 = 0; *p3 = 0;
sink(*p3); // $ SPURIOUS: ast sink(*p3); // $ SPURIOUS: ast
@@ -233,7 +233,7 @@ void test_lambdas()
sink(a()); // $ ast,ir sink(a()); // $ ast,ir
auto b = [&] { auto b = [&] {
sink(t); // $ ast MISSING: ir sink(t); // $ ast,ir
sink(u); // clean sink(u); // clean
v = source(); // (v is reference captured) v = source(); // (v is reference captured)
}; };
@@ -448,9 +448,9 @@ void test_qualifiers()
sink(b); sink(b);
sink(b.getMember()); sink(b.getMember());
b.member = source(); b.member = source();
sink(b); // $ ir MISSING: ast sink(b); // $ MISSING: ast,ir
sink(b.member); // $ ast,ir sink(b.member); // $ ast,ir
sink(b.getMember()); // $ ir MISSING: ast sink(b.getMember()); // $ MISSING: ast,ir
c = new MyClass2(0); c = new MyClass2(0);
@@ -665,7 +665,7 @@ public:
void test_no_const_member(char* source) { void test_no_const_member(char* source) {
C_no_const_member_function c; C_no_const_member_function c;
memcpy(c.data(), source, 16); memcpy(c.data(), source, 16);
sink(c.data()); // $ ast MISSING: ir sink(c.data()); // $ ast,ir
} }
class C_const_member_function { class C_const_member_function {
@@ -691,6 +691,6 @@ void test_argument_source_field_to_obj() {
argument_source(s.x); argument_source(s.x);
sink(s); // $ SPURIOUS: ast sink(s); // $ SPURIOUS: ast
sink(s.x); // $ ast MISSING: ir sink(s.x); // $ ast,ir
sink(s.y); // clean sink(s.y); // clean
} }

View File

@@ -82,7 +82,7 @@ module IRTest {
TestAllocationConfig() { this = "TestAllocationConfig" } TestAllocationConfig() { this = "TestAllocationConfig" }
override predicate isSource(DataFlow::Node source) { override predicate isSource(DataFlow::Node source) {
source.(DataFlow::ExprNode).getConvertedExpr().(FunctionCall).getTarget().getName() = "source" source.asConvertedExpr().(FunctionCall).getTarget().getName() = "source"
or or
source.asParameter().getName().matches("source%") source.asParameter().getName().matches("source%")
or or
@@ -95,11 +95,11 @@ module IRTest {
override predicate isSink(DataFlow::Node sink) { override predicate isSink(DataFlow::Node sink) {
exists(FunctionCall call | exists(FunctionCall call |
call.getTarget().getName() = "sink" and call.getTarget().getName() = "sink" and
sink.(DataFlow::ExprNode).getConvertedExpr() = call.getAnArgument() sink.asConvertedExpr() = call.getAnArgument()
or or
call.getTarget().getName() = "sink" and call.getTarget().getName() = "sink" and
sink.asExpr() = call.getAnArgument() and sink.asExpr() = call.getAnArgument() and
sink.(DataFlow::ExprNode).getConvertedExpr() instanceof ReferenceDereferenceExpr sink.asConvertedExpr() instanceof ReferenceDereferenceExpr
) )
or or
exists(ReadSideEffectInstruction read | exists(ReadSideEffectInstruction read |

View File

@@ -49,22 +49,22 @@ void test_element_taint(int x) {
sink(v1.back()); sink(v1.back());
v2[0] = source(); v2[0] = source();
sink(v2); // $ ast MISSING: ir sink(v2); // $ ast,ir
sink(v2[0]); // $ ast MISSING: ir sink(v2[0]); // $ ast,ir
sink(v2[1]); // $ SPURIOUS: ast sink(v2[1]); // $ SPURIOUS: ast,ir
sink(v2[x]); // $ ast MISSING: ir sink(v2[x]); // $ ast,ir
v3 = v2; v3 = v2;
sink(v3); // $ ast MISSING: ir sink(v3); // $ ast,ir
sink(v3[0]); // $ ast MISSING: ir sink(v3[0]); // $ ast,ir
sink(v3[1]); // $ SPURIOUS: ast sink(v3[1]); // $ SPURIOUS: ast,ir
sink(v3[x]); // $ ast MISSING: ir sink(v3[x]); // $ ast,ir
v4[x] = source(); v4[x] = source();
sink(v4); // $ ast MISSING: ir sink(v4); // $ ast,ir
sink(v4[0]); // $ ast MISSING: ir sink(v4[0]); // $ ast,ir
sink(v4[1]); // $ ast MISSING: ir sink(v4[1]); // $ ast,ir
sink(v4[x]); // $ ast MISSING: ir sink(v4[x]); // $ ast,ir
v5.push_back(source()); v5.push_back(source());
sink(v5); // $ ast,ir sink(v5); // $ ast,ir
@@ -72,8 +72,8 @@ void test_element_taint(int x) {
sink(v5.back()); // $ ast,ir sink(v5.back()); // $ ast,ir
v6.data()[2] = source(); v6.data()[2] = source();
sink(v6); // $ ast MISSING: ir sink(v6); // $ ast,ir
sink(v6.data()[2]); // $ ast MISSING: ir sink(v6.data()[2]); // $ ast,ir
{ {
@@ -94,10 +94,10 @@ void test_element_taint(int x) {
sink(v8.back()); // $ MISSING: ast,ir sink(v8.back()); // $ MISSING: ast,ir
v9.at(x) = source(); v9.at(x) = source();
sink(v9); // $ ast MISSING: ir sink(v9); // $ ast,ir
sink(v9.at(0)); // $ ast MISSING: ir sink(v9.at(0)); // $ ast,ir
sink(v9.at(1)); // $ ast MISSING: ir sink(v9.at(1)); // $ ast,ir
sink(v9.at(x)); // $ ast MISSING: ir sink(v9.at(x)); // $ ast,ir
} }
void test_vector_swap() { void test_vector_swap() {
@@ -168,7 +168,7 @@ void test_nested_vectors()
bb[0].push_back(0); bb[0].push_back(0);
sink(bb[0][0]); sink(bb[0][0]);
bb[0][0] = source(); 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); cc[0].push_back(0);
sink(cc[0][0]); sink(cc[0][0]);
cc[0][0] = source(); 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].a);
sink(dd[0].b); sink(dd[0].b);
dd[0].a = source(); dd[0].a = source();
sink(dd[0].a); // $ MISSING: ast,ir sink(dd[0].a); // $ ir MISSING: ast
sink(dd[0].b); sink(dd[0].b);
} }
@@ -198,7 +198,7 @@ void test_nested_vectors()
ee.vs.push_back(0); ee.vs.push_back(0);
sink(ee.vs[0]); sink(ee.vs[0]);
ee.vs[0] = source(); 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); ff.push_back(mvc);
sink(ff[0].vs[0]); sink(ff[0].vs[0]);
ff[0].vs[0] = source(); 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 sink(v1.data()[2]); // $ ast,ir
*(v2.data()) = ns_int::source(); *(v2.data()) = ns_int::source();
sink(v2); // $ ast MISSING: ir sink(v2); // $ ast,ir
sink(v2.data()); // $ ast MISSING: ir sink(v2.data()); // $ ast,ir
sink(v2.data()[2]); // $ ast MISSING: ir sink(v2.data()[2]); // $ ast,ir
} }
void sink(std::vector<int>::iterator); void sink(std::vector<int>::iterator);
@@ -470,7 +470,7 @@ void test_vector_memcpy()
sink(v); sink(v);
memcpy(&v[i], &s, sizeof(int)); 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); sink(cs);
memcpy(&cs[offs + 1], src.c_str(), len); memcpy(&cs[offs + 1], src.c_str(), len);
sink(src); // $ ast,ir sink(src); // $ ast,ir
sink(cs); // $ ast MISSING: ir sink(cs); // $ ast,ir
} }
} }

View File

@@ -1,9 +1,11 @@
edges 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 | (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 |
| 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 | ... + ... | 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 | (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 |
| 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 | | 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 subpaths
nodes 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 | (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 | 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 |
| 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 #select

View File

@@ -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 | (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 |
| 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 |
| 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 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 | (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 | 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 |
| 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 #select

View File

@@ -1,16 +1,16 @@
edges 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: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: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:12:51:20 | call to badSource | tests.cpp:53:16:53:19 | data indirection |
| tests.cpp:51:22:51:25 | badSource output argument | tests.cpp:53:16:53:19 | data indirection |
nodes 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: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: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:38:39:38:49 | environment indirection | semmle.label | environment indirection |
| tests.cpp:42:5:42:16 | Phi | semmle.label | Phi | | tests.cpp:51:12:51:20 | call to badSource | semmle.label | call to badSource |
| tests.cpp:51:22:51:25 | badSource output argument | semmle.label | badSource output argument |
| tests.cpp:53:16:53:19 | data indirection | semmle.label | data indirection | | tests.cpp:53:16:53:19 | data indirection | semmle.label | data indirection |
subpaths subpaths
#select #select

View File

@@ -31,6 +31,8 @@ edges
| tests.c:29:28:29:31 | argv | tests.c:33:21:33:29 | buffer100 indirection | | 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 |
| 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: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 |
| tests.c:31:15:31:23 | buffer100 | tests.c:31:15:31:23 | buffer100 indirection | | 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 | | tests.c:31:15:31:23 | buffer100 | tests.c:33:21:33:29 | buffer100 |

View File

@@ -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_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 | (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 |
| 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 | ... + ... | 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 | (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 |
| 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_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 | (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 |
| 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 |
| 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 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 | (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 | 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_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 | | 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 | (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 | 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 |
| 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 #select

View File

@@ -1,5 +1,5 @@
edges 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 | (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 | | 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 |
| 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: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 | (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 | | 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: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: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 | (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 | | 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 |
| 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: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 | (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 | * ... | | 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: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: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: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 *)... |
| 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 |
| 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: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 | 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 | | 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: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: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 | 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 | (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 |
| 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: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 | | 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: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 | (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 | ... ++ |
| 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: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 | -- ... | | 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: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:117:15:117:16 | printWrapper output argument | argvLocal.c:136:17:136:18 | i4 |
| argvLocal.c:122:2:122:13 | i4 | 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: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 | 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 | (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 | ... ++ |
| 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: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 | -- ... | | 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: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 | (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 | | 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: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 | 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 | | 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 | ... + ... |
| 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: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: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 | 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 *)... | | 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: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 | | argvLocal.c:170:15:170:26 | i10 indirection | argvLocal.c:9:25:9:31 | *correct |
subpaths 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: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: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: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: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: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 | *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 | ReturnIndirection | 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 | ReturnIndirection | 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 |
nodes 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:9:25:9:31 | correct | semmle.label | correct |
| 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: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 *)... | | 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 | 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 | 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: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 *)... | | 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 | 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 | 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 | (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 | * ... | | 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 | 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: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 | 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 | | 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 | 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: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 | | 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 | 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: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 | 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 | | 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 | ... + ... | semmle.label | ... + ... |
| argvLocal.c:132:15:132:20 | ... + ... indirection | semmle.label | ... + ... indirection | | argvLocal.c:132:15:132:20 | ... + ... indirection | semmle.label | ... + ... indirection |
| 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 | (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 | ... ++ | semmle.label | ... ++ |
| argvLocal.c:135:9:135:12 | ... ++ indirection | semmle.label | ... ++ indirection | | argvLocal.c:135:9:135:12 | ... ++ indirection | semmle.label | ... ++ indirection |
| 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 | -- ... | | 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 | -- ... | 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: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 | (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 | | argvLocal.c:144:9:144:10 | i7 | semmle.label | i7 |

View File

@@ -1,4 +1,10 @@
edges 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 | (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 |
| funcsLocal.c:16:8:16:9 | fread output argument | funcsLocal.c:17:9:17:10 | i1 indirection | | 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 | (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 |
| funcsLocal.c:41:18:41:20 | i61 | funcsLocal.c:42:9:42:10 | i6 indirection | | 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 subpaths
nodes 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 | fread output argument | semmle.label | fread output argument |
| funcsLocal.c:16:8:16:9 | i1 | semmle.label | i1 | | funcsLocal.c:16:8:16:9 | i1 | semmle.label | i1 |
| funcsLocal.c:17:9:17:10 | (const char *)... | semmle.label | (const char *)... | | 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 | 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: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 | (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 | | 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: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: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: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 | | 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 |

View File

@@ -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: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: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 |
| 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: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: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: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: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: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: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: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: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 |
| 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 | | 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: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: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: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 *)... | | 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 | | 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: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 | (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 |
| globalVars.c:50:9:50:13 | copy2 | globalVars.c:50:9:50:13 | copy2 indirection | | globalVars.c:50:9:50:13 | copy2 | globalVars.c:50:9:50:13 | copy2 indirection |
subpaths 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 nodes
| globalVars.c:8:7:8:10 | copy | semmle.label | copy | | globalVars.c:8:7:8:10 | copy | semmle.label | copy |
| globalVars.c:9:7:9:11 | copy2 | semmle.label | copy2 | | 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:12:2:12:15 | Store | semmle.label | Store |
| globalVars.c:15:21:15:23 | val | semmle.label | val | | globalVars.c:15:21:15:23 | val | semmle.label | val |
| globalVars.c:16:2:16:12 | Store | semmle.label | Store | | 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: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 |
| 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 | 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 | 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:2:35:9 | copy | semmle.label | copy |
| globalVars.c:35:11:35:14 | 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 *)... | | 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 | 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 | 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 | (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 | | globalVars.c:50:9:50:13 | copy2 | semmle.label | copy2 |

View File

@@ -86,13 +86,13 @@ int main(int argc, char **argv) {
i3 = argv[1]; i3 = argv[1];
printf(i3); 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; char *i4;
if (varOne) if (varOne)
i4 = argv[1]; i4 = argv[1];
printf(i4); 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; char *i5;
if (!varZero) if (!varZero)
i5 = argv[1]; i5 = argv[1];

View File

@@ -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 |
| 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: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 | (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 | | 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 | 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: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: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 *)... | | 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: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: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: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: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: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 | | 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 |

View File

@@ -6,25 +6,24 @@ edges
| test.c:75:13:75:19 | call to rand | test.c:77:9:77:9 | r | | 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: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: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: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: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: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: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.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: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:8:9:8:12 | Store | | test.cpp:8:9:8:12 | call to rand | test.cpp:6:5:6:12 | ReturnValue |
| test.cpp:13:2:13:15 | Chi [[]] | test.cpp:30:13:30:14 | get_rand2 output argument [[]] | | test.cpp:13:2:13:6 | * ... [post update] | test.cpp:30:3:30:11 | & ... [post update] |
| test.cpp:13:10:13:13 | call to rand | test.cpp:13:2:13:15 | Chi [[]] | | test.cpp:13:3:13:6 | dest [post update] | test.cpp:30:3:30:11 | & ... [post update] |
| test.cpp:18:2:18:14 | Chi [[]] | test.cpp:36:13:36:13 | get_rand3 output argument [[]] | | test.cpp:13:10:13:13 | call to rand | test.cpp:13:2:13:6 | * ... [post update] |
| test.cpp:18:9:18:12 | call to rand | test.cpp:18:2:18:14 | Chi [[]] | | 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: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:3:30:11 | & ... [post update] | 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:3:36:11 | r [post update] | test.cpp:37:7:37:7 | r |
| 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:86:10:86:13 | call to rand | test.cpp:90:10:90:10 | x | | 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: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 | | 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: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:81:23:81:26 | call to rand | semmle.label | call to rand |
| test.c:83:9:83:9 | r | semmle.label | r | | 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:125:13:125:16 | call to rand | semmle.label | call to rand |
| test.c:127:9:127:9 | r | semmle.label | r | | test.c:127:9:127:9 | r | semmle.label | r |
| test.c:131:13:131:16 | call to rand | semmle.label | call to rand | | 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:25 | call to rand | semmle.label | call to rand |
| test.c:155:22:155:27 | (unsigned int)... | semmle.label | (unsigned int)... | | test.c:155:22:155:27 | (unsigned int)... | semmle.label | (unsigned int)... |
| test.c:157:9:157:9 | r | semmle.label | r | | 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: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: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: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: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:25:7:25:7 | r | semmle.label | r |
| test.cpp:30:13:30:14 | Chi | semmle.label | Chi | | test.cpp:30:3:30:11 | & ... [post update] | semmle.label | & ... [post update] |
| test.cpp:30:13:30:14 | get_rand2 output argument [[]] | semmle.label | get_rand2 output argument [[]] |
| test.cpp:31:7:31:7 | r | semmle.label | r | | test.cpp:31:7:31:7 | r | semmle.label | r |
| test.cpp:36:13:36:13 | Chi | semmle.label | Chi | | test.cpp:36:3:36:11 | r [post update] | semmle.label | r [post update] |
| test.cpp:36:13:36:13 | get_rand3 output argument [[]] | semmle.label | get_rand3 output argument [[]] |
| test.cpp:37:7:37:7 | r | semmle.label | r | | 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:86:10:86:13 | call to rand | semmle.label | call to rand |
| test.cpp:90:10:90:10 | x | semmle.label | x | | test.cpp:90:10:90:10 | x | semmle.label | x |
| test.cpp:98:10:98:13 | call to rand | semmle.label | call to rand | | 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: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: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: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: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: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 | | 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: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: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: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: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: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 | | 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 |

View File

@@ -97,7 +97,7 @@ void randomTester() {
int r = 0; int r = 0;
int *ptr_r = &r; int *ptr_r = &r;
*ptr_r = RAND(); *ptr_r = RAND();
r += 100; // BAD r += 100; // BAD [NOT DETECTED]
} }
{ {

View File

@@ -62,7 +62,7 @@ unsigned int test_remainder_subtract_unsigned()
unsigned int x = rand(); unsigned int x = rand();
unsigned int y = x % 100; // y <= x 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; typedef unsigned long size_t;

View File

@@ -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: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: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:209:8:209:23 | ReturnValue | 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: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:211:9:211:42 | Store | | 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:211:9:211:42 | Store | | 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: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 | | 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: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: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: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:9 | (reference dereference) [post update] | test.cpp:289:8:289:15 | size [post update] |
| test.cpp:251:2:251:32 | Chi [[]] | test.cpp:305:18:305:21 | get_size output argument [[]] | | test.cpp:251:2:251:9 | (reference dereference) [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:32 | Chi [[]] | | test.cpp:251:2:251:9 | out_size [post update] | test.cpp:289:8:289:15 | size [post update] |
| test.cpp:251:18:251:31 | (const char *)... | test.cpp:251:2:251:32 | Chi [[]] | | 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: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: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:8:289:15 | size [post update] | test.cpp:291:11:291:28 | ... * ... |
| test.cpp:289:17:289:20 | Chi | test.cpp:291:11:291:28 | ... * ... | | test.cpp:289:8:289:15 | size [post update] | 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:9:305:16 | size [post update] | test.cpp:308:10:308:27 | ... * ... |
| test.cpp:305:18:305:21 | Chi | test.cpp:308:10:308:27 | ... * ... | | test.cpp:305:9:305:16 | size [post update] | 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 |
subpaths subpaths
nodes nodes
| test.cpp:40:21:40:24 | argv | semmle.label | argv | | 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: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:19 | call to getenv | semmle.label | call to getenv |
| test.cpp:211:14:211:27 | (const char *)... | semmle.label | (const char *)... | | test.cpp:211:14:211:27 | (const char *)... | semmle.label | (const char *)... |
| test.cpp:224:23:224:23 | s | semmle.label | s | | 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: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:245:2:245:9 | local_size | semmle.label | local_size |
| test.cpp:247:2:247:8 | 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:9 | (reference dereference) [post update] | semmle.label | (reference dereference) [post update] |
| test.cpp:251:2:251:32 | ChiPartial | semmle.label | ChiPartial | | 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:23 | call to getenv | semmle.label | call to getenv |
| test.cpp:251:18:251:31 | (const char *)... | semmle.label | (const char *)... | | 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 | | 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: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:8:289:15 | size [post update] | semmle.label | size [post update] |
| test.cpp:289:17:289:20 | get_size output argument [[]] | semmle.label | get_size output argument [[]] |
| 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: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:9:305:16 | size [post update] | semmle.label | size [post update] |
| test.cpp:305:18:305:21 | get_size output argument [[]] | semmle.label | get_size output argument [[]] |
| test.cpp:308:10:308:27 | ... * ... | semmle.label | ... * ... | | test.cpp:308:10:308:27 | ... * ... | semmle.label | ... * ... |
| test.cpp:308:10:308:27 | ... * ... | semmle.label | ... * ... | | test.cpp:308:10:308:27 | ... * ... | semmle.label | ... * ... |
| test.cpp:308:10:308:27 | ... * ... | semmle.label | ... * ... | | test.cpp:308:10:308:27 | ... * ... | semmle.label | ... * ... |

View File

@@ -4,11 +4,11 @@ edges
| test2.cpp:25:22:25:23 | & ... | test2.cpp:27:2:27:11 | v | | 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: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 | | 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:5:5:5:17 | ReturnValue | test5.cpp:17:6:17:18 | call to getTaintedInt |
| test5.cpp:9:7:9:9 | gets output argument | test5.cpp:10:9:10:27 | Store | | test5.cpp:5:5:5:17 | ReturnValue | 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:5:5:5:17 | ReturnValue | test5.cpp:18:6:18:18 | call to getTaintedInt |
| test5.cpp:10:9:10:27 | Store | test5.cpp:17:6:17:18 | call to getTaintedInt | | test5.cpp:9:7:9:9 | buf | test5.cpp:5:5:5:17 | ReturnValue |
| test5.cpp:10:9:10:27 | Store | test5.cpp:18:6:18:18 | call to getTaintedInt | | 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 |
| 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 | | 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 | & ... | semmle.label | & ... |
| test2.cpp:25:22:25:23 | fscanf output argument | semmle.label | fscanf output argument | | test2.cpp:25:22:25:23 | fscanf output argument | semmle.label | fscanf output argument |
| test2.cpp:27:2:27:11 | v | semmle.label | v | | 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 | buf | semmle.label | buf |
| test5.cpp:9:7:9:9 | gets output argument | semmle.label | gets output argument | | 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 | | 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 |

View File

@@ -1,12 +1,8 @@
edges 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: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: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: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: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 subpaths
nodes nodes
| test.cpp:20:29:20:34 | call to getenv | semmle.label | call to getenv | | 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: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: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 #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: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 | ... = ... | ... = ... |

View File

@@ -35,7 +35,7 @@ void processRequest()
adminPrivileges = 0; // OK, since it's a 0 and not a 1 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 = &currentUser; const char** userp = &currentUser;
*userp = userName; *userp = userName;
if (!strcmp(currentUser, "admin")) { if (!strcmp(currentUser, "admin")) {

View File

@@ -141,25 +141,23 @@ private module Liveness {
private import Liveness private import Liveness
/** Holds if `bb1` strictly dominates `bb2`. */ /**
private predicate strictlyDominates(BasicBlock bb1, BasicBlock bb2) { * Holds if `df` is in the dominance frontier of `bb`.
bb1 = getImmediateBasicBlockDominator+(bb2) *
} * This is equivalent to:
*
/** Holds if `bb1` dominates a predecessor of `bb2`. */ * ```ql
private predicate dominatesPredecessor(BasicBlock bb1, BasicBlock bb2) { * bb = getImmediateBasicBlockDominator*(getABasicBlockPredecessor(df)) and
exists(BasicBlock pred | pred = getABasicBlockPredecessor(bb2) | * not bb = getImmediateBasicBlockDominator+(df)
bb1 = pred * ```
or */
strictlyDominates(bb1, pred)
)
}
/** Holds if `df` is in the dominance frontier of `bb`. */
pragma[noinline]
private predicate inDominanceFrontier(BasicBlock bb, BasicBlock df) { private predicate inDominanceFrontier(BasicBlock bb, BasicBlock df) {
dominatesPredecessor(bb, df) and bb = getABasicBlockPredecessor(df) and not bb = getImmediateBasicBlockDominator(df)
not strictlyDominates(bb, df) or
exists(BasicBlock prev | inDominanceFrontier(prev, df) |
bb = getImmediateBasicBlockDominator(prev) and
not bb = getImmediateBasicBlockDominator(df)
)
} }
/** /**

View File

@@ -141,25 +141,23 @@ private module Liveness {
private import Liveness private import Liveness
/** Holds if `bb1` strictly dominates `bb2`. */ /**
private predicate strictlyDominates(BasicBlock bb1, BasicBlock bb2) { * Holds if `df` is in the dominance frontier of `bb`.
bb1 = getImmediateBasicBlockDominator+(bb2) *
} * This is equivalent to:
*
/** Holds if `bb1` dominates a predecessor of `bb2`. */ * ```ql
private predicate dominatesPredecessor(BasicBlock bb1, BasicBlock bb2) { * bb = getImmediateBasicBlockDominator*(getABasicBlockPredecessor(df)) and
exists(BasicBlock pred | pred = getABasicBlockPredecessor(bb2) | * not bb = getImmediateBasicBlockDominator+(df)
bb1 = pred * ```
or */
strictlyDominates(bb1, pred)
)
}
/** Holds if `df` is in the dominance frontier of `bb`. */
pragma[noinline]
private predicate inDominanceFrontier(BasicBlock bb, BasicBlock df) { private predicate inDominanceFrontier(BasicBlock bb, BasicBlock df) {
dominatesPredecessor(bb, df) and bb = getABasicBlockPredecessor(df) and not bb = getImmediateBasicBlockDominator(df)
not strictlyDominates(bb, df) or
exists(BasicBlock prev | inDominanceFrontier(prev, df) |
bb = getImmediateBasicBlockDominator(prev) and
not bb = getImmediateBasicBlockDominator(df)
)
} }
/** /**

View File

@@ -141,25 +141,23 @@ private module Liveness {
private import Liveness private import Liveness
/** Holds if `bb1` strictly dominates `bb2`. */ /**
private predicate strictlyDominates(BasicBlock bb1, BasicBlock bb2) { * Holds if `df` is in the dominance frontier of `bb`.
bb1 = getImmediateBasicBlockDominator+(bb2) *
} * This is equivalent to:
*
/** Holds if `bb1` dominates a predecessor of `bb2`. */ * ```ql
private predicate dominatesPredecessor(BasicBlock bb1, BasicBlock bb2) { * bb = getImmediateBasicBlockDominator*(getABasicBlockPredecessor(df)) and
exists(BasicBlock pred | pred = getABasicBlockPredecessor(bb2) | * not bb = getImmediateBasicBlockDominator+(df)
bb1 = pred * ```
or */
strictlyDominates(bb1, pred)
)
}
/** Holds if `df` is in the dominance frontier of `bb`. */
pragma[noinline]
private predicate inDominanceFrontier(BasicBlock bb, BasicBlock df) { private predicate inDominanceFrontier(BasicBlock bb, BasicBlock df) {
dominatesPredecessor(bb, df) and bb = getABasicBlockPredecessor(df) and not bb = getImmediateBasicBlockDominator(df)
not strictlyDominates(bb, df) or
exists(BasicBlock prev | inDominanceFrontier(prev, df) |
bb = getImmediateBasicBlockDominator(prev) and
not bb = getImmediateBasicBlockDominator(df)
)
} }
/** /**

View File

@@ -141,25 +141,23 @@ private module Liveness {
private import Liveness private import Liveness
/** Holds if `bb1` strictly dominates `bb2`. */ /**
private predicate strictlyDominates(BasicBlock bb1, BasicBlock bb2) { * Holds if `df` is in the dominance frontier of `bb`.
bb1 = getImmediateBasicBlockDominator+(bb2) *
} * This is equivalent to:
*
/** Holds if `bb1` dominates a predecessor of `bb2`. */ * ```ql
private predicate dominatesPredecessor(BasicBlock bb1, BasicBlock bb2) { * bb = getImmediateBasicBlockDominator*(getABasicBlockPredecessor(df)) and
exists(BasicBlock pred | pred = getABasicBlockPredecessor(bb2) | * not bb = getImmediateBasicBlockDominator+(df)
bb1 = pred * ```
or */
strictlyDominates(bb1, pred)
)
}
/** Holds if `df` is in the dominance frontier of `bb`. */
pragma[noinline]
private predicate inDominanceFrontier(BasicBlock bb, BasicBlock df) { private predicate inDominanceFrontier(BasicBlock bb, BasicBlock df) {
dominatesPredecessor(bb, df) and bb = getABasicBlockPredecessor(df) and not bb = getImmediateBasicBlockDominator(df)
not strictlyDominates(bb, df) or
exists(BasicBlock prev | inDominanceFrontier(prev, df) |
bb = getImmediateBasicBlockDominator(prev) and
not bb = getImmediateBasicBlockDominator(df)
)
} }
/** /**

View File

@@ -3,7 +3,7 @@
* @description This reports the external APIs that are used with untrusted data, along with how * @description This reports the external APIs that are used with untrusted data, along with how
* frequently the API is called, and how many unique sources of untrusted data flow * frequently the API is called, and how many unique sources of untrusted data flow
* to it. * to it.
* @id csharp/count-untrusted-data-external-api * @id cs/count-untrusted-data-external-api
* @kind table * @kind table
* @tags security external/cwe/cwe-20 * @tags security external/cwe/cwe-20
*/ */

View File

@@ -1,7 +1,7 @@
/** /**
* @name Untrusted data passed to external API * @name Untrusted data passed to external API
* @description Data provided remotely is used in this external API without sanitization, which could be a security risk. * @description Data provided remotely is used in this external API without sanitization, which could be a security risk.
* @id csharp/untrusted-data-to-external-api * @id cs/untrusted-data-to-external-api
* @kind path-problem * @kind path-problem
* @precision low * @precision low
* @problem.severity error * @problem.severity error

View File

@@ -2,7 +2,7 @@
* @name IR Consistency Check * @name IR Consistency Check
* @description Performs consistency checks on the Intermediate Representation. This query should have no results. * @description Performs consistency checks on the Intermediate Representation. This query should have no results.
* @kind table * @kind table
* @id csharp/ir-consistency-check * @id cs/ir-consistency-check
*/ */
import implementation.raw.IRConsistency import implementation.raw.IRConsistency

View File

@@ -1,7 +1,7 @@
/** /**
* @name Print IR * @name Print IR
* @description Outputs a representation of the IR graph * @description Outputs a representation of the IR graph
* @id csharp/print-ir * @id cs/print-ir
* @kind graph * @kind graph
*/ */

View File

@@ -2,7 +2,7 @@
* @name Raw IR Consistency Check * @name Raw IR Consistency Check
* @description Performs consistency checks on the Intermediate Representation. This query should have no results. * @description Performs consistency checks on the Intermediate Representation. This query should have no results.
* @kind table * @kind table
* @id csharp/raw-ir-consistency-check * @id cs/raw-ir-consistency-check
*/ */
import IRConsistency import IRConsistency

View File

@@ -762,11 +762,21 @@ class ReturnValueInstruction extends ReturnInstruction {
*/ */
final LoadOperand getReturnValueOperand() { result = this.getAnOperand() } 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 * Gets the instruction whose result provides the value being returned by the function, if an
* exact definition is available. * exact definition is available.
*/ */
final Instruction getReturnValue() { result = this.getReturnValueOperand().getDef() } 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() }
} }
/** /**

View File

@@ -1,7 +1,7 @@
/** /**
* @name Print Raw IR * @name Print Raw IR
* @description Outputs a representation of the Raw IR graph * @description Outputs a representation of the Raw IR graph
* @id csharp/print-raw-ir * @id cs/print-raw-ir
* @kind graph * @kind graph
*/ */

View File

@@ -762,11 +762,21 @@ class ReturnValueInstruction extends ReturnInstruction {
*/ */
final LoadOperand getReturnValueOperand() { result = this.getAnOperand() } 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 * Gets the instruction whose result provides the value being returned by the function, if an
* exact definition is available. * exact definition is available.
*/ */
final Instruction getReturnValue() { result = this.getReturnValueOperand().getDef() } 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() }
} }
/** /**

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