mirror of
https://github.com/github/codeql.git
synced 2026-04-30 11:15:13 +02:00
Merge branch 'main' into map
This commit is contained in:
@@ -39,7 +39,7 @@ access all the system's passwords.</p>
|
||||
|
||||
<li>
|
||||
OWASP:
|
||||
<a href="https://www.owasp.org/index.php/Path_traversal">Path Traversal</a>.
|
||||
<a href="https://owasp.org/www-community/attacks/Path_Traversal">Path Traversal</a>.
|
||||
</li>
|
||||
|
||||
</references>
|
||||
|
||||
@@ -0,0 +1,65 @@
|
||||
/**
|
||||
* EXPERIMENTAL: The API of this module may change without notice.
|
||||
*
|
||||
* Provides a class for modeling `RangeSsaDefinition`s with a restricted range.
|
||||
*/
|
||||
|
||||
import cpp
|
||||
import semmle.code.cpp.rangeanalysis.SimpleRangeAnalysis
|
||||
|
||||
/**
|
||||
* EXPERIMENTAL: The API of this class may change without notice.
|
||||
*
|
||||
* An SSA definition for which a range can be deduced. As with
|
||||
* `RangeSsaDefinition` and `SsaDefinition`, instances of this class
|
||||
* correspond to points in the program where one or more variables are defined
|
||||
* or have their value constrained in some way.
|
||||
*
|
||||
* Extend this class to add functionality to the range analysis library.
|
||||
*/
|
||||
abstract class SimpleRangeAnalysisDefinition extends RangeSsaDefinition {
|
||||
/**
|
||||
* Holds if this `SimpleRangeAnalysisDefinition` adds range information for
|
||||
* `v`. Because a `SimpleRangeAnalysisDefinition` is just a point in the
|
||||
* program, it's possible that more than one variable might be defined at
|
||||
* this point. This predicate clarifies which variable(s) should get range
|
||||
* information from `this`.
|
||||
*
|
||||
* This predicate **must be overridden** to hold for any `v` that can show
|
||||
* up in the other members of `SimpleRangeAnalysisDefinition`. Conversely,
|
||||
* the other members **must be accurate** for any `v` in this predicate.
|
||||
*/
|
||||
abstract predicate hasRangeInformationFor(StackVariable v);
|
||||
|
||||
/**
|
||||
* Holds if `(this, v)` depends on the range of the unconverted expression
|
||||
* `e`. This information is used to inform the range analysis about cyclic
|
||||
* dependencies. Without this information, range analysis might work for
|
||||
* simple cases but will go into infinite loops on complex code.
|
||||
*
|
||||
* For example, when modelling the definition by reference in a call to an
|
||||
* overloaded `operator=`, written as `v = e`, the definition of `(this, v)`
|
||||
* depends on `e`.
|
||||
*/
|
||||
abstract predicate dependsOnExpr(StackVariable v, Expr e);
|
||||
|
||||
/**
|
||||
* Gets the lower bound of the variable `v` defined by this definition.
|
||||
*
|
||||
* Implementations of this predicate should use
|
||||
* `getFullyConvertedLowerBounds` and `getFullyConvertedUpperBounds` for
|
||||
* recursive calls to get the bounds of their dependencies.
|
||||
*/
|
||||
abstract float getLowerBounds(StackVariable v);
|
||||
|
||||
/**
|
||||
* Gets the upper bound of the variable `v` defined by this definition.
|
||||
*
|
||||
* Implementations of this predicate should use
|
||||
* `getFullyConvertedLowerBounds` and `getFullyConvertedUpperBounds` for
|
||||
* recursive calls to get the bounds of their dependencies.
|
||||
*/
|
||||
abstract float getUpperBounds(StackVariable v);
|
||||
}
|
||||
|
||||
import SimpleRangeAnalysisInternal
|
||||
@@ -0,0 +1,4 @@
|
||||
import semmle.code.cpp.rangeanalysis.SimpleRangeAnalysis
|
||||
//
|
||||
// Import each extension we want to enable
|
||||
import extensions.SubtractSelf
|
||||
@@ -0,0 +1,15 @@
|
||||
import experimental.semmle.code.cpp.models.interfaces.SimpleRangeAnalysisExpr
|
||||
|
||||
private class SelfSub extends SimpleRangeAnalysisExpr, SubExpr {
|
||||
SelfSub() {
|
||||
// Match `x - x` but not `myInt - (unsigned char)myInt`.
|
||||
getLeftOperand().getExplicitlyConverted().(VariableAccess).getTarget() =
|
||||
getRightOperand().getExplicitlyConverted().(VariableAccess).getTarget()
|
||||
}
|
||||
|
||||
override float getLowerBounds() { result = 0 }
|
||||
|
||||
override float getUpperBounds() { result = 0 }
|
||||
|
||||
override predicate dependsOnChild(Expr child) { none() }
|
||||
}
|
||||
@@ -144,6 +144,11 @@ class Variable extends Declaration, @variable {
|
||||
*/
|
||||
predicate isConstexpr() { this.hasSpecifier("is_constexpr") }
|
||||
|
||||
/**
|
||||
* Holds if this variable is declared `constinit`.
|
||||
*/
|
||||
predicate isConstinit() { this.hasSpecifier("declared_constinit") }
|
||||
|
||||
/**
|
||||
* Holds if this variable is `thread_local`.
|
||||
*/
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
private import cpp
|
||||
private import DataFlowUtil
|
||||
private import DataFlowDispatch
|
||||
private import FlowVar
|
||||
|
||||
/** Gets the instance argument of a non-static call. */
|
||||
private Node getInstanceArgument(Call call) {
|
||||
@@ -106,7 +107,7 @@ private class ExprOutNode extends OutNode, ExprNode {
|
||||
override DataFlowCall getCall() { result = this.getExpr() }
|
||||
}
|
||||
|
||||
private class RefOutNode extends OutNode, DefinitionByReferenceNode {
|
||||
private class RefOutNode extends OutNode, DefinitionByReferenceOrIteratorNode {
|
||||
/** Gets the underlying call. */
|
||||
override DataFlowCall getCall() { result = this.getArgument().getParent() }
|
||||
}
|
||||
@@ -120,7 +121,7 @@ OutNode getAnOutNode(DataFlowCall call, ReturnKind kind) {
|
||||
kind = TNormalReturnKind()
|
||||
or
|
||||
exists(int i |
|
||||
result.asDefiningArgument() = call.getArgument(i) and
|
||||
result.(DefinitionByReferenceOrIteratorNode).getArgument() = call.getArgument(i) and
|
||||
kind = TRefReturnKind(i)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -183,28 +183,29 @@ class ImplicitParameterNode extends ParameterNode, TInstanceParameterNode {
|
||||
}
|
||||
|
||||
/**
|
||||
* A node that represents the value of a variable after a function call that
|
||||
* may have changed the variable because it's passed by reference.
|
||||
* INTERNAL: do not use.
|
||||
*
|
||||
* A typical example would be a call `f(&x)`. Firstly, there will be flow into
|
||||
* `x` from previous definitions of `x`. Secondly, there will be a
|
||||
* `DefinitionByReferenceNode` to represent the value of `x` after the call has
|
||||
* returned. This node will have its `getArgument()` equal to `&x`.
|
||||
* A node that represents the value of a variable after a function call that
|
||||
* may have changed the variable because it's passed by reference or because an
|
||||
* iterator for it was passed by value or by reference.
|
||||
*/
|
||||
class DefinitionByReferenceNode extends PartialDefinitionNode {
|
||||
class DefinitionByReferenceOrIteratorNode extends PartialDefinitionNode {
|
||||
Expr inner;
|
||||
Expr argument;
|
||||
|
||||
DefinitionByReferenceNode() {
|
||||
this.getPartialDefinition().(DefinitionByReference).definesExpressions(inner, argument)
|
||||
DefinitionByReferenceOrIteratorNode() {
|
||||
this.getPartialDefinition().definesExpressions(inner, argument) and
|
||||
(
|
||||
this.getPartialDefinition() instanceof DefinitionByReference
|
||||
or
|
||||
this.getPartialDefinition() instanceof DefinitionByIterator
|
||||
)
|
||||
}
|
||||
|
||||
override Function getFunction() { result = inner.getEnclosingFunction() }
|
||||
|
||||
override Type getType() { result = inner.getType() }
|
||||
|
||||
override string toString() { result = "ref arg " + argument.toString() }
|
||||
|
||||
override Location getLocation() { result = argument.getLocation() }
|
||||
|
||||
override ExprNode getPreUpdateNode() { result.getExpr() = argument }
|
||||
@@ -221,6 +222,21 @@ class DefinitionByReferenceNode extends PartialDefinitionNode {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A node that represents the value of a variable after a function call that
|
||||
* may have changed the variable because it's passed by reference.
|
||||
*
|
||||
* A typical example would be a call `f(&x)`. Firstly, there will be flow into
|
||||
* `x` from previous definitions of `x`. Secondly, there will be a
|
||||
* `DefinitionByReferenceNode` to represent the value of `x` after the call has
|
||||
* returned. This node will have its `getArgument()` equal to `&x`.
|
||||
*/
|
||||
class DefinitionByReferenceNode extends DefinitionByReferenceOrIteratorNode {
|
||||
override VariablePartialDefinition pd;
|
||||
|
||||
override string toString() { result = "ref arg " + argument.toString() }
|
||||
}
|
||||
|
||||
/**
|
||||
* The value of an uninitialized local variable, viewed as a node in a data
|
||||
* flow graph.
|
||||
@@ -284,13 +300,11 @@ abstract class PostUpdateNode extends Node {
|
||||
override Location getLocation() { result = getPreUpdateNode().getLocation() }
|
||||
}
|
||||
|
||||
private class PartialDefinitionNode extends PostUpdateNode, TPartialDefinitionNode {
|
||||
abstract private class PartialDefinitionNode extends PostUpdateNode, TPartialDefinitionNode {
|
||||
PartialDefinition pd;
|
||||
|
||||
PartialDefinitionNode() { this = TPartialDefinitionNode(pd) }
|
||||
|
||||
override Node getPreUpdateNode() { pd.definesExpressions(_, result.asExpr()) }
|
||||
|
||||
override Location getLocation() { result = pd.getActualLocation() }
|
||||
|
||||
PartialDefinition getPartialDefinition() { result = pd }
|
||||
@@ -298,6 +312,24 @@ private class PartialDefinitionNode extends PostUpdateNode, TPartialDefinitionNo
|
||||
override string toString() { result = getPreUpdateNode().toString() + " [post update]" }
|
||||
}
|
||||
|
||||
private class VariablePartialDefinitionNode extends PartialDefinitionNode {
|
||||
override VariablePartialDefinition pd;
|
||||
|
||||
override Node getPreUpdateNode() { pd.definesExpressions(_, result.asExpr()) }
|
||||
}
|
||||
|
||||
/**
|
||||
* INTERNAL: do not use.
|
||||
*
|
||||
* A synthetic data flow node used for flow into a collection when an iterator
|
||||
* write occurs in a callee.
|
||||
*/
|
||||
class IteratorPartialDefinitionNode extends PartialDefinitionNode {
|
||||
override IteratorPartialDefinition pd;
|
||||
|
||||
override Node getPreUpdateNode() { pd.definesExpressions(_, result.asExpr()) }
|
||||
}
|
||||
|
||||
/**
|
||||
* A post-update node on the `e->f` in `f(&e->f)` (and other forms).
|
||||
*/
|
||||
|
||||
@@ -6,6 +6,7 @@ import cpp
|
||||
private import semmle.code.cpp.controlflow.SSA
|
||||
private import semmle.code.cpp.dataflow.internal.SubBasicBlocks
|
||||
private import semmle.code.cpp.dataflow.internal.AddressFlow
|
||||
private import semmle.code.cpp.models.implementations.Iterator
|
||||
|
||||
/**
|
||||
* A conceptual variable that is assigned only once, like an SSA variable. This
|
||||
@@ -108,21 +109,12 @@ class FlowVar extends TFlowVar {
|
||||
* ```
|
||||
*/
|
||||
private module PartialDefinitions {
|
||||
class PartialDefinition extends Expr {
|
||||
Expr innerDefinedExpr;
|
||||
abstract class PartialDefinition extends Expr {
|
||||
ControlFlowNode node;
|
||||
|
||||
PartialDefinition() {
|
||||
exists(Expr convertedInner |
|
||||
valueToUpdate(convertedInner, this.getFullyConverted(), node) and
|
||||
innerDefinedExpr = convertedInner.getUnconverted() and
|
||||
not this instanceof Conversion
|
||||
)
|
||||
}
|
||||
abstract deprecated predicate partiallyDefines(Variable v);
|
||||
|
||||
deprecated predicate partiallyDefines(Variable v) { innerDefinedExpr = v.getAnAccess() }
|
||||
|
||||
deprecated predicate partiallyDefinesThis(ThisExpr e) { innerDefinedExpr = e }
|
||||
abstract deprecated predicate partiallyDefinesThis(ThisExpr e);
|
||||
|
||||
/**
|
||||
* Gets the subBasicBlock where this `PartialDefinition` is defined.
|
||||
@@ -133,11 +125,9 @@ private module PartialDefinitions {
|
||||
* Holds if this `PartialDefinition` defines variable `v` at control-flow
|
||||
* node `cfn`.
|
||||
*/
|
||||
// does this work with a dispred?
|
||||
pragma[noinline]
|
||||
predicate partiallyDefinesVariableAt(Variable v, ControlFlowNode cfn) {
|
||||
innerDefinedExpr = v.getAnAccess() and
|
||||
cfn = node
|
||||
}
|
||||
abstract predicate partiallyDefinesVariableAt(Variable v, ControlFlowNode cfn);
|
||||
|
||||
/**
|
||||
* Holds if this partial definition may modify `inner` (or what it points
|
||||
@@ -147,10 +137,7 @@ private module PartialDefinitions {
|
||||
* - `inner` = `... .x`, `outer` = `&...`
|
||||
* - `inner` = `a`, `outer` = `*`
|
||||
*/
|
||||
predicate definesExpressions(Expr inner, Expr outer) {
|
||||
inner = innerDefinedExpr and
|
||||
outer = this
|
||||
}
|
||||
abstract predicate definesExpressions(Expr inner, Expr outer);
|
||||
|
||||
/**
|
||||
* Gets the location of this element, adjusted to avoid unknown locations
|
||||
@@ -166,10 +153,107 @@ private module PartialDefinitions {
|
||||
}
|
||||
}
|
||||
|
||||
class IteratorPartialDefinition extends PartialDefinition {
|
||||
Variable collection;
|
||||
Expr innerDefinedExpr;
|
||||
|
||||
IteratorPartialDefinition() {
|
||||
exists(Expr convertedInner |
|
||||
not this instanceof Conversion and
|
||||
valueToUpdate(convertedInner, this.getFullyConverted(), node) and
|
||||
innerDefinedExpr = convertedInner.getUnconverted() and
|
||||
(
|
||||
innerDefinedExpr.(Call).getQualifier() = getAnIteratorAccess(collection)
|
||||
or
|
||||
innerDefinedExpr.(Call).getQualifier() = collection.getAnAccess() and
|
||||
collection instanceof IteratorParameter
|
||||
) and
|
||||
innerDefinedExpr.(Call).getTarget() instanceof IteratorPointerDereferenceMemberOperator
|
||||
)
|
||||
or
|
||||
// iterators passed by value without a copy constructor
|
||||
exists(Call call |
|
||||
call = node and
|
||||
call.getAnArgument() = innerDefinedExpr and
|
||||
innerDefinedExpr = this and
|
||||
this = getAnIteratorAccess(collection) and
|
||||
not call.getTarget() instanceof IteratorPointerDereferenceMemberOperator
|
||||
)
|
||||
or
|
||||
// iterators passed by value with a copy constructor
|
||||
exists(Call call, ConstructorCall copy |
|
||||
copy.getTarget() instanceof CopyConstructor and
|
||||
call = node and
|
||||
call.getAnArgument() = copy and
|
||||
copy.getArgument(0) = getAnIteratorAccess(collection) and
|
||||
innerDefinedExpr = this and
|
||||
this = copy and
|
||||
not call.getTarget() instanceof IteratorPointerDereferenceMemberOperator
|
||||
)
|
||||
}
|
||||
|
||||
deprecated override predicate partiallyDefines(Variable v) { v = collection }
|
||||
|
||||
deprecated override predicate partiallyDefinesThis(ThisExpr e) { none() }
|
||||
|
||||
override predicate definesExpressions(Expr inner, Expr outer) {
|
||||
inner = innerDefinedExpr and
|
||||
outer = this
|
||||
}
|
||||
|
||||
override predicate partiallyDefinesVariableAt(Variable v, ControlFlowNode cfn) {
|
||||
v = collection and
|
||||
cfn = node
|
||||
}
|
||||
}
|
||||
|
||||
class VariablePartialDefinition extends PartialDefinition {
|
||||
Expr innerDefinedExpr;
|
||||
|
||||
VariablePartialDefinition() {
|
||||
not this instanceof Conversion and
|
||||
exists(Expr convertedInner |
|
||||
valueToUpdate(convertedInner, this.getFullyConverted(), node) and
|
||||
innerDefinedExpr = convertedInner.getUnconverted()
|
||||
)
|
||||
}
|
||||
|
||||
deprecated override predicate partiallyDefines(Variable v) {
|
||||
innerDefinedExpr = v.getAnAccess()
|
||||
}
|
||||
|
||||
deprecated override predicate partiallyDefinesThis(ThisExpr e) { innerDefinedExpr = e }
|
||||
|
||||
/**
|
||||
* Holds if this partial definition may modify `inner` (or what it points
|
||||
* to) through `outer`. These expressions will never be `Conversion`s.
|
||||
*
|
||||
* For example, in `f(& (*a).x)`, there are two results:
|
||||
* - `inner` = `... .x`, `outer` = `&...`
|
||||
* - `inner` = `a`, `outer` = `*`
|
||||
*/
|
||||
override predicate definesExpressions(Expr inner, Expr outer) {
|
||||
inner = innerDefinedExpr and
|
||||
outer = this
|
||||
}
|
||||
|
||||
override predicate partiallyDefinesVariableAt(Variable v, ControlFlowNode cfn) {
|
||||
innerDefinedExpr = v.getAnAccess() and
|
||||
cfn = node
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A partial definition that's a definition via an output iterator.
|
||||
*/
|
||||
class DefinitionByIterator extends IteratorPartialDefinition {
|
||||
DefinitionByIterator() { exists(Call c | this = c.getAnArgument() or this = c.getQualifier()) }
|
||||
}
|
||||
|
||||
/**
|
||||
* A partial definition that's a definition by reference.
|
||||
*/
|
||||
class DefinitionByReference extends PartialDefinition {
|
||||
class DefinitionByReference extends VariablePartialDefinition {
|
||||
DefinitionByReference() { exists(Call c | this = c.getAnArgument() or this = c.getQualifier()) }
|
||||
}
|
||||
}
|
||||
@@ -211,7 +295,8 @@ module FlowVar_internal {
|
||||
// The SSA library has a theoretically accurate treatment of reference types,
|
||||
// treating them as immutable, but for data flow it gives better results in
|
||||
// practice to make the variable synonymous with its contents.
|
||||
not v.getUnspecifiedType() instanceof ReferenceType
|
||||
not v.getUnspecifiedType() instanceof ReferenceType and
|
||||
not v instanceof IteratorParameter
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -240,7 +325,7 @@ module FlowVar_internal {
|
||||
(
|
||||
initializer(v, sbb.getANode())
|
||||
or
|
||||
assignmentLikeOperation(sbb, v, _, _)
|
||||
assignmentLikeOperation(sbb, v, _)
|
||||
or
|
||||
exists(PartialDefinition p | p.partiallyDefinesVariableAt(v, sbb))
|
||||
or
|
||||
@@ -359,7 +444,7 @@ module FlowVar_internal {
|
||||
}
|
||||
|
||||
override predicate definedByExpr(Expr e, ControlFlowNode node) {
|
||||
assignmentLikeOperation(node, v, _, e) and
|
||||
assignmentLikeOperation(node, v, e) and
|
||||
node = sbb
|
||||
or
|
||||
// We pick the defining `ControlFlowNode` of an `Initializer` to be its
|
||||
@@ -449,7 +534,7 @@ module FlowVar_internal {
|
||||
pragma[noinline]
|
||||
private Variable getAVariableAssignedInLoop() {
|
||||
exists(BasicBlock bbAssign |
|
||||
assignmentLikeOperation(bbAssign.getANode(), result, _, _) and
|
||||
assignmentLikeOperation(bbAssign.getANode(), result, _) and
|
||||
this.bbInLoop(bbAssign)
|
||||
)
|
||||
}
|
||||
@@ -487,7 +572,7 @@ module FlowVar_internal {
|
||||
|
||||
pragma[noinline]
|
||||
private predicate assignsToVar(BasicBlock bb, Variable v) {
|
||||
assignmentLikeOperation(bb.getANode(), v, _, _) and
|
||||
assignmentLikeOperation(bb.getANode(), v, _) and
|
||||
exists(AlwaysTrueUponEntryLoop loop | v = loop.getARelevantVariable())
|
||||
}
|
||||
|
||||
@@ -524,7 +609,7 @@ module FlowVar_internal {
|
||||
result = mid.getASuccessor() and
|
||||
variableLiveInSBB(result, v) and
|
||||
forall(AlwaysTrueUponEntryLoop loop | skipLoop(mid, result, v, loop) | loop.sbbInLoop(sbbDef)) and
|
||||
not assignmentLikeOperation(result, v, _, _)
|
||||
not assignmentLikeOperation(result, v, _)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -560,13 +645,15 @@ module FlowVar_internal {
|
||||
refType = p.getUnderlyingType() and
|
||||
not refType.getBaseType().isConst()
|
||||
)
|
||||
or
|
||||
p instanceof IteratorParameter
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if liveness of `v` should stop propagating backwards from `sbb`.
|
||||
*/
|
||||
private predicate variableNotLiveBefore(SubBasicBlock sbb, Variable v) {
|
||||
assignmentLikeOperation(sbb, v, _, _)
|
||||
assignmentLikeOperation(sbb, v, _)
|
||||
or
|
||||
// Liveness of `v` is killed when going backwards from a block that declares it
|
||||
exists(DeclStmt ds | ds.getADeclaration().(LocalVariable) = v and sbb.contains(ds))
|
||||
@@ -686,21 +773,17 @@ module FlowVar_internal {
|
||||
* `node instanceof Initializer` is covered by `initializer` instead of this
|
||||
* predicate.
|
||||
*/
|
||||
predicate assignmentLikeOperation(
|
||||
ControlFlowNode node, Variable v, VariableAccess va, Expr assignedExpr
|
||||
) {
|
||||
predicate assignmentLikeOperation(ControlFlowNode node, Variable v, Expr assignedExpr) {
|
||||
// Together, the two following cases cover `Assignment`
|
||||
node =
|
||||
any(AssignExpr ae |
|
||||
va = ae.getLValue() and
|
||||
v = va.getTarget() and
|
||||
v.getAnAccess() = ae.getLValue() and
|
||||
assignedExpr = ae.getRValue()
|
||||
)
|
||||
or
|
||||
node =
|
||||
any(AssignOperation ao |
|
||||
va = ao.getLValue() and
|
||||
v = va.getTarget() and
|
||||
v.getAnAccess() = ao.getLValue() and
|
||||
// Here and in the `PrefixCrementOperation` case, we say that the assigned
|
||||
// expression is the operation itself. For example, we say that `x += 1`
|
||||
// assigns `x += 1` to `x`. The justification is that after this operation,
|
||||
@@ -712,12 +795,24 @@ module FlowVar_internal {
|
||||
// `PrefixCrementOperation` is itself a source
|
||||
node =
|
||||
any(CrementOperation op |
|
||||
va = op.getOperand() and
|
||||
v = va.getTarget() and
|
||||
v.getAnAccess() = op.getOperand() and
|
||||
assignedExpr = op
|
||||
)
|
||||
}
|
||||
|
||||
Expr getAnIteratorAccess(Variable collection) {
|
||||
exists(Call c, SsaDefinition def, Variable iterator |
|
||||
c.getQualifier() = collection.getAnAccess() and
|
||||
c.getTarget() instanceof BeginOrEndFunction and
|
||||
def.getAnUltimateDefiningValue(iterator) = c and
|
||||
result = def.getAUse(iterator)
|
||||
)
|
||||
}
|
||||
|
||||
class IteratorParameter extends Parameter {
|
||||
IteratorParameter() { this.getUnspecifiedType() instanceof Iterator }
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `v` is initialized to have value `assignedExpr`.
|
||||
*/
|
||||
@@ -749,7 +844,7 @@ module FlowVar_internal {
|
||||
class DataFlowSubBasicBlockCutNode extends SubBasicBlockCutNode {
|
||||
DataFlowSubBasicBlockCutNode() {
|
||||
exists(Variable v | not fullySupportedSsaVariable(v) |
|
||||
assignmentLikeOperation(this, v, _, _)
|
||||
assignmentLikeOperation(this, v, _)
|
||||
or
|
||||
exists(PartialDefinition p | p.partiallyDefinesVariableAt(v, this))
|
||||
// It is not necessary to cut the basic blocks at `Initializer` nodes
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
|
||||
private import semmle.code.cpp.models.interfaces.DataFlow
|
||||
private import semmle.code.cpp.models.interfaces.Taint
|
||||
private import semmle.code.cpp.models.interfaces.Iterator
|
||||
|
||||
private module DataFlow {
|
||||
import semmle.code.cpp.dataflow.internal.DataFlowUtil
|
||||
@@ -255,4 +256,12 @@ private predicate exprToPartialDefinitionStep(Expr exprIn, Expr exprOut) {
|
||||
exprIn = call.getArgument(argInIndex)
|
||||
)
|
||||
)
|
||||
or
|
||||
exists(Assignment a |
|
||||
iteratorDereference(exprOut) and
|
||||
a.getLValue() = exprOut and
|
||||
a.getRValue() = exprIn
|
||||
)
|
||||
}
|
||||
|
||||
private predicate iteratorDereference(Call c) { c.getTarget() instanceof IteratorReferenceFunction }
|
||||
|
||||
@@ -355,14 +355,16 @@ private class ArrayToPointerConvertInstruction extends ConvertInstruction {
|
||||
}
|
||||
}
|
||||
|
||||
private Instruction skipOneCopyValueInstruction(Instruction instr) {
|
||||
not instr instanceof CopyValueInstruction and result = instr
|
||||
private Instruction skipOneCopyValueInstructionRec(CopyValueInstruction copy) {
|
||||
copy.getUnary() = result and not result instanceof CopyValueInstruction
|
||||
or
|
||||
result = instr.(CopyValueInstruction).getUnary()
|
||||
result = skipOneCopyValueInstructionRec(copy.getUnary())
|
||||
}
|
||||
|
||||
private Instruction skipCopyValueInstructions(Instruction instr) {
|
||||
result = skipOneCopyValueInstruction*(instr) and not result instanceof CopyValueInstruction
|
||||
not result instanceof CopyValueInstruction and result = instr
|
||||
or
|
||||
result = skipOneCopyValueInstructionRec(instr)
|
||||
}
|
||||
|
||||
private predicate arrayReadStep(Node node1, ArrayContent a, Node node2) {
|
||||
|
||||
@@ -79,7 +79,8 @@ private PhiOperandBase phiOperand(
|
||||
}
|
||||
|
||||
/**
|
||||
* A source operand of an `Instruction`. The operand represents a value consumed by the instruction.
|
||||
* An operand of an `Instruction`. The operand represents a use of the result of one instruction
|
||||
* (the defining instruction) in another instruction (the use instruction)
|
||||
*/
|
||||
class Operand extends TOperand {
|
||||
/** Gets a textual representation of this element. */
|
||||
|
||||
@@ -133,6 +133,12 @@ abstract class MemoryLocation extends TMemoryLocation {
|
||||
predicate isAlwaysAllocatedOnStack() { none() }
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents a set of `MemoryLocation`s that cannot overlap with
|
||||
* `MemoryLocation`s outside of the set. The `VirtualVariable` will be
|
||||
* represented by a `MemoryLocation` that totally overlaps all other
|
||||
* `MemoryLocations` in the set.
|
||||
*/
|
||||
abstract class VirtualVariable extends MemoryLocation { }
|
||||
|
||||
abstract class AllocationMemoryLocation extends MemoryLocation {
|
||||
|
||||
@@ -79,7 +79,8 @@ private PhiOperandBase phiOperand(
|
||||
}
|
||||
|
||||
/**
|
||||
* A source operand of an `Instruction`. The operand represents a value consumed by the instruction.
|
||||
* An operand of an `Instruction`. The operand represents a use of the result of one instruction
|
||||
* (the defining instruction) in another instruction (the use instruction)
|
||||
*/
|
||||
class Operand extends TOperand {
|
||||
/** Gets a textual representation of this element. */
|
||||
|
||||
@@ -79,7 +79,8 @@ private PhiOperandBase phiOperand(
|
||||
}
|
||||
|
||||
/**
|
||||
* A source operand of an `Instruction`. The operand represents a value consumed by the instruction.
|
||||
* An operand of an `Instruction`. The operand represents a use of the result of one instruction
|
||||
* (the defining instruction) in another instruction (the use instruction)
|
||||
*/
|
||||
class Operand extends TOperand {
|
||||
/** Gets a textual representation of this element. */
|
||||
|
||||
@@ -59,6 +59,12 @@ class MemoryLocation extends TMemoryLocation {
|
||||
final string getUniqueId() { result = var.getUniqueId() }
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents a set of `MemoryLocation`s that cannot overlap with
|
||||
* `MemoryLocation`s outside of the set. The `VirtualVariable` will be
|
||||
* represented by a `MemoryLocation` that totally overlaps all other
|
||||
* `MemoryLocations` in the set.
|
||||
*/
|
||||
class VirtualVariable extends MemoryLocation { }
|
||||
|
||||
/** A virtual variable that groups all escaped memory within a function. */
|
||||
|
||||
@@ -3,18 +3,33 @@ private newtype TOverlap =
|
||||
TMustTotallyOverlap() or
|
||||
TMustExactlyOverlap()
|
||||
|
||||
/**
|
||||
* Represents a possible overlap between two memory ranges.
|
||||
*/
|
||||
abstract class Overlap extends TOverlap {
|
||||
abstract string toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents a partial overlap between two memory ranges, which may or may not
|
||||
* actually occur in practice.
|
||||
*/
|
||||
class MayPartiallyOverlap extends Overlap, TMayPartiallyOverlap {
|
||||
final override string toString() { result = "MayPartiallyOverlap" }
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents an overlap in which the first memory range is known to include all
|
||||
* bits of the second memory range, but may be larger or have a different type.
|
||||
*/
|
||||
class MustTotallyOverlap extends Overlap, TMustTotallyOverlap {
|
||||
final override string toString() { result = "MustTotallyOverlap" }
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents an overlap between two memory ranges that have the same extent and
|
||||
* the same type.
|
||||
*/
|
||||
class MustExactlyOverlap extends Overlap, TMustExactlyOverlap {
|
||||
final override string toString() { result = "MustExactlyOverlap" }
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
import cpp
|
||||
import semmle.code.cpp.models.interfaces.Taint
|
||||
import semmle.code.cpp.models.interfaces.DataFlow
|
||||
import semmle.code.cpp.models.interfaces.Iterator
|
||||
|
||||
/**
|
||||
* An instantiation of the `std::iterator_traits` template.
|
||||
@@ -80,7 +81,7 @@ private FunctionInput getIteratorArgumentInput(Operator op, int index) {
|
||||
/**
|
||||
* A non-member prefix `operator*` function for an iterator type.
|
||||
*/
|
||||
class IteratorPointerDereferenceOperator extends Operator, TaintFunction {
|
||||
class IteratorPointerDereferenceOperator extends Operator, TaintFunction, IteratorReferenceFunction {
|
||||
FunctionInput iteratorInput;
|
||||
|
||||
IteratorPointerDereferenceOperator() {
|
||||
@@ -169,7 +170,8 @@ class IteratorAssignArithmeticOperator extends Operator, DataFlowFunction, Taint
|
||||
/**
|
||||
* A prefix `operator*` member function for an iterator type.
|
||||
*/
|
||||
class IteratorPointerDereferenceMemberOperator extends MemberFunction, TaintFunction {
|
||||
class IteratorPointerDereferenceMemberOperator extends MemberFunction, TaintFunction,
|
||||
IteratorReferenceFunction {
|
||||
IteratorPointerDereferenceMemberOperator() {
|
||||
this.hasName("operator*") and
|
||||
this.getDeclaringType() instanceof Iterator
|
||||
@@ -260,7 +262,7 @@ class IteratorAssignArithmeticMemberOperator extends MemberFunction, DataFlowFun
|
||||
/**
|
||||
* An `operator[]` member function of an iterator class.
|
||||
*/
|
||||
class IteratorArrayMemberOperator extends MemberFunction, TaintFunction {
|
||||
class IteratorArrayMemberOperator extends MemberFunction, TaintFunction, IteratorReferenceFunction {
|
||||
IteratorArrayMemberOperator() {
|
||||
this.hasName("operator[]") and
|
||||
this.getDeclaringType() instanceof Iterator
|
||||
@@ -271,3 +273,19 @@ class IteratorArrayMemberOperator extends MemberFunction, TaintFunction {
|
||||
output.isReturnValue()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A `begin` or `end` member function, or a related member function, that
|
||||
* returns an iterator.
|
||||
*/
|
||||
class BeginOrEndFunction extends MemberFunction, TaintFunction {
|
||||
BeginOrEndFunction() {
|
||||
this.hasName(["begin", "cbegin", "rbegin", "crbegin", "end", "cend", "rend", "crend"]) and
|
||||
this.getType().getUnspecifiedType() instanceof Iterator
|
||||
}
|
||||
|
||||
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
|
||||
input.isQualifierObject() and
|
||||
output.isReturnValue()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -216,23 +216,6 @@ class StdStringAssign extends TaintFunction {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The standard functions `std::string.begin` and `std::string.end` and their
|
||||
* variants.
|
||||
*/
|
||||
class StdStringBeginEnd extends TaintFunction {
|
||||
StdStringBeginEnd() {
|
||||
this
|
||||
.hasQualifiedName("std", "basic_string",
|
||||
["begin", "cbegin", "rbegin", "crbegin", "end", "cend", "rend", "crend"])
|
||||
}
|
||||
|
||||
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
|
||||
input.isQualifierObject() and
|
||||
output.isReturnValue()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The standard function `std::string.copy`.
|
||||
*/
|
||||
|
||||
17
cpp/ql/src/semmle/code/cpp/models/interfaces/Iterator.qll
Normal file
17
cpp/ql/src/semmle/code/cpp/models/interfaces/Iterator.qll
Normal file
@@ -0,0 +1,17 @@
|
||||
/**
|
||||
* Provides an abstract class for accurate modeling of flow through output
|
||||
* iterators. To use this QL library, create a QL class extending
|
||||
* `IteratorReferenceFunction` with a characteristic predicate that selects the
|
||||
* function or set of functions you are modeling. Within that class, override
|
||||
* the predicates provided by `AliasFunction` to match the flow within that
|
||||
* function.
|
||||
*/
|
||||
|
||||
import cpp
|
||||
import semmle.code.cpp.models.Models
|
||||
|
||||
/**
|
||||
* A function which takes an iterator argument and returns a reference that
|
||||
* can be used to write to the iterator's underlying collection.
|
||||
*/
|
||||
abstract class IteratorReferenceFunction extends Function { }
|
||||
@@ -45,6 +45,7 @@
|
||||
import cpp
|
||||
private import RangeAnalysisUtils
|
||||
private import experimental.semmle.code.cpp.models.interfaces.SimpleRangeAnalysisExpr
|
||||
private import experimental.semmle.code.cpp.models.interfaces.SimpleRangeAnalysisDefinition
|
||||
import RangeSSA
|
||||
import SimpleRangeAnalysisCached
|
||||
private import NanAnalysis
|
||||
@@ -335,6 +336,11 @@ private predicate defDependsOnDef(
|
||||
or
|
||||
// Phi nodes.
|
||||
phiDependsOnDef(def, v, srcDef, srcVar)
|
||||
or
|
||||
// Extensions
|
||||
exists(Expr expr | def.(SimpleRangeAnalysisDefinition).dependsOnExpr(v, expr) |
|
||||
exprDependsOnDef(expr, srcDef, srcVar)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -492,6 +498,9 @@ private predicate analyzableDef(RangeSsaDefinition def, StackVariable v) {
|
||||
v = def.getAVariable()
|
||||
or
|
||||
phiDependsOnDef(def, v, _, _)
|
||||
or
|
||||
// A modeled def for range analysis
|
||||
def.(SimpleRangeAnalysisDefinition).hasRangeInformationFor(v)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1215,6 +1224,9 @@ private float getDefLowerBoundsImpl(RangeSsaDefinition def, StackVariable v) {
|
||||
// Phi nodes.
|
||||
result = getPhiLowerBounds(v, def)
|
||||
or
|
||||
// A modeled def for range analysis
|
||||
result = def.(SimpleRangeAnalysisDefinition).getLowerBounds(v)
|
||||
or
|
||||
// Unanalyzable definitions.
|
||||
unanalyzableDefBounds(def, v, result, _)
|
||||
}
|
||||
@@ -1248,6 +1260,9 @@ private float getDefUpperBoundsImpl(RangeSsaDefinition def, StackVariable v) {
|
||||
// Phi nodes.
|
||||
result = getPhiUpperBounds(v, def)
|
||||
or
|
||||
// A modeled def for range analysis
|
||||
result = def.(SimpleRangeAnalysisDefinition).getUpperBounds(v)
|
||||
or
|
||||
// Unanalyzable definitions.
|
||||
unanalyzableDefBounds(def, v, _, result)
|
||||
}
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
|
||||
|
||||
void test_overridability_sub(int x) {
|
||||
int zero = x - x;
|
||||
zero; // 0
|
||||
|
||||
int nonzero = x - (unsigned char)x;
|
||||
nonzero; // full range
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
| extended.cpp:4:14:4:14 | x | -2.147483648E9 | 2.147483647E9 |
|
||||
| extended.cpp:4:18:4:18 | x | -2.147483648E9 | 2.147483647E9 |
|
||||
| extended.cpp:5:3:5:6 | zero | 0.0 | 0.0 |
|
||||
| extended.cpp:7:17:7:17 | x | -2.147483648E9 | 2.147483647E9 |
|
||||
| extended.cpp:7:36:7:36 | x | -2.147483648E9 | 2.147483647E9 |
|
||||
| extended.cpp:8:3:8:9 | nonzero | -2.147483648E9 | 2.147483647E9 |
|
||||
@@ -0,0 +1,7 @@
|
||||
import experimental.semmle.code.cpp.rangeanalysis.ExtendedRangeAnalysis
|
||||
|
||||
from VariableAccess expr, float lower, float upper
|
||||
where
|
||||
lower = lowerBound(expr) and
|
||||
upper = upperBound(expr)
|
||||
select expr, lower, upper
|
||||
@@ -9,6 +9,11 @@ int test_extensibility_add(int x) {
|
||||
}
|
||||
|
||||
int test_overridability_sub(int x) {
|
||||
int result = x - x; // Returns 0 due to custom modeling in QL
|
||||
int result = x - (unsigned char)x; // Returns 0 due to custom modeling for this test being deliberately wrong
|
||||
return result; // 0
|
||||
}
|
||||
}
|
||||
|
||||
void test_parameter_override(int magic_name_at_most_10, int magic_name_at_most_20) {
|
||||
magic_name_at_most_10;
|
||||
magic_name_at_most_20;
|
||||
}
|
||||
|
||||
@@ -3,5 +3,7 @@
|
||||
| extensibility.c:6:38:6:38 | x | -10.0 | 10.0 |
|
||||
| extensibility.c:7:12:7:17 | result | 90.0 | 110.0 |
|
||||
| extensibility.c:12:16:12:16 | x | -2.147483648E9 | 2.147483647E9 |
|
||||
| extensibility.c:12:20:12:20 | x | -2.147483648E9 | 2.147483647E9 |
|
||||
| extensibility.c:12:35:12:35 | x | -2.147483648E9 | 2.147483647E9 |
|
||||
| extensibility.c:13:10:13:15 | result | 0.0 | 0.0 |
|
||||
| extensibility.c:17:3:17:23 | magic_name_at_most_10 | -2.147483648E9 | 10.0 |
|
||||
| extensibility.c:18:3:18:23 | magic_name_at_most_20 | -2.147483648E9 | 20.0 |
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
import semmle.code.cpp.rangeanalysis.SimpleRangeAnalysis
|
||||
import semmle.code.cpp.rangeanalysis.RangeAnalysisUtils
|
||||
import experimental.semmle.code.cpp.models.interfaces.SimpleRangeAnalysisExpr
|
||||
import experimental.semmle.code.cpp.models.interfaces.SimpleRangeAnalysisDefinition
|
||||
|
||||
class CustomAddFunctionCall extends SimpleRangeAnalysisExpr, FunctionCall {
|
||||
CustomAddFunctionCall() { this.getTarget().hasGlobalName("custom_add_function") }
|
||||
@@ -37,6 +39,40 @@ class SelfSub extends SimpleRangeAnalysisExpr, SubExpr {
|
||||
override predicate dependsOnChild(Expr child) { child = this.getAnOperand() }
|
||||
}
|
||||
|
||||
/**
|
||||
* A definition for test purposes of a parameter `p` that starts with a
|
||||
* special prefix. This class is written to exploit how QL behaves when class
|
||||
* fields are not functionally determined by `this`. When multiple parameters
|
||||
* of the same function have the special prefix, there is still only one
|
||||
* instance of this class.
|
||||
*/
|
||||
class MagicParameterName extends SimpleRangeAnalysisDefinition {
|
||||
Parameter p;
|
||||
float value;
|
||||
|
||||
MagicParameterName() {
|
||||
this.definedByParameter(p) and
|
||||
value = p.getName().regexpCapture("magic_name_at_most_(\\d+)", 1).toFloat()
|
||||
}
|
||||
|
||||
override predicate hasRangeInformationFor(StackVariable v) { v = p }
|
||||
|
||||
override predicate dependsOnExpr(StackVariable v, Expr e) {
|
||||
// No dependencies. This sample class yields constant values.
|
||||
none()
|
||||
}
|
||||
|
||||
override float getLowerBounds(StackVariable var) {
|
||||
var = p and
|
||||
result = typeLowerBound(p.getUnspecifiedType())
|
||||
}
|
||||
|
||||
override float getUpperBounds(StackVariable var) {
|
||||
var = p and
|
||||
result = value
|
||||
}
|
||||
}
|
||||
|
||||
from VariableAccess expr, float lower, float upper
|
||||
where
|
||||
lower = lowerBound(expr) and
|
||||
|
||||
@@ -1884,23 +1884,29 @@
|
||||
| smart_pointer.cpp:65:28:65:46 | call to make_unique | smart_pointer.cpp:67:10:67:10 | p | |
|
||||
| smart_pointer.cpp:65:48:65:53 | call to source | smart_pointer.cpp:65:28:65:46 | call to make_unique | TAINT |
|
||||
| smart_pointer.cpp:65:58:65:58 | 0 | smart_pointer.cpp:65:28:65:46 | call to make_unique | TAINT |
|
||||
| standalone_iterators.cpp:39:45:39:51 | source1 | standalone_iterators.cpp:39:45:39:51 | source1 | |
|
||||
| standalone_iterators.cpp:39:45:39:51 | source1 | standalone_iterators.cpp:40:11:40:17 | source1 | |
|
||||
| standalone_iterators.cpp:39:45:39:51 | source1 | standalone_iterators.cpp:41:12:41:18 | source1 | |
|
||||
| standalone_iterators.cpp:39:45:39:51 | source1 | standalone_iterators.cpp:42:14:42:20 | source1 | |
|
||||
| standalone_iterators.cpp:40:11:40:17 | source1 | standalone_iterators.cpp:40:10:40:10 | call to operator* | TAINT |
|
||||
| standalone_iterators.cpp:41:12:41:18 | ref arg source1 | standalone_iterators.cpp:39:45:39:51 | source1 | |
|
||||
| standalone_iterators.cpp:41:12:41:18 | ref arg source1 | standalone_iterators.cpp:42:14:42:20 | source1 | |
|
||||
| standalone_iterators.cpp:41:12:41:18 | source1 | standalone_iterators.cpp:41:19:41:19 | call to operator++ | |
|
||||
| standalone_iterators.cpp:41:19:41:19 | call to operator++ | standalone_iterators.cpp:41:10:41:10 | call to operator* | TAINT |
|
||||
| standalone_iterators.cpp:42:12:42:12 | call to operator++ | standalone_iterators.cpp:42:10:42:10 | call to operator* | TAINT |
|
||||
| standalone_iterators.cpp:42:14:42:20 | ref arg source1 | standalone_iterators.cpp:39:45:39:51 | source1 | |
|
||||
| standalone_iterators.cpp:42:14:42:20 | source1 | standalone_iterators.cpp:42:12:42:12 | call to operator++ | |
|
||||
| standalone_iterators.cpp:45:39:45:45 | source1 | standalone_iterators.cpp:45:39:45:45 | source1 | |
|
||||
| standalone_iterators.cpp:45:39:45:45 | source1 | standalone_iterators.cpp:46:11:46:17 | source1 | |
|
||||
| standalone_iterators.cpp:45:39:45:45 | source1 | standalone_iterators.cpp:47:12:47:18 | source1 | |
|
||||
| standalone_iterators.cpp:45:39:45:45 | source1 | standalone_iterators.cpp:48:14:48:20 | source1 | |
|
||||
| standalone_iterators.cpp:46:11:46:17 | source1 | standalone_iterators.cpp:46:10:46:10 | call to operator* | TAINT |
|
||||
| standalone_iterators.cpp:47:12:47:18 | ref arg source1 | standalone_iterators.cpp:45:39:45:45 | source1 | |
|
||||
| standalone_iterators.cpp:47:12:47:18 | ref arg source1 | standalone_iterators.cpp:48:14:48:20 | source1 | |
|
||||
| standalone_iterators.cpp:47:12:47:18 | source1 | standalone_iterators.cpp:47:19:47:19 | call to operator++ | |
|
||||
| standalone_iterators.cpp:47:19:47:19 | call to operator++ | standalone_iterators.cpp:47:10:47:10 | call to operator* | TAINT |
|
||||
| standalone_iterators.cpp:48:12:48:12 | call to operator++ | standalone_iterators.cpp:48:10:48:10 | call to operator* | TAINT |
|
||||
| standalone_iterators.cpp:48:14:48:20 | ref arg source1 | standalone_iterators.cpp:45:39:45:45 | source1 | |
|
||||
| standalone_iterators.cpp:48:14:48:20 | source1 | standalone_iterators.cpp:48:12:48:12 | call to operator++ | |
|
||||
| standalone_iterators.cpp:51:37:51:43 | source1 | standalone_iterators.cpp:52:11:52:17 | source1 | |
|
||||
| standalone_iterators.cpp:51:37:51:43 | source1 | standalone_iterators.cpp:53:12:53:18 | source1 | |
|
||||
@@ -5309,11 +5315,14 @@
|
||||
| vector.cpp:255:3:255:4 | ref arg v6 | vector.cpp:261:8:261:9 | v6 | |
|
||||
| vector.cpp:255:3:255:4 | ref arg v6 | vector.cpp:262:2:262:2 | v6 | |
|
||||
| vector.cpp:255:13:255:14 | call to iterator | vector.cpp:255:3:255:4 | ref arg v6 | TAINT |
|
||||
| vector.cpp:255:13:255:14 | call to iterator [post update] | vector.cpp:277:1:277:1 | v3 | |
|
||||
| vector.cpp:255:13:255:14 | i1 | vector.cpp:255:13:255:14 | call to iterator | |
|
||||
| vector.cpp:255:13:255:14 | i1 [post update] | vector.cpp:277:1:277:1 | v3 | |
|
||||
| vector.cpp:255:17:255:18 | call to iterator | vector.cpp:255:3:255:4 | ref arg v6 | TAINT |
|
||||
| vector.cpp:255:17:255:18 | i2 | vector.cpp:255:17:255:18 | call to iterator | |
|
||||
| vector.cpp:257:8:257:9 | ref arg v4 | vector.cpp:262:2:262:2 | v4 | |
|
||||
| vector.cpp:258:8:258:9 | ref arg v5 | vector.cpp:262:2:262:2 | v5 | |
|
||||
| vector.cpp:259:8:259:9 | ref arg i1 | vector.cpp:277:1:277:1 | v3 | |
|
||||
| vector.cpp:261:8:261:9 | ref arg v6 | vector.cpp:262:2:262:2 | v6 | |
|
||||
| vector.cpp:265:22:265:23 | call to vector | vector.cpp:269:3:269:4 | v7 | |
|
||||
| vector.cpp:265:22:265:23 | call to vector | vector.cpp:273:8:273:9 | v7 | |
|
||||
@@ -5516,3 +5525,265 @@
|
||||
| vector.cpp:324:7:324:8 | ref arg v2 | vector.cpp:327:1:327:1 | v2 | |
|
||||
| vector.cpp:325:7:325:8 | ref arg v3 | vector.cpp:327:1:327:1 | v3 | |
|
||||
| vector.cpp:326:7:326:8 | ref arg v4 | vector.cpp:327:1:327:1 | v4 | |
|
||||
| vector.cpp:329:62:329:65 | iter | vector.cpp:329:62:329:65 | iter | |
|
||||
| vector.cpp:329:62:329:65 | iter | vector.cpp:330:3:330:6 | iter | |
|
||||
| vector.cpp:330:2:330:2 | call to operator* [post update] | vector.cpp:329:62:329:65 | iter | |
|
||||
| vector.cpp:330:2:330:17 | ... = ... | vector.cpp:330:2:330:2 | call to operator* [post update] | |
|
||||
| vector.cpp:330:3:330:6 | iter | vector.cpp:330:2:330:2 | call to operator* | TAINT |
|
||||
| vector.cpp:330:10:330:15 | call to source | vector.cpp:330:2:330:2 | call to operator* [post update] | TAINT |
|
||||
| vector.cpp:330:10:330:15 | call to source | vector.cpp:330:2:330:17 | ... = ... | |
|
||||
| vector.cpp:333:64:333:67 | iter | vector.cpp:333:64:333:67 | iter | |
|
||||
| vector.cpp:333:64:333:67 | iter | vector.cpp:334:3:334:6 | iter | |
|
||||
| vector.cpp:333:74:333:74 | i | vector.cpp:334:10:334:10 | i | |
|
||||
| vector.cpp:334:2:334:2 | call to operator* [post update] | vector.cpp:333:64:333:67 | iter | |
|
||||
| vector.cpp:334:2:334:10 | ... = ... | vector.cpp:334:2:334:2 | call to operator* [post update] | |
|
||||
| vector.cpp:334:3:334:6 | iter | vector.cpp:334:2:334:2 | call to operator* | TAINT |
|
||||
| vector.cpp:334:10:334:10 | i | vector.cpp:334:2:334:2 | call to operator* [post update] | TAINT |
|
||||
| vector.cpp:334:10:334:10 | i | vector.cpp:334:2:334:10 | ... = ... | |
|
||||
| vector.cpp:337:38:337:38 | b | vector.cpp:372:5:372:5 | b | |
|
||||
| vector.cpp:338:22:338:24 | call to vector | vector.cpp:340:34:340:35 | v1 | |
|
||||
| vector.cpp:338:22:338:24 | call to vector | vector.cpp:342:7:342:8 | v1 | |
|
||||
| vector.cpp:338:22:338:24 | call to vector | vector.cpp:401:1:401:1 | v1 | |
|
||||
| vector.cpp:338:30:338:32 | call to vector | vector.cpp:344:38:344:39 | v2 | |
|
||||
| vector.cpp:338:30:338:32 | call to vector | vector.cpp:344:56:344:57 | v2 | |
|
||||
| vector.cpp:338:30:338:32 | call to vector | vector.cpp:347:7:347:8 | v2 | |
|
||||
| vector.cpp:338:30:338:32 | call to vector | vector.cpp:401:1:401:1 | v2 | |
|
||||
| vector.cpp:338:38:338:40 | call to vector | vector.cpp:349:15:349:16 | v3 | |
|
||||
| vector.cpp:338:38:338:40 | call to vector | vector.cpp:352:7:352:8 | v3 | |
|
||||
| vector.cpp:338:38:338:40 | call to vector | vector.cpp:401:1:401:1 | v3 | |
|
||||
| vector.cpp:338:46:338:48 | call to vector | vector.cpp:354:38:354:39 | v4 | |
|
||||
| vector.cpp:338:46:338:48 | call to vector | vector.cpp:354:56:354:57 | v4 | |
|
||||
| vector.cpp:338:46:338:48 | call to vector | vector.cpp:357:7:357:8 | v4 | |
|
||||
| vector.cpp:338:46:338:48 | call to vector | vector.cpp:401:1:401:1 | v4 | |
|
||||
| vector.cpp:338:54:338:56 | call to vector | vector.cpp:359:34:359:35 | v5 | |
|
||||
| vector.cpp:338:54:338:56 | call to vector | vector.cpp:361:7:361:8 | v5 | |
|
||||
| vector.cpp:338:54:338:56 | call to vector | vector.cpp:363:7:363:8 | v5 | |
|
||||
| vector.cpp:338:54:338:56 | call to vector | vector.cpp:401:1:401:1 | v5 | |
|
||||
| vector.cpp:338:62:338:64 | call to vector | vector.cpp:365:34:365:35 | v6 | |
|
||||
| vector.cpp:338:62:338:64 | call to vector | vector.cpp:367:7:367:8 | v6 | |
|
||||
| vector.cpp:338:62:338:64 | call to vector | vector.cpp:368:2:368:3 | v6 | |
|
||||
| vector.cpp:338:62:338:64 | call to vector | vector.cpp:369:7:369:8 | v6 | |
|
||||
| vector.cpp:338:62:338:64 | call to vector | vector.cpp:401:1:401:1 | v6 | |
|
||||
| vector.cpp:338:70:338:72 | call to vector | vector.cpp:371:34:371:35 | v7 | |
|
||||
| vector.cpp:338:70:338:72 | call to vector | vector.cpp:374:8:374:9 | v7 | |
|
||||
| vector.cpp:338:70:338:72 | call to vector | vector.cpp:377:8:377:9 | v7 | |
|
||||
| vector.cpp:338:70:338:72 | call to vector | vector.cpp:379:7:379:8 | v7 | |
|
||||
| vector.cpp:338:70:338:72 | call to vector | vector.cpp:401:1:401:1 | v7 | |
|
||||
| vector.cpp:338:78:338:80 | call to vector | vector.cpp:381:34:381:35 | v8 | |
|
||||
| vector.cpp:338:78:338:80 | call to vector | vector.cpp:383:7:383:8 | v8 | |
|
||||
| vector.cpp:338:78:338:80 | call to vector | vector.cpp:385:7:385:8 | v8 | |
|
||||
| vector.cpp:338:78:338:80 | call to vector | vector.cpp:401:1:401:1 | v8 | |
|
||||
| vector.cpp:338:86:338:88 | call to vector | vector.cpp:387:34:387:35 | v9 | |
|
||||
| vector.cpp:338:86:338:88 | call to vector | vector.cpp:392:7:392:8 | v9 | |
|
||||
| vector.cpp:338:86:338:88 | call to vector | vector.cpp:401:1:401:1 | v9 | |
|
||||
| vector.cpp:338:95:338:97 | call to vector | vector.cpp:394:35:394:37 | v10 | |
|
||||
| vector.cpp:338:95:338:97 | call to vector | vector.cpp:396:7:396:9 | v10 | |
|
||||
| vector.cpp:338:95:338:97 | call to vector | vector.cpp:401:1:401:1 | v10 | |
|
||||
| vector.cpp:338:104:338:106 | call to vector | vector.cpp:398:35:398:37 | v11 | |
|
||||
| vector.cpp:338:104:338:106 | call to vector | vector.cpp:400:7:400:9 | v11 | |
|
||||
| vector.cpp:338:104:338:106 | call to vector | vector.cpp:401:1:401:1 | v11 | |
|
||||
| vector.cpp:340:34:340:35 | ref arg v1 | vector.cpp:342:7:342:8 | v1 | |
|
||||
| vector.cpp:340:34:340:35 | ref arg v1 | vector.cpp:401:1:401:1 | v1 | |
|
||||
| vector.cpp:340:34:340:35 | v1 | vector.cpp:340:37:340:41 | call to begin | TAINT |
|
||||
| vector.cpp:340:37:340:41 | call to begin | vector.cpp:341:3:341:4 | i1 | |
|
||||
| vector.cpp:341:2:341:2 | call to operator* [post update] | vector.cpp:342:7:342:8 | v1 | |
|
||||
| vector.cpp:341:2:341:2 | call to operator* [post update] | vector.cpp:401:1:401:1 | v1 | |
|
||||
| vector.cpp:341:2:341:15 | ... = ... | vector.cpp:341:2:341:2 | call to operator* [post update] | |
|
||||
| vector.cpp:341:3:341:4 | i1 | vector.cpp:341:2:341:2 | call to operator* | TAINT |
|
||||
| vector.cpp:341:8:341:13 | call to source | vector.cpp:341:2:341:2 | call to operator* [post update] | TAINT |
|
||||
| vector.cpp:341:8:341:13 | call to source | vector.cpp:341:2:341:15 | ... = ... | |
|
||||
| vector.cpp:342:7:342:8 | ref arg v1 | vector.cpp:401:1:401:1 | v1 | |
|
||||
| vector.cpp:344:38:344:39 | ref arg v2 | vector.cpp:344:56:344:57 | v2 | |
|
||||
| vector.cpp:344:38:344:39 | ref arg v2 | vector.cpp:347:7:347:8 | v2 | |
|
||||
| vector.cpp:344:38:344:39 | ref arg v2 | vector.cpp:401:1:401:1 | v2 | |
|
||||
| vector.cpp:344:38:344:39 | v2 | vector.cpp:344:41:344:45 | call to begin | TAINT |
|
||||
| vector.cpp:344:41:344:45 | call to begin | vector.cpp:344:50:344:51 | it | |
|
||||
| vector.cpp:344:41:344:45 | call to begin | vector.cpp:344:68:344:69 | it | |
|
||||
| vector.cpp:344:41:344:45 | call to begin | vector.cpp:345:4:345:5 | it | |
|
||||
| vector.cpp:344:56:344:57 | ref arg v2 | vector.cpp:344:56:344:57 | v2 | |
|
||||
| vector.cpp:344:56:344:57 | ref arg v2 | vector.cpp:347:7:347:8 | v2 | |
|
||||
| vector.cpp:344:56:344:57 | ref arg v2 | vector.cpp:401:1:401:1 | v2 | |
|
||||
| vector.cpp:344:56:344:57 | v2 | vector.cpp:344:59:344:61 | call to end | TAINT |
|
||||
| vector.cpp:344:68:344:69 | it | vector.cpp:344:66:344:66 | call to operator++ | |
|
||||
| vector.cpp:344:68:344:69 | ref arg it | vector.cpp:344:50:344:51 | it | |
|
||||
| vector.cpp:344:68:344:69 | ref arg it | vector.cpp:344:68:344:69 | it | |
|
||||
| vector.cpp:344:68:344:69 | ref arg it | vector.cpp:345:4:345:5 | it | |
|
||||
| vector.cpp:345:3:345:3 | call to operator* [post update] | vector.cpp:344:56:344:57 | v2 | |
|
||||
| vector.cpp:345:3:345:3 | call to operator* [post update] | vector.cpp:347:7:347:8 | v2 | |
|
||||
| vector.cpp:345:3:345:3 | call to operator* [post update] | vector.cpp:401:1:401:1 | v2 | |
|
||||
| vector.cpp:345:3:345:16 | ... = ... | vector.cpp:345:3:345:3 | call to operator* [post update] | |
|
||||
| vector.cpp:345:4:345:5 | it | vector.cpp:345:3:345:3 | call to operator* | TAINT |
|
||||
| vector.cpp:345:9:345:14 | call to source | vector.cpp:345:3:345:3 | call to operator* [post update] | TAINT |
|
||||
| vector.cpp:345:9:345:14 | call to source | vector.cpp:345:3:345:16 | ... = ... | |
|
||||
| vector.cpp:347:7:347:8 | ref arg v2 | vector.cpp:401:1:401:1 | v2 | |
|
||||
| vector.cpp:349:15:349:15 | (__begin) | vector.cpp:349:15:349:15 | call to operator* | TAINT |
|
||||
| vector.cpp:349:15:349:15 | (__begin) | vector.cpp:349:15:349:15 | call to operator++ | |
|
||||
| vector.cpp:349:15:349:15 | (__end) | vector.cpp:349:15:349:15 | call to iterator | |
|
||||
| vector.cpp:349:15:349:15 | (__range) | vector.cpp:349:15:349:15 | call to begin | TAINT |
|
||||
| vector.cpp:349:15:349:15 | (__range) | vector.cpp:349:15:349:15 | call to end | TAINT |
|
||||
| vector.cpp:349:15:349:15 | call to begin | vector.cpp:349:15:349:15 | (__begin) | |
|
||||
| vector.cpp:349:15:349:15 | call to begin | vector.cpp:349:15:349:15 | (__begin) | |
|
||||
| vector.cpp:349:15:349:15 | call to begin | vector.cpp:349:15:349:15 | (__begin) | |
|
||||
| vector.cpp:349:15:349:15 | call to end | vector.cpp:349:15:349:15 | (__end) | |
|
||||
| vector.cpp:349:15:349:15 | ref arg (__begin) | vector.cpp:349:15:349:15 | (__begin) | |
|
||||
| vector.cpp:349:15:349:15 | ref arg (__begin) | vector.cpp:349:15:349:15 | (__begin) | |
|
||||
| vector.cpp:349:15:349:15 | ref arg (__begin) | vector.cpp:349:15:349:15 | (__begin) | |
|
||||
| vector.cpp:349:15:349:15 | ref arg (__range) | vector.cpp:349:15:349:15 | (__range) | |
|
||||
| vector.cpp:349:15:349:16 | v3 | vector.cpp:349:15:349:15 | (__range) | |
|
||||
| vector.cpp:349:15:349:16 | v3 | vector.cpp:349:15:349:15 | (__range) | |
|
||||
| vector.cpp:349:15:349:16 | v3 | vector.cpp:349:15:349:15 | call to operator* | TAINT |
|
||||
| vector.cpp:350:3:350:14 | ... = ... | vector.cpp:350:3:350:3 | x [post update] | |
|
||||
| vector.cpp:350:7:350:12 | call to source | vector.cpp:350:3:350:14 | ... = ... | |
|
||||
| vector.cpp:352:7:352:8 | ref arg v3 | vector.cpp:401:1:401:1 | v3 | |
|
||||
| vector.cpp:354:38:354:39 | ref arg v4 | vector.cpp:354:56:354:57 | v4 | |
|
||||
| vector.cpp:354:38:354:39 | ref arg v4 | vector.cpp:357:7:357:8 | v4 | |
|
||||
| vector.cpp:354:38:354:39 | ref arg v4 | vector.cpp:401:1:401:1 | v4 | |
|
||||
| vector.cpp:354:38:354:39 | v4 | vector.cpp:354:41:354:45 | call to begin | TAINT |
|
||||
| vector.cpp:354:41:354:45 | call to begin | vector.cpp:354:50:354:51 | it | |
|
||||
| vector.cpp:354:41:354:45 | call to begin | vector.cpp:354:68:354:69 | it | |
|
||||
| vector.cpp:354:41:354:45 | call to begin | vector.cpp:355:32:355:33 | it | |
|
||||
| vector.cpp:354:56:354:57 | ref arg v4 | vector.cpp:354:56:354:57 | v4 | |
|
||||
| vector.cpp:354:56:354:57 | ref arg v4 | vector.cpp:357:7:357:8 | v4 | |
|
||||
| vector.cpp:354:56:354:57 | ref arg v4 | vector.cpp:401:1:401:1 | v4 | |
|
||||
| vector.cpp:354:56:354:57 | v4 | vector.cpp:354:59:354:61 | call to end | TAINT |
|
||||
| vector.cpp:354:68:354:69 | it | vector.cpp:354:66:354:66 | call to operator++ | |
|
||||
| vector.cpp:354:68:354:69 | ref arg it | vector.cpp:354:50:354:51 | it | |
|
||||
| vector.cpp:354:68:354:69 | ref arg it | vector.cpp:354:68:354:69 | it | |
|
||||
| vector.cpp:354:68:354:69 | ref arg it | vector.cpp:355:32:355:33 | it | |
|
||||
| vector.cpp:355:32:355:33 | call to iterator [post update] | vector.cpp:354:56:354:57 | v4 | |
|
||||
| vector.cpp:355:32:355:33 | call to iterator [post update] | vector.cpp:357:7:357:8 | v4 | |
|
||||
| vector.cpp:355:32:355:33 | call to iterator [post update] | vector.cpp:401:1:401:1 | v4 | |
|
||||
| vector.cpp:355:32:355:33 | it | vector.cpp:355:32:355:33 | call to iterator | |
|
||||
| vector.cpp:355:32:355:33 | it [post update] | vector.cpp:354:56:354:57 | v4 | |
|
||||
| vector.cpp:355:32:355:33 | it [post update] | vector.cpp:357:7:357:8 | v4 | |
|
||||
| vector.cpp:355:32:355:33 | it [post update] | vector.cpp:401:1:401:1 | v4 | |
|
||||
| vector.cpp:357:7:357:8 | ref arg v4 | vector.cpp:401:1:401:1 | v4 | |
|
||||
| vector.cpp:359:34:359:35 | ref arg v5 | vector.cpp:361:7:361:8 | v5 | |
|
||||
| vector.cpp:359:34:359:35 | ref arg v5 | vector.cpp:363:7:363:8 | v5 | |
|
||||
| vector.cpp:359:34:359:35 | ref arg v5 | vector.cpp:401:1:401:1 | v5 | |
|
||||
| vector.cpp:359:34:359:35 | v5 | vector.cpp:359:37:359:41 | call to begin | TAINT |
|
||||
| vector.cpp:359:37:359:41 | call to begin | vector.cpp:360:3:360:4 | i5 | |
|
||||
| vector.cpp:359:37:359:41 | call to begin | vector.cpp:362:3:362:4 | i5 | |
|
||||
| vector.cpp:360:2:360:2 | call to operator* [post update] | vector.cpp:361:7:361:8 | v5 | |
|
||||
| vector.cpp:360:2:360:2 | call to operator* [post update] | vector.cpp:363:7:363:8 | v5 | |
|
||||
| vector.cpp:360:2:360:2 | call to operator* [post update] | vector.cpp:401:1:401:1 | v5 | |
|
||||
| vector.cpp:360:2:360:15 | ... = ... | vector.cpp:360:2:360:2 | call to operator* [post update] | |
|
||||
| vector.cpp:360:3:360:4 | i5 | vector.cpp:360:2:360:2 | call to operator* | TAINT |
|
||||
| vector.cpp:360:8:360:13 | call to source | vector.cpp:360:2:360:2 | call to operator* [post update] | TAINT |
|
||||
| vector.cpp:360:8:360:13 | call to source | vector.cpp:360:2:360:15 | ... = ... | |
|
||||
| vector.cpp:361:7:361:8 | ref arg v5 | vector.cpp:363:7:363:8 | v5 | |
|
||||
| vector.cpp:361:7:361:8 | ref arg v5 | vector.cpp:401:1:401:1 | v5 | |
|
||||
| vector.cpp:362:2:362:2 | call to operator* [post update] | vector.cpp:363:7:363:8 | v5 | |
|
||||
| vector.cpp:362:2:362:2 | call to operator* [post update] | vector.cpp:401:1:401:1 | v5 | |
|
||||
| vector.cpp:362:2:362:8 | ... = ... | vector.cpp:362:2:362:2 | call to operator* [post update] | |
|
||||
| vector.cpp:362:3:362:4 | i5 | vector.cpp:362:2:362:2 | call to operator* | TAINT |
|
||||
| vector.cpp:362:8:362:8 | 1 | vector.cpp:362:2:362:2 | call to operator* [post update] | TAINT |
|
||||
| vector.cpp:362:8:362:8 | 1 | vector.cpp:362:2:362:8 | ... = ... | |
|
||||
| vector.cpp:363:7:363:8 | ref arg v5 | vector.cpp:401:1:401:1 | v5 | |
|
||||
| vector.cpp:365:34:365:35 | ref arg v6 | vector.cpp:367:7:367:8 | v6 | |
|
||||
| vector.cpp:365:34:365:35 | ref arg v6 | vector.cpp:368:2:368:3 | v6 | |
|
||||
| vector.cpp:365:34:365:35 | ref arg v6 | vector.cpp:369:7:369:8 | v6 | |
|
||||
| vector.cpp:365:34:365:35 | ref arg v6 | vector.cpp:401:1:401:1 | v6 | |
|
||||
| vector.cpp:365:34:365:35 | v6 | vector.cpp:365:37:365:41 | call to begin | TAINT |
|
||||
| vector.cpp:365:37:365:41 | call to begin | vector.cpp:366:3:366:4 | i6 | |
|
||||
| vector.cpp:366:2:366:2 | call to operator* [post update] | vector.cpp:367:7:367:8 | v6 | |
|
||||
| vector.cpp:366:2:366:2 | call to operator* [post update] | vector.cpp:368:2:368:3 | v6 | |
|
||||
| vector.cpp:366:2:366:2 | call to operator* [post update] | vector.cpp:369:7:369:8 | v6 | |
|
||||
| vector.cpp:366:2:366:2 | call to operator* [post update] | vector.cpp:401:1:401:1 | v6 | |
|
||||
| vector.cpp:366:2:366:15 | ... = ... | vector.cpp:366:2:366:2 | call to operator* [post update] | |
|
||||
| vector.cpp:366:3:366:4 | i6 | vector.cpp:366:2:366:2 | call to operator* | TAINT |
|
||||
| vector.cpp:366:8:366:13 | call to source | vector.cpp:366:2:366:2 | call to operator* [post update] | TAINT |
|
||||
| vector.cpp:366:8:366:13 | call to source | vector.cpp:366:2:366:15 | ... = ... | |
|
||||
| vector.cpp:367:7:367:8 | ref arg v6 | vector.cpp:368:2:368:3 | v6 | |
|
||||
| vector.cpp:367:7:367:8 | ref arg v6 | vector.cpp:369:7:369:8 | v6 | |
|
||||
| vector.cpp:367:7:367:8 | ref arg v6 | vector.cpp:401:1:401:1 | v6 | |
|
||||
| vector.cpp:368:2:368:3 | ref arg v6 | vector.cpp:369:7:369:8 | v6 | |
|
||||
| vector.cpp:368:2:368:3 | ref arg v6 | vector.cpp:401:1:401:1 | v6 | |
|
||||
| vector.cpp:368:7:368:26 | call to vector | vector.cpp:368:2:368:3 | ref arg v6 | TAINT |
|
||||
| vector.cpp:368:7:368:26 | call to vector | vector.cpp:368:5:368:5 | call to operator= | TAINT |
|
||||
| vector.cpp:369:7:369:8 | ref arg v6 | vector.cpp:401:1:401:1 | v6 | |
|
||||
| vector.cpp:371:34:371:35 | ref arg v7 | vector.cpp:374:8:374:9 | v7 | |
|
||||
| vector.cpp:371:34:371:35 | ref arg v7 | vector.cpp:377:8:377:9 | v7 | |
|
||||
| vector.cpp:371:34:371:35 | ref arg v7 | vector.cpp:379:7:379:8 | v7 | |
|
||||
| vector.cpp:371:34:371:35 | ref arg v7 | vector.cpp:401:1:401:1 | v7 | |
|
||||
| vector.cpp:371:34:371:35 | v7 | vector.cpp:371:37:371:41 | call to begin | TAINT |
|
||||
| vector.cpp:371:37:371:41 | call to begin | vector.cpp:373:4:373:5 | i7 | |
|
||||
| vector.cpp:371:37:371:41 | call to begin | vector.cpp:376:4:376:5 | i7 | |
|
||||
| vector.cpp:373:3:373:3 | call to operator* [post update] | vector.cpp:374:8:374:9 | v7 | |
|
||||
| vector.cpp:373:3:373:3 | call to operator* [post update] | vector.cpp:379:7:379:8 | v7 | |
|
||||
| vector.cpp:373:3:373:3 | call to operator* [post update] | vector.cpp:401:1:401:1 | v7 | |
|
||||
| vector.cpp:373:3:373:16 | ... = ... | vector.cpp:373:3:373:3 | call to operator* [post update] | |
|
||||
| vector.cpp:373:4:373:5 | i7 | vector.cpp:373:3:373:3 | call to operator* | TAINT |
|
||||
| vector.cpp:373:9:373:14 | call to source | vector.cpp:373:3:373:3 | call to operator* [post update] | TAINT |
|
||||
| vector.cpp:373:9:373:14 | call to source | vector.cpp:373:3:373:16 | ... = ... | |
|
||||
| vector.cpp:374:8:374:9 | ref arg v7 | vector.cpp:379:7:379:8 | v7 | |
|
||||
| vector.cpp:374:8:374:9 | ref arg v7 | vector.cpp:401:1:401:1 | v7 | |
|
||||
| vector.cpp:376:3:376:3 | call to operator* [post update] | vector.cpp:377:8:377:9 | v7 | |
|
||||
| vector.cpp:376:3:376:3 | call to operator* [post update] | vector.cpp:379:7:379:8 | v7 | |
|
||||
| vector.cpp:376:3:376:3 | call to operator* [post update] | vector.cpp:401:1:401:1 | v7 | |
|
||||
| vector.cpp:376:3:376:9 | ... = ... | vector.cpp:376:3:376:3 | call to operator* [post update] | |
|
||||
| vector.cpp:376:4:376:5 | i7 | vector.cpp:376:3:376:3 | call to operator* | TAINT |
|
||||
| vector.cpp:376:9:376:9 | 1 | vector.cpp:376:3:376:3 | call to operator* [post update] | TAINT |
|
||||
| vector.cpp:376:9:376:9 | 1 | vector.cpp:376:3:376:9 | ... = ... | |
|
||||
| vector.cpp:377:8:377:9 | ref arg v7 | vector.cpp:379:7:379:8 | v7 | |
|
||||
| vector.cpp:377:8:377:9 | ref arg v7 | vector.cpp:401:1:401:1 | v7 | |
|
||||
| vector.cpp:379:7:379:8 | ref arg v7 | vector.cpp:401:1:401:1 | v7 | |
|
||||
| vector.cpp:381:34:381:35 | ref arg v8 | vector.cpp:383:7:383:8 | v8 | |
|
||||
| vector.cpp:381:34:381:35 | ref arg v8 | vector.cpp:385:7:385:8 | v8 | |
|
||||
| vector.cpp:381:34:381:35 | ref arg v8 | vector.cpp:401:1:401:1 | v8 | |
|
||||
| vector.cpp:381:34:381:35 | v8 | vector.cpp:381:37:381:41 | call to begin | TAINT |
|
||||
| vector.cpp:381:37:381:41 | call to begin | vector.cpp:382:3:382:4 | i8 | |
|
||||
| vector.cpp:381:37:381:41 | call to begin | vector.cpp:384:3:384:4 | i8 | |
|
||||
| vector.cpp:382:2:382:2 | call to operator* [post update] | vector.cpp:383:7:383:8 | v8 | |
|
||||
| vector.cpp:382:2:382:2 | call to operator* [post update] | vector.cpp:385:7:385:8 | v8 | |
|
||||
| vector.cpp:382:2:382:2 | call to operator* [post update] | vector.cpp:401:1:401:1 | v8 | |
|
||||
| vector.cpp:382:2:382:15 | ... = ... | vector.cpp:382:2:382:2 | call to operator* [post update] | |
|
||||
| vector.cpp:382:3:382:4 | i8 | vector.cpp:382:2:382:2 | call to operator* | TAINT |
|
||||
| vector.cpp:382:8:382:13 | call to source | vector.cpp:382:2:382:2 | call to operator* [post update] | TAINT |
|
||||
| vector.cpp:382:8:382:13 | call to source | vector.cpp:382:2:382:15 | ... = ... | |
|
||||
| vector.cpp:383:7:383:8 | ref arg v8 | vector.cpp:385:7:385:8 | v8 | |
|
||||
| vector.cpp:383:7:383:8 | ref arg v8 | vector.cpp:401:1:401:1 | v8 | |
|
||||
| vector.cpp:384:2:384:2 | call to operator* [post update] | vector.cpp:385:7:385:8 | v8 | |
|
||||
| vector.cpp:384:2:384:2 | call to operator* [post update] | vector.cpp:401:1:401:1 | v8 | |
|
||||
| vector.cpp:384:2:384:8 | ... = ... | vector.cpp:384:2:384:2 | call to operator* [post update] | |
|
||||
| vector.cpp:384:3:384:4 | i8 | vector.cpp:384:2:384:2 | call to operator* | TAINT |
|
||||
| vector.cpp:384:8:384:8 | 1 | vector.cpp:384:2:384:2 | call to operator* [post update] | TAINT |
|
||||
| vector.cpp:384:8:384:8 | 1 | vector.cpp:384:2:384:8 | ... = ... | |
|
||||
| vector.cpp:385:7:385:8 | ref arg v8 | vector.cpp:401:1:401:1 | v8 | |
|
||||
| vector.cpp:387:34:387:35 | ref arg v9 | vector.cpp:392:7:392:8 | v9 | |
|
||||
| vector.cpp:387:34:387:35 | ref arg v9 | vector.cpp:401:1:401:1 | v9 | |
|
||||
| vector.cpp:387:34:387:35 | v9 | vector.cpp:387:37:387:41 | call to begin | TAINT |
|
||||
| vector.cpp:387:37:387:41 | call to begin | vector.cpp:389:3:389:4 | i9 | |
|
||||
| vector.cpp:387:37:387:41 | call to begin | vector.cpp:390:31:390:32 | i9 | |
|
||||
| vector.cpp:389:2:389:2 | call to operator* [post update] | vector.cpp:392:7:392:8 | v9 | |
|
||||
| vector.cpp:389:2:389:2 | call to operator* [post update] | vector.cpp:401:1:401:1 | v9 | |
|
||||
| vector.cpp:389:2:389:15 | ... = ... | vector.cpp:389:2:389:2 | call to operator* [post update] | |
|
||||
| vector.cpp:389:3:389:4 | i9 | vector.cpp:389:2:389:2 | call to operator* | TAINT |
|
||||
| vector.cpp:389:8:389:13 | call to source | vector.cpp:389:2:389:2 | call to operator* [post update] | TAINT |
|
||||
| vector.cpp:389:8:389:13 | call to source | vector.cpp:389:2:389:15 | ... = ... | |
|
||||
| vector.cpp:390:31:390:32 | call to iterator [post update] | vector.cpp:392:7:392:8 | v9 | |
|
||||
| vector.cpp:390:31:390:32 | call to iterator [post update] | vector.cpp:401:1:401:1 | v9 | |
|
||||
| vector.cpp:390:31:390:32 | i9 | vector.cpp:390:31:390:32 | call to iterator | |
|
||||
| vector.cpp:390:31:390:32 | i9 [post update] | vector.cpp:392:7:392:8 | v9 | |
|
||||
| vector.cpp:390:31:390:32 | i9 [post update] | vector.cpp:401:1:401:1 | v9 | |
|
||||
| vector.cpp:392:7:392:8 | ref arg v9 | vector.cpp:401:1:401:1 | v9 | |
|
||||
| vector.cpp:394:35:394:37 | ref arg v10 | vector.cpp:396:7:396:9 | v10 | |
|
||||
| vector.cpp:394:35:394:37 | ref arg v10 | vector.cpp:401:1:401:1 | v10 | |
|
||||
| vector.cpp:394:35:394:37 | v10 | vector.cpp:394:39:394:43 | call to begin | TAINT |
|
||||
| vector.cpp:394:39:394:43 | call to begin | vector.cpp:395:33:395:35 | i10 | |
|
||||
| vector.cpp:395:33:395:35 | call to iterator [post update] | vector.cpp:396:7:396:9 | v10 | |
|
||||
| vector.cpp:395:33:395:35 | call to iterator [post update] | vector.cpp:401:1:401:1 | v10 | |
|
||||
| vector.cpp:395:33:395:35 | i10 | vector.cpp:395:33:395:35 | call to iterator | |
|
||||
| vector.cpp:395:33:395:35 | i10 [post update] | vector.cpp:396:7:396:9 | v10 | |
|
||||
| vector.cpp:395:33:395:35 | i10 [post update] | vector.cpp:401:1:401:1 | v10 | |
|
||||
| vector.cpp:396:7:396:9 | ref arg v10 | vector.cpp:401:1:401:1 | v10 | |
|
||||
| vector.cpp:398:35:398:37 | ref arg v11 | vector.cpp:400:7:400:9 | v11 | |
|
||||
| vector.cpp:398:35:398:37 | ref arg v11 | vector.cpp:401:1:401:1 | v11 | |
|
||||
| vector.cpp:398:35:398:37 | v11 | vector.cpp:398:39:398:43 | call to begin | TAINT |
|
||||
| vector.cpp:398:39:398:43 | call to begin | vector.cpp:399:33:399:35 | i11 | |
|
||||
| vector.cpp:399:33:399:35 | call to iterator [post update] | vector.cpp:400:7:400:9 | v11 | |
|
||||
| vector.cpp:399:33:399:35 | call to iterator [post update] | vector.cpp:401:1:401:1 | v11 | |
|
||||
| vector.cpp:399:33:399:35 | i11 | vector.cpp:399:33:399:35 | call to iterator | |
|
||||
| vector.cpp:399:33:399:35 | i11 [post update] | vector.cpp:400:7:400:9 | v11 | |
|
||||
| vector.cpp:399:33:399:35 | i11 [post update] | vector.cpp:401:1:401:1 | v11 | |
|
||||
| vector.cpp:400:7:400:9 | ref arg v11 | vector.cpp:401:1:401:1 | v11 | |
|
||||
|
||||
@@ -531,3 +531,17 @@
|
||||
| vector.cpp:312:7:312:7 | d | vector.cpp:303:14:303:19 | call to source |
|
||||
| vector.cpp:324:7:324:8 | v2 | vector.cpp:318:15:318:20 | call to source |
|
||||
| vector.cpp:326:7:326:8 | v4 | vector.cpp:318:15:318:20 | call to source |
|
||||
| vector.cpp:342:7:342:8 | v1 | vector.cpp:341:8:341:13 | call to source |
|
||||
| vector.cpp:347:7:347:8 | v2 | vector.cpp:345:9:345:14 | call to source |
|
||||
| vector.cpp:357:7:357:8 | v4 | vector.cpp:330:10:330:15 | call to source |
|
||||
| vector.cpp:361:7:361:8 | v5 | vector.cpp:360:8:360:13 | call to source |
|
||||
| vector.cpp:363:7:363:8 | v5 | vector.cpp:360:8:360:13 | call to source |
|
||||
| vector.cpp:367:7:367:8 | v6 | vector.cpp:366:8:366:13 | call to source |
|
||||
| vector.cpp:369:7:369:8 | v6 | vector.cpp:366:8:366:13 | call to source |
|
||||
| vector.cpp:374:8:374:9 | v7 | vector.cpp:373:9:373:14 | call to source |
|
||||
| vector.cpp:379:7:379:8 | v7 | vector.cpp:373:9:373:14 | call to source |
|
||||
| vector.cpp:383:7:383:8 | v8 | vector.cpp:382:8:382:13 | call to source |
|
||||
| vector.cpp:385:7:385:8 | v8 | vector.cpp:382:8:382:13 | call to source |
|
||||
| vector.cpp:392:7:392:8 | v9 | vector.cpp:330:10:330:15 | call to source |
|
||||
| vector.cpp:392:7:392:8 | v9 | vector.cpp:389:8:389:13 | call to source |
|
||||
| vector.cpp:400:7:400:9 | v11 | vector.cpp:399:38:399:43 | call to source |
|
||||
|
||||
@@ -267,3 +267,17 @@
|
||||
| vector.cpp:292:7:292:18 | vector.cpp:289:17:289:30 | AST only |
|
||||
| vector.cpp:308:9:308:14 | vector.cpp:303:14:303:19 | AST only |
|
||||
| vector.cpp:311:9:311:14 | vector.cpp:303:14:303:19 | AST only |
|
||||
| vector.cpp:342:7:342:8 | vector.cpp:341:8:341:13 | AST only |
|
||||
| vector.cpp:347:7:347:8 | vector.cpp:345:9:345:14 | AST only |
|
||||
| vector.cpp:357:7:357:8 | vector.cpp:330:10:330:15 | AST only |
|
||||
| vector.cpp:361:7:361:8 | vector.cpp:360:8:360:13 | AST only |
|
||||
| vector.cpp:363:7:363:8 | vector.cpp:360:8:360:13 | AST only |
|
||||
| vector.cpp:367:7:367:8 | vector.cpp:366:8:366:13 | AST only |
|
||||
| vector.cpp:369:7:369:8 | vector.cpp:366:8:366:13 | AST only |
|
||||
| vector.cpp:374:8:374:9 | vector.cpp:373:9:373:14 | AST only |
|
||||
| vector.cpp:379:7:379:8 | vector.cpp:373:9:373:14 | AST only |
|
||||
| vector.cpp:383:7:383:8 | vector.cpp:382:8:382:13 | AST only |
|
||||
| vector.cpp:385:7:385:8 | vector.cpp:382:8:382:13 | AST only |
|
||||
| vector.cpp:392:7:392:8 | vector.cpp:330:10:330:15 | AST only |
|
||||
| vector.cpp:392:7:392:8 | vector.cpp:389:8:389:13 | AST only |
|
||||
| vector.cpp:400:7:400:9 | vector.cpp:399:38:399:43 | AST only |
|
||||
|
||||
@@ -21,7 +21,7 @@ void test_range_based_for_loop_vector(int source1) {
|
||||
}
|
||||
|
||||
for(std::vector<int>::iterator it = v.begin(); it != v.end(); ++it) {
|
||||
sink(*it); // tainted
|
||||
sink(*it); // tainted [NOT DETECTED by IR]
|
||||
}
|
||||
|
||||
for(int& x : v) {
|
||||
@@ -325,3 +325,77 @@ void test_constructors_more() {
|
||||
sink(v3);
|
||||
sink(v4); // tainted
|
||||
}
|
||||
|
||||
void taint_vector_output_iterator(std::vector<int>::iterator iter) {
|
||||
*iter = source();
|
||||
}
|
||||
|
||||
void vector_iterator_assign_wrapper(std::vector<int>::iterator iter, int i) {
|
||||
*iter = i;
|
||||
}
|
||||
|
||||
void test_vector_output_iterator(int b) {
|
||||
std::vector<int> v1(10), v2(10), v3(10), v4(10), v5(10), v6(10), v7(10), v8(10), v9(10), v10(10), v11(10);
|
||||
|
||||
std::vector<int>::iterator i1 = v1.begin();
|
||||
*i1 = source();
|
||||
sink(v1); // tainted [NOT DETECTED by IR]
|
||||
|
||||
for(std::vector<int>::iterator it = v2.begin(); it != v2.end(); ++it) {
|
||||
*it = source();
|
||||
}
|
||||
sink(v2); // tainted [NOT DETECTED by IR]
|
||||
|
||||
for(int& x : v3) {
|
||||
x = source();
|
||||
}
|
||||
sink(v3); // tainted [NOT DETECTED]
|
||||
|
||||
for(std::vector<int>::iterator it = v4.begin(); it != v4.end(); ++it) {
|
||||
taint_vector_output_iterator(it);
|
||||
}
|
||||
sink(v4); // tainted [NOT DETECTED by IR]
|
||||
|
||||
std::vector<int>::iterator i5 = v5.begin();
|
||||
*i5 = source();
|
||||
sink(v5); // tainted [NOT DETECTED by IR]
|
||||
*i5 = 1;
|
||||
sink(v5); // tainted [NOT DETECTED by IR]
|
||||
|
||||
std::vector<int>::iterator i6 = v6.begin();
|
||||
*i6 = source();
|
||||
sink(v6); // tainted [NOT DETECTED by IR]
|
||||
v6 = std::vector<int>(10);
|
||||
sink(v6); // [FALSE POSITIVE in AST]
|
||||
|
||||
std::vector<int>::iterator i7 = v7.begin();
|
||||
if(b) {
|
||||
*i7 = source();
|
||||
sink(v7); // tainted [NOT DETECTED by IR]
|
||||
} else {
|
||||
*i7 = 1;
|
||||
sink(v7);
|
||||
}
|
||||
sink(v7); // tainted [NOT DETECTED by IR]
|
||||
|
||||
std::vector<int>::iterator i8 = v8.begin();
|
||||
*i8 = source();
|
||||
sink(v8); // tainted [NOT DETECTED by IR]
|
||||
*i8 = 1;
|
||||
sink(v8);
|
||||
|
||||
std::vector<int>::iterator i9 = v9.begin();
|
||||
|
||||
*i9 = source();
|
||||
taint_vector_output_iterator(i9);
|
||||
|
||||
sink(v9);
|
||||
|
||||
std::vector<int>::iterator i10 = v10.begin();
|
||||
vector_iterator_assign_wrapper(i10, 10);
|
||||
sink(v10);
|
||||
|
||||
std::vector<int>::iterator i11 = v11.begin();
|
||||
vector_iterator_assign_wrapper(i11, source());
|
||||
sink(v11); // tainted [NOT DETECTED by IR]
|
||||
}
|
||||
|
||||
@@ -13,9 +13,9 @@
|
||||
| captures.cpp:3:5:3:5 | (constructor) |
|
||||
| captures.cpp:3:5:3:5 | (constructor) |
|
||||
| captures.cpp:3:5:3:5 | (constructor) |
|
||||
| captures.cpp:3:5:3:5 | declaration of (null) |
|
||||
| captures.cpp:3:5:3:5 | declaration of (null) |
|
||||
| captures.cpp:3:5:3:5 | definition of (null) |
|
||||
| captures.cpp:3:5:3:5 | declaration of (constructor) |
|
||||
| captures.cpp:3:5:3:5 | declaration of (constructor) |
|
||||
| captures.cpp:3:5:3:5 | definition of (constructor) |
|
||||
| captures.cpp:3:5:3:5 | definition of operator= |
|
||||
| captures.cpp:3:5:3:5 | operator= |
|
||||
| captures.cpp:3:5:5:5 | [...](...){...} |
|
||||
@@ -50,9 +50,9 @@
|
||||
| captures.cpp:9:5:9:5 | (constructor) |
|
||||
| captures.cpp:9:5:9:5 | (constructor) |
|
||||
| captures.cpp:9:5:9:5 | (constructor) |
|
||||
| captures.cpp:9:5:9:5 | declaration of (null) |
|
||||
| captures.cpp:9:5:9:5 | declaration of (null) |
|
||||
| captures.cpp:9:5:9:5 | definition of (null) |
|
||||
| captures.cpp:9:5:9:5 | declaration of (constructor) |
|
||||
| captures.cpp:9:5:9:5 | declaration of (constructor) |
|
||||
| captures.cpp:9:5:9:5 | definition of (constructor) |
|
||||
| captures.cpp:9:5:9:5 | definition of operator= |
|
||||
| captures.cpp:9:5:9:5 | operator= |
|
||||
| captures.cpp:9:5:11:5 | [...](...){...} |
|
||||
@@ -87,9 +87,9 @@
|
||||
| captures.cpp:15:5:15:5 | (constructor) |
|
||||
| captures.cpp:15:5:15:5 | (constructor) |
|
||||
| captures.cpp:15:5:15:5 | (constructor) |
|
||||
| captures.cpp:15:5:15:5 | declaration of (null) |
|
||||
| captures.cpp:15:5:15:5 | declaration of (null) |
|
||||
| captures.cpp:15:5:15:5 | definition of (null) |
|
||||
| captures.cpp:15:5:15:5 | declaration of (constructor) |
|
||||
| captures.cpp:15:5:15:5 | declaration of (constructor) |
|
||||
| captures.cpp:15:5:15:5 | definition of (constructor) |
|
||||
| captures.cpp:15:5:15:5 | definition of operator= |
|
||||
| captures.cpp:15:5:15:5 | operator= |
|
||||
| captures.cpp:15:5:17:5 | [...](...){...} |
|
||||
@@ -129,9 +129,9 @@
|
||||
| captures.cpp:22:19:22:19 | Unknown literal |
|
||||
| captures.cpp:22:19:22:19 | constructor init of field x |
|
||||
| captures.cpp:22:19:22:19 | constructor init of field y |
|
||||
| captures.cpp:22:19:22:19 | declaration of (null) |
|
||||
| captures.cpp:22:19:22:19 | definition of (null) |
|
||||
| captures.cpp:22:19:22:19 | definition of (null) |
|
||||
| captures.cpp:22:19:22:19 | declaration of (constructor) |
|
||||
| captures.cpp:22:19:22:19 | definition of (constructor) |
|
||||
| captures.cpp:22:19:22:19 | definition of (constructor) |
|
||||
| captures.cpp:22:19:22:19 | definition of operator= |
|
||||
| captures.cpp:22:19:22:19 | operator= |
|
||||
| captures.cpp:22:19:22:19 | return ... |
|
||||
@@ -187,9 +187,9 @@
|
||||
| end_pos.cpp:9:15:9:15 | (constructor) |
|
||||
| end_pos.cpp:9:15:9:15 | Unknown literal |
|
||||
| end_pos.cpp:9:15:9:15 | constructor init of field ii |
|
||||
| end_pos.cpp:9:15:9:15 | declaration of (null) |
|
||||
| end_pos.cpp:9:15:9:15 | definition of (null) |
|
||||
| end_pos.cpp:9:15:9:15 | definition of (null) |
|
||||
| end_pos.cpp:9:15:9:15 | declaration of (constructor) |
|
||||
| end_pos.cpp:9:15:9:15 | definition of (constructor) |
|
||||
| end_pos.cpp:9:15:9:15 | definition of (constructor) |
|
||||
| end_pos.cpp:9:15:9:15 | definition of operator= |
|
||||
| end_pos.cpp:9:15:9:15 | operator= |
|
||||
| end_pos.cpp:9:15:9:15 | return ... |
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
| copy_from_prototype.cpp:3:7:3:7 | a | a<int>::a(const a<int> &) -> void | copy_from_prototype.cpp:3:7:3:7 | a<int> | <no expr> |
|
||||
| copy_from_prototype.cpp:3:7:3:7 | operator= | a<int>::operator=(a<int> &&) -> a<int> & | copy_from_prototype.cpp:3:7:3:7 | a<int> | <no expr> |
|
||||
| copy_from_prototype.cpp:3:7:3:7 | operator= | a<int>::operator=(const a<int> &) -> a<int> & | copy_from_prototype.cpp:3:7:3:7 | a<int> | <no expr> |
|
||||
| copy_from_prototype.cpp:4:26:4:26 | a | a<<unnamed>>::a<(unnamed)>() -> void | copy_from_prototype.cpp:3:7:3:7 | a<<unnamed>> | 123 |
|
||||
| copy_from_prototype.cpp:4:26:4:26 | a | a<int>::a<(unnamed)>() -> void | copy_from_prototype.cpp:3:7:3:7 | a<int> | <no expr> |
|
||||
| copy_from_prototype.cpp:4:26:4:26 | a | a<<unnamed>>::a<(unnamed template parameter)>() -> void | copy_from_prototype.cpp:3:7:3:7 | a<<unnamed>> | 123 |
|
||||
| copy_from_prototype.cpp:4:26:4:26 | a | a<int>::a<(unnamed template parameter)>() -> void | copy_from_prototype.cpp:3:7:3:7 | a<int> | <no expr> |
|
||||
| copy_from_prototype.cpp:7:7:7:7 | b | b::b() -> void | copy_from_prototype.cpp:7:7:7:7 | b | <no expr> |
|
||||
| copy_from_prototype.cpp:7:7:7:7 | b | b::b(b &&) -> void | copy_from_prototype.cpp:7:7:7:7 | b | <no expr> |
|
||||
| copy_from_prototype.cpp:7:7:7:7 | b | b::b(const b &) -> void | copy_from_prototype.cpp:7:7:7:7 | b | <no expr> |
|
||||
@@ -13,8 +13,8 @@
|
||||
| copy_from_prototype.cpp:13:7:13:7 | c | c<int>::c(const c<int> &) -> void | copy_from_prototype.cpp:13:7:13:7 | c<int> | <no expr> |
|
||||
| copy_from_prototype.cpp:13:7:13:7 | operator= | c<int>::operator=(c<int> &&) -> c<int> & | copy_from_prototype.cpp:13:7:13:7 | c<int> | <no expr> |
|
||||
| copy_from_prototype.cpp:13:7:13:7 | operator= | c<int>::operator=(const c<int> &) -> c<int> & | copy_from_prototype.cpp:13:7:13:7 | c<int> | <no expr> |
|
||||
| copy_from_prototype.cpp:14:26:14:26 | c | c<T>::c<(unnamed)>() -> void | copy_from_prototype.cpp:13:7:13:7 | c<T> | X |
|
||||
| copy_from_prototype.cpp:14:26:14:26 | c | c<int>::c<(unnamed)>() -> void | copy_from_prototype.cpp:13:7:13:7 | c<int> | <no expr> |
|
||||
| copy_from_prototype.cpp:14:26:14:26 | c | c<T>::c<(unnamed template parameter)>() -> void | copy_from_prototype.cpp:13:7:13:7 | c<T> | X |
|
||||
| copy_from_prototype.cpp:14:26:14:26 | c | c<int>::c<(unnamed template parameter)>() -> void | copy_from_prototype.cpp:13:7:13:7 | c<int> | <no expr> |
|
||||
| copy_from_prototype.cpp:17:7:17:7 | d | d::d() -> void | copy_from_prototype.cpp:17:7:17:7 | d | <no expr> |
|
||||
| copy_from_prototype.cpp:17:7:17:7 | d | d::d(const d &) -> void | copy_from_prototype.cpp:17:7:17:7 | d | <no expr> |
|
||||
| copy_from_prototype.cpp:17:7:17:7 | d | d::d(d &&) -> void | copy_from_prototype.cpp:17:7:17:7 | d | <no expr> |
|
||||
@@ -24,7 +24,7 @@
|
||||
| copy_from_prototype.cpp:22:8:22:8 | e | e<int>::e(e<int> &&) -> void | copy_from_prototype.cpp:22:8:22:8 | e<int> | <no expr> |
|
||||
| copy_from_prototype.cpp:22:8:22:8 | operator= | e<int>::operator=(const e<int> &) -> e<int> & | copy_from_prototype.cpp:22:8:22:8 | e<int> | <no expr> |
|
||||
| copy_from_prototype.cpp:22:8:22:8 | operator= | e<int>::operator=(e<int> &&) -> e<int> & | copy_from_prototype.cpp:22:8:22:8 | e<int> | <no expr> |
|
||||
| copy_from_prototype.cpp:23:26:23:26 | e | e<T>::e<(unnamed)>() -> void | copy_from_prototype.cpp:22:8:22:8 | e<T> | 456 |
|
||||
| copy_from_prototype.cpp:26:35:26:43 | e | e<int>::e<(unnamed)>() -> void | copy_from_prototype.cpp:22:8:22:8 | e<int> | 456 |
|
||||
| copy_from_prototype.cpp:23:26:23:26 | e | e<T>::e<(unnamed template parameter)>() -> void | copy_from_prototype.cpp:22:8:22:8 | e<T> | 456 |
|
||||
| copy_from_prototype.cpp:26:35:26:43 | e | e<int>::e<(unnamed template parameter)>() -> void | copy_from_prototype.cpp:22:8:22:8 | e<int> | 456 |
|
||||
| file://:0:0:0:0 | operator= | __va_list_tag::operator=(__va_list_tag &&) -> __va_list_tag & | file://:0:0:0:0 | __va_list_tag | <none> |
|
||||
| file://:0:0:0:0 | operator= | __va_list_tag::operator=(const __va_list_tag &) -> __va_list_tag & | file://:0:0:0:0 | __va_list_tag | <none> |
|
||||
|
||||
@@ -78,8 +78,6 @@
|
||||
| copy.cpp:111:9:111:9 | MoveAssign | deleted | |
|
||||
| copy.cpp:111:9:111:9 | operator= | deleted | |
|
||||
| copy.cpp:113:17:113:25 | operator= | | |
|
||||
| copy.cpp:120:9:120:9 | OnlyCtor | | |
|
||||
| copy.cpp:120:9:120:9 | OnlyCtor | | |
|
||||
| copy.cpp:120:9:120:9 | OnlyCtor | deleted | |
|
||||
| copy.cpp:120:9:120:9 | operator= | deleted | |
|
||||
| copy.cpp:126:11:126:19 | operator= | | |
|
||||
|
||||
@@ -539,8 +539,6 @@ uniqueNodeLocation
|
||||
| file://:0:0:0:0 | p#0 | Node should have one location but has 0. |
|
||||
| file://:0:0:0:0 | p#0 | Node should have one location but has 0. |
|
||||
| file://:0:0:0:0 | p#0 | Node should have one location but has 0. |
|
||||
| file://:0:0:0:0 | p#0 | Node should have one location but has 0. |
|
||||
| file://:0:0:0:0 | p#0 | Node should have one location but has 0. |
|
||||
| file://:0:0:0:0 | p#1 | Node should have one location but has 0. |
|
||||
| file://:0:0:0:0 | p#1 | Node should have one location but has 0. |
|
||||
| file://:0:0:0:0 | p#1 | Node should have one location but has 0. |
|
||||
@@ -1418,7 +1416,7 @@ uniqueNodeLocation
|
||||
| whilestmt.c:39:6:39:11 | ReturnVoid | Node should have one location but has 4. |
|
||||
| whilestmt.c:39:6:39:11 | SideEffect | Node should have one location but has 4. |
|
||||
missingLocation
|
||||
| Nodes without location: 36 |
|
||||
| Nodes without location: 34 |
|
||||
uniqueNodeToString
|
||||
| break_labels.c:2:11:2:11 | i | Node should have one toString but has 2. |
|
||||
| break_labels.c:2:11:2:11 | i | Node should have one toString but has 2. |
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
| file://:0:0:0:0 | __va_list_tag | <none> |
|
||||
| test.cpp:3:8:3:9 | s1<<expression>> | {...} |
|
||||
| test.cpp:3:8:3:9 | s1<<unnamed>> | (null) |
|
||||
| test.cpp:3:8:3:9 | s1<<unnamed>> | (unnamed template parameter constant) |
|
||||
| test.cpp:5:8:5:9 | s2<T> | T |
|
||||
| test.cpp:5:8:5:9 | s2<T> | T |
|
||||
| test.cpp:7:8:7:9 | s3<T, <unnamed>> | (unnamed) |
|
||||
| test.cpp:7:8:7:9 | s3<T, <unnamed>> | (unnamed template parameter) |
|
||||
| test.cpp:7:8:7:9 | s3<T, <unnamed>> | T |
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
| decls.cpp:4:30:4:34 | p#0 |
|
||||
| decls.cpp:4:30:4:34 | p#0 |
|
||||
| decls.cpp:6:17:6:17 | f |
|
||||
| decls.cpp:8:18:8:18 | (unnamed) |
|
||||
| decls.cpp:8:18:8:18 | (unnamed template parameter) |
|
||||
| decls.cpp:8:25:8:25 | g |
|
||||
| file://:0:0:0:0 | __va_list_tag |
|
||||
| file://:0:0:0:0 | auto |
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
| file://:0:0:0:0 | | Other |
|
||||
| file://:0:0:0:0 | (global namespace) | Other |
|
||||
| file://:0:0:0:0 | <unnamed> | Other |
|
||||
| file://:0:0:0:0 | (unnamed global/namespace variable) | Other |
|
||||
| file://:0:0:0:0 | _Complex __float128 | Other |
|
||||
| file://:0:0:0:0 | _Complex double | Other |
|
||||
| file://:0:0:0:0 | _Complex float | Other |
|
||||
@@ -111,8 +111,8 @@
|
||||
| test.c:0:0:0:0 | test.c | Other |
|
||||
| test.c:2:6:2:6 | a | Other |
|
||||
| test.c:2:6:2:6 | definition of a | Other |
|
||||
| test.c:2:10:2:18 | <unnamed> | Variable access |
|
||||
| test.c:2:10:2:18 | (unnamed global/namespace variable) | Variable access |
|
||||
| test.c:2:10:2:18 | array to pointer conversion | Other |
|
||||
| test.c:2:10:2:18 | initializer for a | Other |
|
||||
| test.c:2:17:2:18 | initializer for <unnamed> | Other |
|
||||
| test.c:2:17:2:18 | initializer for (unnamed global/namespace variable) | Other |
|
||||
| test.c:2:17:2:18 | {...} | Other |
|
||||
|
||||
Reference in New Issue
Block a user