Merge pull request #115 from github/aibaars/dataflow

My first dataflow step
This commit is contained in:
Arthur Baars
2021-02-05 14:13:38 +01:00
committed by GitHub
6 changed files with 55 additions and 8 deletions

View File

@@ -193,6 +193,11 @@ module ExprNodes {
final ExprCfgNode getRhs() { e.hasCfgChild(e.getRhs(), this, result) }
}
/** A control-flow node that wraps an `AssignExpr` AST expression. */
class AssignExprCfgNode extends AssignmentCfgNode {
AssignExprCfgNode() { this.getExpr() instanceof AssignExpr }
}
private class BinaryOperationExprChildMapping extends ExprChildMapping, BinaryOperation {
override predicate relevantChild(Expr e) { e = this.getAnOperand() }
}
@@ -244,6 +249,11 @@ module ExprNodes {
final ExprCfgNode getExpr(int n) { e.hasCfgChild(e.getExpr(n), this, result) }
}
/** A control-flow node that wraps an `ExprSequence` AST expression. */
class ParenthesizedExprCfgNode extends ExprSequenceCfgNode {
ParenthesizedExprCfgNode() { this.getExpr() instanceof ParenthesizedExpr }
}
/** A control-flow node that wraps a `VariableReadAccess` AST expression. */
class VariableReadAccessCfgNode extends ExprCfgNode {
override VariableReadAccess e;

View File

@@ -39,8 +39,8 @@ DataFlowCallable viableCallable(DataFlowCall call) { none() }
/**
* Holds if the set of viable implementations that can be called by `call`
* might be improved by knowing the call context. This is the case if the
* call is a delegate call, or if the qualifier accesses a parameter of
* the enclosing callable `c` (including the implicit `this` parameter).
* qualifier accesses a parameter of the enclosing callable `c` (including
* the implicit `self` parameter).
*/
predicate mayBenefitFromCallContext(DataFlowCall call, Callable c) { none() }

View File

@@ -123,7 +123,10 @@ private module Cached {
predicate simpleLocalFlowStep(Node nodeFrom, Node nodeTo) {
exists(Ssa::Definition def | LocalFlow::localSsaFlowStep(def, nodeFrom, nodeTo))
or
nodeFrom.asExpr() = nodeTo.asExpr().(CfgNodes::ExprNodes::AssignmentCfgNode).getRhs()
nodeFrom.asExpr() = nodeTo.asExpr().(CfgNodes::ExprNodes::AssignExprCfgNode).getRhs()
or
nodeFrom.asExpr() =
nodeTo.asExpr().(CfgNodes::ExprNodes::ParenthesizedExprCfgNode).getLastExpr()
}
cached
@@ -217,7 +220,7 @@ abstract class ReturnNode extends Node {
private module ReturnNodes {
/**
* A data-flow node that represents an expression returned by a callable,
* either using a (`yield`) `return` statement or an expression body (`=>`).
* either using an explict `return` statement or as the expression of a method body.
*/
class ExprReturnNode extends ReturnNode, ExprNode {
ExprReturnNode() {
@@ -240,7 +243,7 @@ abstract class OutNode extends Node {
private module OutNodes {
/**
* A data-flow node that reads a value returned directly by a callable,
* either via a C# call or a CIL call.
* either via a call or a `yield` of a block.
*/
class ExprOutNode extends OutNode, ExprNode {
private DataFlowCall call;
@@ -297,8 +300,7 @@ predicate compatibleTypes(DataFlowType t1, DataFlowType t2) { any() }
* an update to the field.
*
* Nodes corresponding to AST elements, for example `ExprNode`, usually refer
* to the value before the update with the exception of `ObjectCreation`,
* which represents the value after the constructor has run.
* to the value before the update.
*/
abstract class PostUpdateNode extends Node {
/** Gets the node before the state update. */
@@ -355,7 +357,10 @@ predicate isImmutableOrUnobservable(Node n) { none() }
*/
predicate isUnreachableInCall(Node n, DataFlowCall call) { none() }
class BarrierGuard extends AstNode {
/**
* A guard that validates some expression.
*/
class BarrierGuard extends Expr {
BarrierGuard() { none() }
Node getAGuardedNode() { none() }