mirror of
https://github.com/github/codeql.git
synced 2026-04-24 08:15:14 +02:00
Rust: Extend data flow library instantiation for global data flow
This commit is contained in:
@@ -13,6 +13,8 @@ class AstCfgNode = CfgImpl::AstCfgNode;
|
||||
|
||||
class ExitCfgNode = CfgImpl::ExitNode;
|
||||
|
||||
class AnnotatedExitCfgNode = CfgImpl::AnnotatedExitNode;
|
||||
|
||||
/**
|
||||
* An assignment expression, for example
|
||||
*
|
||||
|
||||
@@ -43,22 +43,59 @@ final class DataFlowCallable extends TDataFlowCallable {
|
||||
}
|
||||
|
||||
final class DataFlowCall extends TDataFlowCall {
|
||||
private CallExprBaseCfgNode call;
|
||||
|
||||
DataFlowCall() { this = TCall(call) }
|
||||
|
||||
/** Gets the underlying call in the CFG, if any. */
|
||||
CallExprCfgNode asCallExprCfgNode() { this = TNormalCall(result) }
|
||||
CallExprCfgNode asCallExprCfgNode() { result = call }
|
||||
|
||||
MethodCallExprCfgNode asMethodCallExprCfgNode() { this = TMethodCall(result) }
|
||||
MethodCallExprCfgNode asMethodCallExprCfgNode() { result = call }
|
||||
|
||||
CallExprBaseCfgNode asExprCfgNode() {
|
||||
result = this.asCallExprCfgNode() or result = this.asMethodCallExprCfgNode()
|
||||
}
|
||||
CallExprBaseCfgNode asCallBaseExprCfgNode() { result = call }
|
||||
|
||||
DataFlowCallable getEnclosingCallable() {
|
||||
result = TCfgScope(this.asExprCfgNode().getExpr().getEnclosingCfgScope())
|
||||
result = TCfgScope(call.getExpr().getEnclosingCfgScope())
|
||||
}
|
||||
|
||||
string toString() { result = this.asExprCfgNode().toString() }
|
||||
string toString() { result = this.asCallBaseExprCfgNode().toString() }
|
||||
|
||||
Location getLocation() { result = this.asExprCfgNode().getLocation() }
|
||||
Location getLocation() { result = this.asCallBaseExprCfgNode().getLocation() }
|
||||
}
|
||||
|
||||
/**
|
||||
* The position of a parameter or an argument in a function or call.
|
||||
*
|
||||
* As there is a 1-to-1 correspondence between parameter positions and
|
||||
* arguments positions in Rust we use the same type for both.
|
||||
*/
|
||||
final class ParameterPosition extends TParameterPosition {
|
||||
/** Gets the underlying integer position, if any. */
|
||||
int getPosition() { this = TPositionalParameterPosition(result) }
|
||||
|
||||
/** Holds if this position represents the `self` position. */
|
||||
predicate isSelf() { this = TSelfParameterPosition() }
|
||||
|
||||
/** Gets a textual representation of this position. */
|
||||
string toString() {
|
||||
result = this.getPosition().toString()
|
||||
or
|
||||
result = "self" and this.isSelf()
|
||||
}
|
||||
|
||||
AstNode getParameterIn(ParamList ps) {
|
||||
result = ps.getParam(this.getPosition())
|
||||
or
|
||||
result = ps.getSelfParam() and this.isSelf()
|
||||
}
|
||||
}
|
||||
|
||||
/** Holds if `arg` is an argument of `call` at the position `pos`. */
|
||||
private predicate isArgumentForCall(ExprCfgNode arg, CallExprBaseCfgNode call, ParameterPosition pos) {
|
||||
arg = call.getArgument(pos.getPosition())
|
||||
or
|
||||
// The self argument in a method call.
|
||||
arg = call.(MethodCallExprCfgNode).getReceiver() and pos.isSelf()
|
||||
}
|
||||
|
||||
module Node {
|
||||
@@ -93,11 +130,6 @@ module Node {
|
||||
* Gets this node's underlying SSA definition, if any.
|
||||
*/
|
||||
Ssa::Definition asDefinition() { none() }
|
||||
|
||||
/**
|
||||
* Gets the parameter that corresponds to this node, if any.
|
||||
*/
|
||||
Param asParameter() { none() }
|
||||
}
|
||||
|
||||
/** A node type that is not implemented. */
|
||||
@@ -111,7 +143,7 @@ module Node {
|
||||
override Location getLocation() { none() }
|
||||
}
|
||||
|
||||
/** A data flow node that corresponds to a CFG node for an AST node. */
|
||||
/** A data flow node that corresponds directly to a CFG node for an AST node. */
|
||||
abstract class AstCfgFlowNode extends Node {
|
||||
AstCfgNode n;
|
||||
|
||||
@@ -145,24 +177,37 @@ module Node {
|
||||
|
||||
PatNode() { this = TPatNode(n) }
|
||||
|
||||
/** Gets the `Pat` in the AST that this node corresponds to. */
|
||||
Pat getPat() { result = n.getPat() }
|
||||
/** Gets the `PatCfgNode` in the CFG that this node corresponds to. */
|
||||
PatCfgNode getPat() { result = n }
|
||||
}
|
||||
|
||||
abstract class ParameterNode extends AstCfgFlowNode { }
|
||||
|
||||
/**
|
||||
* The value of a parameter at function entry, viewed as a node in a data
|
||||
* flow graph.
|
||||
*/
|
||||
final class ParameterNode extends AstCfgFlowNode, TParameterNode {
|
||||
final class NormalParameterNode extends ParameterNode, TParameterNode {
|
||||
override ParamCfgNode n;
|
||||
|
||||
ParameterNode() { this = TParameterNode(n) }
|
||||
NormalParameterNode() { this = TParameterNode(n) }
|
||||
|
||||
/** Gets the parameter in the CFG that this node corresponds to. */
|
||||
ParamCfgNode getParameter() { result = n }
|
||||
}
|
||||
|
||||
final class ArgumentNode = NaNode;
|
||||
final class SelfParameterNode extends ParameterNode, TSelfParameterNode {
|
||||
override SelfParamCfgNode n;
|
||||
|
||||
SelfParameterNode() { this = TSelfParameterNode(n) }
|
||||
|
||||
/** Gets the self parameter in the AST that this node corresponds to. */
|
||||
SelfParamCfgNode getSelfParameter() { result = n }
|
||||
}
|
||||
|
||||
final class ArgumentNode extends ExprNode {
|
||||
ArgumentNode() { isArgumentForCall(n, _, _) }
|
||||
}
|
||||
|
||||
/** An SSA node. */
|
||||
class SsaNode extends Node, TSsaNode {
|
||||
@@ -185,7 +230,10 @@ module Node {
|
||||
|
||||
/** A data flow node that represents a value returned by a callable. */
|
||||
final class ReturnNode extends ExprNode {
|
||||
ReturnNode() { this.getCfgNode().getASuccessor() instanceof ExitCfgNode }
|
||||
ReturnNode() {
|
||||
this.getCfgNode().getASuccessor() instanceof ExitCfgNode or
|
||||
this.getCfgNode().getASuccessor() instanceof AnnotatedExitCfgNode
|
||||
}
|
||||
|
||||
ReturnKind getKind() { any() }
|
||||
}
|
||||
@@ -197,10 +245,10 @@ module Node {
|
||||
}
|
||||
|
||||
final private class ExprOutNode extends ExprNode, OutNode {
|
||||
ExprOutNode() { this.asExpr() instanceof CallExprCfgNode }
|
||||
ExprOutNode() { this.asExpr() instanceof CallExprBaseCfgNode }
|
||||
|
||||
/** Gets the underlying call CFG node that includes this out node. */
|
||||
override DataFlowCall getCall() { result.asExprCfgNode() = this.getCfgNode() }
|
||||
override DataFlowCall getCall() { result.asCallBaseExprCfgNode() = this.getCfgNode() }
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -214,9 +262,19 @@ module Node {
|
||||
* Nodes corresponding to AST elements, for example `ExprNode`, usually refer
|
||||
* to the value before the update.
|
||||
*/
|
||||
final class PostUpdateNode extends Node::NaNode {
|
||||
final class PostUpdateNode extends Node, TArgumentPostUpdateNode {
|
||||
private ExprCfgNode n;
|
||||
|
||||
PostUpdateNode() { this = TArgumentPostUpdateNode(n) }
|
||||
|
||||
/** Gets the node before the state update. */
|
||||
Node getPreUpdateNode() { none() }
|
||||
Node getPreUpdateNode() { result = TExprNode(n) }
|
||||
|
||||
final override CfgScope getCfgScope() { result = n.getAstNode().getEnclosingCfgScope() }
|
||||
|
||||
final override Location getLocation() { result = n.getAstNode().getLocation() }
|
||||
|
||||
final override string toString() { result = n.getAstNode().toString() }
|
||||
}
|
||||
|
||||
final class CastNode = NaNode;
|
||||
@@ -226,25 +284,27 @@ final class Node = Node::Node;
|
||||
|
||||
/** Provides logic related to SSA. */
|
||||
module SsaFlow {
|
||||
private module Impl = SsaImpl::DataFlowIntegration;
|
||||
private module SsaFlow = SsaImpl::DataFlowIntegration;
|
||||
|
||||
private Node::ParameterNode toParameterNode(ParamCfgNode p) { result.getParameter() = p }
|
||||
private Node::ParameterNode toParameterNode(ParamCfgNode p) {
|
||||
result.(Node::NormalParameterNode).getParameter() = p
|
||||
}
|
||||
|
||||
/** Converts a control flow node into an SSA control flow node. */
|
||||
Impl::Node asNode(Node n) {
|
||||
SsaFlow::Node asNode(Node n) {
|
||||
n = TSsaNode(result)
|
||||
or
|
||||
result.(Impl::ExprNode).getExpr() = n.asExpr()
|
||||
result.(SsaFlow::ExprNode).getExpr() = n.asExpr()
|
||||
or
|
||||
n = toParameterNode(result.(Impl::ParameterNode).getParameter())
|
||||
n = toParameterNode(result.(SsaFlow::ParameterNode).getParameter())
|
||||
}
|
||||
|
||||
predicate localFlowStep(SsaImpl::DefinitionExt def, Node nodeFrom, Node nodeTo, boolean isUseStep) {
|
||||
Impl::localFlowStep(def, asNode(nodeFrom), asNode(nodeTo), isUseStep)
|
||||
SsaFlow::localFlowStep(def, asNode(nodeFrom), asNode(nodeTo), isUseStep)
|
||||
}
|
||||
|
||||
predicate localMustFlowStep(SsaImpl::DefinitionExt def, Node nodeFrom, Node nodeTo) {
|
||||
Impl::localMustFlowStep(def, asNode(nodeFrom), asNode(nodeTo))
|
||||
SsaFlow::localMustFlowStep(def, asNode(nodeFrom), asNode(nodeTo))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -276,6 +336,8 @@ module LocalFlow {
|
||||
nodeFrom.(Node::AstCfgFlowNode).getCfgNode() =
|
||||
nodeTo.(Node::SsaNode).getDefinitionExt().(Ssa::WriteDefinition).getControlFlowNode()
|
||||
or
|
||||
nodeFrom.(Node::NormalParameterNode).getParameter().getPat() = nodeTo.(Node::PatNode).getPat()
|
||||
or
|
||||
SsaFlow::localFlowStep(_, nodeFrom, nodeTo, _)
|
||||
or
|
||||
exists(AssignmentExprCfgNode a |
|
||||
@@ -291,6 +353,8 @@ private class ReturnKindAlias = ReturnKind;
|
||||
|
||||
private class DataFlowCallAlias = DataFlowCall;
|
||||
|
||||
private class ParameterPositionAlias = ParameterPosition;
|
||||
|
||||
module RustDataFlow implements InputSig<Location> {
|
||||
/**
|
||||
* An element, viewed as a node in a data flow graph. Either an expression
|
||||
@@ -310,9 +374,15 @@ module RustDataFlow implements InputSig<Location> {
|
||||
|
||||
final class CastNode = Node::NaNode;
|
||||
|
||||
predicate isParameterNode(ParameterNode p, DataFlowCallable c, ParameterPosition pos) { none() }
|
||||
/** Holds if `p` is a parameter of `c` at the position `pos`. */
|
||||
predicate isParameterNode(ParameterNode p, DataFlowCallable c, ParameterPosition pos) {
|
||||
p.getCfgNode().getAstNode() = pos.getParameterIn(c.asCfgScope().(Function).getParamList())
|
||||
}
|
||||
|
||||
predicate isArgumentNode(ArgumentNode n, DataFlowCall call, ArgumentPosition pos) { none() }
|
||||
/** Holds if `n` is an argument of `c` at the position `pos`. */
|
||||
predicate isArgumentNode(ArgumentNode n, DataFlowCall call, ArgumentPosition pos) {
|
||||
isArgumentForCall(n.getCfgNode(), call.asCallBaseExprCfgNode(), pos)
|
||||
}
|
||||
|
||||
DataFlowCallable nodeGetEnclosingCallable(Node node) { result = node.getEnclosingCallable() }
|
||||
|
||||
@@ -335,10 +405,9 @@ module RustDataFlow implements InputSig<Location> {
|
||||
DataFlowCallable viableCallable(DataFlowCall c) {
|
||||
exists(Function f, string name | result.asCfgScope() = f and name = f.getName().toString() |
|
||||
if f.getParamList().hasSelfParam()
|
||||
then name = c.asMethodCallExprCfgNode().getMethodCallExpr().getNameRef().getText()
|
||||
then name = c.asMethodCallExprCfgNode().getNameRef().getText()
|
||||
else
|
||||
name =
|
||||
c.asCallExprCfgNode().getCallExpr().getExpr().(PathExpr).getPath().getPart().toString()
|
||||
name = c.asCallExprCfgNode().getExpr().getExpr().(PathExpr).getPath().getPart().toString()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -377,19 +446,15 @@ module RustDataFlow implements InputSig<Location> {
|
||||
|
||||
ContentApprox getContentApprox(Content c) { any() }
|
||||
|
||||
class ParameterPosition extends string {
|
||||
ParameterPosition() { this = "pos" }
|
||||
}
|
||||
class ParameterPosition = ParameterPositionAlias;
|
||||
|
||||
class ArgumentPosition extends string {
|
||||
ArgumentPosition() { this = "pos" }
|
||||
}
|
||||
class ArgumentPosition = ParameterPosition;
|
||||
|
||||
/**
|
||||
* Holds if the parameter position `ppos` matches the argument position
|
||||
* `apos`.
|
||||
*/
|
||||
predicate parameterMatch(ParameterPosition ppos, ArgumentPosition apos) { none() }
|
||||
predicate parameterMatch(ParameterPosition ppos, ArgumentPosition apos) { ppos = apos }
|
||||
|
||||
/**
|
||||
* Holds if there is a simple local flow step from `node1` to `node2`. These
|
||||
@@ -497,13 +562,13 @@ private module Cached {
|
||||
newtype TNode =
|
||||
TExprNode(ExprCfgNode n) or
|
||||
TParameterNode(ParamCfgNode p) or
|
||||
TSelfParameterNode(SelfParamCfgNode p) or
|
||||
TPatNode(PatCfgNode p) or
|
||||
TArgumentPostUpdateNode(ExprCfgNode e) { isArgumentForCall(e, _, _) } or
|
||||
TSsaNode(SsaImpl::DataFlowIntegration::SsaNode node)
|
||||
|
||||
cached
|
||||
newtype TDataFlowCall =
|
||||
TNormalCall(CallExprCfgNode c) or
|
||||
TMethodCall(MethodCallExprCfgNode c)
|
||||
newtype TDataFlowCall = TCall(CallExprBaseCfgNode c)
|
||||
|
||||
cached
|
||||
newtype TOptionalContentSet =
|
||||
@@ -521,6 +586,13 @@ private module Cached {
|
||||
predicate localFlowStepImpl(Node::Node nodeFrom, Node::Node nodeTo) {
|
||||
LocalFlow::localFlowStepCommon(nodeFrom, nodeTo)
|
||||
}
|
||||
|
||||
cached
|
||||
newtype TParameterPosition =
|
||||
TPositionalParameterPosition(int i) {
|
||||
exists(any(ParamList l).getParam(i)) or exists(any(ArgList l).getArg(i))
|
||||
} or
|
||||
TSelfParameterPosition()
|
||||
}
|
||||
|
||||
import Cached
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
uniqueNodeLocation
|
||||
| file://:0:0:0:0 | ... .parent(...) | Node should have one location but has 0. |
|
||||
| file://:0:0:0:0 | ... .parent(...) | Node should have one location but has 0. |
|
||||
| file://:0:0:0:0 | ... .unwrap(...) | Node should have one location but has 0. |
|
||||
| file://:0:0:0:0 | BlockExpr | Node should have one location but has 0. |
|
||||
| file://:0:0:0:0 | Param | Node should have one location but has 0. |
|
||||
| file://:0:0:0:0 | path | Node should have one location but has 0. |
|
||||
| file://:0:0:0:0 | path | Node should have one location but has 0. |
|
||||
| file://:0:0:0:0 | path | Node should have one location but has 0. |
|
||||
missingLocation
|
||||
| Nodes without location: 6 |
|
||||
| Nodes without location: 8 |
|
||||
|
||||
@@ -1,16 +1,29 @@
|
||||
models
|
||||
edges
|
||||
| main.rs:9:13:9:19 | Param : unit | main.rs:9:30:14:1 | BlockExpr : unit | provenance | |
|
||||
| main.rs:21:13:21:21 | CallExpr : unit | main.rs:22:10:22:10 | s | provenance | |
|
||||
| main.rs:26:13:26:21 | CallExpr : unit | main.rs:27:22:27:22 | s : unit | provenance | |
|
||||
| main.rs:27:13:27:23 | CallExpr : unit | main.rs:28:10:28:10 | s | provenance | |
|
||||
| main.rs:27:22:27:22 | s : unit | main.rs:9:13:9:19 | Param : unit | provenance | |
|
||||
| main.rs:27:22:27:22 | s : unit | main.rs:27:13:27:23 | CallExpr : unit | provenance | |
|
||||
| main.rs:32:13:32:21 | CallExpr : unit | main.rs:33:10:33:10 | s | provenance | |
|
||||
nodes
|
||||
| main.rs:9:13:9:19 | Param : unit | semmle.label | Param : unit |
|
||||
| main.rs:9:30:14:1 | BlockExpr : unit | semmle.label | BlockExpr : unit |
|
||||
| main.rs:17:10:17:18 | CallExpr | semmle.label | CallExpr |
|
||||
| main.rs:21:13:21:21 | CallExpr : unit | semmle.label | CallExpr : unit |
|
||||
| main.rs:22:10:22:10 | s | semmle.label | s |
|
||||
| main.rs:26:13:26:21 | CallExpr : unit | semmle.label | CallExpr : unit |
|
||||
| main.rs:27:13:27:23 | CallExpr : unit | semmle.label | CallExpr : unit |
|
||||
| main.rs:27:22:27:22 | s : unit | semmle.label | s : unit |
|
||||
| main.rs:28:10:28:10 | s | semmle.label | s |
|
||||
| main.rs:32:13:32:21 | CallExpr : unit | semmle.label | CallExpr : unit |
|
||||
| main.rs:33:10:33:10 | s | semmle.label | s |
|
||||
subpaths
|
||||
| main.rs:27:22:27:22 | s : unit | main.rs:9:13:9:19 | Param : unit | main.rs:9:30:14:1 | BlockExpr : unit | main.rs:27:13:27:23 | CallExpr : unit |
|
||||
testFailures
|
||||
#select
|
||||
| main.rs:17:10:17:18 | CallExpr | main.rs:17:10:17:18 | CallExpr | main.rs:17:10:17:18 | CallExpr | $@ | main.rs:17:10:17:18 | CallExpr | CallExpr |
|
||||
| main.rs:22:10:22:10 | s | main.rs:21:13:21:21 | CallExpr : unit | main.rs:22:10:22:10 | s | $@ | main.rs:21:13:21:21 | CallExpr : unit | CallExpr : unit |
|
||||
| main.rs:28:10:28:10 | s | main.rs:26:13:26:21 | CallExpr : unit | main.rs:28:10:28:10 | s | $@ | main.rs:26:13:26:21 | CallExpr : unit | CallExpr : unit |
|
||||
| main.rs:33:10:33:10 | s | main.rs:32:13:32:21 | CallExpr : unit | main.rs:33:10:33:10 | s | $@ | main.rs:32:13:32:21 | CallExpr : unit | CallExpr : unit |
|
||||
|
||||
@@ -9,7 +9,7 @@ fn sink(s: &str) {
|
||||
fn sanitize(s: &str) -> &str {
|
||||
match s {
|
||||
"dangerous" => "",
|
||||
s => s
|
||||
s => s,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,7 +25,7 @@ fn through_variable() {
|
||||
fn with_barrier() {
|
||||
let s = source(1);
|
||||
let s = sanitize(s);
|
||||
sink(s);
|
||||
sink(s); // $ SPURIOUS: hasValueFlow=1
|
||||
}
|
||||
|
||||
fn main() {
|
||||
|
||||
@@ -1,6 +1,75 @@
|
||||
models
|
||||
edges
|
||||
| main.rs:12:28:14:1 | BlockExpr : unit | main.rs:17:13:17:23 | CallExpr : unit | provenance | |
|
||||
| main.rs:13:5:13:13 | CallExpr : unit | main.rs:12:28:14:1 | BlockExpr : unit | provenance | |
|
||||
| main.rs:17:13:17:23 | CallExpr : unit | main.rs:18:10:18:10 | a | provenance | |
|
||||
| main.rs:21:12:21:17 | Param : unit | main.rs:22:10:22:10 | n | provenance | |
|
||||
| main.rs:26:13:26:21 | CallExpr : unit | main.rs:27:13:27:13 | a : unit | provenance | |
|
||||
| main.rs:27:13:27:13 | a : unit | main.rs:21:12:21:17 | Param : unit | provenance | |
|
||||
| main.rs:30:17:30:22 | Param : unit | main.rs:30:32:32:1 | BlockExpr : unit | provenance | |
|
||||
| main.rs:35:13:35:21 | CallExpr : unit | main.rs:36:26:36:26 | a : unit | provenance | |
|
||||
| main.rs:36:13:36:27 | CallExpr : unit | main.rs:37:10:37:10 | b | provenance | |
|
||||
| main.rs:36:26:36:26 | a : unit | main.rs:30:17:30:22 | Param : unit | provenance | |
|
||||
| main.rs:36:26:36:26 | a : unit | main.rs:36:13:36:27 | CallExpr : unit | provenance | |
|
||||
| main.rs:41:13:44:6 | CallExpr : unit | main.rs:45:10:45:10 | a | provenance | |
|
||||
| main.rs:41:26:44:5 | BlockExpr : unit | main.rs:30:17:30:22 | Param : unit | provenance | |
|
||||
| main.rs:41:26:44:5 | BlockExpr : unit | main.rs:41:13:44:6 | CallExpr : unit | provenance | |
|
||||
| main.rs:43:9:43:18 | CallExpr : unit | main.rs:41:26:44:5 | BlockExpr : unit | provenance | |
|
||||
| main.rs:56:23:56:28 | Param : unit | main.rs:57:14:57:14 | n | provenance | |
|
||||
| main.rs:59:31:65:5 | BlockExpr : unit | main.rs:77:13:77:25 | ... .get_data(...) : unit | provenance | |
|
||||
| main.rs:63:13:63:21 | CallExpr : unit | main.rs:59:31:65:5 | BlockExpr : unit | provenance | |
|
||||
| main.rs:66:28:66:33 | Param : unit | main.rs:66:43:72:5 | BlockExpr : unit | provenance | |
|
||||
| main.rs:77:13:77:25 | ... .get_data(...) : unit | main.rs:78:10:78:10 | a | provenance | |
|
||||
| main.rs:83:13:83:21 | CallExpr : unit | main.rs:84:16:84:16 | a : unit | provenance | |
|
||||
| main.rs:84:16:84:16 | a : unit | main.rs:56:23:56:28 | Param : unit | provenance | |
|
||||
| main.rs:89:13:89:21 | CallExpr : unit | main.rs:90:29:90:29 | a : unit | provenance | |
|
||||
| main.rs:90:13:90:30 | ... .data_through(...) : unit | main.rs:91:10:91:10 | b | provenance | |
|
||||
| main.rs:90:29:90:29 | a : unit | main.rs:66:28:66:33 | Param : unit | provenance | |
|
||||
| main.rs:90:29:90:29 | a : unit | main.rs:90:13:90:30 | ... .data_through(...) : unit | provenance | |
|
||||
nodes
|
||||
| main.rs:12:28:14:1 | BlockExpr : unit | semmle.label | BlockExpr : unit |
|
||||
| main.rs:13:5:13:13 | CallExpr : unit | semmle.label | CallExpr : unit |
|
||||
| main.rs:17:13:17:23 | CallExpr : unit | semmle.label | CallExpr : unit |
|
||||
| main.rs:18:10:18:10 | a | semmle.label | a |
|
||||
| main.rs:21:12:21:17 | Param : unit | semmle.label | Param : unit |
|
||||
| main.rs:22:10:22:10 | n | semmle.label | n |
|
||||
| main.rs:26:13:26:21 | CallExpr : unit | semmle.label | CallExpr : unit |
|
||||
| main.rs:27:13:27:13 | a : unit | semmle.label | a : unit |
|
||||
| main.rs:30:17:30:22 | Param : unit | semmle.label | Param : unit |
|
||||
| main.rs:30:32:32:1 | BlockExpr : unit | semmle.label | BlockExpr : unit |
|
||||
| main.rs:35:13:35:21 | CallExpr : unit | semmle.label | CallExpr : unit |
|
||||
| main.rs:36:13:36:27 | CallExpr : unit | semmle.label | CallExpr : unit |
|
||||
| main.rs:36:26:36:26 | a : unit | semmle.label | a : unit |
|
||||
| main.rs:37:10:37:10 | b | semmle.label | b |
|
||||
| main.rs:41:13:44:6 | CallExpr : unit | semmle.label | CallExpr : unit |
|
||||
| main.rs:41:26:44:5 | BlockExpr : unit | semmle.label | BlockExpr : unit |
|
||||
| main.rs:43:9:43:18 | CallExpr : unit | semmle.label | CallExpr : unit |
|
||||
| main.rs:45:10:45:10 | a | semmle.label | a |
|
||||
| main.rs:56:23:56:28 | Param : unit | semmle.label | Param : unit |
|
||||
| main.rs:57:14:57:14 | n | semmle.label | n |
|
||||
| main.rs:59:31:65:5 | BlockExpr : unit | semmle.label | BlockExpr : unit |
|
||||
| main.rs:63:13:63:21 | CallExpr : unit | semmle.label | CallExpr : unit |
|
||||
| main.rs:66:28:66:33 | Param : unit | semmle.label | Param : unit |
|
||||
| main.rs:66:43:72:5 | BlockExpr : unit | semmle.label | BlockExpr : unit |
|
||||
| main.rs:77:13:77:25 | ... .get_data(...) : unit | semmle.label | ... .get_data(...) : unit |
|
||||
| main.rs:78:10:78:10 | a | semmle.label | a |
|
||||
| main.rs:83:13:83:21 | CallExpr : unit | semmle.label | CallExpr : unit |
|
||||
| main.rs:84:16:84:16 | a : unit | semmle.label | a : unit |
|
||||
| main.rs:89:13:89:21 | CallExpr : unit | semmle.label | CallExpr : unit |
|
||||
| main.rs:90:13:90:30 | ... .data_through(...) : unit | semmle.label | ... .data_through(...) : unit |
|
||||
| main.rs:90:29:90:29 | a : unit | semmle.label | a : unit |
|
||||
| main.rs:91:10:91:10 | b | semmle.label | b |
|
||||
subpaths
|
||||
| main.rs:36:26:36:26 | a : unit | main.rs:30:17:30:22 | Param : unit | main.rs:30:32:32:1 | BlockExpr : unit | main.rs:36:13:36:27 | CallExpr : unit |
|
||||
| main.rs:41:26:44:5 | BlockExpr : unit | main.rs:30:17:30:22 | Param : unit | main.rs:30:32:32:1 | BlockExpr : unit | main.rs:41:13:44:6 | CallExpr : unit |
|
||||
| main.rs:90:29:90:29 | a : unit | main.rs:66:28:66:33 | Param : unit | main.rs:66:43:72:5 | BlockExpr : unit | main.rs:90:13:90:30 | ... .data_through(...) : unit |
|
||||
testFailures
|
||||
| main.rs:45:10:45:10 | a | Fixed missing result: hasValueFlow=14 |
|
||||
#select
|
||||
| main.rs:18:10:18:10 | a | main.rs:13:5:13:13 | CallExpr : unit | main.rs:18:10:18:10 | a | $@ | main.rs:13:5:13:13 | CallExpr : unit | CallExpr : unit |
|
||||
| main.rs:22:10:22:10 | n | main.rs:26:13:26:21 | CallExpr : unit | main.rs:22:10:22:10 | n | $@ | main.rs:26:13:26:21 | CallExpr : unit | CallExpr : unit |
|
||||
| main.rs:37:10:37:10 | b | main.rs:35:13:35:21 | CallExpr : unit | main.rs:37:10:37:10 | b | $@ | main.rs:35:13:35:21 | CallExpr : unit | CallExpr : unit |
|
||||
| main.rs:45:10:45:10 | a | main.rs:43:9:43:18 | CallExpr : unit | main.rs:45:10:45:10 | a | $@ | main.rs:43:9:43:18 | CallExpr : unit | CallExpr : unit |
|
||||
| main.rs:57:14:57:14 | n | main.rs:83:13:83:21 | CallExpr : unit | main.rs:57:14:57:14 | n | $@ | main.rs:83:13:83:21 | CallExpr : unit | CallExpr : unit |
|
||||
| main.rs:78:10:78:10 | a | main.rs:63:13:63:21 | CallExpr : unit | main.rs:78:10:78:10 | a | $@ | main.rs:63:13:63:21 | CallExpr : unit | CallExpr : unit |
|
||||
| main.rs:91:10:91:10 | b | main.rs:89:13:89:21 | CallExpr : unit | main.rs:91:10:91:10 | b | $@ | main.rs:89:13:89:21 | CallExpr : unit | CallExpr : unit |
|
||||
|
||||
@@ -15,11 +15,11 @@ fn get_data(n: i64) -> i64 {
|
||||
|
||||
fn data_out_of_call() {
|
||||
let a = get_data(7);
|
||||
sink(a); // $ MISSING: hasValueFlow=n
|
||||
sink(a); // $ hasValueFlow=n
|
||||
}
|
||||
|
||||
fn data_in(n: i64) {
|
||||
sink(n); // $ MISSING: hasValueFlow=3
|
||||
sink(n); // $ hasValueFlow=3
|
||||
}
|
||||
|
||||
fn data_in_to_call() {
|
||||
@@ -34,7 +34,7 @@ fn pass_through(i: i64) -> i64 {
|
||||
fn data_through_call() {
|
||||
let a = source(1);
|
||||
let b = pass_through(a);
|
||||
sink(b); // $ MISSING: hasValueFlow=1
|
||||
sink(b); // $ hasValueFlow=1
|
||||
}
|
||||
|
||||
fn block_expression_as_argument() {
|
||||
@@ -54,7 +54,7 @@ struct MyFlag {
|
||||
|
||||
impl MyFlag {
|
||||
fn data_in(&self, n: i64) {
|
||||
sink(n); // $ MISSING: hasValueFlow=1
|
||||
sink(n); // $ hasValueFlow=1
|
||||
}
|
||||
fn get_data(&self) -> i64 {
|
||||
if self.flag {
|
||||
@@ -75,7 +75,7 @@ impl MyFlag {
|
||||
fn data_out_of_method() {
|
||||
let mn = MyFlag { flag: true };
|
||||
let a = mn.get_data();
|
||||
sink(a); // $ MISSING: hasValueFlow=2
|
||||
sink(a); // $ hasValueFlow=2
|
||||
}
|
||||
|
||||
fn data_in_to_method_call() {
|
||||
@@ -88,7 +88,7 @@ fn data_through_method() {
|
||||
let mn = MyFlag { flag: true };
|
||||
let a = source(4);
|
||||
let b = mn.data_through(a);
|
||||
sink(b); // $ MISSING: hasValueFlow=4
|
||||
sink(b); // $ hasValueFlow=4
|
||||
}
|
||||
|
||||
fn main() {
|
||||
|
||||
@@ -1,13 +1,16 @@
|
||||
| main.rs:3:11:3:11 | [SSA] i | main.rs:4:12:4:12 | i |
|
||||
| main.rs:3:11:3:11 | i | main.rs:3:11:3:11 | [SSA] i |
|
||||
| main.rs:3:11:3:16 | Param | main.rs:3:11:3:11 | i |
|
||||
| main.rs:4:5:4:12 | ... + ... | main.rs:3:26:5:1 | BlockExpr |
|
||||
| main.rs:7:9:7:9 | [SSA] s | main.rs:8:20:8:20 | s |
|
||||
| main.rs:7:9:7:9 | s | main.rs:7:9:7:9 | [SSA] s |
|
||||
| main.rs:7:9:7:14 | Param | main.rs:7:9:7:9 | s |
|
||||
| main.rs:19:9:19:9 | [SSA] s | main.rs:20:10:20:10 | s |
|
||||
| main.rs:19:9:19:9 | s | main.rs:19:9:19:9 | [SSA] s |
|
||||
| main.rs:19:13:19:21 | CallExpr | main.rs:19:9:19:9 | s |
|
||||
| main.rs:23:18:23:21 | [SSA] cond | main.rs:26:16:26:19 | cond |
|
||||
| main.rs:23:18:23:21 | cond | main.rs:23:18:23:21 | [SSA] cond |
|
||||
| main.rs:23:18:23:27 | Param | main.rs:23:18:23:21 | cond |
|
||||
| main.rs:24:9:24:9 | [SSA] a | main.rs:26:23:26:23 | a |
|
||||
| main.rs:24:9:24:9 | a | main.rs:24:9:24:9 | [SSA] a |
|
||||
| main.rs:24:13:24:21 | CallExpr | main.rs:24:9:24:9 | a |
|
||||
@@ -23,6 +26,7 @@
|
||||
| main.rs:26:34:26:34 | b | main.rs:26:32:26:36 | BlockExpr |
|
||||
| main.rs:30:21:30:21 | [SSA] m | main.rs:32:19:32:19 | m |
|
||||
| main.rs:30:21:30:21 | m | main.rs:30:21:30:21 | [SSA] m |
|
||||
| main.rs:30:21:30:34 | Param | main.rs:30:21:30:21 | m |
|
||||
| main.rs:31:9:31:9 | [SSA] a | main.rs:33:20:33:20 | a |
|
||||
| main.rs:31:9:31:9 | a | main.rs:31:9:31:9 | [SSA] a |
|
||||
| main.rs:31:13:31:21 | CallExpr | main.rs:31:9:31:9 | a |
|
||||
@@ -91,6 +95,7 @@
|
||||
| main.rs:118:5:118:5 | a | main.rs:116:31:119:1 | BlockExpr |
|
||||
| main.rs:121:22:121:22 | [SSA] b | main.rs:123:12:123:12 | b |
|
||||
| main.rs:121:22:121:22 | b | main.rs:121:22:121:22 | [SSA] b |
|
||||
| main.rs:121:22:121:28 | Param | main.rs:121:22:121:22 | b |
|
||||
| main.rs:122:9:122:9 | [SSA] a | main.rs:128:5:128:5 | a |
|
||||
| main.rs:122:9:122:9 | a | main.rs:122:9:122:9 | [SSA] a |
|
||||
| main.rs:122:13:127:5 | BlockExpr | main.rs:122:9:122:9 | a |
|
||||
@@ -100,6 +105,7 @@
|
||||
| main.rs:128:5:128:5 | a | main.rs:121:38:129:1 | BlockExpr |
|
||||
| main.rs:131:22:131:22 | [SSA] b | main.rs:133:12:133:12 | b |
|
||||
| main.rs:131:22:131:22 | b | main.rs:131:22:131:22 | [SSA] b |
|
||||
| main.rs:131:22:131:28 | Param | main.rs:131:22:131:22 | b |
|
||||
| main.rs:132:9:132:9 | [SSA] a | main.rs:138:5:138:5 | a |
|
||||
| main.rs:132:9:132:9 | a | main.rs:132:9:132:9 | [SSA] a |
|
||||
| main.rs:132:13:137:5 | BlockExpr | main.rs:132:9:132:9 | a |
|
||||
|
||||
Reference in New Issue
Block a user