mirror of
https://github.com/github/codeql.git
synced 2026-04-30 03:05:15 +02:00
Merge remote-tracking branch 'upstream/master' into dataflow-indirect-args
Conflicts: cpp/ql/test/library-tests/dataflow/fields/ir-flow.expected
This commit is contained in:
@@ -4,6 +4,10 @@
|
||||
|
||||
import cpp
|
||||
|
||||
/**
|
||||
* Gets a string representation of the comment `c` containing the caption 'TODO' or 'FIXME'.
|
||||
* If `c` spans multiple lines, all lines after the first are abbreviated as [...].
|
||||
*/
|
||||
string getCommentTextCaptioned(Comment c, string caption) {
|
||||
(caption = "TODO" or caption = "FIXME") and
|
||||
exists(
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
/**
|
||||
* Provides classes and predicates for identifying C/C++ comments that look like code.
|
||||
*/
|
||||
|
||||
import cpp
|
||||
|
||||
/**
|
||||
@@ -137,8 +141,14 @@ class CommentBlock extends Comment {
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the last comment associated with this comment block.
|
||||
*/
|
||||
Comment lastComment() { result = this.getComment(max(int i | exists(this.getComment(i)))) }
|
||||
|
||||
/**
|
||||
* Gets the contents of the `i`'th comment associated with this comment block.
|
||||
*/
|
||||
string getLine(int i) {
|
||||
this instanceof CStyleComment and
|
||||
result = this.getContents().regexpCapture("(?s)/\\*+(.*)\\*+/", 1).splitAt("\n", i)
|
||||
@@ -146,14 +156,24 @@ class CommentBlock extends Comment {
|
||||
this instanceof CppStyleComment and result = this.getComment(i).getContents().suffix(2)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the number of lines in the comments associated with this comment block.
|
||||
*/
|
||||
int numLines() {
|
||||
result = strictcount(int i, string line | line = this.getLine(i) and line.trim() != "")
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the number of lines that look like code in the comments associated with this comment block.
|
||||
*/
|
||||
int numCodeLines() {
|
||||
result = strictcount(int i, string line | line = this.getLine(i) and looksLikeCode(line))
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if the comment block is a C-style comment, and each
|
||||
* comment line starts with a *.
|
||||
*/
|
||||
predicate isDocumentation() {
|
||||
// If a C-style comment starts each line with a *, then it's
|
||||
// probably documentation rather than code.
|
||||
@@ -161,6 +181,12 @@ class CommentBlock extends Comment {
|
||||
forex(int i | i in [1 .. this.numLines() - 1] | this.getLine(i).trim().matches("*%"))
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if this comment block looks like code that has been commented out. Specifically:
|
||||
* 1. It does not look like documentation (see `isDocumentation`).
|
||||
* 2. It is not in a header file without any declaration entries or top level declarations.
|
||||
* 3. More than half of the lines in the comment block look like code.
|
||||
*/
|
||||
predicate isCommentedOutCode() {
|
||||
not this.isDocumentation() and
|
||||
not this.getFile().(HeaderFile).noTopLevelCode() and
|
||||
|
||||
9
cpp/ql/src/semmle/code/cpp/ASTConsistency.ql
Normal file
9
cpp/ql/src/semmle/code/cpp/ASTConsistency.ql
Normal file
@@ -0,0 +1,9 @@
|
||||
/**
|
||||
* @name AST Consistency Check
|
||||
* @description Performs consistency checks on the Abstract Syntax Tree. This query should have no results.
|
||||
* @kind table
|
||||
* @id cpp/ast-consistency-check
|
||||
*/
|
||||
|
||||
import cpp
|
||||
import CastConsistency
|
||||
@@ -1,9 +0,0 @@
|
||||
/**
|
||||
* @name AST Sanity Check
|
||||
* @description Performs sanity checks on the Abstract Syntax Tree. This query should have no results.
|
||||
* @kind table
|
||||
* @id cpp/ast-sanity-check
|
||||
*/
|
||||
|
||||
import cpp
|
||||
import CastSanity
|
||||
@@ -4,6 +4,14 @@
|
||||
* passed to a function, or similar.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Maintainer note: this file is one of several files that are similar but not
|
||||
* identical. Many changes to this file will also apply to the others:
|
||||
* - AddressConstantExpression.qll
|
||||
* - AddressFlow.qll
|
||||
* - EscapesTree.qll
|
||||
*/
|
||||
|
||||
private import cpp
|
||||
|
||||
/**
|
||||
@@ -11,15 +19,13 @@ private import cpp
|
||||
* template functions, these functions are essentially casts, so we treat them
|
||||
* as such.
|
||||
*/
|
||||
private predicate stdIdentityFunction(Function f) {
|
||||
f.getNamespace().getParentNamespace() instanceof GlobalNamespace and
|
||||
f.getNamespace().getName() = "std" and
|
||||
(
|
||||
f.getName() = "move"
|
||||
or
|
||||
f.getName() = "forward"
|
||||
)
|
||||
}
|
||||
private predicate stdIdentityFunction(Function f) { f.hasQualifiedName("std", ["move", "forward"]) }
|
||||
|
||||
/**
|
||||
* Holds if `f` is an instantiation of `std::addressof`, which effectively
|
||||
* converts a reference to a pointer.
|
||||
*/
|
||||
private predicate stdAddressOf(Function f) { f.hasQualifiedName("std", "addressof") }
|
||||
|
||||
private predicate lvalueToLvalueStepPure(Expr lvalueIn, Expr lvalueOut) {
|
||||
lvalueIn = lvalueOut.(DotFieldAccess).getQualifier().getFullyConverted()
|
||||
@@ -91,12 +97,17 @@ private predicate lvalueToReferenceStep(Expr lvalueIn, Expr referenceOut) {
|
||||
}
|
||||
|
||||
private predicate referenceToLvalueStep(Expr referenceIn, Expr lvalueOut) {
|
||||
// This probably cannot happen. It would require an expression to be
|
||||
// converted to a reference and back again without an intermediate variable
|
||||
// assignment.
|
||||
referenceIn.getConversion() = lvalueOut.(ReferenceDereferenceExpr)
|
||||
}
|
||||
|
||||
private predicate referenceToPointerStep(Expr referenceIn, Expr pointerOut) {
|
||||
pointerOut =
|
||||
any(FunctionCall call |
|
||||
stdAddressOf(call.getTarget()) and
|
||||
referenceIn = call.getArgument(0).getFullyConverted()
|
||||
)
|
||||
}
|
||||
|
||||
private predicate referenceToReferenceStep(Expr referenceIn, Expr referenceOut) {
|
||||
referenceOut =
|
||||
any(FunctionCall call |
|
||||
@@ -145,6 +156,12 @@ private predicate pointerFromVariableAccess(VariableAccess va, Expr pointer) {
|
||||
pointerToPointerStep(prev, pointer)
|
||||
)
|
||||
or
|
||||
// reference -> pointer
|
||||
exists(Expr prev |
|
||||
referenceFromVariableAccess(va, prev) and
|
||||
referenceToPointerStep(prev, pointer)
|
||||
)
|
||||
or
|
||||
// lvalue -> pointer
|
||||
exists(Expr prev |
|
||||
lvalueFromVariableAccess(va, prev) and
|
||||
@@ -169,7 +186,8 @@ private predicate referenceFromVariableAccess(VariableAccess va, Expr reference)
|
||||
private predicate addressMayEscapeAt(Expr e) {
|
||||
exists(Call call |
|
||||
e = call.getAnArgument().getFullyConverted() and
|
||||
not stdIdentityFunction(call.getTarget())
|
||||
not stdIdentityFunction(call.getTarget()) and
|
||||
not stdAddressOf(call.getTarget())
|
||||
or
|
||||
e = call.getQualifier().getFullyConverted() and
|
||||
e.getUnderlyingType() instanceof PointerType
|
||||
|
||||
247
cpp/ql/src/semmle/code/cpp/dataflow/internal/AddressFlow.qll
Normal file
247
cpp/ql/src/semmle/code/cpp/dataflow/internal/AddressFlow.qll
Normal file
@@ -0,0 +1,247 @@
|
||||
/**
|
||||
* Provides a local analysis for identifying where a variable address
|
||||
* is effectively taken. Array-like offsets are allowed to pass through but
|
||||
* not field-like offsets.
|
||||
*
|
||||
* This library is specialized to meet the needs of `FlowVar.qll`.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Maintainer note: this file is one of several files that are similar but not
|
||||
* identical. Many changes to this file will also apply to the others:
|
||||
* - AddressConstantExpression.qll
|
||||
* - AddressFlow.qll
|
||||
* - EscapesTree.qll
|
||||
*/
|
||||
|
||||
private import cpp
|
||||
|
||||
/**
|
||||
* Holds if `f` is an instantiation of the `std::move` or `std::forward`
|
||||
* template functions, these functions are essentially casts, so we treat them
|
||||
* as such.
|
||||
*/
|
||||
private predicate stdIdentityFunction(Function f) { f.hasQualifiedName("std", ["move", "forward"]) }
|
||||
|
||||
/**
|
||||
* Holds if `f` is an instantiation of `std::addressof`, which effectively
|
||||
* converts a reference to a pointer.
|
||||
*/
|
||||
private predicate stdAddressOf(Function f) { f.hasQualifiedName("std", "addressof") }
|
||||
|
||||
private predicate lvalueToLvalueStep(Expr lvalueIn, Expr lvalueOut) {
|
||||
lvalueIn.getConversion() = lvalueOut.(ParenthesisExpr)
|
||||
or
|
||||
// When an object is implicitly converted to a reference to one of its base
|
||||
// classes, it gets two `Conversion`s: there is first an implicit
|
||||
// `CStyleCast` to its base class followed by a `ReferenceToExpr` to a
|
||||
// reference to its base class. Whereas an explicit cast to the base class
|
||||
// would produce an rvalue, which would not be convertible to an lvalue
|
||||
// reference, this implicit cast instead produces an lvalue. The following
|
||||
// case ensures that we propagate the property of being an lvalue through
|
||||
// such casts.
|
||||
lvalueIn.getConversion() = lvalueOut and
|
||||
lvalueOut.(CStyleCast).isImplicit()
|
||||
or
|
||||
// C++ only
|
||||
lvalueIn = lvalueOut.(PrefixCrementOperation).getOperand().getFullyConverted()
|
||||
or
|
||||
// C++ only
|
||||
lvalueIn = lvalueOut.(Assignment).getLValue().getFullyConverted()
|
||||
}
|
||||
|
||||
private predicate pointerToLvalueStep(Expr pointerIn, Expr lvalueOut) {
|
||||
pointerIn = lvalueOut.(ArrayExpr).getArrayBase().getFullyConverted()
|
||||
or
|
||||
pointerIn = lvalueOut.(PointerDereferenceExpr).getOperand().getFullyConverted()
|
||||
}
|
||||
|
||||
private predicate lvalueToPointerStep(Expr lvalueIn, Expr pointerOut) {
|
||||
lvalueIn.getConversion() = pointerOut.(ArrayToPointerConversion)
|
||||
or
|
||||
lvalueIn = pointerOut.(AddressOfExpr).getOperand().getFullyConverted()
|
||||
}
|
||||
|
||||
private predicate pointerToPointerStep(Expr pointerIn, Expr pointerOut) {
|
||||
(
|
||||
pointerOut instanceof PointerAddExpr
|
||||
or
|
||||
pointerOut instanceof PointerSubExpr
|
||||
) and
|
||||
pointerIn = pointerOut.getAChild().getFullyConverted() and
|
||||
pointerIn.getUnspecifiedType() instanceof PointerType
|
||||
or
|
||||
pointerIn = pointerOut.(UnaryPlusExpr).getOperand().getFullyConverted()
|
||||
or
|
||||
pointerIn.getConversion() = pointerOut.(Cast)
|
||||
or
|
||||
pointerIn.getConversion() = pointerOut.(ParenthesisExpr)
|
||||
or
|
||||
pointerIn = pointerOut.(ConditionalExpr).getThen().getFullyConverted()
|
||||
or
|
||||
pointerIn = pointerOut.(ConditionalExpr).getElse().getFullyConverted()
|
||||
or
|
||||
pointerIn = pointerOut.(CommaExpr).getRightOperand().getFullyConverted()
|
||||
or
|
||||
pointerIn = pointerOut.(StmtExpr).getResultExpr().getFullyConverted()
|
||||
}
|
||||
|
||||
private predicate lvalueToReferenceStep(Expr lvalueIn, Expr referenceOut) {
|
||||
lvalueIn.getConversion() = referenceOut.(ReferenceToExpr)
|
||||
}
|
||||
|
||||
private predicate referenceToLvalueStep(Expr referenceIn, Expr lvalueOut) {
|
||||
referenceIn.getConversion() = lvalueOut.(ReferenceDereferenceExpr)
|
||||
}
|
||||
|
||||
private predicate referenceToPointerStep(Expr referenceIn, Expr pointerOut) {
|
||||
pointerOut =
|
||||
any(FunctionCall call |
|
||||
stdAddressOf(call.getTarget()) and
|
||||
referenceIn = call.getArgument(0).getFullyConverted()
|
||||
)
|
||||
}
|
||||
|
||||
private predicate referenceToReferenceStep(Expr referenceIn, Expr referenceOut) {
|
||||
referenceOut =
|
||||
any(FunctionCall call |
|
||||
stdIdentityFunction(call.getTarget()) and
|
||||
referenceIn = call.getArgument(0).getFullyConverted()
|
||||
)
|
||||
or
|
||||
referenceIn.getConversion() = referenceOut.(Cast)
|
||||
or
|
||||
referenceIn.getConversion() = referenceOut.(ParenthesisExpr)
|
||||
}
|
||||
|
||||
private predicate assignmentTo(Expr updated, ControlFlowNode node) {
|
||||
updated = node.(Assignment).getLValue().getFullyConverted()
|
||||
or
|
||||
updated = node.(CrementOperation).getOperand().getFullyConverted()
|
||||
}
|
||||
|
||||
private predicate lvalueToUpdate(Expr lvalue, Expr outer, ControlFlowNode node) {
|
||||
(
|
||||
exists(Call call | node = call |
|
||||
outer = call.getQualifier().getFullyConverted() and
|
||||
outer.getUnspecifiedType() instanceof Class and
|
||||
not call.getTarget().hasSpecifier("const")
|
||||
)
|
||||
or
|
||||
assignmentTo(outer, node)
|
||||
or
|
||||
exists(DotFieldAccess fa |
|
||||
// `fa.otherField = ...` or `f(&fa)` or similar
|
||||
outer = fa.getQualifier().getFullyConverted() and
|
||||
valueToUpdate(fa, _, node)
|
||||
)
|
||||
) and
|
||||
lvalue = outer
|
||||
or
|
||||
exists(Expr lvalueMid |
|
||||
lvalueToLvalueStep(lvalue, lvalueMid) and
|
||||
lvalueToUpdate(lvalueMid, outer, node)
|
||||
)
|
||||
or
|
||||
exists(Expr pointerMid |
|
||||
lvalueToPointerStep(lvalue, pointerMid) and
|
||||
pointerToUpdate(pointerMid, outer, node)
|
||||
)
|
||||
or
|
||||
exists(Expr referenceMid |
|
||||
lvalueToReferenceStep(lvalue, referenceMid) and
|
||||
referenceToUpdate(referenceMid, outer, node)
|
||||
)
|
||||
}
|
||||
|
||||
private predicate pointerToUpdate(Expr pointer, Expr outer, ControlFlowNode node) {
|
||||
(
|
||||
exists(Call call | node = call |
|
||||
outer = call.getAnArgument().getFullyConverted() and
|
||||
exists(PointerType pt | pt = outer.getType().stripTopLevelSpecifiers() |
|
||||
not pt.getBaseType().isConst()
|
||||
)
|
||||
or
|
||||
outer = call.getQualifier().getFullyConverted() and
|
||||
outer.getUnspecifiedType() instanceof PointerType and
|
||||
not call.getTarget().hasSpecifier("const")
|
||||
)
|
||||
or
|
||||
exists(PointerFieldAccess fa |
|
||||
// `fa.otherField = ...` or `f(&fa)` or similar
|
||||
outer = fa.getQualifier().getFullyConverted() and
|
||||
valueToUpdate(fa, _, node)
|
||||
)
|
||||
) and
|
||||
pointer = outer
|
||||
or
|
||||
exists(Expr lvalueMid |
|
||||
pointerToLvalueStep(pointer, lvalueMid) and
|
||||
lvalueToUpdate(lvalueMid, outer, node)
|
||||
)
|
||||
or
|
||||
exists(Expr pointerMid |
|
||||
pointerToPointerStep(pointer, pointerMid) and
|
||||
pointerToUpdate(pointerMid, outer, node)
|
||||
)
|
||||
}
|
||||
|
||||
private predicate referenceToUpdate(Expr reference, Expr outer, ControlFlowNode node) {
|
||||
exists(Call call |
|
||||
node = call and
|
||||
outer = call.getAnArgument().getFullyConverted() and
|
||||
not stdIdentityFunction(call.getTarget()) and
|
||||
not stdAddressOf(call.getTarget()) and
|
||||
exists(ReferenceType rt | rt = outer.getType().stripTopLevelSpecifiers() |
|
||||
not rt.getBaseType().isConst()
|
||||
)
|
||||
) and
|
||||
reference = outer
|
||||
or
|
||||
exists(Expr lvalueMid |
|
||||
referenceToLvalueStep(reference, lvalueMid) and
|
||||
lvalueToUpdate(lvalueMid, outer, node)
|
||||
)
|
||||
or
|
||||
exists(Expr pointerMid |
|
||||
referenceToPointerStep(reference, pointerMid) and
|
||||
pointerToUpdate(pointerMid, outer, node)
|
||||
)
|
||||
or
|
||||
exists(Expr referenceMid |
|
||||
referenceToReferenceStep(reference, referenceMid) and
|
||||
referenceToUpdate(referenceMid, outer, node)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `node` is a control-flow node that may modify `inner` (or what it
|
||||
* points to) through `outer`. The two expressions may be `Conversion`s. Plain
|
||||
* assignments to variables are not included in this predicate since they are
|
||||
* assumed to be analyzed by SSA or similar means.
|
||||
*
|
||||
* For example, in `f(& (*a).x)`, there are two results:
|
||||
* - `inner` = `... .x`, `outer` = `&...`, `node` = `f(...)`.
|
||||
* - `inner` = `a`, `outer` = `(...)`, `node` = `f(...)`.
|
||||
*/
|
||||
cached
|
||||
predicate valueToUpdate(Expr inner, Expr outer, ControlFlowNode node) {
|
||||
(
|
||||
lvalueToUpdate(inner, outer, node)
|
||||
or
|
||||
pointerToUpdate(inner, outer, node)
|
||||
or
|
||||
referenceToUpdate(inner, outer, node)
|
||||
) and
|
||||
(
|
||||
inner instanceof VariableAccess and
|
||||
// Don't track non-field assignments
|
||||
(assignmentTo(outer, _) implies inner instanceof FieldAccess)
|
||||
or
|
||||
inner instanceof ThisExpr
|
||||
or
|
||||
inner instanceof Call
|
||||
// `inner` could also be `*` or `ReferenceDereferenceExpr`, but we
|
||||
// can't do anything useful with those at the moment.
|
||||
)
|
||||
}
|
||||
@@ -311,9 +311,6 @@ predicate isImmutableOrUnobservable(Node n) {
|
||||
or
|
||||
dt.getBaseType() instanceof RoutineType
|
||||
)
|
||||
or
|
||||
// Isn't something we can track
|
||||
n.asExpr() instanceof Call
|
||||
// The above list of cases isn't exhaustive, but it narrows down the
|
||||
// consistency alerts enough that most of them are interesting.
|
||||
}
|
||||
|
||||
@@ -20,10 +20,12 @@ private newtype TNode =
|
||||
TInstanceParameterNode(MemberFunction f) { exists(f.getBlock()) and not f.isStatic() } or
|
||||
TPreConstructorInitThis(ConstructorFieldInit cfi) or
|
||||
TPostConstructorInitThis(ConstructorFieldInit cfi) or
|
||||
TThisArgumentPostUpdate(ThisExpr ta) {
|
||||
exists(Call c, int i |
|
||||
ta = c.getArgument(i) and
|
||||
not c.getTarget().getParameter(i).getUnderlyingType().(PointerType).getBaseType().isConst()
|
||||
TInnerPartialDefinitionNode(Expr e) {
|
||||
exists(PartialDefinition def, Expr outer |
|
||||
def.definesExpressions(e, outer) and
|
||||
// This condition ensures that we don't get two post-update nodes sharing
|
||||
// the same pre-update node.
|
||||
e != outer
|
||||
)
|
||||
} or
|
||||
TUninitializedNode(LocalVariable v) { not v.hasInitializer() } or
|
||||
@@ -66,7 +68,7 @@ class Node extends TNode {
|
||||
* a partial definition of `&x`).
|
||||
*/
|
||||
Expr asPartialDefinition() {
|
||||
result = this.(PartialDefinitionNode).getPartialDefinition().getDefinedExpr()
|
||||
this.(PartialDefinitionNode).getPartialDefinition().definesExpressions(_, result)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -198,25 +200,23 @@ class ImplicitParameterNode extends ParameterNode, TInstanceParameterNode {
|
||||
* returned. This node will have its `getArgument()` equal to `&x`.
|
||||
*/
|
||||
class DefinitionByReferenceNode extends PartialDefinitionNode {
|
||||
VariableAccess va;
|
||||
Expr inner;
|
||||
Expr argument;
|
||||
|
||||
DefinitionByReferenceNode() {
|
||||
exists(DefinitionByReference def |
|
||||
def = this.getPartialDefinition() and
|
||||
argument = def.getDefinedExpr() and
|
||||
va = def.getVariableAccess()
|
||||
)
|
||||
this.getPartialDefinition().(DefinitionByReference).definesExpressions(inner, argument)
|
||||
}
|
||||
|
||||
override Function getFunction() { result = va.getEnclosingFunction() }
|
||||
override Function getFunction() { result = inner.getEnclosingFunction() }
|
||||
|
||||
override Type getType() { result = va.getType() }
|
||||
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 }
|
||||
|
||||
/** Gets the argument corresponding to this node. */
|
||||
Expr getArgument() { result = argument }
|
||||
|
||||
@@ -297,7 +297,7 @@ private class PartialDefinitionNode extends PostUpdateNode, TPartialDefinitionNo
|
||||
|
||||
PartialDefinitionNode() { this = TPartialDefinitionNode(pd) }
|
||||
|
||||
override Node getPreUpdateNode() { result.asExpr() = pd.getDefinedExpr() }
|
||||
override Node getPreUpdateNode() { pd.definesExpressions(_, result.asExpr()) }
|
||||
|
||||
override Location getLocation() { result = pd.getActualLocation() }
|
||||
|
||||
@@ -306,14 +306,23 @@ private class PartialDefinitionNode extends PostUpdateNode, TPartialDefinitionNo
|
||||
override string toString() { result = getPreUpdateNode().toString() + " [post update]" }
|
||||
}
|
||||
|
||||
private class ThisArgumentPostUpdateNode extends PostUpdateNode, TThisArgumentPostUpdate {
|
||||
ThisExpr thisExpr;
|
||||
/**
|
||||
* A post-update node on the `e->f` in `f(&e->f)` (and other forms).
|
||||
*/
|
||||
private class InnerPartialDefinitionNode extends TInnerPartialDefinitionNode, PostUpdateNode {
|
||||
Expr e;
|
||||
|
||||
ThisArgumentPostUpdateNode() { this = TThisArgumentPostUpdate(thisExpr) }
|
||||
InnerPartialDefinitionNode() { this = TInnerPartialDefinitionNode(e) }
|
||||
|
||||
override Node getPreUpdateNode() { result.asExpr() = thisExpr }
|
||||
override ExprNode getPreUpdateNode() { result.getExpr() = e }
|
||||
|
||||
override string toString() { result = "ref arg this" }
|
||||
override Function getFunction() { result = e.getEnclosingFunction() }
|
||||
|
||||
override Type getType() { result = e.getType() }
|
||||
|
||||
override string toString() { result = e.toString() + " [inner post update]" }
|
||||
|
||||
override Location getLocation() { result = e.getLocation() }
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -518,6 +527,14 @@ predicate simpleLocalFlowStep(Node nodeFrom, Node nodeTo) {
|
||||
or
|
||||
// post-update-`this` -> following-`this`-ref
|
||||
ThisFlow::adjacentThisRefs(nodeFrom.(PostUpdateNode).getPreUpdateNode(), nodeTo)
|
||||
or
|
||||
// In `f(&x->a)`, this step provides the flow from post-`&` to post-`x->a`,
|
||||
// from which there is field flow to `x` via reverse read.
|
||||
exists(PartialDefinition def, Expr inner, Expr outer |
|
||||
def.definesExpressions(inner, outer) and
|
||||
inner = nodeTo.(InnerPartialDefinitionNode).getPreUpdateNode().asExpr() and
|
||||
outer = nodeFrom.(PartialDefinitionNode).getPreUpdateNode().asExpr()
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -5,6 +5,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
|
||||
|
||||
/**
|
||||
* A conceptual variable that is assigned only once, like an SSA variable. This
|
||||
@@ -56,15 +57,9 @@ class FlowVar extends TFlowVar {
|
||||
abstract predicate definedByExpr(Expr e, ControlFlowNode node);
|
||||
|
||||
/**
|
||||
* Holds if this `FlowVar` corresponds to the data written by a call that
|
||||
* passes a variable as argument `arg`.
|
||||
*/
|
||||
cached
|
||||
abstract predicate definedByReference(Expr arg);
|
||||
|
||||
/**
|
||||
* Holds if this `FlowVar` is a `PartialDefinition` whose defined expression
|
||||
* is `e`.
|
||||
* Holds if this `FlowVar` is a `PartialDefinition` whose outer defined
|
||||
* expression is `e`. For example, in `f(&x)`, the outer defined expression
|
||||
* is `&x`.
|
||||
*/
|
||||
cached
|
||||
abstract predicate definedPartiallyAt(Expr e);
|
||||
@@ -113,39 +108,21 @@ class FlowVar extends TFlowVar {
|
||||
* ```
|
||||
*/
|
||||
private module PartialDefinitions {
|
||||
private predicate isInstanceFieldWrite(FieldAccess fa, ControlFlowNode node) {
|
||||
assignmentLikeOperation(node, _, fa, _)
|
||||
}
|
||||
|
||||
class PartialDefinition extends Expr {
|
||||
Expr innerDefinedExpr;
|
||||
ControlFlowNode node;
|
||||
|
||||
PartialDefinition() {
|
||||
exists(FieldAccess fa | this = fa.getQualifier() |
|
||||
// `fa = ...`, `fa += ...`, etc.
|
||||
isInstanceFieldWrite(fa, node)
|
||||
or
|
||||
// `fa.a = ...`, `f(&fa)`, etc.
|
||||
exists(PartialDefinition pd |
|
||||
node = pd.getSubBasicBlockStart() and
|
||||
fa = pd.getDefinedExpr()
|
||||
)
|
||||
exists(Expr convertedInner |
|
||||
valueToUpdate(convertedInner, this.getFullyConverted(), node) and
|
||||
innerDefinedExpr = convertedInner.getUnconverted() and
|
||||
not this instanceof Conversion
|
||||
)
|
||||
or
|
||||
// `e.f(...)`
|
||||
exists(Call call |
|
||||
this = call.getQualifier() and
|
||||
not call.getTarget().hasSpecifier("const")
|
||||
) and
|
||||
node = this
|
||||
or
|
||||
// `f(e)`, `f(&e)`, etc.
|
||||
referenceArgument(node, this)
|
||||
}
|
||||
|
||||
predicate partiallyDefines(Variable v) { this = v.getAnAccess() }
|
||||
predicate partiallyDefines(Variable v) { innerDefinedExpr = v.getAnAccess() }
|
||||
|
||||
predicate partiallyDefinesThis(ThisExpr e) { this = e }
|
||||
predicate partiallyDefinesThis(ThisExpr e) { innerDefinedExpr = e }
|
||||
|
||||
/**
|
||||
* Gets the subBasicBlock where this `PartialDefinition` is defined.
|
||||
@@ -153,14 +130,17 @@ private module PartialDefinitions {
|
||||
ControlFlowNode getSubBasicBlockStart() { result = node }
|
||||
|
||||
/**
|
||||
* Gets the expression that is being partially defined. For example in the
|
||||
* following code:
|
||||
* ```
|
||||
* x.y = 1;
|
||||
* ```
|
||||
* The expression `x` is being partially defined.
|
||||
* 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` = `*`
|
||||
*/
|
||||
Expr getDefinedExpr() { result = this }
|
||||
predicate definesExpressions(Expr inner, Expr outer) {
|
||||
inner = innerDefinedExpr and
|
||||
outer = this
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the location of this element, adjusted to avoid unknown locations
|
||||
@@ -180,38 +160,7 @@ private module PartialDefinitions {
|
||||
* A partial definition that's a definition by reference.
|
||||
*/
|
||||
class DefinitionByReference extends PartialDefinition {
|
||||
VariableAccess va;
|
||||
|
||||
DefinitionByReference() { referenceArgument(va, this) }
|
||||
|
||||
VariableAccess getVariableAccess() { result = va }
|
||||
|
||||
override predicate partiallyDefines(Variable v) { va = v.getAnAccess() }
|
||||
}
|
||||
|
||||
private predicate referenceArgument(VariableAccess va, Expr argument) {
|
||||
argument = any(Call c).getAnArgument() and
|
||||
exists(Type argumentType |
|
||||
argumentType = argument.getFullyConverted().getType().stripTopLevelSpecifiers()
|
||||
|
|
||||
argumentType instanceof ReferenceType and
|
||||
not argumentType.(ReferenceType).getBaseType().isConst() and
|
||||
va = argument
|
||||
or
|
||||
argumentType instanceof PointerType and
|
||||
not argumentType.(PointerType).getBaseType().isConst() and
|
||||
(
|
||||
// f(variable)
|
||||
va = argument
|
||||
or
|
||||
// f(&variable)
|
||||
va = argument.(AddressOfExpr).getOperand()
|
||||
or
|
||||
// f(&array[0])
|
||||
va.getType().getUnspecifiedType() instanceof ArrayType and
|
||||
va = argument.(AddressOfExpr).getOperand().(ArrayExpr).getArrayBase()
|
||||
)
|
||||
)
|
||||
DefinitionByReference() { exists(Call c | this = c.getAnArgument() or this = c.getQualifier()) }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -328,10 +277,6 @@ module FlowVar_internal {
|
||||
)
|
||||
}
|
||||
|
||||
override predicate definedByReference(Expr arg) {
|
||||
none() // Not supported for SSA. See `fullySupportedSsaVariable`.
|
||||
}
|
||||
|
||||
override predicate definedPartiallyAt(Expr e) { none() }
|
||||
|
||||
override predicate definedByInitialValue(StackVariable param) {
|
||||
@@ -416,19 +361,11 @@ module FlowVar_internal {
|
||||
node = sbb.getANode()
|
||||
}
|
||||
|
||||
override predicate definedByReference(Expr arg) {
|
||||
exists(DefinitionByReference def |
|
||||
def.partiallyDefines(v) and
|
||||
sbb = def.getSubBasicBlockStart() and
|
||||
arg = def.getDefinedExpr()
|
||||
)
|
||||
}
|
||||
|
||||
override predicate definedPartiallyAt(Expr e) {
|
||||
exists(PartialDefinition p |
|
||||
p.partiallyDefines(v) and
|
||||
sbb = p.getSubBasicBlockStart() and
|
||||
e = p.getDefinedExpr()
|
||||
p.definesExpressions(_, e)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -441,11 +378,6 @@ module FlowVar_internal {
|
||||
this.definedByInitialValue(_) and
|
||||
result = "initial value of " + v
|
||||
or
|
||||
exists(Expr arg |
|
||||
this.definedByReference(arg) and
|
||||
result = "definition by reference of " + v
|
||||
)
|
||||
or
|
||||
exists(Expr partialDef |
|
||||
this.definedPartiallyAt(partialDef) and
|
||||
result = "partial definition at " + partialDef
|
||||
@@ -454,7 +386,6 @@ module FlowVar_internal {
|
||||
// impossible case
|
||||
not this.definedByExpr(_, _) and
|
||||
not this.definedByInitialValue(_) and
|
||||
not this.definedByReference(_) and
|
||||
not this.definedPartiallyAt(_) and
|
||||
result = "undefined " + v
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@ import semmle.code.cpp.exprs.Expr
|
||||
* A C/C++ builtin operation. This is the root QL class encompassing
|
||||
* built-in functionality.
|
||||
*/
|
||||
abstract class BuiltInOperation extends Expr {
|
||||
class BuiltInOperation extends Expr, @builtin_op {
|
||||
override string getCanonicalQLClass() { result = "BuiltInOperation" }
|
||||
}
|
||||
|
||||
@@ -12,17 +12,7 @@ abstract class BuiltInOperation extends Expr {
|
||||
* A C/C++ built-in operation that is used to support functions with variable numbers of arguments.
|
||||
* This includes `va_start`, `va_end`, `va_copy`, and `va_arg`.
|
||||
*/
|
||||
class VarArgsExpr extends BuiltInOperation {
|
||||
VarArgsExpr() {
|
||||
this instanceof BuiltInVarArgsStart
|
||||
or
|
||||
this instanceof BuiltInVarArgsEnd
|
||||
or
|
||||
this instanceof BuiltInVarArg
|
||||
or
|
||||
this instanceof BuiltInVarArgCopy
|
||||
}
|
||||
}
|
||||
class VarArgsExpr extends BuiltInOperation, @var_args_expr { }
|
||||
|
||||
/**
|
||||
* A C/C++ `__builtin_va_start` built-in operation (used by some
|
||||
|
||||
@@ -82,7 +82,8 @@ abstract class Call extends Expr, NameQualifiableElement {
|
||||
|
||||
/**
|
||||
* Holds if this call passes the variable accessed by `va` by
|
||||
* reference as the `i`th argument.
|
||||
* reference as the `i`th argument. The qualifier of a call to a member
|
||||
* function is `i = -1`.
|
||||
*
|
||||
* A variable is passed by reference if the `i`th parameter of the function
|
||||
* receives an address that points within the object denoted by `va`. For a
|
||||
@@ -101,11 +102,15 @@ abstract class Call extends Expr, NameQualifiableElement {
|
||||
*/
|
||||
predicate passesByReference(int i, VariableAccess va) {
|
||||
variableAddressEscapesTree(va, this.getArgument(i).getFullyConverted())
|
||||
or
|
||||
variableAddressEscapesTree(va, this.getQualifier().getFullyConverted()) and
|
||||
i = -1
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if this call passes the variable accessed by `va` by
|
||||
* reference to non-const data as the `i`th argument.
|
||||
* reference to non-const data as the `i`th argument. The qualifier of a
|
||||
* call to a member function is `i = -1`.
|
||||
*
|
||||
* A variable is passed by reference if the `i`th parameter of the function
|
||||
* receives an address that points within the object denoted by `va`. For a
|
||||
@@ -124,6 +129,9 @@ abstract class Call extends Expr, NameQualifiableElement {
|
||||
*/
|
||||
predicate passesByReferenceNonConst(int i, VariableAccess va) {
|
||||
variableAddressEscapesTreeNonConst(va, this.getArgument(i).getFullyConverted())
|
||||
or
|
||||
variableAddressEscapesTreeNonConst(va, this.getQualifier().getFullyConverted()) and
|
||||
i = -1
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -48,10 +48,13 @@ class Cast extends Conversion, @cast {
|
||||
/**
|
||||
* INTERNAL: Do not use.
|
||||
* Query predicates used to check invariants that should hold for all `Cast`
|
||||
* nodes. To run all sanity queries for the ASTs, including the ones below,
|
||||
* run "semmle/code/cpp/ASTSanity.ql".
|
||||
* nodes. To run all consistency queries for the ASTs, including the ones below,
|
||||
* run "semmle/code/cpp/ASTConsistency.ql".
|
||||
*/
|
||||
module CastSanity {
|
||||
module CastConsistency {
|
||||
/**
|
||||
* Holds if the cast has more than one result for `Cast.getSemanticConversionString()`.
|
||||
*/
|
||||
query predicate multipleSemanticConversionStrings(Cast cast, Type fromType, string kind) {
|
||||
// Every cast should have exactly one semantic conversion kind
|
||||
count(cast.getSemanticConversionString()) > 1 and
|
||||
@@ -59,12 +62,19 @@ module CastSanity {
|
||||
fromType = cast.getExpr().getUnspecifiedType()
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if the cast has no result for `Cast.getSemanticConversionString()`.
|
||||
*/
|
||||
query predicate missingSemanticConversionString(Cast cast, Type fromType) {
|
||||
// Every cast should have exactly one semantic conversion kind
|
||||
not exists(cast.getSemanticConversionString()) and
|
||||
fromType = cast.getExpr().getUnspecifiedType()
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if the cast has a result for `Cast.getSemanticConversionString()` that indicates that the
|
||||
* kind of its semantic conversion is not known.
|
||||
*/
|
||||
query predicate unknownSemanticConversionString(Cast cast, Type fromType) {
|
||||
// Every cast should have a known semantic conversion kind
|
||||
cast.getSemanticConversionString() = "unknown conversion" and
|
||||
|
||||
@@ -1,3 +1,11 @@
|
||||
/*
|
||||
* Maintainer note: this file is one of several files that are similar but not
|
||||
* identical. Many changes to this file will also apply to the others:
|
||||
* - AddressConstantExpression.qll
|
||||
* - AddressFlow.qll
|
||||
* - EscapesTree.qll
|
||||
*/
|
||||
|
||||
private import cpp
|
||||
|
||||
predicate addressConstantExpression(Expr e) {
|
||||
|
||||
8
cpp/ql/src/semmle/code/cpp/ir/IRConsistency.ql
Normal file
8
cpp/ql/src/semmle/code/cpp/ir/IRConsistency.ql
Normal file
@@ -0,0 +1,8 @@
|
||||
/**
|
||||
* @name IR Consistency Check
|
||||
* @description Performs consistency checks on the Intermediate Representation. This query should have no results.
|
||||
* @kind table
|
||||
* @id cpp/ir-consistency-check
|
||||
*/
|
||||
|
||||
import implementation.aliased_ssa.IRConsistency
|
||||
@@ -1,8 +0,0 @@
|
||||
/**
|
||||
* @name IR Sanity Check
|
||||
* @description Performs sanity checks on the Intermediate Representation. This query should have no results.
|
||||
* @kind table
|
||||
* @id cpp/ir-sanity-check
|
||||
*/
|
||||
|
||||
import implementation.aliased_ssa.IRSanity
|
||||
@@ -17,6 +17,7 @@ private newtype TEdgeKind =
|
||||
* `EdgeKind`.
|
||||
*/
|
||||
abstract class EdgeKind extends TEdgeKind {
|
||||
/** Gets a textual representation of this edge kind. */
|
||||
abstract string toString();
|
||||
}
|
||||
|
||||
@@ -28,8 +29,6 @@ class GotoEdge extends EdgeKind, TGotoEdge {
|
||||
final override string toString() { result = "Goto" }
|
||||
}
|
||||
|
||||
GotoEdge gotoEdge() { result = TGotoEdge() }
|
||||
|
||||
/**
|
||||
* A "true" edge, representing the successor of a conditional branch when the
|
||||
* condition is non-zero.
|
||||
@@ -38,8 +37,6 @@ class TrueEdge extends EdgeKind, TTrueEdge {
|
||||
final override string toString() { result = "True" }
|
||||
}
|
||||
|
||||
TrueEdge trueEdge() { result = TTrueEdge() }
|
||||
|
||||
/**
|
||||
* A "false" edge, representing the successor of a conditional branch when the
|
||||
* condition is zero.
|
||||
@@ -48,8 +45,6 @@ class FalseEdge extends EdgeKind, TFalseEdge {
|
||||
final override string toString() { result = "False" }
|
||||
}
|
||||
|
||||
FalseEdge falseEdge() { result = TFalseEdge() }
|
||||
|
||||
/**
|
||||
* An "exception" edge, representing the successor of an instruction when that
|
||||
* instruction's evaluation throws an exception.
|
||||
@@ -58,8 +53,6 @@ class ExceptionEdge extends EdgeKind, TExceptionEdge {
|
||||
final override string toString() { result = "Exception" }
|
||||
}
|
||||
|
||||
ExceptionEdge exceptionEdge() { result = TExceptionEdge() }
|
||||
|
||||
/**
|
||||
* A "default" edge, representing the successor of a `Switch` instruction when
|
||||
* none of the case values matches the condition value.
|
||||
@@ -68,8 +61,6 @@ class DefaultEdge extends EdgeKind, TDefaultEdge {
|
||||
final override string toString() { result = "Default" }
|
||||
}
|
||||
|
||||
DefaultEdge defaultEdge() { result = TDefaultEdge() }
|
||||
|
||||
/**
|
||||
* A "case" edge, representing the successor of a `Switch` instruction when the
|
||||
* the condition value matches a correponding `case` label.
|
||||
@@ -91,4 +82,48 @@ class CaseEdge extends EdgeKind, TCaseEdge {
|
||||
string getMaxValue() { result = maxValue }
|
||||
}
|
||||
|
||||
CaseEdge caseEdge(string minValue, string maxValue) { result = TCaseEdge(minValue, maxValue) }
|
||||
/**
|
||||
* Predicates to access the single instance of each `EdgeKind` class.
|
||||
*/
|
||||
module EdgeKind {
|
||||
/**
|
||||
* Gets the single instance of the `GotoEdge` class.
|
||||
*/
|
||||
GotoEdge gotoEdge() { result = TGotoEdge() }
|
||||
|
||||
/**
|
||||
* Gets the single instance of the `TrueEdge` class.
|
||||
*/
|
||||
TrueEdge trueEdge() { result = TTrueEdge() }
|
||||
|
||||
/**
|
||||
* Gets the single instance of the `FalseEdge` class.
|
||||
*/
|
||||
FalseEdge falseEdge() { result = TFalseEdge() }
|
||||
|
||||
/**
|
||||
* Gets the single instance of the `ExceptionEdge` class.
|
||||
*/
|
||||
ExceptionEdge exceptionEdge() { result = TExceptionEdge() }
|
||||
|
||||
/**
|
||||
* Gets the single instance of the `DefaultEdge` class.
|
||||
*/
|
||||
DefaultEdge defaultEdge() { result = TDefaultEdge() }
|
||||
|
||||
/**
|
||||
* Gets the `CaseEdge` representing a `case` label with the specified lower and upper bounds.
|
||||
* For example:
|
||||
* ```
|
||||
* switch (x) {
|
||||
* case 1: // Edge kind is `caseEdge("1", "1")`
|
||||
* return x;
|
||||
* case 2...8: // Edge kind is `caseEdge("2", "8")`
|
||||
* return x - 1;
|
||||
* default: // Edge kind is `defaultEdge()`
|
||||
* return 0;
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
CaseEdge caseEdge(string minValue, string maxValue) { result = TCaseEdge(minValue, maxValue) }
|
||||
}
|
||||
|
||||
@@ -275,12 +275,24 @@ class IROpaqueType extends IRSizedType, TIROpaqueType {
|
||||
final override int getByteSize() { result = byteSize }
|
||||
}
|
||||
|
||||
module IRTypeSanity {
|
||||
/**
|
||||
* INTERNAL: Do not use.
|
||||
* Query predicates used to check invariants that should hold for all `IRType` objects. To run all
|
||||
* consistency queries for the IR, including the ones below, run
|
||||
* "semmle/code/cpp/IR/IRConsistency.ql".
|
||||
*/
|
||||
module IRTypeConsistency {
|
||||
/**
|
||||
* Holds if the type has no result for `IRType.getCanonicalLanguageType()`.
|
||||
*/
|
||||
query predicate missingCanonicalLanguageType(IRType type, string message) {
|
||||
not exists(type.getCanonicalLanguageType()) and
|
||||
message = "Type does not have a canonical `LanguageType`"
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if the type has more than one result for `IRType.getCanonicalLanguageType()`.
|
||||
*/
|
||||
query predicate multipleCanonicalLanguageTypes(IRType type, string message) {
|
||||
strictcount(type.getCanonicalLanguageType()) > 1 and
|
||||
message =
|
||||
@@ -288,11 +300,17 @@ module IRTypeSanity {
|
||||
concat(type.getCanonicalLanguageType().toString(), ", ")
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if the type has no result for `LanguageType.getIRType()`.
|
||||
*/
|
||||
query predicate missingIRType(Language::LanguageType type, string message) {
|
||||
not exists(type.getIRType()) and
|
||||
message = "`LanguageType` does not have a corresponding `IRType`."
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if the type has more than one result for `LanguageType.getIRType()`.
|
||||
*/
|
||||
query predicate multipleIRTypes(Language::LanguageType type, string message) {
|
||||
strictcount(type.getIRType()) > 1 and
|
||||
message =
|
||||
@@ -300,5 +318,5 @@ module IRTypeSanity {
|
||||
concat(type.getIRType().toString(), ", ")
|
||||
}
|
||||
|
||||
import Language::LanguageTypeSanity
|
||||
import Language::LanguageTypeConsistency
|
||||
}
|
||||
|
||||
@@ -1,6 +1,16 @@
|
||||
/**
|
||||
* Defines the public interface to temporary variable tags, which describe the reason a particular
|
||||
* `IRTempVariable` was generated.
|
||||
*/
|
||||
|
||||
private import internal.TempVariableTagInternal
|
||||
private import Imports::TempVariableTag
|
||||
|
||||
/**
|
||||
* A reason that a particular IR temporary variable was generated. For example, it could be
|
||||
* generated to hold the return value of a function, or to hold the result of a `?:` operator
|
||||
* computed on each branch. The set of possible `TempVariableTag`s is language-dependent.
|
||||
*/
|
||||
class TempVariableTag extends TTempVariableTag {
|
||||
string toString() { result = getTempVariableTagId(this) }
|
||||
}
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
/**
|
||||
* @name Aliased SSA IR Consistency Check
|
||||
* @description Performs consistency checks on the Intermediate Representation. This query should have no results.
|
||||
* @kind table
|
||||
* @id cpp/aliased-ssa-ir-consistency-check
|
||||
*/
|
||||
|
||||
import IRConsistency
|
||||
@@ -1,8 +1,8 @@
|
||||
private import IR
|
||||
import InstructionSanity // module is below
|
||||
import IRTypeSanity // module is in IRType.qll
|
||||
import InstructionConsistency // module is below
|
||||
import IRTypeConsistency // module is in IRType.qll
|
||||
|
||||
module InstructionSanity {
|
||||
module InstructionConsistency {
|
||||
private import internal.InstructionImports as Imports
|
||||
private import Imports::OperandTag
|
||||
private import Imports::Overlap
|
||||
@@ -1,8 +0,0 @@
|
||||
/**
|
||||
* @name Aliased SSA IR Sanity Check
|
||||
* @description Performs sanity checks on the Intermediate Representation. This query should have no results.
|
||||
* @kind table
|
||||
* @id cpp/aliased-ssa-ir-sanity-check
|
||||
*/
|
||||
|
||||
import IRSanity
|
||||
@@ -585,9 +585,9 @@ class ConditionalBranchInstruction extends Instruction {
|
||||
|
||||
final Instruction getCondition() { result = getConditionOperand().getDef() }
|
||||
|
||||
final Instruction getTrueSuccessor() { result = getSuccessor(trueEdge()) }
|
||||
final Instruction getTrueSuccessor() { result = getSuccessor(EdgeKind::trueEdge()) }
|
||||
|
||||
final Instruction getFalseSuccessor() { result = getSuccessor(falseEdge()) }
|
||||
final Instruction getFalseSuccessor() { result = getSuccessor(EdgeKind::falseEdge()) }
|
||||
}
|
||||
|
||||
class ExitFunctionInstruction extends Instruction {
|
||||
@@ -907,7 +907,7 @@ class SwitchInstruction extends Instruction {
|
||||
|
||||
final Instruction getACaseSuccessor() { exists(CaseEdge edge | result = getSuccessor(edge)) }
|
||||
|
||||
final Instruction getDefaultSuccessor() { result = getSuccessor(defaultEdge()) }
|
||||
final Instruction getDefaultSuccessor() { result = getSuccessor(EdgeKind::defaultEdge()) }
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
/**
|
||||
* @name Aliased SSA Consistency Check
|
||||
* @description Performs consistency checks on the SSA construction. This query should have no results.
|
||||
* @kind table
|
||||
* @id cpp/aliased-ssa-consistency-check
|
||||
*/
|
||||
|
||||
import SSAConsistency
|
||||
@@ -1,2 +1,2 @@
|
||||
private import SSAConstruction as SSA
|
||||
import SSA::SSASanity
|
||||
import SSA::SSAConsistency
|
||||
@@ -941,7 +941,7 @@ private module CachedForDebugging {
|
||||
}
|
||||
}
|
||||
|
||||
module SSASanity {
|
||||
module SSAConsistency {
|
||||
query predicate multipleOperandMemoryLocations(
|
||||
OldIR::MemoryOperand operand, string message, OldIR::IRFunction func, string funcText
|
||||
) {
|
||||
|
||||
@@ -1,8 +0,0 @@
|
||||
/**
|
||||
* @name Aliased SSA Sanity Check
|
||||
* @description Performs sanity checks on the SSA construction. This query should have no results.
|
||||
* @kind table
|
||||
* @id cpp/aliased-ssa-sanity-check
|
||||
*/
|
||||
|
||||
import SSASanity
|
||||
@@ -1,3 +1,8 @@
|
||||
/**
|
||||
* Defines the set of possible `OperandTag`s, which are used to identify the role each `Operand`
|
||||
* plays in the evaluation of its `Instruction`.
|
||||
*/
|
||||
|
||||
private import OperandTagInternal
|
||||
|
||||
private newtype TOperandTag =
|
||||
@@ -24,10 +29,18 @@ private newtype TOperandTag =
|
||||
* an `Instruction` is determined by the instruction's opcode.
|
||||
*/
|
||||
abstract class OperandTag extends TOperandTag {
|
||||
/** Gets a textual representation of this operand tag */
|
||||
abstract string toString();
|
||||
|
||||
/**
|
||||
* Gets an integer that represents where this this operand will appear in the operand list of an
|
||||
* instruction when the IR is printed.
|
||||
*/
|
||||
abstract int getSortOrder();
|
||||
|
||||
/**
|
||||
* Gets a label that will appear before the operand when the IR is printed.
|
||||
*/
|
||||
string getLabel() { result = "" }
|
||||
}
|
||||
|
||||
@@ -47,7 +60,7 @@ abstract class RegisterOperandTag extends OperandTag { }
|
||||
abstract class TypedOperandTag extends MemoryOperandTag { }
|
||||
|
||||
// Note: individual subtypes are listed in the order that the operands should
|
||||
// appear in the operand list of the instruction when printing.
|
||||
// appear in the operand list of the instruction when the IR is printed.
|
||||
/**
|
||||
* The address operand of an instruction that loads or stores a value from
|
||||
* memory (e.g. `Load`, `Store`, `InitializeParameter`, `IndirectReadSideEffect`).
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
/**
|
||||
* @name Raw IR Consistency Check
|
||||
* @description Performs consistency checks on the Intermediate Representation. This query should have no results.
|
||||
* @kind table
|
||||
* @id cpp/raw-ir-consistency-check
|
||||
*/
|
||||
|
||||
import IRConsistency
|
||||
@@ -1,8 +1,8 @@
|
||||
private import IR
|
||||
import InstructionSanity // module is below
|
||||
import IRTypeSanity // module is in IRType.qll
|
||||
import InstructionConsistency // module is below
|
||||
import IRTypeConsistency // module is in IRType.qll
|
||||
|
||||
module InstructionSanity {
|
||||
module InstructionConsistency {
|
||||
private import internal.InstructionImports as Imports
|
||||
private import Imports::OperandTag
|
||||
private import Imports::Overlap
|
||||
@@ -1,8 +0,0 @@
|
||||
/**
|
||||
* @name Raw IR Sanity Check
|
||||
* @description Performs sanity checks on the Intermediate Representation. This query should have no results.
|
||||
* @kind table
|
||||
* @id cpp/raw-ir-sanity-check
|
||||
*/
|
||||
|
||||
import IRSanity
|
||||
@@ -585,9 +585,9 @@ class ConditionalBranchInstruction extends Instruction {
|
||||
|
||||
final Instruction getCondition() { result = getConditionOperand().getDef() }
|
||||
|
||||
final Instruction getTrueSuccessor() { result = getSuccessor(trueEdge()) }
|
||||
final Instruction getTrueSuccessor() { result = getSuccessor(EdgeKind::trueEdge()) }
|
||||
|
||||
final Instruction getFalseSuccessor() { result = getSuccessor(falseEdge()) }
|
||||
final Instruction getFalseSuccessor() { result = getSuccessor(EdgeKind::falseEdge()) }
|
||||
}
|
||||
|
||||
class ExitFunctionInstruction extends Instruction {
|
||||
@@ -907,7 +907,7 @@ class SwitchInstruction extends Instruction {
|
||||
|
||||
final Instruction getACaseSuccessor() { exists(CaseEdge edge | result = getSuccessor(edge)) }
|
||||
|
||||
final Instruction getDefaultSuccessor() { result = getSuccessor(defaultEdge()) }
|
||||
final Instruction getDefaultSuccessor() { result = getSuccessor(EdgeKind::defaultEdge()) }
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -375,7 +375,7 @@ class TranslatedAllocationSideEffects extends TranslatedSideEffects,
|
||||
|
||||
override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) {
|
||||
tag = OnlyInstructionTag() and
|
||||
kind = gotoEdge() and
|
||||
kind = EdgeKind::gotoEdge() and
|
||||
if exists(getChild(0))
|
||||
then result = getChild(0).getFirstInstruction()
|
||||
else result = getParent().getChildSuccessor(this)
|
||||
|
||||
@@ -720,7 +720,7 @@ class TranslatedReadEffect extends TranslatedElement, TTranslatedReadEffect {
|
||||
|
||||
override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind edge) {
|
||||
tag = OnlyInstructionTag() and
|
||||
edge = gotoEdge() and
|
||||
edge = EdgeKind::gotoEdge() and
|
||||
result = getParent().getChildSuccessor(this)
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
/**
|
||||
* @name SSA IR Consistency Check
|
||||
* @description Performs consistency checks on the Intermediate Representation. This query should have no results.
|
||||
* @kind table
|
||||
* @id cpp/ssa-ir-consistency-check
|
||||
*/
|
||||
|
||||
import IRConsistency
|
||||
@@ -1,8 +1,8 @@
|
||||
private import IR
|
||||
import InstructionSanity // module is below
|
||||
import IRTypeSanity // module is in IRType.qll
|
||||
import InstructionConsistency // module is below
|
||||
import IRTypeConsistency // module is in IRType.qll
|
||||
|
||||
module InstructionSanity {
|
||||
module InstructionConsistency {
|
||||
private import internal.InstructionImports as Imports
|
||||
private import Imports::OperandTag
|
||||
private import Imports::Overlap
|
||||
@@ -1,8 +0,0 @@
|
||||
/**
|
||||
* @name SSA IR Sanity Check
|
||||
* @description Performs sanity checks on the Intermediate Representation. This query should have no results.
|
||||
* @kind table
|
||||
* @id cpp/ssa-ir-sanity-check
|
||||
*/
|
||||
|
||||
import IRSanity
|
||||
@@ -585,9 +585,9 @@ class ConditionalBranchInstruction extends Instruction {
|
||||
|
||||
final Instruction getCondition() { result = getConditionOperand().getDef() }
|
||||
|
||||
final Instruction getTrueSuccessor() { result = getSuccessor(trueEdge()) }
|
||||
final Instruction getTrueSuccessor() { result = getSuccessor(EdgeKind::trueEdge()) }
|
||||
|
||||
final Instruction getFalseSuccessor() { result = getSuccessor(falseEdge()) }
|
||||
final Instruction getFalseSuccessor() { result = getSuccessor(EdgeKind::falseEdge()) }
|
||||
}
|
||||
|
||||
class ExitFunctionInstruction extends Instruction {
|
||||
@@ -907,7 +907,7 @@ class SwitchInstruction extends Instruction {
|
||||
|
||||
final Instruction getACaseSuccessor() { exists(CaseEdge edge | result = getSuccessor(edge)) }
|
||||
|
||||
final Instruction getDefaultSuccessor() { result = getSuccessor(defaultEdge()) }
|
||||
final Instruction getDefaultSuccessor() { result = getSuccessor(EdgeKind::defaultEdge()) }
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
/**
|
||||
* @name Unaliased SSA Consistency Check
|
||||
* @description Performs consistency checks on the SSA construction. This query should have no results.
|
||||
* @kind table
|
||||
* @id cpp/unaliased-ssa-consistency-check
|
||||
*/
|
||||
|
||||
import SSAConsistency
|
||||
@@ -1,2 +1,2 @@
|
||||
private import SSAConstruction as SSA
|
||||
import SSA::SSASanity
|
||||
import SSA::SSAConsistency
|
||||
@@ -941,7 +941,7 @@ private module CachedForDebugging {
|
||||
}
|
||||
}
|
||||
|
||||
module SSASanity {
|
||||
module SSAConsistency {
|
||||
query predicate multipleOperandMemoryLocations(
|
||||
OldIR::MemoryOperand operand, string message, OldIR::IRFunction func, string funcText
|
||||
) {
|
||||
|
||||
@@ -1,8 +0,0 @@
|
||||
/**
|
||||
* @name Unaliased SSA Sanity Check
|
||||
* @description Performs sanity checks on the SSA construction. This query should have no results.
|
||||
* @kind table
|
||||
* @id cpp/unaliased-ssa-sanity-check
|
||||
*/
|
||||
|
||||
import SSASanity
|
||||
@@ -203,6 +203,7 @@ private newtype TCppType =
|
||||
* of a `VariableAddress` where the variable is of reference type)
|
||||
*/
|
||||
class CppType extends TCppType {
|
||||
/** Gets a textual representation of this type. */
|
||||
string toString() { none() }
|
||||
|
||||
/** Gets a string used in IR dumps */
|
||||
@@ -224,6 +225,10 @@ class CppType extends TCppType {
|
||||
*/
|
||||
predicate hasType(Type type, boolean isGLValue) { none() }
|
||||
|
||||
/**
|
||||
* Holds if this type represents the C++ type `type`. If `isGLValue` is `true`, then this type
|
||||
* represents a glvalue of type `type`. Otherwise, it represents a prvalue of type `type`.
|
||||
*/
|
||||
final predicate hasUnspecifiedType(Type type, boolean isGLValue) {
|
||||
exists(Type specifiedType |
|
||||
hasType(specifiedType, isGLValue) and
|
||||
@@ -539,7 +544,10 @@ string getOpaqueTagIdentityString(Type tag) {
|
||||
result = getTypeIdentityString(tag)
|
||||
}
|
||||
|
||||
module LanguageTypeSanity {
|
||||
module LanguageTypeConsistency {
|
||||
/**
|
||||
* Consistency query to detect C++ `Type` objects which have no corresponding `CppType` object.
|
||||
*/
|
||||
query predicate missingCppType(Type type, string message) {
|
||||
not exists(getTypeForPRValue(type)) and
|
||||
exists(type.getSize()) and
|
||||
|
||||
@@ -1,3 +1,15 @@
|
||||
/**
|
||||
* Provides predicates for manipulating integer constants that are tracked by constant folding and
|
||||
* similar analyses.
|
||||
*/
|
||||
|
||||
/**
|
||||
* An alias used to represent the constant value of an integer, if one can be determined. If no
|
||||
* single constant value can be determined, or if the constant value is out of the representable
|
||||
* range, it will be represented as the special value `unknown()`. This allows `IntValue` to be used
|
||||
* in contexts where there must always be a value for the `IntValue`, even if no constant value is
|
||||
* known.
|
||||
*/
|
||||
class IntValue = int;
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
/**
|
||||
* @name Padding Sanity Check
|
||||
* @description Performs sanity checks for the padding library. This query should have no results.
|
||||
* @name Padding Consistency Check
|
||||
* @description Performs consistency checks for the padding library. This query should have no results.
|
||||
* @kind table
|
||||
* @id cpp/padding-sanity-check
|
||||
* @id cpp/padding-consistency-check
|
||||
*/
|
||||
|
||||
import Padding
|
||||
|
||||
/*
|
||||
* Sanity-check: Find discrepancies between computed and actual size on LP64.
|
||||
* Consistency-check: Find discrepancies between computed and actual size on LP64.
|
||||
*/
|
||||
|
||||
/*
|
||||
@@ -140,6 +140,22 @@ private class UnsignedBitwiseAndExpr extends BitwiseAndExpr {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the floor of `v`, with additional logic to work around issues with
|
||||
* large numbers.
|
||||
*/
|
||||
bindingset[v]
|
||||
float safeFloor(float v) {
|
||||
// return the floor of v
|
||||
v.abs() < 2.pow(31) and
|
||||
result = v.floor()
|
||||
or
|
||||
// `floor()` doesn't work correctly on large numbers (since it returns an integer),
|
||||
// so fall back to unrounded numbers at this scale.
|
||||
not v.abs() < 2.pow(31) and
|
||||
result = v
|
||||
}
|
||||
|
||||
/** Set of expressions which we know how to analyze. */
|
||||
private predicate analyzableExpr(Expr e) {
|
||||
// The type of the expression must be arithmetic. We reuse the logic in
|
||||
@@ -709,7 +725,7 @@ private float getLowerBoundsImpl(Expr expr) {
|
||||
rsExpr = expr and
|
||||
left = getFullyConvertedLowerBounds(rsExpr.getLeftOperand()) and
|
||||
right = rsExpr.getRightOperand().getValue().toInt() and
|
||||
result = left / 2.pow(right)
|
||||
result = safeFloor(left / 2.pow(right))
|
||||
)
|
||||
}
|
||||
|
||||
@@ -878,7 +894,7 @@ private float getUpperBoundsImpl(Expr expr) {
|
||||
rsExpr = expr and
|
||||
left = getFullyConvertedUpperBounds(rsExpr.getLeftOperand()) and
|
||||
right = rsExpr.getRightOperand().getValue().toInt() and
|
||||
result = left / 2.pow(right)
|
||||
result = safeFloor(left / 2.pow(right))
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -1641,6 +1641,67 @@ case @expr.kind of
|
||||
| 326 = @spaceshipexpr
|
||||
;
|
||||
|
||||
@var_args_expr = @vastartexpr
|
||||
| @vaendexpr
|
||||
| @vaargexpr
|
||||
| @vacopyexpr
|
||||
;
|
||||
|
||||
@builtin_op = @var_args_expr
|
||||
| @noopexpr
|
||||
| @offsetofexpr
|
||||
| @intaddrexpr
|
||||
| @hasassignexpr
|
||||
| @hascopyexpr
|
||||
| @hasnothrowassign
|
||||
| @hasnothrowconstr
|
||||
| @hasnothrowcopy
|
||||
| @hastrivialassign
|
||||
| @hastrivialconstr
|
||||
| @hastrivialcopy
|
||||
| @hastrivialdestructor
|
||||
| @hasuserdestr
|
||||
| @hasvirtualdestr
|
||||
| @isabstractexpr
|
||||
| @isbaseofexpr
|
||||
| @isclassexpr
|
||||
| @isconvtoexpr
|
||||
| @isemptyexpr
|
||||
| @isenumexpr
|
||||
| @ispodexpr
|
||||
| @ispolyexpr
|
||||
| @isunionexpr
|
||||
| @typescompexpr
|
||||
| @builtinshufflevector
|
||||
| @builtinconvertvector
|
||||
| @builtinaddressof
|
||||
| @istriviallyconstructibleexpr
|
||||
| @isdestructibleexpr
|
||||
| @isnothrowdestructibleexpr
|
||||
| @istriviallydestructibleexpr
|
||||
| @istriviallyassignableexpr
|
||||
| @isnothrowassignableexpr
|
||||
| @isstandardlayoutexpr
|
||||
| @istriviallycopyableexpr
|
||||
| @isliteraltypeexpr
|
||||
| @hastrivialmoveconstructorexpr
|
||||
| @hastrivialmoveassignexpr
|
||||
| @hasnothrowmoveassignexpr
|
||||
| @isconstructibleexpr
|
||||
| @isnothrowconstructibleexpr
|
||||
| @hasfinalizerexpr
|
||||
| @isdelegateexpr
|
||||
| @isinterfaceclassexpr
|
||||
| @isrefarrayexpr
|
||||
| @isrefclassexpr
|
||||
| @issealedexpr
|
||||
| @issimplevalueclassexpr
|
||||
| @isvalueclassexpr
|
||||
| @isfinalexpr
|
||||
| @builtinchooseexpr
|
||||
| @builtincomplex
|
||||
;
|
||||
|
||||
new_allocated_type(
|
||||
unique int expr: @new_expr ref,
|
||||
int type_id: @type ref
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
1
cpp/ql/test/library-tests/conversions/consistency.qlref
Normal file
1
cpp/ql/test/library-tests/conversions/consistency.qlref
Normal file
@@ -0,0 +1 @@
|
||||
semmle/code/cpp/ASTConsistency.ql
|
||||
@@ -1 +0,0 @@
|
||||
semmle/code/cpp/ASTSanity.ql
|
||||
@@ -23,9 +23,9 @@ postIsInSameCallable
|
||||
reverseRead
|
||||
storeIsPostUpdate
|
||||
argHasPostUpdate
|
||||
| dispatch.cpp:78:23:78:39 | * ... | ArgumentNode is missing PostUpdateNode. |
|
||||
| lambdas.cpp:18:7:18:7 | a | ArgumentNode is missing PostUpdateNode. |
|
||||
| lambdas.cpp:25:2:25:2 | b | ArgumentNode is missing PostUpdateNode. |
|
||||
| lambdas.cpp:32:2:32:2 | c | ArgumentNode is missing PostUpdateNode. |
|
||||
| lambdas.cpp:38:2:38:2 | d | ArgumentNode is missing PostUpdateNode. |
|
||||
| lambdas.cpp:45:2:45:2 | e | ArgumentNode is missing PostUpdateNode. |
|
||||
| test.cpp:67:29:67:35 | source1 | ArgumentNode is missing PostUpdateNode. |
|
||||
|
||||
@@ -14,7 +14,9 @@
|
||||
| example.c:24:24:24:30 | ... + ... | example.c:24:13:24:30 | ... = ... |
|
||||
| example.c:26:13:26:16 | call to getX | example.c:26:2:26:25 | ... = ... |
|
||||
| example.c:26:18:26:24 | ref arg & ... | example.c:26:2:26:7 | coords |
|
||||
| example.c:26:18:26:24 | ref arg & ... | example.c:26:19:26:24 | coords [inner post update] |
|
||||
| example.c:26:19:26:24 | coords | example.c:26:18:26:24 | & ... |
|
||||
| example.c:28:22:28:25 | ref arg & ... | example.c:28:23:28:25 | pos [inner post update] |
|
||||
| example.c:28:23:28:25 | pos | example.c:28:22:28:25 | & ... |
|
||||
| test.cpp:6:12:6:17 | call to source | test.cpp:7:8:7:9 | t1 |
|
||||
| test.cpp:6:12:6:17 | call to source | test.cpp:8:8:8:9 | t1 |
|
||||
@@ -44,7 +46,7 @@
|
||||
| test.cpp:383:12:383:13 | 0 | test.cpp:384:33:384:35 | tmp |
|
||||
| test.cpp:383:12:383:13 | 0 | test.cpp:385:8:385:10 | tmp |
|
||||
| test.cpp:384:10:384:13 | & ... | test.cpp:384:3:384:8 | call to memcpy |
|
||||
| test.cpp:384:10:384:13 | ref arg & ... | test.cpp:384:33:384:35 | tmp |
|
||||
| test.cpp:384:10:384:13 | ref arg & ... | test.cpp:384:11:384:13 | tmp [inner post update] |
|
||||
| test.cpp:384:10:384:13 | ref arg & ... | test.cpp:385:8:385:10 | tmp |
|
||||
| test.cpp:384:11:384:13 | tmp | test.cpp:384:10:384:13 | & ... |
|
||||
| test.cpp:384:17:384:23 | source1 | test.cpp:384:10:384:13 | ref arg & ... |
|
||||
@@ -58,7 +60,7 @@
|
||||
| test.cpp:389:12:389:13 | 0 | test.cpp:394:10:394:12 | tmp |
|
||||
| test.cpp:390:19:390:21 | tmp | test.cpp:390:18:390:21 | & ... |
|
||||
| test.cpp:391:10:391:13 | & ... | test.cpp:391:3:391:8 | call to memcpy |
|
||||
| test.cpp:391:10:391:13 | ref arg & ... | test.cpp:391:33:391:35 | tmp |
|
||||
| test.cpp:391:10:391:13 | ref arg & ... | test.cpp:391:11:391:13 | tmp [inner post update] |
|
||||
| test.cpp:391:10:391:13 | ref arg & ... | test.cpp:392:8:392:10 | tmp |
|
||||
| test.cpp:391:10:391:13 | ref arg & ... | test.cpp:394:10:394:12 | tmp |
|
||||
| test.cpp:391:11:391:13 | tmp | test.cpp:391:10:391:13 | & ... |
|
||||
|
||||
@@ -68,3 +68,70 @@ void test_nonMemberSetA() {
|
||||
nonMemberSetA(&s, user_input());
|
||||
sink(nonMemberGetA(&s)); // flow
|
||||
}
|
||||
|
||||
////////////////////
|
||||
|
||||
struct Inner {
|
||||
void *a;
|
||||
};
|
||||
|
||||
struct Outer {
|
||||
Inner inner_nested, *inner_ptr;
|
||||
void *a;
|
||||
};
|
||||
|
||||
void taint_inner_a_ptr(Inner *inner) {
|
||||
inner->a = user_input();
|
||||
}
|
||||
|
||||
void taint_inner_a_ref(Inner &inner) {
|
||||
inner.a = user_input();
|
||||
}
|
||||
|
||||
void taint_a_ptr(void **pa) {
|
||||
*pa = user_input();
|
||||
}
|
||||
|
||||
void taint_a_ref(void *&pa) {
|
||||
pa = user_input();
|
||||
}
|
||||
|
||||
void test_outer_with_ptr(Outer *pouter) {
|
||||
Outer outer;
|
||||
|
||||
taint_inner_a_ptr(&outer.inner_nested);
|
||||
taint_inner_a_ptr(outer.inner_ptr);
|
||||
taint_a_ptr(&outer.a);
|
||||
|
||||
taint_inner_a_ptr(&pouter->inner_nested);
|
||||
taint_inner_a_ptr(pouter->inner_ptr);
|
||||
taint_a_ptr(&pouter->a);
|
||||
|
||||
sink(outer.inner_nested.a); // flow
|
||||
sink(outer.inner_ptr->a); // flow [NOT DETECTED by IR]
|
||||
sink(outer.a); // flow [NOT DETECTED]
|
||||
|
||||
sink(pouter->inner_nested.a); // flow
|
||||
sink(pouter->inner_ptr->a); // flow [NOT DETECTED by IR]
|
||||
sink(pouter->a); // flow [NOT DETECTED]
|
||||
}
|
||||
|
||||
void test_outer_with_ref(Outer *pouter) {
|
||||
Outer outer;
|
||||
|
||||
taint_inner_a_ref(outer.inner_nested);
|
||||
taint_inner_a_ref(*outer.inner_ptr);
|
||||
taint_a_ref(outer.a);
|
||||
|
||||
taint_inner_a_ref(pouter->inner_nested);
|
||||
taint_inner_a_ref(*pouter->inner_ptr);
|
||||
taint_a_ref(pouter->a);
|
||||
|
||||
sink(outer.inner_nested.a); // flow
|
||||
sink(outer.inner_ptr->a); // flow [NOT DETECTED by IR]
|
||||
sink(outer.a); // flow [NOT DETECTED by IR]
|
||||
|
||||
sink(pouter->inner_nested.a); // flow
|
||||
sink(pouter->inner_ptr->a); // flow [NOT DETECTED by IR]
|
||||
sink(pouter->a); // flow [NOT DETECTED by IR]
|
||||
}
|
||||
|
||||
@@ -43,6 +43,7 @@ storeIsPostUpdate
|
||||
argHasPostUpdate
|
||||
| A.cpp:41:15:41:21 | new | ArgumentNode is missing PostUpdateNode. |
|
||||
| A.cpp:55:12:55:19 | new | ArgumentNode is missing PostUpdateNode. |
|
||||
| A.cpp:57:11:57:24 | new | ArgumentNode is missing PostUpdateNode. |
|
||||
| A.cpp:57:17:57:23 | new | ArgumentNode is missing PostUpdateNode. |
|
||||
| A.cpp:64:21:64:28 | new | ArgumentNode is missing PostUpdateNode. |
|
||||
| A.cpp:73:25:73:32 | new | ArgumentNode is missing PostUpdateNode. |
|
||||
|
||||
@@ -1,13 +1,16 @@
|
||||
uniqueEnclosingCallable
|
||||
uniqueTypeBound
|
||||
| by_reference.cpp:106:21:106:41 | Chi | Node should have one type bound but has 2. |
|
||||
| by_reference.cpp:126:21:126:40 | Chi | Node should have one type bound but has 2. |
|
||||
uniqueTypeRepr
|
||||
uniqueNodeLocation
|
||||
| D.cpp:1:17:1:17 | o | Node should have one location but has 2. |
|
||||
| by_reference.cpp:1:17:1:17 | o | Node should have one location but has 2. |
|
||||
| D.cpp:1:17:1:17 | o | Node should have one location but has 3. |
|
||||
| by_reference.cpp:1:17:1:17 | o | Node should have one location but has 3. |
|
||||
| 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. |
|
||||
| qualifiers.cpp:1:17:1:17 | o | Node should have one location but has 3. |
|
||||
missingLocation
|
||||
| Nodes without location: 4 |
|
||||
uniqueNodeToString
|
||||
|
||||
@@ -4,8 +4,8 @@ edges
|
||||
| A.cpp:48:12:48:18 | call to make [c] | A.cpp:49:10:49:10 | b [c] |
|
||||
| A.cpp:48:20:48:20 | c | A.cpp:48:12:48:18 | call to make [c] |
|
||||
| A.cpp:49:10:49:10 | b [c] | A.cpp:49:13:49:13 | c |
|
||||
| A.cpp:55:5:55:5 | b [post update] [c] | A.cpp:56:10:56:10 | b [c] |
|
||||
| A.cpp:55:12:55:19 | new | A.cpp:55:5:55:5 | b [post update] [c] |
|
||||
| A.cpp:55:5:55:5 | ref arg b [c] | A.cpp:56:10:56:10 | b [c] |
|
||||
| A.cpp:55:12:55:19 | new | A.cpp:55:5:55:5 | ref arg b [c] |
|
||||
| A.cpp:56:10:56:10 | b [c] | A.cpp:56:13:56:15 | call to get |
|
||||
| A.cpp:57:11:57:24 | call to B [c] | A.cpp:57:11:57:24 | new [c] |
|
||||
| A.cpp:57:11:57:24 | new [c] | A.cpp:57:28:57:30 | call to get |
|
||||
@@ -24,8 +24,8 @@ edges
|
||||
| A.cpp:103:14:103:14 | c [a] | A.cpp:120:12:120:13 | c1 [a] |
|
||||
| A.cpp:107:12:107:13 | c1 [a] | A.cpp:107:16:107:16 | a |
|
||||
| A.cpp:120:12:120:13 | c1 [a] | A.cpp:120:16:120:16 | a |
|
||||
| A.cpp:126:5:126:5 | b [post update] [c] | A.cpp:131:8:131:8 | ref arg b [c] |
|
||||
| A.cpp:126:12:126:18 | new | A.cpp:126:5:126:5 | b [post update] [c] |
|
||||
| A.cpp:126:5:126:5 | ref arg b [c] | A.cpp:131:8:131:8 | ref arg b [c] |
|
||||
| A.cpp:126:12:126:18 | new | A.cpp:126:5:126:5 | ref arg b [c] |
|
||||
| A.cpp:131:8:131:8 | ref arg b [c] | A.cpp:132:10:132:10 | b [c] |
|
||||
| A.cpp:132:10:132:10 | b [c] | A.cpp:132:13:132:13 | c |
|
||||
| A.cpp:142:7:142:7 | b [post update] [c] | A.cpp:143:7:143:31 | ... = ... [c] |
|
||||
@@ -99,18 +99,18 @@ edges
|
||||
| D.cpp:31:14:31:14 | b [box, elem] | D.cpp:21:30:21:31 | b2 [box, elem] |
|
||||
| D.cpp:35:15:35:24 | new | D.cpp:37:21:37:21 | e |
|
||||
| D.cpp:37:5:37:5 | b [post update] [box, elem] | D.cpp:38:14:38:14 | b [box, elem] |
|
||||
| D.cpp:37:8:37:10 | box [post update] [elem] | D.cpp:37:5:37:5 | b [post update] [box, elem] |
|
||||
| D.cpp:37:21:37:21 | e | D.cpp:37:8:37:10 | box [post update] [elem] |
|
||||
| D.cpp:37:8:37:10 | ref arg box [elem] | D.cpp:37:5:37:5 | b [post update] [box, elem] |
|
||||
| D.cpp:37:21:37:21 | e | D.cpp:37:8:37:10 | ref arg box [elem] |
|
||||
| D.cpp:38:14:38:14 | b [box, elem] | D.cpp:21:30:21:31 | b2 [box, elem] |
|
||||
| D.cpp:42:15:42:24 | new | D.cpp:44:5:44:26 | ... = ... |
|
||||
| D.cpp:44:5:44:5 | b [post update] [box, elem] | D.cpp:45:14:45:14 | b [box, elem] |
|
||||
| D.cpp:44:5:44:5 | ref arg b [box, elem] | D.cpp:45:14:45:14 | b [box, elem] |
|
||||
| D.cpp:44:5:44:26 | ... = ... | D.cpp:44:8:44:14 | call to getBox1 [post update] [elem] |
|
||||
| D.cpp:44:8:44:14 | call to getBox1 [post update] [elem] | D.cpp:44:5:44:5 | b [post update] [box, elem] |
|
||||
| D.cpp:44:8:44:14 | call to getBox1 [post update] [elem] | D.cpp:44:5:44:5 | ref arg b [box, elem] |
|
||||
| D.cpp:45:14:45:14 | b [box, elem] | D.cpp:21:30:21:31 | b2 [box, elem] |
|
||||
| D.cpp:49:15:49:24 | new | D.cpp:51:27:51:27 | e |
|
||||
| D.cpp:51:5:51:5 | b [post update] [box, elem] | D.cpp:52:14:52:14 | b [box, elem] |
|
||||
| D.cpp:51:8:51:14 | call to getBox1 [post update] [elem] | D.cpp:51:5:51:5 | b [post update] [box, elem] |
|
||||
| D.cpp:51:27:51:27 | e | D.cpp:51:8:51:14 | call to getBox1 [post update] [elem] |
|
||||
| D.cpp:51:5:51:5 | ref arg b [box, elem] | D.cpp:52:14:52:14 | b [box, elem] |
|
||||
| D.cpp:51:8:51:14 | ref arg call to getBox1 [elem] | D.cpp:51:5:51:5 | ref arg b [box, elem] |
|
||||
| D.cpp:51:27:51:27 | e | D.cpp:51:8:51:14 | ref arg call to getBox1 [elem] |
|
||||
| D.cpp:52:14:52:14 | b [box, elem] | D.cpp:21:30:21:31 | b2 [box, elem] |
|
||||
| D.cpp:56:15:56:24 | new | D.cpp:58:5:58:27 | ... = ... |
|
||||
| D.cpp:58:5:58:12 | boxfield [post update] [box, elem] | D.cpp:58:5:58:12 | this [post update] [boxfield, box, ... (3)] |
|
||||
@@ -155,18 +155,80 @@ edges
|
||||
| aliasing.cpp:92:12:92:21 | call to user_input | aliasing.cpp:92:3:92:23 | ... = ... |
|
||||
| aliasing.cpp:93:8:93:8 | w [s, m1] | aliasing.cpp:93:10:93:10 | s [m1] |
|
||||
| aliasing.cpp:93:10:93:10 | s [m1] | aliasing.cpp:93:12:93:13 | m1 |
|
||||
| by_reference.cpp:50:3:50:3 | s [post update] [a] | by_reference.cpp:51:8:51:8 | s [a] |
|
||||
| by_reference.cpp:50:17:50:26 | call to user_input | by_reference.cpp:50:3:50:3 | s [post update] [a] |
|
||||
| by_reference.cpp:50:3:50:3 | ref arg s [a] | by_reference.cpp:51:8:51:8 | s [a] |
|
||||
| by_reference.cpp:50:17:50:26 | call to user_input | by_reference.cpp:50:3:50:3 | ref arg s [a] |
|
||||
| by_reference.cpp:51:8:51:8 | s [a] | by_reference.cpp:51:10:51:20 | call to getDirectly |
|
||||
| by_reference.cpp:56:3:56:3 | s [post update] [a] | by_reference.cpp:57:8:57:8 | s [a] |
|
||||
| by_reference.cpp:56:19:56:28 | call to user_input | by_reference.cpp:56:3:56:3 | s [post update] [a] |
|
||||
| by_reference.cpp:56:3:56:3 | ref arg s [a] | by_reference.cpp:57:8:57:8 | s [a] |
|
||||
| by_reference.cpp:56:19:56:28 | call to user_input | by_reference.cpp:56:3:56:3 | ref arg s [a] |
|
||||
| by_reference.cpp:57:8:57:8 | s [a] | by_reference.cpp:57:10:57:22 | call to getIndirectly |
|
||||
| by_reference.cpp:62:3:62:3 | s [post update] [a] | by_reference.cpp:63:8:63:8 | s [a] |
|
||||
| by_reference.cpp:62:25:62:34 | call to user_input | by_reference.cpp:62:3:62:3 | s [post update] [a] |
|
||||
| by_reference.cpp:62:3:62:3 | ref arg s [a] | by_reference.cpp:63:8:63:8 | s [a] |
|
||||
| by_reference.cpp:62:25:62:34 | call to user_input | by_reference.cpp:62:3:62:3 | ref arg s [a] |
|
||||
| by_reference.cpp:63:8:63:8 | s [a] | by_reference.cpp:63:10:63:28 | call to getThroughNonMember |
|
||||
| by_reference.cpp:68:17:68:18 | ref arg & ... [a] | by_reference.cpp:69:22:69:23 | & ... [a] |
|
||||
| by_reference.cpp:68:21:68:30 | call to user_input | by_reference.cpp:68:17:68:18 | ref arg & ... [a] |
|
||||
| by_reference.cpp:69:22:69:23 | & ... [a] | by_reference.cpp:69:8:69:20 | call to nonMemberGetA |
|
||||
| by_reference.cpp:84:3:84:7 | inner [post update] [a] | by_reference.cpp:102:21:102:39 | ref arg & ... [a] |
|
||||
| by_reference.cpp:84:3:84:7 | inner [post update] [a] | by_reference.cpp:103:27:103:35 | ref arg inner_ptr [a] |
|
||||
| by_reference.cpp:84:3:84:7 | inner [post update] [a] | by_reference.cpp:106:21:106:41 | ref arg & ... [a] |
|
||||
| by_reference.cpp:84:3:84:7 | inner [post update] [a] | by_reference.cpp:107:29:107:37 | ref arg inner_ptr [a] |
|
||||
| by_reference.cpp:84:3:84:25 | ... = ... | by_reference.cpp:84:3:84:7 | inner [post update] [a] |
|
||||
| by_reference.cpp:84:14:84:23 | call to user_input | by_reference.cpp:84:3:84:25 | ... = ... |
|
||||
| by_reference.cpp:87:31:87:35 | inner [a] | by_reference.cpp:122:27:122:38 | ref arg inner_nested [a] |
|
||||
| by_reference.cpp:87:31:87:35 | inner [a] | by_reference.cpp:123:21:123:36 | ref arg * ... [a] |
|
||||
| by_reference.cpp:87:31:87:35 | inner [a] | by_reference.cpp:126:29:126:40 | ref arg inner_nested [a] |
|
||||
| by_reference.cpp:87:31:87:35 | inner [a] | by_reference.cpp:127:21:127:38 | ref arg * ... [a] |
|
||||
| by_reference.cpp:88:3:88:7 | inner [post update] [a] | by_reference.cpp:87:31:87:35 | inner [a] |
|
||||
| by_reference.cpp:88:3:88:7 | inner [post update] [a] | by_reference.cpp:122:27:122:38 | ref arg inner_nested [a] |
|
||||
| by_reference.cpp:88:3:88:7 | inner [post update] [a] | by_reference.cpp:123:21:123:36 | ref arg * ... [a] |
|
||||
| by_reference.cpp:88:3:88:7 | inner [post update] [a] | by_reference.cpp:126:29:126:40 | ref arg inner_nested [a] |
|
||||
| by_reference.cpp:88:3:88:7 | inner [post update] [a] | by_reference.cpp:127:21:127:38 | ref arg * ... [a] |
|
||||
| by_reference.cpp:88:3:88:24 | ... = ... | by_reference.cpp:88:3:88:7 | inner [post update] [a] |
|
||||
| by_reference.cpp:88:13:88:22 | call to user_input | by_reference.cpp:88:3:88:24 | ... = ... |
|
||||
| by_reference.cpp:95:25:95:26 | pa | by_reference.cpp:124:21:124:21 | ref arg a |
|
||||
| by_reference.cpp:95:25:95:26 | pa | by_reference.cpp:128:23:128:23 | ref arg a |
|
||||
| by_reference.cpp:96:8:96:17 | call to user_input | by_reference.cpp:95:25:95:26 | pa |
|
||||
| by_reference.cpp:102:21:102:39 | ref arg & ... [a] | by_reference.cpp:102:28:102:39 | inner_nested [inner post update] [a] |
|
||||
| by_reference.cpp:102:22:102:26 | outer [post update] [inner_nested, a] | by_reference.cpp:110:8:110:12 | outer [inner_nested, a] |
|
||||
| by_reference.cpp:102:28:102:39 | inner_nested [inner post update] [a] | by_reference.cpp:102:22:102:26 | outer [post update] [inner_nested, a] |
|
||||
| by_reference.cpp:103:21:103:25 | outer [post update] [inner_ptr, a] | by_reference.cpp:111:8:111:12 | outer [inner_ptr, a] |
|
||||
| by_reference.cpp:103:27:103:35 | ref arg inner_ptr [a] | by_reference.cpp:103:21:103:25 | outer [post update] [inner_ptr, a] |
|
||||
| by_reference.cpp:106:21:106:41 | ref arg & ... [a] | by_reference.cpp:106:30:106:41 | inner_nested [inner post update] [a] |
|
||||
| by_reference.cpp:106:22:106:27 | pouter [post update] [inner_nested, a] | by_reference.cpp:114:8:114:13 | pouter [inner_nested, a] |
|
||||
| by_reference.cpp:106:30:106:41 | inner_nested [inner post update] [a] | by_reference.cpp:106:22:106:27 | pouter [post update] [inner_nested, a] |
|
||||
| by_reference.cpp:107:21:107:26 | pouter [post update] [inner_ptr, a] | by_reference.cpp:115:8:115:13 | pouter [inner_ptr, a] |
|
||||
| by_reference.cpp:107:29:107:37 | ref arg inner_ptr [a] | by_reference.cpp:107:21:107:26 | pouter [post update] [inner_ptr, a] |
|
||||
| by_reference.cpp:110:8:110:12 | outer [inner_nested, a] | by_reference.cpp:110:14:110:25 | inner_nested [a] |
|
||||
| by_reference.cpp:110:14:110:25 | inner_nested [a] | by_reference.cpp:110:27:110:27 | a |
|
||||
| by_reference.cpp:111:8:111:12 | outer [inner_ptr, a] | by_reference.cpp:111:14:111:22 | inner_ptr [a] |
|
||||
| by_reference.cpp:111:14:111:22 | inner_ptr [a] | by_reference.cpp:111:25:111:25 | a |
|
||||
| by_reference.cpp:114:8:114:13 | pouter [inner_nested, a] | by_reference.cpp:114:16:114:27 | inner_nested [a] |
|
||||
| by_reference.cpp:114:16:114:27 | inner_nested [a] | by_reference.cpp:114:29:114:29 | a |
|
||||
| by_reference.cpp:115:8:115:13 | pouter [inner_ptr, a] | by_reference.cpp:115:16:115:24 | inner_ptr [a] |
|
||||
| by_reference.cpp:115:16:115:24 | inner_ptr [a] | by_reference.cpp:115:27:115:27 | a |
|
||||
| by_reference.cpp:122:21:122:25 | outer [post update] [inner_nested, a] | by_reference.cpp:130:8:130:12 | outer [inner_nested, a] |
|
||||
| by_reference.cpp:122:27:122:38 | ref arg inner_nested [a] | by_reference.cpp:122:21:122:25 | outer [post update] [inner_nested, a] |
|
||||
| by_reference.cpp:123:21:123:36 | ref arg * ... [a] | by_reference.cpp:123:28:123:36 | inner_ptr [inner post update] [a] |
|
||||
| by_reference.cpp:123:22:123:26 | outer [post update] [inner_ptr, a] | by_reference.cpp:131:8:131:12 | outer [inner_ptr, a] |
|
||||
| by_reference.cpp:123:28:123:36 | inner_ptr [inner post update] [a] | by_reference.cpp:123:22:123:26 | outer [post update] [inner_ptr, a] |
|
||||
| by_reference.cpp:124:15:124:19 | outer [post update] [a] | by_reference.cpp:132:8:132:12 | outer [a] |
|
||||
| by_reference.cpp:124:21:124:21 | ref arg a | by_reference.cpp:124:15:124:19 | outer [post update] [a] |
|
||||
| by_reference.cpp:126:21:126:26 | pouter [post update] [inner_nested, a] | by_reference.cpp:134:8:134:13 | pouter [inner_nested, a] |
|
||||
| by_reference.cpp:126:29:126:40 | ref arg inner_nested [a] | by_reference.cpp:126:21:126:26 | pouter [post update] [inner_nested, a] |
|
||||
| by_reference.cpp:127:21:127:38 | ref arg * ... [a] | by_reference.cpp:127:30:127:38 | inner_ptr [inner post update] [a] |
|
||||
| by_reference.cpp:127:22:127:27 | pouter [post update] [inner_ptr, a] | by_reference.cpp:135:8:135:13 | pouter [inner_ptr, a] |
|
||||
| by_reference.cpp:127:30:127:38 | inner_ptr [inner post update] [a] | by_reference.cpp:127:22:127:27 | pouter [post update] [inner_ptr, a] |
|
||||
| by_reference.cpp:128:15:128:20 | pouter [post update] [a] | by_reference.cpp:136:8:136:13 | pouter [a] |
|
||||
| by_reference.cpp:128:23:128:23 | ref arg a | by_reference.cpp:128:15:128:20 | pouter [post update] [a] |
|
||||
| by_reference.cpp:130:8:130:12 | outer [inner_nested, a] | by_reference.cpp:130:14:130:25 | inner_nested [a] |
|
||||
| by_reference.cpp:130:14:130:25 | inner_nested [a] | by_reference.cpp:130:27:130:27 | a |
|
||||
| by_reference.cpp:131:8:131:12 | outer [inner_ptr, a] | by_reference.cpp:131:14:131:22 | inner_ptr [a] |
|
||||
| by_reference.cpp:131:14:131:22 | inner_ptr [a] | by_reference.cpp:131:25:131:25 | a |
|
||||
| by_reference.cpp:132:8:132:12 | outer [a] | by_reference.cpp:132:14:132:14 | a |
|
||||
| by_reference.cpp:134:8:134:13 | pouter [inner_nested, a] | by_reference.cpp:134:16:134:27 | inner_nested [a] |
|
||||
| by_reference.cpp:134:16:134:27 | inner_nested [a] | by_reference.cpp:134:29:134:29 | a |
|
||||
| by_reference.cpp:135:8:135:13 | pouter [inner_ptr, a] | by_reference.cpp:135:16:135:24 | inner_ptr [a] |
|
||||
| by_reference.cpp:135:16:135:24 | inner_ptr [a] | by_reference.cpp:135:27:135:27 | a |
|
||||
| by_reference.cpp:136:8:136:13 | pouter [a] | by_reference.cpp:136:16:136:16 | a |
|
||||
| complex.cpp:34:15:34:15 | b [f, a_] | complex.cpp:44:8:44:8 | b [f, a_] |
|
||||
| complex.cpp:34:15:34:15 | b [f, b_] | complex.cpp:45:8:45:8 | b [f, b_] |
|
||||
| complex.cpp:44:8:44:8 | b [f, a_] | complex.cpp:44:10:44:10 | f [a_] |
|
||||
@@ -174,17 +236,17 @@ edges
|
||||
| complex.cpp:45:8:45:8 | b [f, b_] | complex.cpp:45:10:45:10 | f [b_] |
|
||||
| complex.cpp:45:10:45:10 | f [b_] | complex.cpp:45:12:45:12 | call to b |
|
||||
| complex.cpp:55:3:55:4 | b1 [post update] [f, a_] | complex.cpp:61:7:61:8 | b1 [f, a_] |
|
||||
| complex.cpp:55:6:55:6 | f [post update] [a_] | complex.cpp:55:3:55:4 | b1 [post update] [f, a_] |
|
||||
| complex.cpp:55:13:55:22 | call to user_input | complex.cpp:55:6:55:6 | f [post update] [a_] |
|
||||
| complex.cpp:55:6:55:6 | ref arg f [a_] | complex.cpp:55:3:55:4 | b1 [post update] [f, a_] |
|
||||
| complex.cpp:55:13:55:22 | call to user_input | complex.cpp:55:6:55:6 | ref arg f [a_] |
|
||||
| complex.cpp:56:3:56:4 | b2 [post update] [f, b_] | complex.cpp:64:7:64:8 | b2 [f, b_] |
|
||||
| complex.cpp:56:6:56:6 | f [post update] [b_] | complex.cpp:56:3:56:4 | b2 [post update] [f, b_] |
|
||||
| complex.cpp:56:13:56:22 | call to user_input | complex.cpp:56:6:56:6 | f [post update] [b_] |
|
||||
| complex.cpp:56:6:56:6 | ref arg f [b_] | complex.cpp:56:3:56:4 | b2 [post update] [f, b_] |
|
||||
| complex.cpp:56:13:56:22 | call to user_input | complex.cpp:56:6:56:6 | ref arg f [b_] |
|
||||
| complex.cpp:57:3:57:4 | b3 [post update] [f, a_] | complex.cpp:67:7:67:8 | b3 [f, a_] |
|
||||
| complex.cpp:57:6:57:6 | f [post update] [a_] | complex.cpp:57:3:57:4 | b3 [post update] [f, a_] |
|
||||
| complex.cpp:57:13:57:22 | call to user_input | complex.cpp:57:6:57:6 | f [post update] [a_] |
|
||||
| complex.cpp:57:6:57:6 | ref arg f [a_] | complex.cpp:57:3:57:4 | b3 [post update] [f, a_] |
|
||||
| complex.cpp:57:13:57:22 | call to user_input | complex.cpp:57:6:57:6 | ref arg f [a_] |
|
||||
| complex.cpp:58:3:58:4 | b3 [post update] [f, b_] | complex.cpp:67:7:67:8 | b3 [f, b_] |
|
||||
| complex.cpp:58:6:58:6 | f [post update] [b_] | complex.cpp:58:3:58:4 | b3 [post update] [f, b_] |
|
||||
| complex.cpp:58:13:58:22 | call to user_input | complex.cpp:58:6:58:6 | f [post update] [b_] |
|
||||
| complex.cpp:58:6:58:6 | ref arg f [b_] | complex.cpp:58:3:58:4 | b3 [post update] [f, b_] |
|
||||
| complex.cpp:58:13:58:22 | call to user_input | complex.cpp:58:6:58:6 | ref arg f [b_] |
|
||||
| complex.cpp:61:7:61:8 | b1 [f, a_] | complex.cpp:34:15:34:15 | b [f, a_] |
|
||||
| complex.cpp:64:7:64:8 | b2 [f, b_] | complex.cpp:34:15:34:15 | b [f, b_] |
|
||||
| complex.cpp:67:7:67:8 | b3 [f, a_] | complex.cpp:34:15:34:15 | b [f, a_] |
|
||||
@@ -205,18 +267,53 @@ edges
|
||||
| constructors.cpp:43:9:43:9 | g [b_] | constructors.cpp:26:15:26:15 | f [b_] |
|
||||
| constructors.cpp:46:9:46:9 | h [a_] | constructors.cpp:26:15:26:15 | f [a_] |
|
||||
| constructors.cpp:46:9:46:9 | h [b_] | constructors.cpp:26:15:26:15 | f [b_] |
|
||||
| qualifiers.cpp:22:5:22:9 | ref arg outer [inner, a] | qualifiers.cpp:23:10:23:14 | outer [inner, a] |
|
||||
| qualifiers.cpp:22:5:22:38 | ... = ... | qualifiers.cpp:22:11:22:18 | call to getInner [post update] [a] |
|
||||
| qualifiers.cpp:22:11:22:18 | call to getInner [post update] [a] | qualifiers.cpp:22:5:22:9 | ref arg outer [inner, a] |
|
||||
| qualifiers.cpp:22:27:22:36 | call to user_input | qualifiers.cpp:22:5:22:38 | ... = ... |
|
||||
| qualifiers.cpp:23:10:23:14 | outer [inner, a] | qualifiers.cpp:23:16:23:20 | inner [a] |
|
||||
| qualifiers.cpp:23:16:23:20 | inner [a] | qualifiers.cpp:23:23:23:23 | a |
|
||||
| qualifiers.cpp:27:5:27:9 | ref arg outer [inner, a] | qualifiers.cpp:28:10:28:14 | outer [inner, a] |
|
||||
| qualifiers.cpp:27:11:27:18 | ref arg call to getInner [a] | qualifiers.cpp:27:5:27:9 | ref arg outer [inner, a] |
|
||||
| qualifiers.cpp:27:28:27:37 | call to user_input | qualifiers.cpp:27:11:27:18 | ref arg call to getInner [a] |
|
||||
| qualifiers.cpp:28:10:28:14 | outer [inner, a] | qualifiers.cpp:28:16:28:20 | inner [a] |
|
||||
| qualifiers.cpp:28:16:28:20 | inner [a] | qualifiers.cpp:28:23:28:23 | a |
|
||||
| qualifiers.cpp:32:17:32:21 | ref arg outer [inner, a] | qualifiers.cpp:33:10:33:14 | outer [inner, a] |
|
||||
| qualifiers.cpp:32:23:32:30 | ref arg call to getInner [a] | qualifiers.cpp:32:17:32:21 | ref arg outer [inner, a] |
|
||||
| qualifiers.cpp:32:35:32:44 | call to user_input | qualifiers.cpp:32:23:32:30 | ref arg call to getInner [a] |
|
||||
| qualifiers.cpp:33:10:33:14 | outer [inner, a] | qualifiers.cpp:33:16:33:20 | inner [a] |
|
||||
| qualifiers.cpp:33:16:33:20 | inner [a] | qualifiers.cpp:33:23:33:23 | a |
|
||||
| qualifiers.cpp:37:19:37:35 | ref arg * ... [a] | qualifiers.cpp:37:26:37:33 | call to getInner [inner post update] [a] |
|
||||
| qualifiers.cpp:37:20:37:24 | ref arg outer [inner, a] | qualifiers.cpp:38:10:38:14 | outer [inner, a] |
|
||||
| qualifiers.cpp:37:26:37:33 | call to getInner [inner post update] [a] | qualifiers.cpp:37:20:37:24 | ref arg outer [inner, a] |
|
||||
| qualifiers.cpp:37:38:37:47 | call to user_input | qualifiers.cpp:37:19:37:35 | ref arg * ... [a] |
|
||||
| qualifiers.cpp:38:10:38:14 | outer [inner, a] | qualifiers.cpp:38:16:38:20 | inner [a] |
|
||||
| qualifiers.cpp:38:16:38:20 | inner [a] | qualifiers.cpp:38:23:38:23 | a |
|
||||
| qualifiers.cpp:42:5:42:40 | ... = ... | qualifiers.cpp:42:6:42:22 | * ... [post update] [a] |
|
||||
| qualifiers.cpp:42:6:42:22 | * ... [post update] [a] | qualifiers.cpp:42:13:42:20 | call to getInner [inner post update] [a] |
|
||||
| qualifiers.cpp:42:7:42:11 | ref arg outer [inner, a] | qualifiers.cpp:43:10:43:14 | outer [inner, a] |
|
||||
| qualifiers.cpp:42:13:42:20 | call to getInner [inner post update] [a] | qualifiers.cpp:42:7:42:11 | ref arg outer [inner, a] |
|
||||
| qualifiers.cpp:42:29:42:38 | call to user_input | qualifiers.cpp:42:5:42:40 | ... = ... |
|
||||
| qualifiers.cpp:43:10:43:14 | outer [inner, a] | qualifiers.cpp:43:16:43:20 | inner [a] |
|
||||
| qualifiers.cpp:43:16:43:20 | inner [a] | qualifiers.cpp:43:23:43:23 | a |
|
||||
| qualifiers.cpp:47:5:47:42 | ... = ... | qualifiers.cpp:47:15:47:22 | call to getInner [post update] [a] |
|
||||
| qualifiers.cpp:47:6:47:11 | ref arg & ... [inner, a] | qualifiers.cpp:48:10:48:14 | outer [inner, a] |
|
||||
| qualifiers.cpp:47:15:47:22 | call to getInner [post update] [a] | qualifiers.cpp:47:6:47:11 | ref arg & ... [inner, a] |
|
||||
| qualifiers.cpp:47:31:47:40 | call to user_input | qualifiers.cpp:47:5:47:42 | ... = ... |
|
||||
| qualifiers.cpp:48:10:48:14 | outer [inner, a] | qualifiers.cpp:48:16:48:20 | inner [a] |
|
||||
| qualifiers.cpp:48:16:48:20 | inner [a] | qualifiers.cpp:48:23:48:23 | a |
|
||||
| simple.cpp:26:15:26:15 | f [a_] | simple.cpp:28:10:28:10 | f [a_] |
|
||||
| simple.cpp:26:15:26:15 | f [b_] | simple.cpp:29:10:29:10 | f [b_] |
|
||||
| simple.cpp:28:10:28:10 | f [a_] | simple.cpp:28:12:28:12 | call to a |
|
||||
| simple.cpp:29:10:29:10 | f [b_] | simple.cpp:29:12:29:12 | call to b |
|
||||
| simple.cpp:39:5:39:5 | f [post update] [a_] | simple.cpp:45:9:45:9 | f [a_] |
|
||||
| simple.cpp:39:12:39:21 | call to user_input | simple.cpp:39:5:39:5 | f [post update] [a_] |
|
||||
| simple.cpp:40:5:40:5 | g [post update] [b_] | simple.cpp:48:9:48:9 | g [b_] |
|
||||
| simple.cpp:40:12:40:21 | call to user_input | simple.cpp:40:5:40:5 | g [post update] [b_] |
|
||||
| simple.cpp:41:5:41:5 | h [post update] [a_] | simple.cpp:51:9:51:9 | h [a_] |
|
||||
| simple.cpp:41:12:41:21 | call to user_input | simple.cpp:41:5:41:5 | h [post update] [a_] |
|
||||
| simple.cpp:42:5:42:5 | h [post update] [b_] | simple.cpp:51:9:51:9 | h [b_] |
|
||||
| simple.cpp:42:12:42:21 | call to user_input | simple.cpp:42:5:42:5 | h [post update] [b_] |
|
||||
| simple.cpp:39:5:39:5 | ref arg f [a_] | simple.cpp:45:9:45:9 | f [a_] |
|
||||
| simple.cpp:39:12:39:21 | call to user_input | simple.cpp:39:5:39:5 | ref arg f [a_] |
|
||||
| simple.cpp:40:5:40:5 | ref arg g [b_] | simple.cpp:48:9:48:9 | g [b_] |
|
||||
| simple.cpp:40:12:40:21 | call to user_input | simple.cpp:40:5:40:5 | ref arg g [b_] |
|
||||
| simple.cpp:41:5:41:5 | ref arg h [a_] | simple.cpp:51:9:51:9 | h [a_] |
|
||||
| simple.cpp:41:12:41:21 | call to user_input | simple.cpp:41:5:41:5 | ref arg h [a_] |
|
||||
| simple.cpp:42:5:42:5 | ref arg h [b_] | simple.cpp:51:9:51:9 | h [b_] |
|
||||
| simple.cpp:42:12:42:21 | call to user_input | simple.cpp:42:5:42:5 | ref arg h [b_] |
|
||||
| simple.cpp:45:9:45:9 | f [a_] | simple.cpp:26:15:26:15 | f [a_] |
|
||||
| simple.cpp:48:9:48:9 | g [b_] | simple.cpp:26:15:26:15 | f [b_] |
|
||||
| simple.cpp:51:9:51:9 | h [a_] | simple.cpp:26:15:26:15 | f [a_] |
|
||||
@@ -265,7 +362,7 @@ nodes
|
||||
| A.cpp:48:20:48:20 | c | semmle.label | c |
|
||||
| A.cpp:49:10:49:10 | b [c] | semmle.label | b [c] |
|
||||
| A.cpp:49:13:49:13 | c | semmle.label | c |
|
||||
| A.cpp:55:5:55:5 | b [post update] [c] | semmle.label | b [post update] [c] |
|
||||
| A.cpp:55:5:55:5 | ref arg b [c] | semmle.label | ref arg b [c] |
|
||||
| A.cpp:55:12:55:19 | new | semmle.label | new |
|
||||
| A.cpp:56:10:56:10 | b [c] | semmle.label | b [c] |
|
||||
| A.cpp:56:13:56:15 | call to get | semmle.label | call to get |
|
||||
@@ -290,7 +387,7 @@ nodes
|
||||
| A.cpp:107:16:107:16 | a | semmle.label | a |
|
||||
| A.cpp:120:12:120:13 | c1 [a] | semmle.label | c1 [a] |
|
||||
| A.cpp:120:16:120:16 | a | semmle.label | a |
|
||||
| A.cpp:126:5:126:5 | b [post update] [c] | semmle.label | b [post update] [c] |
|
||||
| A.cpp:126:5:126:5 | ref arg b [c] | semmle.label | ref arg b [c] |
|
||||
| A.cpp:126:12:126:18 | new | semmle.label | new |
|
||||
| A.cpp:131:8:131:8 | ref arg b [c] | semmle.label | ref arg b [c] |
|
||||
| A.cpp:132:10:132:10 | b [c] | semmle.label | b [c] |
|
||||
@@ -374,17 +471,17 @@ nodes
|
||||
| D.cpp:31:14:31:14 | b [box, elem] | semmle.label | b [box, elem] |
|
||||
| D.cpp:35:15:35:24 | new | semmle.label | new |
|
||||
| D.cpp:37:5:37:5 | b [post update] [box, elem] | semmle.label | b [post update] [box, elem] |
|
||||
| D.cpp:37:8:37:10 | box [post update] [elem] | semmle.label | box [post update] [elem] |
|
||||
| D.cpp:37:8:37:10 | ref arg box [elem] | semmle.label | ref arg box [elem] |
|
||||
| D.cpp:37:21:37:21 | e | semmle.label | e |
|
||||
| D.cpp:38:14:38:14 | b [box, elem] | semmle.label | b [box, elem] |
|
||||
| D.cpp:42:15:42:24 | new | semmle.label | new |
|
||||
| D.cpp:44:5:44:5 | b [post update] [box, elem] | semmle.label | b [post update] [box, elem] |
|
||||
| D.cpp:44:5:44:5 | ref arg b [box, elem] | semmle.label | ref arg b [box, elem] |
|
||||
| D.cpp:44:5:44:26 | ... = ... | semmle.label | ... = ... |
|
||||
| D.cpp:44:8:44:14 | call to getBox1 [post update] [elem] | semmle.label | call to getBox1 [post update] [elem] |
|
||||
| D.cpp:45:14:45:14 | b [box, elem] | semmle.label | b [box, elem] |
|
||||
| D.cpp:49:15:49:24 | new | semmle.label | new |
|
||||
| D.cpp:51:5:51:5 | b [post update] [box, elem] | semmle.label | b [post update] [box, elem] |
|
||||
| D.cpp:51:8:51:14 | call to getBox1 [post update] [elem] | semmle.label | call to getBox1 [post update] [elem] |
|
||||
| D.cpp:51:5:51:5 | ref arg b [box, elem] | semmle.label | ref arg b [box, elem] |
|
||||
| D.cpp:51:8:51:14 | ref arg call to getBox1 [elem] | semmle.label | ref arg call to getBox1 [elem] |
|
||||
| D.cpp:51:27:51:27 | e | semmle.label | e |
|
||||
| D.cpp:52:14:52:14 | b [box, elem] | semmle.label | b [box, elem] |
|
||||
| D.cpp:56:15:56:24 | new | semmle.label | new |
|
||||
@@ -437,15 +534,15 @@ nodes
|
||||
| aliasing.cpp:93:8:93:8 | w [s, m1] | semmle.label | w [s, m1] |
|
||||
| aliasing.cpp:93:10:93:10 | s [m1] | semmle.label | s [m1] |
|
||||
| aliasing.cpp:93:12:93:13 | m1 | semmle.label | m1 |
|
||||
| by_reference.cpp:50:3:50:3 | s [post update] [a] | semmle.label | s [post update] [a] |
|
||||
| by_reference.cpp:50:3:50:3 | ref arg s [a] | semmle.label | ref arg s [a] |
|
||||
| by_reference.cpp:50:17:50:26 | call to user_input | semmle.label | call to user_input |
|
||||
| by_reference.cpp:51:8:51:8 | s [a] | semmle.label | s [a] |
|
||||
| by_reference.cpp:51:10:51:20 | call to getDirectly | semmle.label | call to getDirectly |
|
||||
| by_reference.cpp:56:3:56:3 | s [post update] [a] | semmle.label | s [post update] [a] |
|
||||
| by_reference.cpp:56:3:56:3 | ref arg s [a] | semmle.label | ref arg s [a] |
|
||||
| by_reference.cpp:56:19:56:28 | call to user_input | semmle.label | call to user_input |
|
||||
| by_reference.cpp:57:8:57:8 | s [a] | semmle.label | s [a] |
|
||||
| by_reference.cpp:57:10:57:22 | call to getIndirectly | semmle.label | call to getIndirectly |
|
||||
| by_reference.cpp:62:3:62:3 | s [post update] [a] | semmle.label | s [post update] [a] |
|
||||
| by_reference.cpp:62:3:62:3 | ref arg s [a] | semmle.label | ref arg s [a] |
|
||||
| by_reference.cpp:62:25:62:34 | call to user_input | semmle.label | call to user_input |
|
||||
| by_reference.cpp:63:8:63:8 | s [a] | semmle.label | s [a] |
|
||||
| by_reference.cpp:63:10:63:28 | call to getThroughNonMember | semmle.label | call to getThroughNonMember |
|
||||
@@ -453,6 +550,67 @@ nodes
|
||||
| by_reference.cpp:68:21:68:30 | call to user_input | semmle.label | call to user_input |
|
||||
| by_reference.cpp:69:8:69:20 | call to nonMemberGetA | semmle.label | call to nonMemberGetA |
|
||||
| by_reference.cpp:69:22:69:23 | & ... [a] | semmle.label | & ... [a] |
|
||||
| by_reference.cpp:84:3:84:7 | inner [post update] [a] | semmle.label | inner [post update] [a] |
|
||||
| by_reference.cpp:84:3:84:25 | ... = ... | semmle.label | ... = ... |
|
||||
| by_reference.cpp:84:14:84:23 | call to user_input | semmle.label | call to user_input |
|
||||
| by_reference.cpp:87:31:87:35 | inner [a] | semmle.label | inner [a] |
|
||||
| by_reference.cpp:88:3:88:7 | inner [post update] [a] | semmle.label | inner [post update] [a] |
|
||||
| by_reference.cpp:88:3:88:24 | ... = ... | semmle.label | ... = ... |
|
||||
| by_reference.cpp:88:13:88:22 | call to user_input | semmle.label | call to user_input |
|
||||
| by_reference.cpp:95:25:95:26 | pa | semmle.label | pa |
|
||||
| by_reference.cpp:96:8:96:17 | call to user_input | semmle.label | call to user_input |
|
||||
| by_reference.cpp:102:21:102:39 | ref arg & ... [a] | semmle.label | ref arg & ... [a] |
|
||||
| by_reference.cpp:102:22:102:26 | outer [post update] [inner_nested, a] | semmle.label | outer [post update] [inner_nested, a] |
|
||||
| by_reference.cpp:102:28:102:39 | inner_nested [inner post update] [a] | semmle.label | inner_nested [inner post update] [a] |
|
||||
| by_reference.cpp:103:21:103:25 | outer [post update] [inner_ptr, a] | semmle.label | outer [post update] [inner_ptr, a] |
|
||||
| by_reference.cpp:103:27:103:35 | ref arg inner_ptr [a] | semmle.label | ref arg inner_ptr [a] |
|
||||
| by_reference.cpp:106:21:106:41 | ref arg & ... [a] | semmle.label | ref arg & ... [a] |
|
||||
| by_reference.cpp:106:22:106:27 | pouter [post update] [inner_nested, a] | semmle.label | pouter [post update] [inner_nested, a] |
|
||||
| by_reference.cpp:106:30:106:41 | inner_nested [inner post update] [a] | semmle.label | inner_nested [inner post update] [a] |
|
||||
| by_reference.cpp:107:21:107:26 | pouter [post update] [inner_ptr, a] | semmle.label | pouter [post update] [inner_ptr, a] |
|
||||
| by_reference.cpp:107:29:107:37 | ref arg inner_ptr [a] | semmle.label | ref arg inner_ptr [a] |
|
||||
| by_reference.cpp:110:8:110:12 | outer [inner_nested, a] | semmle.label | outer [inner_nested, a] |
|
||||
| by_reference.cpp:110:14:110:25 | inner_nested [a] | semmle.label | inner_nested [a] |
|
||||
| by_reference.cpp:110:27:110:27 | a | semmle.label | a |
|
||||
| by_reference.cpp:111:8:111:12 | outer [inner_ptr, a] | semmle.label | outer [inner_ptr, a] |
|
||||
| by_reference.cpp:111:14:111:22 | inner_ptr [a] | semmle.label | inner_ptr [a] |
|
||||
| by_reference.cpp:111:25:111:25 | a | semmle.label | a |
|
||||
| by_reference.cpp:114:8:114:13 | pouter [inner_nested, a] | semmle.label | pouter [inner_nested, a] |
|
||||
| by_reference.cpp:114:16:114:27 | inner_nested [a] | semmle.label | inner_nested [a] |
|
||||
| by_reference.cpp:114:29:114:29 | a | semmle.label | a |
|
||||
| by_reference.cpp:115:8:115:13 | pouter [inner_ptr, a] | semmle.label | pouter [inner_ptr, a] |
|
||||
| by_reference.cpp:115:16:115:24 | inner_ptr [a] | semmle.label | inner_ptr [a] |
|
||||
| by_reference.cpp:115:27:115:27 | a | semmle.label | a |
|
||||
| by_reference.cpp:122:21:122:25 | outer [post update] [inner_nested, a] | semmle.label | outer [post update] [inner_nested, a] |
|
||||
| by_reference.cpp:122:27:122:38 | ref arg inner_nested [a] | semmle.label | ref arg inner_nested [a] |
|
||||
| by_reference.cpp:123:21:123:36 | ref arg * ... [a] | semmle.label | ref arg * ... [a] |
|
||||
| by_reference.cpp:123:22:123:26 | outer [post update] [inner_ptr, a] | semmle.label | outer [post update] [inner_ptr, a] |
|
||||
| by_reference.cpp:123:28:123:36 | inner_ptr [inner post update] [a] | semmle.label | inner_ptr [inner post update] [a] |
|
||||
| by_reference.cpp:124:15:124:19 | outer [post update] [a] | semmle.label | outer [post update] [a] |
|
||||
| by_reference.cpp:124:21:124:21 | ref arg a | semmle.label | ref arg a |
|
||||
| by_reference.cpp:126:21:126:26 | pouter [post update] [inner_nested, a] | semmle.label | pouter [post update] [inner_nested, a] |
|
||||
| by_reference.cpp:126:29:126:40 | ref arg inner_nested [a] | semmle.label | ref arg inner_nested [a] |
|
||||
| by_reference.cpp:127:21:127:38 | ref arg * ... [a] | semmle.label | ref arg * ... [a] |
|
||||
| by_reference.cpp:127:22:127:27 | pouter [post update] [inner_ptr, a] | semmle.label | pouter [post update] [inner_ptr, a] |
|
||||
| by_reference.cpp:127:30:127:38 | inner_ptr [inner post update] [a] | semmle.label | inner_ptr [inner post update] [a] |
|
||||
| by_reference.cpp:128:15:128:20 | pouter [post update] [a] | semmle.label | pouter [post update] [a] |
|
||||
| by_reference.cpp:128:23:128:23 | ref arg a | semmle.label | ref arg a |
|
||||
| by_reference.cpp:130:8:130:12 | outer [inner_nested, a] | semmle.label | outer [inner_nested, a] |
|
||||
| by_reference.cpp:130:14:130:25 | inner_nested [a] | semmle.label | inner_nested [a] |
|
||||
| by_reference.cpp:130:27:130:27 | a | semmle.label | a |
|
||||
| by_reference.cpp:131:8:131:12 | outer [inner_ptr, a] | semmle.label | outer [inner_ptr, a] |
|
||||
| by_reference.cpp:131:14:131:22 | inner_ptr [a] | semmle.label | inner_ptr [a] |
|
||||
| by_reference.cpp:131:25:131:25 | a | semmle.label | a |
|
||||
| by_reference.cpp:132:8:132:12 | outer [a] | semmle.label | outer [a] |
|
||||
| by_reference.cpp:132:14:132:14 | a | semmle.label | a |
|
||||
| by_reference.cpp:134:8:134:13 | pouter [inner_nested, a] | semmle.label | pouter [inner_nested, a] |
|
||||
| by_reference.cpp:134:16:134:27 | inner_nested [a] | semmle.label | inner_nested [a] |
|
||||
| by_reference.cpp:134:29:134:29 | a | semmle.label | a |
|
||||
| by_reference.cpp:135:8:135:13 | pouter [inner_ptr, a] | semmle.label | pouter [inner_ptr, a] |
|
||||
| by_reference.cpp:135:16:135:24 | inner_ptr [a] | semmle.label | inner_ptr [a] |
|
||||
| by_reference.cpp:135:27:135:27 | a | semmle.label | a |
|
||||
| by_reference.cpp:136:8:136:13 | pouter [a] | semmle.label | pouter [a] |
|
||||
| by_reference.cpp:136:16:136:16 | a | semmle.label | a |
|
||||
| complex.cpp:34:15:34:15 | b [f, a_] | semmle.label | b [f, a_] |
|
||||
| complex.cpp:34:15:34:15 | b [f, b_] | semmle.label | b [f, b_] |
|
||||
| complex.cpp:44:8:44:8 | b [f, a_] | semmle.label | b [f, a_] |
|
||||
@@ -462,16 +620,16 @@ nodes
|
||||
| complex.cpp:45:10:45:10 | f [b_] | semmle.label | f [b_] |
|
||||
| complex.cpp:45:12:45:12 | call to b | semmle.label | call to b |
|
||||
| complex.cpp:55:3:55:4 | b1 [post update] [f, a_] | semmle.label | b1 [post update] [f, a_] |
|
||||
| complex.cpp:55:6:55:6 | f [post update] [a_] | semmle.label | f [post update] [a_] |
|
||||
| complex.cpp:55:6:55:6 | ref arg f [a_] | semmle.label | ref arg f [a_] |
|
||||
| complex.cpp:55:13:55:22 | call to user_input | semmle.label | call to user_input |
|
||||
| complex.cpp:56:3:56:4 | b2 [post update] [f, b_] | semmle.label | b2 [post update] [f, b_] |
|
||||
| complex.cpp:56:6:56:6 | f [post update] [b_] | semmle.label | f [post update] [b_] |
|
||||
| complex.cpp:56:6:56:6 | ref arg f [b_] | semmle.label | ref arg f [b_] |
|
||||
| complex.cpp:56:13:56:22 | call to user_input | semmle.label | call to user_input |
|
||||
| complex.cpp:57:3:57:4 | b3 [post update] [f, a_] | semmle.label | b3 [post update] [f, a_] |
|
||||
| complex.cpp:57:6:57:6 | f [post update] [a_] | semmle.label | f [post update] [a_] |
|
||||
| complex.cpp:57:6:57:6 | ref arg f [a_] | semmle.label | ref arg f [a_] |
|
||||
| complex.cpp:57:13:57:22 | call to user_input | semmle.label | call to user_input |
|
||||
| complex.cpp:58:3:58:4 | b3 [post update] [f, b_] | semmle.label | b3 [post update] [f, b_] |
|
||||
| complex.cpp:58:6:58:6 | f [post update] [b_] | semmle.label | f [post update] [b_] |
|
||||
| complex.cpp:58:6:58:6 | ref arg f [b_] | semmle.label | ref arg f [b_] |
|
||||
| complex.cpp:58:13:58:22 | call to user_input | semmle.label | call to user_input |
|
||||
| complex.cpp:61:7:61:8 | b1 [f, a_] | semmle.label | b1 [f, a_] |
|
||||
| complex.cpp:64:7:64:8 | b2 [f, b_] | semmle.label | b2 [f, b_] |
|
||||
@@ -495,19 +653,60 @@ nodes
|
||||
| constructors.cpp:43:9:43:9 | g [b_] | semmle.label | g [b_] |
|
||||
| constructors.cpp:46:9:46:9 | h [a_] | semmle.label | h [a_] |
|
||||
| constructors.cpp:46:9:46:9 | h [b_] | semmle.label | h [b_] |
|
||||
| qualifiers.cpp:22:5:22:9 | ref arg outer [inner, a] | semmle.label | ref arg outer [inner, a] |
|
||||
| qualifiers.cpp:22:5:22:38 | ... = ... | semmle.label | ... = ... |
|
||||
| qualifiers.cpp:22:11:22:18 | call to getInner [post update] [a] | semmle.label | call to getInner [post update] [a] |
|
||||
| qualifiers.cpp:22:27:22:36 | call to user_input | semmle.label | call to user_input |
|
||||
| qualifiers.cpp:23:10:23:14 | outer [inner, a] | semmle.label | outer [inner, a] |
|
||||
| qualifiers.cpp:23:16:23:20 | inner [a] | semmle.label | inner [a] |
|
||||
| qualifiers.cpp:23:23:23:23 | a | semmle.label | a |
|
||||
| qualifiers.cpp:27:5:27:9 | ref arg outer [inner, a] | semmle.label | ref arg outer [inner, a] |
|
||||
| qualifiers.cpp:27:11:27:18 | ref arg call to getInner [a] | semmle.label | ref arg call to getInner [a] |
|
||||
| qualifiers.cpp:27:28:27:37 | call to user_input | semmle.label | call to user_input |
|
||||
| qualifiers.cpp:28:10:28:14 | outer [inner, a] | semmle.label | outer [inner, a] |
|
||||
| qualifiers.cpp:28:16:28:20 | inner [a] | semmle.label | inner [a] |
|
||||
| qualifiers.cpp:28:23:28:23 | a | semmle.label | a |
|
||||
| qualifiers.cpp:32:17:32:21 | ref arg outer [inner, a] | semmle.label | ref arg outer [inner, a] |
|
||||
| qualifiers.cpp:32:23:32:30 | ref arg call to getInner [a] | semmle.label | ref arg call to getInner [a] |
|
||||
| qualifiers.cpp:32:35:32:44 | call to user_input | semmle.label | call to user_input |
|
||||
| qualifiers.cpp:33:10:33:14 | outer [inner, a] | semmle.label | outer [inner, a] |
|
||||
| qualifiers.cpp:33:16:33:20 | inner [a] | semmle.label | inner [a] |
|
||||
| qualifiers.cpp:33:23:33:23 | a | semmle.label | a |
|
||||
| qualifiers.cpp:37:19:37:35 | ref arg * ... [a] | semmle.label | ref arg * ... [a] |
|
||||
| qualifiers.cpp:37:20:37:24 | ref arg outer [inner, a] | semmle.label | ref arg outer [inner, a] |
|
||||
| qualifiers.cpp:37:26:37:33 | call to getInner [inner post update] [a] | semmle.label | call to getInner [inner post update] [a] |
|
||||
| qualifiers.cpp:37:38:37:47 | call to user_input | semmle.label | call to user_input |
|
||||
| qualifiers.cpp:38:10:38:14 | outer [inner, a] | semmle.label | outer [inner, a] |
|
||||
| qualifiers.cpp:38:16:38:20 | inner [a] | semmle.label | inner [a] |
|
||||
| qualifiers.cpp:38:23:38:23 | a | semmle.label | a |
|
||||
| qualifiers.cpp:42:5:42:40 | ... = ... | semmle.label | ... = ... |
|
||||
| qualifiers.cpp:42:6:42:22 | * ... [post update] [a] | semmle.label | * ... [post update] [a] |
|
||||
| qualifiers.cpp:42:7:42:11 | ref arg outer [inner, a] | semmle.label | ref arg outer [inner, a] |
|
||||
| qualifiers.cpp:42:13:42:20 | call to getInner [inner post update] [a] | semmle.label | call to getInner [inner post update] [a] |
|
||||
| qualifiers.cpp:42:29:42:38 | call to user_input | semmle.label | call to user_input |
|
||||
| qualifiers.cpp:43:10:43:14 | outer [inner, a] | semmle.label | outer [inner, a] |
|
||||
| qualifiers.cpp:43:16:43:20 | inner [a] | semmle.label | inner [a] |
|
||||
| qualifiers.cpp:43:23:43:23 | a | semmle.label | a |
|
||||
| qualifiers.cpp:47:5:47:42 | ... = ... | semmle.label | ... = ... |
|
||||
| qualifiers.cpp:47:6:47:11 | ref arg & ... [inner, a] | semmle.label | ref arg & ... [inner, a] |
|
||||
| qualifiers.cpp:47:15:47:22 | call to getInner [post update] [a] | semmle.label | call to getInner [post update] [a] |
|
||||
| qualifiers.cpp:47:31:47:40 | call to user_input | semmle.label | call to user_input |
|
||||
| qualifiers.cpp:48:10:48:14 | outer [inner, a] | semmle.label | outer [inner, a] |
|
||||
| qualifiers.cpp:48:16:48:20 | inner [a] | semmle.label | inner [a] |
|
||||
| qualifiers.cpp:48:23:48:23 | a | semmle.label | a |
|
||||
| simple.cpp:26:15:26:15 | f [a_] | semmle.label | f [a_] |
|
||||
| simple.cpp:26:15:26:15 | f [b_] | semmle.label | f [b_] |
|
||||
| simple.cpp:28:10:28:10 | f [a_] | semmle.label | f [a_] |
|
||||
| simple.cpp:28:12:28:12 | call to a | semmle.label | call to a |
|
||||
| simple.cpp:29:10:29:10 | f [b_] | semmle.label | f [b_] |
|
||||
| simple.cpp:29:12:29:12 | call to b | semmle.label | call to b |
|
||||
| simple.cpp:39:5:39:5 | f [post update] [a_] | semmle.label | f [post update] [a_] |
|
||||
| simple.cpp:39:5:39:5 | ref arg f [a_] | semmle.label | ref arg f [a_] |
|
||||
| simple.cpp:39:12:39:21 | call to user_input | semmle.label | call to user_input |
|
||||
| simple.cpp:40:5:40:5 | g [post update] [b_] | semmle.label | g [post update] [b_] |
|
||||
| simple.cpp:40:5:40:5 | ref arg g [b_] | semmle.label | ref arg g [b_] |
|
||||
| simple.cpp:40:12:40:21 | call to user_input | semmle.label | call to user_input |
|
||||
| simple.cpp:41:5:41:5 | h [post update] [a_] | semmle.label | h [post update] [a_] |
|
||||
| simple.cpp:41:5:41:5 | ref arg h [a_] | semmle.label | ref arg h [a_] |
|
||||
| simple.cpp:41:12:41:21 | call to user_input | semmle.label | call to user_input |
|
||||
| simple.cpp:42:5:42:5 | h [post update] [b_] | semmle.label | h [post update] [b_] |
|
||||
| simple.cpp:42:5:42:5 | ref arg h [b_] | semmle.label | ref arg h [b_] |
|
||||
| simple.cpp:42:12:42:21 | call to user_input | semmle.label | call to user_input |
|
||||
| simple.cpp:45:9:45:9 | f [a_] | semmle.label | f [a_] |
|
||||
| simple.cpp:48:9:48:9 | g [b_] | semmle.label | g [b_] |
|
||||
@@ -588,6 +787,16 @@ nodes
|
||||
| by_reference.cpp:57:10:57:22 | call to getIndirectly | by_reference.cpp:56:19:56:28 | call to user_input | by_reference.cpp:57:10:57:22 | call to getIndirectly | call to getIndirectly flows from $@ | by_reference.cpp:56:19:56:28 | call to user_input | call to user_input |
|
||||
| by_reference.cpp:63:10:63:28 | call to getThroughNonMember | by_reference.cpp:62:25:62:34 | call to user_input | by_reference.cpp:63:10:63:28 | call to getThroughNonMember | call to getThroughNonMember flows from $@ | by_reference.cpp:62:25:62:34 | call to user_input | call to user_input |
|
||||
| by_reference.cpp:69:8:69:20 | call to nonMemberGetA | by_reference.cpp:68:21:68:30 | call to user_input | by_reference.cpp:69:8:69:20 | call to nonMemberGetA | call to nonMemberGetA flows from $@ | by_reference.cpp:68:21:68:30 | call to user_input | call to user_input |
|
||||
| by_reference.cpp:110:27:110:27 | a | by_reference.cpp:84:14:84:23 | call to user_input | by_reference.cpp:110:27:110:27 | a | a flows from $@ | by_reference.cpp:84:14:84:23 | call to user_input | call to user_input |
|
||||
| by_reference.cpp:111:25:111:25 | a | by_reference.cpp:84:14:84:23 | call to user_input | by_reference.cpp:111:25:111:25 | a | a flows from $@ | by_reference.cpp:84:14:84:23 | call to user_input | call to user_input |
|
||||
| by_reference.cpp:114:29:114:29 | a | by_reference.cpp:84:14:84:23 | call to user_input | by_reference.cpp:114:29:114:29 | a | a flows from $@ | by_reference.cpp:84:14:84:23 | call to user_input | call to user_input |
|
||||
| by_reference.cpp:115:27:115:27 | a | by_reference.cpp:84:14:84:23 | call to user_input | by_reference.cpp:115:27:115:27 | a | a flows from $@ | by_reference.cpp:84:14:84:23 | call to user_input | call to user_input |
|
||||
| by_reference.cpp:130:27:130:27 | a | by_reference.cpp:88:13:88:22 | call to user_input | by_reference.cpp:130:27:130:27 | a | a flows from $@ | by_reference.cpp:88:13:88:22 | call to user_input | call to user_input |
|
||||
| by_reference.cpp:131:25:131:25 | a | by_reference.cpp:88:13:88:22 | call to user_input | by_reference.cpp:131:25:131:25 | a | a flows from $@ | by_reference.cpp:88:13:88:22 | call to user_input | call to user_input |
|
||||
| by_reference.cpp:132:14:132:14 | a | by_reference.cpp:96:8:96:17 | call to user_input | by_reference.cpp:132:14:132:14 | a | a flows from $@ | by_reference.cpp:96:8:96:17 | call to user_input | call to user_input |
|
||||
| by_reference.cpp:134:29:134:29 | a | by_reference.cpp:88:13:88:22 | call to user_input | by_reference.cpp:134:29:134:29 | a | a flows from $@ | by_reference.cpp:88:13:88:22 | call to user_input | call to user_input |
|
||||
| by_reference.cpp:135:27:135:27 | a | by_reference.cpp:88:13:88:22 | call to user_input | by_reference.cpp:135:27:135:27 | a | a flows from $@ | by_reference.cpp:88:13:88:22 | call to user_input | call to user_input |
|
||||
| by_reference.cpp:136:16:136:16 | a | by_reference.cpp:96:8:96:17 | call to user_input | by_reference.cpp:136:16:136:16 | a | a flows from $@ | by_reference.cpp:96:8:96:17 | call to user_input | call to user_input |
|
||||
| complex.cpp:44:12:44:12 | call to a | complex.cpp:55:13:55:22 | call to user_input | complex.cpp:44:12:44:12 | call to a | call to a flows from $@ | complex.cpp:55:13:55:22 | call to user_input | call to user_input |
|
||||
| complex.cpp:44:12:44:12 | call to a | complex.cpp:57:13:57:22 | call to user_input | complex.cpp:44:12:44:12 | call to a | call to a flows from $@ | complex.cpp:57:13:57:22 | call to user_input | call to user_input |
|
||||
| complex.cpp:45:12:45:12 | call to b | complex.cpp:56:13:56:22 | call to user_input | complex.cpp:45:12:45:12 | call to b | call to b flows from $@ | complex.cpp:56:13:56:22 | call to user_input | call to user_input |
|
||||
@@ -596,6 +805,12 @@ nodes
|
||||
| constructors.cpp:28:12:28:12 | call to a | constructors.cpp:36:11:36:20 | call to user_input | constructors.cpp:28:12:28:12 | call to a | call to a flows from $@ | constructors.cpp:36:11:36:20 | call to user_input | call to user_input |
|
||||
| constructors.cpp:29:12:29:12 | call to b | constructors.cpp:35:14:35:23 | call to user_input | constructors.cpp:29:12:29:12 | call to b | call to b flows from $@ | constructors.cpp:35:14:35:23 | call to user_input | call to user_input |
|
||||
| constructors.cpp:29:12:29:12 | call to b | constructors.cpp:36:25:36:34 | call to user_input | constructors.cpp:29:12:29:12 | call to b | call to b flows from $@ | constructors.cpp:36:25:36:34 | call to user_input | call to user_input |
|
||||
| qualifiers.cpp:23:23:23:23 | a | qualifiers.cpp:22:27:22:36 | call to user_input | qualifiers.cpp:23:23:23:23 | a | a flows from $@ | qualifiers.cpp:22:27:22:36 | call to user_input | call to user_input |
|
||||
| qualifiers.cpp:28:23:28:23 | a | qualifiers.cpp:27:28:27:37 | call to user_input | qualifiers.cpp:28:23:28:23 | a | a flows from $@ | qualifiers.cpp:27:28:27:37 | call to user_input | call to user_input |
|
||||
| qualifiers.cpp:33:23:33:23 | a | qualifiers.cpp:32:35:32:44 | call to user_input | qualifiers.cpp:33:23:33:23 | a | a flows from $@ | qualifiers.cpp:32:35:32:44 | call to user_input | call to user_input |
|
||||
| qualifiers.cpp:38:23:38:23 | a | qualifiers.cpp:37:38:37:47 | call to user_input | qualifiers.cpp:38:23:38:23 | a | a flows from $@ | qualifiers.cpp:37:38:37:47 | call to user_input | call to user_input |
|
||||
| qualifiers.cpp:43:23:43:23 | a | qualifiers.cpp:42:29:42:38 | call to user_input | qualifiers.cpp:43:23:43:23 | a | a flows from $@ | qualifiers.cpp:42:29:42:38 | call to user_input | call to user_input |
|
||||
| qualifiers.cpp:48:23:48:23 | a | qualifiers.cpp:47:31:47:40 | call to user_input | qualifiers.cpp:48:23:48:23 | a | a flows from $@ | qualifiers.cpp:47:31:47:40 | call to user_input | call to user_input |
|
||||
| simple.cpp:28:12:28:12 | call to a | simple.cpp:39:12:39:21 | call to user_input | simple.cpp:28:12:28:12 | call to a | call to a flows from $@ | simple.cpp:39:12:39:21 | call to user_input | call to user_input |
|
||||
| simple.cpp:28:12:28:12 | call to a | simple.cpp:41:12:41:21 | call to user_input | simple.cpp:28:12:28:12 | call to a | call to a flows from $@ | simple.cpp:41:12:41:21 | call to user_input | call to user_input |
|
||||
| simple.cpp:29:12:29:12 | call to b | simple.cpp:40:12:40:21 | call to user_input | simple.cpp:29:12:29:12 | call to b | call to b flows from $@ | simple.cpp:40:12:40:21 | call to user_input | call to user_input |
|
||||
|
||||
@@ -35,6 +35,22 @@ edges
|
||||
| by_reference.cpp:68:17:68:18 | nonMemberSetA output argument [a] | by_reference.cpp:69:22:69:23 | BufferReadSideEffect [a] |
|
||||
| by_reference.cpp:68:21:68:30 | call to user_input | by_reference.cpp:68:17:68:18 | nonMemberSetA output argument [a] |
|
||||
| by_reference.cpp:69:22:69:23 | BufferReadSideEffect [a] | by_reference.cpp:69:8:69:20 | call to nonMemberGetA |
|
||||
| by_reference.cpp:84:3:84:25 | Chi [a] | by_reference.cpp:102:21:102:39 | taint_inner_a_ptr output argument [a] |
|
||||
| by_reference.cpp:84:3:84:25 | Chi [a] | by_reference.cpp:106:21:106:41 | taint_inner_a_ptr output argument [a] |
|
||||
| by_reference.cpp:84:3:84:25 | Store | by_reference.cpp:84:3:84:25 | Chi [a] |
|
||||
| by_reference.cpp:84:14:84:23 | call to user_input | by_reference.cpp:84:3:84:25 | Store |
|
||||
| by_reference.cpp:88:3:88:24 | Chi [a] | by_reference.cpp:122:21:122:38 | taint_inner_a_ref output argument [a] |
|
||||
| by_reference.cpp:88:3:88:24 | Chi [a] | by_reference.cpp:126:21:126:40 | taint_inner_a_ref output argument [a] |
|
||||
| by_reference.cpp:88:3:88:24 | Store | by_reference.cpp:88:3:88:24 | Chi [a] |
|
||||
| by_reference.cpp:88:13:88:22 | call to user_input | by_reference.cpp:88:3:88:24 | Store |
|
||||
| by_reference.cpp:102:21:102:39 | Chi [a] | by_reference.cpp:110:27:110:27 | a |
|
||||
| by_reference.cpp:102:21:102:39 | taint_inner_a_ptr output argument [a] | by_reference.cpp:102:21:102:39 | Chi [a] |
|
||||
| by_reference.cpp:106:21:106:41 | Chi [a] | by_reference.cpp:114:29:114:29 | a |
|
||||
| by_reference.cpp:106:21:106:41 | taint_inner_a_ptr output argument [a] | by_reference.cpp:106:21:106:41 | Chi [a] |
|
||||
| by_reference.cpp:122:21:122:38 | Chi [a] | by_reference.cpp:130:27:130:27 | a |
|
||||
| by_reference.cpp:122:21:122:38 | taint_inner_a_ref output argument [a] | by_reference.cpp:122:21:122:38 | Chi [a] |
|
||||
| by_reference.cpp:126:21:126:40 | Chi [a] | by_reference.cpp:134:29:134:29 | a |
|
||||
| by_reference.cpp:126:21:126:40 | taint_inner_a_ref output argument [a] | by_reference.cpp:126:21:126:40 | Chi [a] |
|
||||
| simple.cpp:65:5:65:22 | Store [i] | simple.cpp:66:12:66:12 | Store [i] |
|
||||
| simple.cpp:65:11:65:20 | call to user_input | simple.cpp:65:5:65:22 | Store [i] |
|
||||
| simple.cpp:66:12:66:12 | Store [i] | simple.cpp:67:13:67:13 | i |
|
||||
@@ -97,6 +113,24 @@ nodes
|
||||
| by_reference.cpp:68:21:68:30 | call to user_input | semmle.label | call to user_input |
|
||||
| by_reference.cpp:69:8:69:20 | call to nonMemberGetA | semmle.label | call to nonMemberGetA |
|
||||
| by_reference.cpp:69:22:69:23 | BufferReadSideEffect [a] | semmle.label | BufferReadSideEffect [a] |
|
||||
| by_reference.cpp:84:3:84:25 | Chi [a] | semmle.label | Chi [a] |
|
||||
| by_reference.cpp:84:3:84:25 | Store | semmle.label | Store |
|
||||
| by_reference.cpp:84:14:84:23 | call to user_input | semmle.label | call to user_input |
|
||||
| by_reference.cpp:88:3:88:24 | Chi [a] | semmle.label | Chi [a] |
|
||||
| by_reference.cpp:88:3:88:24 | Store | semmle.label | Store |
|
||||
| by_reference.cpp:88:13:88:22 | call to user_input | semmle.label | call to user_input |
|
||||
| by_reference.cpp:102:21:102:39 | Chi [a] | semmle.label | Chi [a] |
|
||||
| by_reference.cpp:102:21:102:39 | taint_inner_a_ptr output argument [a] | semmle.label | taint_inner_a_ptr output argument [a] |
|
||||
| by_reference.cpp:106:21:106:41 | Chi [a] | semmle.label | Chi [a] |
|
||||
| by_reference.cpp:106:21:106:41 | taint_inner_a_ptr output argument [a] | semmle.label | taint_inner_a_ptr output argument [a] |
|
||||
| by_reference.cpp:110:27:110:27 | a | semmle.label | a |
|
||||
| by_reference.cpp:114:29:114:29 | a | semmle.label | a |
|
||||
| by_reference.cpp:122:21:122:38 | Chi [a] | semmle.label | Chi [a] |
|
||||
| by_reference.cpp:122:21:122:38 | taint_inner_a_ref output argument [a] | semmle.label | taint_inner_a_ref output argument [a] |
|
||||
| by_reference.cpp:126:21:126:40 | Chi [a] | semmle.label | Chi [a] |
|
||||
| by_reference.cpp:126:21:126:40 | taint_inner_a_ref output argument [a] | semmle.label | taint_inner_a_ref output argument [a] |
|
||||
| by_reference.cpp:130:27:130:27 | a | semmle.label | a |
|
||||
| by_reference.cpp:134:29:134:29 | a | semmle.label | a |
|
||||
| simple.cpp:65:5:65:22 | Store [i] | semmle.label | Store [i] |
|
||||
| simple.cpp:65:11:65:20 | call to user_input | semmle.label | call to user_input |
|
||||
| simple.cpp:66:12:66:12 | Store [i] | semmle.label | Store [i] |
|
||||
@@ -127,6 +161,10 @@ nodes
|
||||
| aliasing.cpp:87:12:87:13 | m1 | aliasing.cpp:86:10:86:19 | call to user_input | aliasing.cpp:87:12:87:13 | m1 | m1 flows from $@ | aliasing.cpp:86:10:86:19 | call to user_input | call to user_input |
|
||||
| aliasing.cpp:93:12:93:13 | m1 | aliasing.cpp:92:12:92:21 | call to user_input | aliasing.cpp:93:12:93:13 | m1 | m1 flows from $@ | aliasing.cpp:92:12:92:21 | call to user_input | call to user_input |
|
||||
| by_reference.cpp:69:8:69:20 | call to nonMemberGetA | by_reference.cpp:68:21:68:30 | call to user_input | by_reference.cpp:69:8:69:20 | call to nonMemberGetA | call to nonMemberGetA flows from $@ | by_reference.cpp:68:21:68:30 | call to user_input | call to user_input |
|
||||
| by_reference.cpp:110:27:110:27 | a | by_reference.cpp:84:14:84:23 | call to user_input | by_reference.cpp:110:27:110:27 | a | a flows from $@ | by_reference.cpp:84:14:84:23 | call to user_input | call to user_input |
|
||||
| by_reference.cpp:114:29:114:29 | a | by_reference.cpp:84:14:84:23 | call to user_input | by_reference.cpp:114:29:114:29 | a | a flows from $@ | by_reference.cpp:84:14:84:23 | call to user_input | call to user_input |
|
||||
| by_reference.cpp:130:27:130:27 | a | by_reference.cpp:88:13:88:22 | call to user_input | by_reference.cpp:130:27:130:27 | a | a flows from $@ | by_reference.cpp:88:13:88:22 | call to user_input | call to user_input |
|
||||
| by_reference.cpp:134:29:134:29 | a | by_reference.cpp:88:13:88:22 | call to user_input | by_reference.cpp:134:29:134:29 | a | a flows from $@ | by_reference.cpp:88:13:88:22 | call to user_input | call to user_input |
|
||||
| simple.cpp:67:13:67:13 | i | simple.cpp:65:11:65:20 | call to user_input | simple.cpp:67:13:67:13 | i | i flows from $@ | simple.cpp:65:11:65:20 | call to user_input | call to user_input |
|
||||
| struct_init.c:15:12:15:12 | a | struct_init.c:20:20:20:29 | call to user_input | struct_init.c:15:12:15:12 | a | a flows from $@ | struct_init.c:20:20:20:29 | call to user_input | call to user_input |
|
||||
| struct_init.c:15:12:15:12 | a | struct_init.c:27:7:27:16 | call to user_input | struct_init.c:15:12:15:12 | a | a flows from $@ | struct_init.c:27:7:27:16 | call to user_input | call to user_input |
|
||||
|
||||
50
cpp/ql/test/library-tests/dataflow/fields/qualifiers.cpp
Normal file
50
cpp/ql/test/library-tests/dataflow/fields/qualifiers.cpp
Normal file
@@ -0,0 +1,50 @@
|
||||
void sink(void *o);
|
||||
void *user_input(void);
|
||||
|
||||
namespace qualifiers {
|
||||
|
||||
struct Inner {
|
||||
void *a;
|
||||
|
||||
void setA(void *value) { this->a = value; }
|
||||
};
|
||||
|
||||
void pointerSetA(Inner *inner, void *value) { inner->a = value; }
|
||||
void referenceSetA(Inner &inner, void *value) { inner.a = value; }
|
||||
|
||||
struct Outer {
|
||||
Inner *inner;
|
||||
|
||||
Inner *getInner() { return inner; }
|
||||
};
|
||||
|
||||
void assignToGetter(Outer outer) {
|
||||
outer.getInner()->a = user_input();
|
||||
sink(outer.inner->a); // flow [NOT DETECTED by IR]
|
||||
}
|
||||
|
||||
void getterArgument1(Outer outer) {
|
||||
outer.getInner()->setA(user_input());
|
||||
sink(outer.inner->a); // flow [NOT DETECTED by IR]
|
||||
}
|
||||
|
||||
void getterArgument2(Outer outer) {
|
||||
pointerSetA(outer.getInner(), user_input());
|
||||
sink(outer.inner->a); // flow [NOT DETECTED by IR]
|
||||
}
|
||||
|
||||
void getterArgument2Ref(Outer outer) {
|
||||
referenceSetA(*outer.getInner(), user_input());
|
||||
sink(outer.inner->a); // flow [NOT DETECTED by IR]
|
||||
}
|
||||
|
||||
void assignToGetterStar(Outer outer) {
|
||||
(*outer.getInner()).a = user_input();
|
||||
sink(outer.inner->a); // flow [NOT DETECTED by IR]
|
||||
}
|
||||
|
||||
void assignToGetterAmp(Outer outer) {
|
||||
(&outer)->getInner()->a = user_input();
|
||||
sink(outer.inner->a); // flow [NOT DETECTED by IR]
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,8 @@
|
||||
| partialdefinitions.cpp:14:2:14:2 | partial def of s | partialdefinitions.cpp:14:2:14:2 | s | partialdefinitions.cpp:14:2:14:8 | ... = ... |
|
||||
| partialdefinitions.cpp:14:4:14:4 | partial def of x | partialdefinitions.cpp:14:4:14:4 | x | partialdefinitions.cpp:14:2:14:8 | ... = ... |
|
||||
| partialdefinitions.cpp:15:2:15:2 | partial def of s | partialdefinitions.cpp:15:2:15:2 | s | partialdefinitions.cpp:15:2:15:10 | ... = ... |
|
||||
| partialdefinitions.cpp:15:4:15:4 | partial def of y | partialdefinitions.cpp:15:4:15:4 | y | partialdefinitions.cpp:15:2:15:10 | ... = ... |
|
||||
| partialdefinitions.cpp:15:6:15:6 | partial def of z | partialdefinitions.cpp:15:6:15:6 | z | partialdefinitions.cpp:15:2:15:10 | ... = ... |
|
||||
| partialdefinitions.cpp:22:29:22:32 | partial def of data | partialdefinitions.cpp:22:29:22:32 | data | partialdefinitions.cpp:22:29:22:40 | ... = ... |
|
||||
| partialdefinitions.cpp:22:29:22:32 | partial def of this | file://:0:0:0:0 | this | partialdefinitions.cpp:22:29:22:40 | ... = ... |
|
||||
| partialdefinitions.cpp:27:3:27:7 | partial def of myInt | partialdefinitions.cpp:27:3:27:7 | myInt | partialdefinitions.cpp:27:3:27:7 | myInt |
|
||||
| partialdefinitions.cpp:27:3:27:7 | partial def of myInt | partialdefinitions.cpp:27:3:27:7 | myInt | partialdefinitions.cpp:27:9:27:15 | call to setData |
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import semmle.code.cpp.dataflow.internal.FlowVar
|
||||
|
||||
from PartialDefinition def
|
||||
select def.getActualLocation().toString(), "partial def of " + def.toString(), def.getDefinedExpr(),
|
||||
select def.getActualLocation().toString(), "partial def of " + def.toString(), def,
|
||||
def.getSubBasicBlockStart()
|
||||
|
||||
@@ -89,20 +89,24 @@
|
||||
| format.cpp:110:18:110:23 | ref arg buffer | format.cpp:111:8:111:13 | buffer | |
|
||||
| format.cpp:115:10:115:11 | 0 | format.cpp:116:29:116:29 | i | |
|
||||
| format.cpp:115:10:115:11 | 0 | format.cpp:117:8:117:8 | i | |
|
||||
| format.cpp:116:28:116:29 | ref arg & ... | format.cpp:116:29:116:29 | i [inner post update] | |
|
||||
| format.cpp:116:28:116:29 | ref arg & ... | format.cpp:117:8:117:8 | i | |
|
||||
| format.cpp:116:29:116:29 | i | format.cpp:116:28:116:29 | & ... | |
|
||||
| format.cpp:120:10:120:11 | 0 | format.cpp:121:40:121:40 | i | |
|
||||
| format.cpp:120:10:120:11 | 0 | format.cpp:122:8:122:8 | i | |
|
||||
| format.cpp:121:39:121:40 | ref arg & ... | format.cpp:121:40:121:40 | i [inner post update] | |
|
||||
| format.cpp:121:39:121:40 | ref arg & ... | format.cpp:122:8:122:8 | i | |
|
||||
| format.cpp:121:40:121:40 | i | format.cpp:121:39:121:40 | & ... | |
|
||||
| format.cpp:125:21:125:24 | {...} | format.cpp:126:32:126:37 | buffer | |
|
||||
| format.cpp:125:21:125:24 | {...} | format.cpp:127:8:127:13 | buffer | |
|
||||
| format.cpp:125:23:125:23 | 0 | format.cpp:125:21:125:24 | {...} | TAINT |
|
||||
| format.cpp:126:31:126:37 | ref arg & ... | format.cpp:126:32:126:37 | buffer [inner post update] | |
|
||||
| format.cpp:126:31:126:37 | ref arg & ... | format.cpp:127:8:127:13 | buffer | |
|
||||
| format.cpp:126:32:126:37 | buffer | format.cpp:126:31:126:37 | & ... | |
|
||||
| format.cpp:130:21:130:24 | {...} | format.cpp:131:40:131:45 | buffer | |
|
||||
| format.cpp:130:21:130:24 | {...} | format.cpp:132:8:132:13 | buffer | |
|
||||
| format.cpp:130:23:130:23 | 0 | format.cpp:130:21:130:24 | {...} | TAINT |
|
||||
| format.cpp:131:39:131:45 | ref arg & ... | format.cpp:131:40:131:45 | buffer [inner post update] | |
|
||||
| format.cpp:131:39:131:45 | ref arg & ... | format.cpp:132:8:132:13 | buffer | |
|
||||
| format.cpp:131:40:131:45 | buffer | format.cpp:131:39:131:45 | & ... | |
|
||||
| stl.cpp:67:12:67:17 | call to source | stl.cpp:71:7:71:7 | a | |
|
||||
@@ -148,10 +152,10 @@
|
||||
| stl.cpp:103:25:103:27 | call to basic_stringstream | stl.cpp:106:2:106:4 | ss2 | |
|
||||
| stl.cpp:103:25:103:27 | call to basic_stringstream | stl.cpp:109:7:109:9 | ss2 | |
|
||||
| stl.cpp:103:25:103:27 | call to basic_stringstream | stl.cpp:111:7:111:9 | ss2 | |
|
||||
| stl.cpp:105:2:105:4 | ss1 [post update] | stl.cpp:108:7:108:9 | ss1 | |
|
||||
| stl.cpp:105:2:105:4 | ss1 [post update] | stl.cpp:110:7:110:9 | ss1 | |
|
||||
| stl.cpp:106:2:106:4 | ss2 [post update] | stl.cpp:109:7:109:9 | ss2 | |
|
||||
| stl.cpp:106:2:106:4 | ss2 [post update] | stl.cpp:111:7:111:9 | ss2 | |
|
||||
| stl.cpp:105:2:105:4 | ref arg ss1 | stl.cpp:108:7:108:9 | ss1 | |
|
||||
| stl.cpp:105:2:105:4 | ref arg ss1 | stl.cpp:110:7:110:9 | ss1 | |
|
||||
| stl.cpp:106:2:106:4 | ref arg ss2 | stl.cpp:109:7:109:9 | ss2 | |
|
||||
| stl.cpp:106:2:106:4 | ref arg ss2 | stl.cpp:111:7:111:9 | ss2 | |
|
||||
| stl.cpp:124:16:124:28 | call to basic_string | stl.cpp:125:7:125:11 | path1 | |
|
||||
| stl.cpp:124:17:124:26 | call to user_input | stl.cpp:124:16:124:28 | call to basic_string | TAINT |
|
||||
| stl.cpp:125:7:125:11 | path1 | stl.cpp:125:13:125:17 | call to c_str | TAINT |
|
||||
@@ -226,10 +230,10 @@
|
||||
| taint.cpp:84:15:84:17 | call to MyClass | taint.cpp:93:7:93:9 | mc2 | |
|
||||
| taint.cpp:84:15:84:17 | call to MyClass | taint.cpp:94:7:94:9 | mc2 | |
|
||||
| taint.cpp:84:15:84:17 | call to MyClass | taint.cpp:95:7:95:9 | mc2 | |
|
||||
| taint.cpp:86:2:86:4 | mc1 [post update] | taint.cpp:88:7:88:9 | mc1 | |
|
||||
| taint.cpp:86:2:86:4 | mc1 [post update] | taint.cpp:89:7:89:9 | mc1 | |
|
||||
| taint.cpp:86:2:86:4 | mc1 [post update] | taint.cpp:90:7:90:9 | mc1 | |
|
||||
| taint.cpp:86:2:86:4 | mc1 [post update] | taint.cpp:91:7:91:9 | mc1 | |
|
||||
| taint.cpp:86:2:86:4 | ref arg mc1 | taint.cpp:88:7:88:9 | mc1 | |
|
||||
| taint.cpp:86:2:86:4 | ref arg mc1 | taint.cpp:89:7:89:9 | mc1 | |
|
||||
| taint.cpp:86:2:86:4 | ref arg mc1 | taint.cpp:90:7:90:9 | mc1 | |
|
||||
| taint.cpp:86:2:86:4 | ref arg mc1 | taint.cpp:91:7:91:9 | mc1 | |
|
||||
| taint.cpp:100:21:100:21 | i | taint.cpp:106:7:106:7 | i | |
|
||||
| taint.cpp:100:21:100:21 | i | taint.cpp:110:12:110:12 | i | |
|
||||
| taint.cpp:100:21:100:21 | i | taint.cpp:112:12:112:12 | i | |
|
||||
@@ -313,11 +317,13 @@
|
||||
| taint.cpp:180:19:180:19 | p | taint.cpp:181:9:181:9 | p | |
|
||||
| taint.cpp:181:9:181:9 | p | taint.cpp:181:8:181:9 | * ... | TAINT |
|
||||
| taint.cpp:185:11:185:16 | call to source | taint.cpp:186:11:186:11 | x | |
|
||||
| taint.cpp:186:10:186:11 | ref arg & ... | taint.cpp:186:11:186:11 | x [inner post update] | |
|
||||
| taint.cpp:186:11:186:11 | x | taint.cpp:186:10:186:11 | & ... | |
|
||||
| taint.cpp:192:23:192:28 | source | taint.cpp:194:13:194:18 | source | |
|
||||
| taint.cpp:193:6:193:6 | x | taint.cpp:194:10:194:10 | x | |
|
||||
| taint.cpp:193:6:193:6 | x | taint.cpp:195:7:195:7 | x | |
|
||||
| taint.cpp:194:9:194:10 | & ... | taint.cpp:194:2:194:7 | call to memcpy | |
|
||||
| taint.cpp:194:9:194:10 | ref arg & ... | taint.cpp:194:10:194:10 | x [inner post update] | |
|
||||
| taint.cpp:194:9:194:10 | ref arg & ... | taint.cpp:195:7:195:7 | x | |
|
||||
| taint.cpp:194:10:194:10 | x | taint.cpp:194:9:194:10 | & ... | |
|
||||
| taint.cpp:194:13:194:18 | source | taint.cpp:194:2:194:7 | call to memcpy | TAINT |
|
||||
@@ -477,8 +483,10 @@
|
||||
| taint.cpp:344:15:344:15 | ref arg t | taint.cpp:348:17:348:17 | t | |
|
||||
| taint.cpp:344:15:344:15 | ref arg t | taint.cpp:350:7:350:7 | t | |
|
||||
| taint.cpp:345:12:345:12 | ref arg b | taint.cpp:352:7:352:7 | b | |
|
||||
| taint.cpp:346:12:346:13 | ref arg & ... | taint.cpp:346:13:346:13 | c [inner post update] | |
|
||||
| taint.cpp:346:12:346:13 | ref arg & ... | taint.cpp:353:7:353:7 | c | |
|
||||
| taint.cpp:346:13:346:13 | c | taint.cpp:346:12:346:13 | & ... | |
|
||||
| taint.cpp:347:12:347:13 | ref arg & ... | taint.cpp:347:13:347:13 | d [inner post update] | |
|
||||
| taint.cpp:347:12:347:13 | ref arg & ... | taint.cpp:354:7:354:7 | d | |
|
||||
| taint.cpp:347:13:347:13 | d | taint.cpp:347:12:347:13 | & ... | |
|
||||
| taint.cpp:348:14:348:14 | ref arg e | taint.cpp:355:7:355:7 | e | |
|
||||
@@ -523,15 +531,15 @@
|
||||
| taint.cpp:418:13:418:15 | call to MyClass3 | taint.cpp:445:2:445:2 | d | |
|
||||
| taint.cpp:418:13:418:15 | call to MyClass3 | taint.cpp:446:7:446:7 | d | |
|
||||
| taint.cpp:418:13:418:15 | call to MyClass3 | taint.cpp:447:7:447:7 | d | |
|
||||
| taint.cpp:421:7:421:7 | a [post update] | taint.cpp:422:2:422:2 | a | |
|
||||
| taint.cpp:421:7:421:7 | a [post update] | taint.cpp:423:7:423:7 | a | |
|
||||
| taint.cpp:421:7:421:7 | a [post update] | taint.cpp:424:7:424:7 | a | |
|
||||
| taint.cpp:422:2:422:2 | a [post update] | taint.cpp:423:7:423:7 | a | |
|
||||
| taint.cpp:422:2:422:2 | a [post update] | taint.cpp:424:7:424:7 | a | |
|
||||
| taint.cpp:427:7:427:7 | b [post update] | taint.cpp:428:2:428:2 | b | |
|
||||
| taint.cpp:427:7:427:7 | b [post update] | taint.cpp:429:7:429:7 | b | |
|
||||
| taint.cpp:427:7:427:7 | b [post update] | taint.cpp:430:7:430:7 | b | |
|
||||
| taint.cpp:427:7:427:7 | b [post update] | taint.cpp:431:7:431:7 | b | |
|
||||
| taint.cpp:421:7:421:7 | ref arg a | taint.cpp:422:2:422:2 | a | |
|
||||
| taint.cpp:421:7:421:7 | ref arg a | taint.cpp:423:7:423:7 | a | |
|
||||
| taint.cpp:421:7:421:7 | ref arg a | taint.cpp:424:7:424:7 | a | |
|
||||
| taint.cpp:422:2:422:2 | ref arg a | taint.cpp:423:7:423:7 | a | |
|
||||
| taint.cpp:422:2:422:2 | ref arg a | taint.cpp:424:7:424:7 | a | |
|
||||
| taint.cpp:427:7:427:7 | ref arg b | taint.cpp:428:2:428:2 | b | |
|
||||
| taint.cpp:427:7:427:7 | ref arg b | taint.cpp:429:7:429:7 | b | |
|
||||
| taint.cpp:427:7:427:7 | ref arg b | taint.cpp:430:7:430:7 | b | |
|
||||
| taint.cpp:427:7:427:7 | ref arg b | taint.cpp:431:7:431:7 | b | |
|
||||
| taint.cpp:428:2:428:2 | b [post update] | taint.cpp:429:7:429:7 | b | |
|
||||
| taint.cpp:428:2:428:2 | b [post update] | taint.cpp:430:7:430:7 | b | |
|
||||
| taint.cpp:428:2:428:2 | b [post update] | taint.cpp:431:7:431:7 | b | |
|
||||
@@ -550,22 +558,22 @@
|
||||
| taint.cpp:435:7:435:7 | ref arg c | taint.cpp:438:7:438:7 | c | |
|
||||
| taint.cpp:435:7:435:7 | ref arg c | taint.cpp:439:7:439:7 | c | |
|
||||
| taint.cpp:435:7:435:7 | ref arg c | taint.cpp:441:9:441:9 | c | |
|
||||
| taint.cpp:436:7:436:7 | c [post update] | taint.cpp:437:2:437:2 | c | |
|
||||
| taint.cpp:436:7:436:7 | c [post update] | taint.cpp:438:7:438:7 | c | |
|
||||
| taint.cpp:436:7:436:7 | c [post update] | taint.cpp:439:7:439:7 | c | |
|
||||
| taint.cpp:436:7:436:7 | c [post update] | taint.cpp:441:9:441:9 | c | |
|
||||
| taint.cpp:437:2:437:2 | c [post update] | taint.cpp:438:7:438:7 | c | |
|
||||
| taint.cpp:437:2:437:2 | c [post update] | taint.cpp:439:7:439:7 | c | |
|
||||
| taint.cpp:437:2:437:2 | c [post update] | taint.cpp:441:9:441:9 | c | |
|
||||
| taint.cpp:436:7:436:7 | ref arg c | taint.cpp:437:2:437:2 | c | |
|
||||
| taint.cpp:436:7:436:7 | ref arg c | taint.cpp:438:7:438:7 | c | |
|
||||
| taint.cpp:436:7:436:7 | ref arg c | taint.cpp:439:7:439:7 | c | |
|
||||
| taint.cpp:436:7:436:7 | ref arg c | taint.cpp:441:9:441:9 | c | |
|
||||
| taint.cpp:437:2:437:2 | ref arg c | taint.cpp:438:7:438:7 | c | |
|
||||
| taint.cpp:437:2:437:2 | ref arg c | taint.cpp:439:7:439:7 | c | |
|
||||
| taint.cpp:437:2:437:2 | ref arg c | taint.cpp:441:9:441:9 | c | |
|
||||
| taint.cpp:438:7:438:7 | ref arg c | taint.cpp:439:7:439:7 | c | |
|
||||
| taint.cpp:438:7:438:7 | ref arg c | taint.cpp:441:9:441:9 | c | |
|
||||
| taint.cpp:439:7:439:7 | c [post update] | taint.cpp:441:9:441:9 | c | |
|
||||
| taint.cpp:439:7:439:7 | ref arg c | taint.cpp:441:9:441:9 | c | |
|
||||
| taint.cpp:441:9:441:9 | c | taint.cpp:441:2:441:9 | delete | TAINT |
|
||||
| taint.cpp:444:7:444:7 | d [post update] | taint.cpp:445:2:445:2 | d | |
|
||||
| taint.cpp:444:7:444:7 | d [post update] | taint.cpp:446:7:446:7 | d | |
|
||||
| taint.cpp:444:7:444:7 | d [post update] | taint.cpp:447:7:447:7 | d | |
|
||||
| taint.cpp:445:2:445:2 | d [post update] | taint.cpp:446:7:446:7 | d | |
|
||||
| taint.cpp:445:2:445:2 | d [post update] | taint.cpp:447:7:447:7 | d | |
|
||||
| taint.cpp:444:7:444:7 | ref arg d | taint.cpp:445:2:445:2 | d | |
|
||||
| taint.cpp:444:7:444:7 | ref arg d | taint.cpp:446:7:446:7 | d | |
|
||||
| taint.cpp:444:7:444:7 | ref arg d | taint.cpp:447:7:447:7 | d | |
|
||||
| taint.cpp:445:2:445:2 | ref arg d | taint.cpp:446:7:446:7 | d | |
|
||||
| taint.cpp:445:2:445:2 | ref arg d | taint.cpp:447:7:447:7 | d | |
|
||||
| taint.cpp:452:16:452:16 | a | taint.cpp:454:10:454:10 | a | |
|
||||
| taint.cpp:452:24:452:24 | b | taint.cpp:455:6:455:6 | b | |
|
||||
| taint.cpp:454:10:454:10 | a | taint.cpp:456:6:456:6 | c | |
|
||||
|
||||
@@ -63,3 +63,18 @@ void nonexamples(int *ptr, int &ref) {
|
||||
nonexamples(&*ptr, ref);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
namespace std {
|
||||
template<typename T>
|
||||
constexpr T *addressof(T &obj) noexcept {
|
||||
return __builtin_addressof(obj);
|
||||
}
|
||||
}
|
||||
|
||||
void use_std_addressof() {
|
||||
int x = 0;
|
||||
int *y = std::addressof(x) + *std::addressof(x);
|
||||
}
|
||||
|
||||
// semmle-extractor-options: --clang
|
||||
|
||||
@@ -17,6 +17,8 @@
|
||||
| addressOf.cpp:56:7:56:7 | a | addressOf.cpp:57:18:57:45 | ... + ... |
|
||||
| addressOf.cpp:56:7:56:7 | a | addressOf.cpp:58:18:58:18 | a |
|
||||
| addressOf.cpp:61:33:61:35 | ref | addressOf.cpp:63:24:63:26 | ref |
|
||||
| addressOf.cpp:76:7:76:7 | x | addressOf.cpp:76:10:76:11 | 0 |
|
||||
| addressOf.cpp:77:8:77:8 | y | addressOf.cpp:77:12:77:49 | ... + ... |
|
||||
| indirect_use.cpp:20:10:20:10 | p | indirect_use.cpp:20:14:20:15 | ip |
|
||||
| indirect_use.cpp:25:10:25:10 | p | indirect_use.cpp:25:14:25:19 | ... + ... |
|
||||
| indirect_use.cpp:25:10:25:10 | p | indirect_use.cpp:26:5:26:7 | ... -- |
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
| addressOf.cpp:49:8:49:9 | f2 | addressOf.cpp:49:12:49:39 | [...](...){...} | addressOf.cpp:50:3:50:4 | f2 |
|
||||
| addressOf.cpp:56:7:56:7 | a | addressOf.cpp:56:13:56:28 | {...} | addressOf.cpp:57:19:57:19 | a |
|
||||
| addressOf.cpp:56:7:56:7 | a | addressOf.cpp:57:18:57:45 | ... + ... | addressOf.cpp:58:18:58:18 | a |
|
||||
| addressOf.cpp:76:7:76:7 | x | addressOf.cpp:76:10:76:11 | 0 | addressOf.cpp:77:27:77:27 | x |
|
||||
| indirect_use.cpp:20:10:20:10 | p | indirect_use.cpp:20:14:20:15 | ip | indirect_use.cpp:21:17:21:17 | p |
|
||||
| indirect_use.cpp:25:10:25:10 | p | indirect_use.cpp:25:14:25:19 | ... + ... | indirect_use.cpp:26:5:26:5 | p |
|
||||
| indirect_use.cpp:25:10:25:10 | p | indirect_use.cpp:26:5:26:7 | ... -- | indirect_use.cpp:27:17:27:17 | p |
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
| addressOf.cpp:47:8:47:9 | f1 | addressOf.cpp:47:12:47:31 | [...](...){...} | addressOf.cpp:47:12:47:31 | [...](...){...} |
|
||||
| addressOf.cpp:49:8:49:9 | f2 | addressOf.cpp:49:12:49:39 | [...](...){...} | addressOf.cpp:49:12:49:39 | [...](...){...} |
|
||||
| addressOf.cpp:56:7:56:7 | a | addressOf.cpp:56:13:56:28 | {...} | addressOf.cpp:56:13:56:28 | {...} |
|
||||
| addressOf.cpp:76:7:76:7 | x | addressOf.cpp:76:10:76:11 | 0 | addressOf.cpp:76:10:76:11 | 0 |
|
||||
| addressOf.cpp:77:8:77:8 | y | addressOf.cpp:77:12:77:49 | ... + ... | addressOf.cpp:77:12:77:49 | ... + ... |
|
||||
| indirect_use.cpp:20:10:20:10 | p | indirect_use.cpp:20:14:20:15 | ip | indirect_use.cpp:20:14:20:15 | ip |
|
||||
| indirect_use.cpp:25:10:25:10 | p | indirect_use.cpp:25:14:25:19 | ... + ... | indirect_use.cpp:25:14:25:19 | ... + ... |
|
||||
| indirect_use.cpp:35:10:35:10 | p | indirect_use.cpp:35:14:35:15 | ip | indirect_use.cpp:35:14:35:15 | ip |
|
||||
|
||||
@@ -25,6 +25,10 @@
|
||||
| addressOf.cpp:62:11:62:13 | ptr | |
|
||||
| addressOf.cpp:63:19:63:21 | ptr | |
|
||||
| addressOf.cpp:63:24:63:26 | ref | non-const address |
|
||||
| addressOf.cpp:71:32:71:34 | obj | |
|
||||
| addressOf.cpp:71:32:71:34 | obj | |
|
||||
| addressOf.cpp:77:27:77:27 | x | non-const address |
|
||||
| addressOf.cpp:77:48:77:48 | x | |
|
||||
| file://:0:0:0:0 | captured | |
|
||||
| file://:0:0:0:0 | captured | |
|
||||
| file://:0:0:0:0 | captured | non-const address |
|
||||
|
||||
@@ -6,6 +6,8 @@
|
||||
| addressOf.cpp:61:23:61:25 | ptr | addressOf.cpp:62:11:62:13 | ptr |
|
||||
| addressOf.cpp:61:23:61:25 | ptr | addressOf.cpp:63:19:63:21 | ptr |
|
||||
| addressOf.cpp:61:33:61:35 | ref | addressOf.cpp:63:24:63:26 | ref |
|
||||
| addressOf.cpp:70:29:70:31 | obj | addressOf.cpp:71:32:71:34 | obj |
|
||||
| addressOf.cpp:70:29:70:31 | obj | addressOf.cpp:71:32:71:34 | obj |
|
||||
| indirect_use.cpp:19:31:19:32 | ip | indirect_use.cpp:20:14:20:15 | ip |
|
||||
| indirect_use.cpp:24:31:24:32 | ip | indirect_use.cpp:25:14:25:15 | ip |
|
||||
| indirect_use.cpp:30:28:30:30 | ppp | indirect_use.cpp:31:19:31:21 | ppp |
|
||||
|
||||
@@ -23,6 +23,9 @@
|
||||
| addressOf.cpp:61:23:61:25 | ptr | addressOf.cpp:62:11:62:13 | ptr |
|
||||
| addressOf.cpp:61:23:61:25 | ptr | addressOf.cpp:63:19:63:21 | ptr |
|
||||
| addressOf.cpp:61:33:61:35 | ref | addressOf.cpp:63:24:63:26 | ref |
|
||||
| addressOf.cpp:70:29:70:31 | obj | addressOf.cpp:71:32:71:34 | obj |
|
||||
| addressOf.cpp:76:7:76:7 | x | addressOf.cpp:77:27:77:27 | x |
|
||||
| addressOf.cpp:76:7:76:7 | x | addressOf.cpp:77:48:77:48 | x |
|
||||
| indirect_use.cpp:19:31:19:32 | ip | indirect_use.cpp:20:14:20:15 | ip |
|
||||
| indirect_use.cpp:20:10:20:10 | p | indirect_use.cpp:21:17:21:17 | p |
|
||||
| indirect_use.cpp:24:31:24:32 | ip | indirect_use.cpp:25:14:25:15 | ip |
|
||||
|
||||
@@ -10,6 +10,8 @@
|
||||
| addressOf.cpp:55:17:55:17 | i | addressOf.cpp:56:24:56:24 | i |
|
||||
| addressOf.cpp:61:23:61:25 | ptr | addressOf.cpp:62:11:62:13 | ptr |
|
||||
| addressOf.cpp:61:23:61:25 | ptr | addressOf.cpp:63:19:63:21 | ptr |
|
||||
| addressOf.cpp:70:29:70:31 | obj | addressOf.cpp:71:32:71:34 | obj |
|
||||
| addressOf.cpp:76:7:76:7 | x | addressOf.cpp:77:48:77:48 | x |
|
||||
| indirect_use.cpp:19:31:19:32 | ip | indirect_use.cpp:20:14:20:15 | ip |
|
||||
| indirect_use.cpp:20:10:20:10 | p | indirect_use.cpp:21:17:21:17 | p |
|
||||
| indirect_use.cpp:24:31:24:32 | ip | indirect_use.cpp:25:14:25:15 | ip |
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
import semmle.code.cpp.ir.implementation.aliased_ssa.IRConsistency
|
||||
import semmle.code.cpp.ir.implementation.UseSoundEscapeAnalysis
|
||||
@@ -0,0 +1 @@
|
||||
semmle/code/cpp/ir/IRConsistency.ql
|
||||
@@ -1,2 +0,0 @@
|
||||
import semmle.code.cpp.ir.implementation.aliased_ssa.IRSanity
|
||||
import semmle.code.cpp.ir.implementation.UseSoundEscapeAnalysis
|
||||
@@ -1 +0,0 @@
|
||||
semmle/code/cpp/ir/IRSanity.ql
|
||||
@@ -1,2 +1,2 @@
|
||||
import semmle.code.cpp.ir.implementation.aliased_ssa.internal.SSASanity
|
||||
import semmle.code.cpp.ir.implementation.aliased_ssa.internal.SSAConsistency
|
||||
import semmle.code.cpp.ir.implementation.UseSoundEscapeAnalysis
|
||||
@@ -0,0 +1 @@
|
||||
semmle/code/cpp/ir/implementation/aliased_ssa/internal/SSAConsistency.ql
|
||||
@@ -1 +0,0 @@
|
||||
semmle/code/cpp/ir/implementation/aliased_ssa/internal/SSASanity.ql
|
||||
1
cpp/ql/test/library-tests/ir/ir/raw_consistency.qlref
Normal file
1
cpp/ql/test/library-tests/ir/ir/raw_consistency.qlref
Normal file
@@ -0,0 +1 @@
|
||||
semmle/code/cpp/ir/implementation/raw/IRConsistency.ql
|
||||
@@ -1 +0,0 @@
|
||||
semmle/code/cpp/ir/implementation/raw/IRSanity.ql
|
||||
@@ -0,0 +1,2 @@
|
||||
import semmle.code.cpp.ir.implementation.unaliased_ssa.IRConsistency
|
||||
import semmle.code.cpp.ir.implementation.UseSoundEscapeAnalysis
|
||||
@@ -0,0 +1 @@
|
||||
semmle/code/cpp/ir/implementation/unaliased_ssa/IRConsistency.ql
|
||||
@@ -1,2 +0,0 @@
|
||||
import semmle.code.cpp.ir.implementation.unaliased_ssa.IRSanity
|
||||
import semmle.code.cpp.ir.implementation.UseSoundEscapeAnalysis
|
||||
@@ -1 +0,0 @@
|
||||
semmle/code/cpp/ir/implementation/unaliased_ssa/IRSanity.ql
|
||||
@@ -1,2 +1,2 @@
|
||||
import semmle.code.cpp.ir.implementation.unaliased_ssa.internal.SSASanity
|
||||
import semmle.code.cpp.ir.implementation.unaliased_ssa.internal.SSAConsistency
|
||||
import semmle.code.cpp.ir.implementation.UseSoundEscapeAnalysis
|
||||
@@ -0,0 +1 @@
|
||||
semmle/code/cpp/ir/implementation/unaliased_ssa/internal/SSAConsistency.ql
|
||||
@@ -1 +0,0 @@
|
||||
semmle/code/cpp/ir/implementation/unaliased_ssa/internal/SSASanity.ql
|
||||
@@ -0,0 +1,2 @@
|
||||
import semmle.code.cpp.ir.implementation.aliased_ssa.IRConsistency
|
||||
import semmle.code.cpp.ir.implementation.UseSoundEscapeAnalysis
|
||||
@@ -0,0 +1 @@
|
||||
semmle/code/cpp/ir/IRConsistency.ql
|
||||
@@ -1,2 +0,0 @@
|
||||
import semmle.code.cpp.ir.implementation.aliased_ssa.IRSanity
|
||||
import semmle.code.cpp.ir.implementation.UseSoundEscapeAnalysis
|
||||
@@ -1 +0,0 @@
|
||||
semmle/code/cpp/ir/IRSanity.ql
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user