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:
Jonas Jensen
2020-05-13 12:05:58 +02:00
300 changed files with 9437 additions and 3211 deletions

View File

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

View File

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

View 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

View File

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

View File

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

View 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.
)
}

View File

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

View File

@@ -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()
)
}
/**

View File

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

View File

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

View File

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

View File

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

View File

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

View 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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -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()) }
}
/**

View File

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

View File

@@ -1,2 +1,2 @@
private import SSAConstruction as SSA
import SSA::SSASanity
import SSA::SSAConsistency

View File

@@ -941,7 +941,7 @@ private module CachedForDebugging {
}
}
module SSASanity {
module SSAConsistency {
query predicate multipleOperandMemoryLocations(
OldIR::MemoryOperand operand, string message, OldIR::IRFunction func, string funcText
) {

View File

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

View File

@@ -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`).

View File

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

View File

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

View File

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

View File

@@ -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()) }
}
/**

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -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()) }
}
/**

View File

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

View File

@@ -1,2 +1,2 @@
private import SSAConstruction as SSA
import SSA::SSASanity
import SSA::SSAConsistency

View File

@@ -941,7 +941,7 @@ private module CachedForDebugging {
}
}
module SSASanity {
module SSAConsistency {
query predicate multipleOperandMemoryLocations(
OldIR::MemoryOperand operand, string message, OldIR::IRFunction func, string funcText
) {

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -0,0 +1 @@
semmle/code/cpp/ASTConsistency.ql

View File

@@ -1 +0,0 @@
semmle/code/cpp/ASTSanity.ql

View File

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

View File

@@ -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 | & ... |

View File

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

View File

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

View File

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

View File

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

View File

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

View 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]
}
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -0,0 +1,2 @@
import semmle.code.cpp.ir.implementation.aliased_ssa.IRConsistency
import semmle.code.cpp.ir.implementation.UseSoundEscapeAnalysis

View File

@@ -0,0 +1 @@
semmle/code/cpp/ir/IRConsistency.ql

View File

@@ -1,2 +0,0 @@
import semmle.code.cpp.ir.implementation.aliased_ssa.IRSanity
import semmle.code.cpp.ir.implementation.UseSoundEscapeAnalysis

View File

@@ -1 +0,0 @@
semmle/code/cpp/ir/IRSanity.ql

View File

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

View File

@@ -0,0 +1 @@
semmle/code/cpp/ir/implementation/aliased_ssa/internal/SSAConsistency.ql

View File

@@ -1 +0,0 @@
semmle/code/cpp/ir/implementation/aliased_ssa/internal/SSASanity.ql

View File

@@ -0,0 +1 @@
semmle/code/cpp/ir/implementation/raw/IRConsistency.ql

View File

@@ -1 +0,0 @@
semmle/code/cpp/ir/implementation/raw/IRSanity.ql

View File

@@ -0,0 +1,2 @@
import semmle.code.cpp.ir.implementation.unaliased_ssa.IRConsistency
import semmle.code.cpp.ir.implementation.UseSoundEscapeAnalysis

View File

@@ -0,0 +1 @@
semmle/code/cpp/ir/implementation/unaliased_ssa/IRConsistency.ql

View File

@@ -1,2 +0,0 @@
import semmle.code.cpp.ir.implementation.unaliased_ssa.IRSanity
import semmle.code.cpp.ir.implementation.UseSoundEscapeAnalysis

View File

@@ -1 +0,0 @@
semmle/code/cpp/ir/implementation/unaliased_ssa/IRSanity.ql

View File

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

View File

@@ -0,0 +1 @@
semmle/code/cpp/ir/implementation/unaliased_ssa/internal/SSAConsistency.ql

View File

@@ -1 +0,0 @@
semmle/code/cpp/ir/implementation/unaliased_ssa/internal/SSASanity.ql

View File

@@ -0,0 +1,2 @@
import semmle.code.cpp.ir.implementation.aliased_ssa.IRConsistency
import semmle.code.cpp.ir.implementation.UseSoundEscapeAnalysis

View File

@@ -0,0 +1 @@
semmle/code/cpp/ir/IRConsistency.ql

View File

@@ -1,2 +0,0 @@
import semmle.code.cpp.ir.implementation.aliased_ssa.IRSanity
import semmle.code.cpp.ir.implementation.UseSoundEscapeAnalysis

View File

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