Add Ssa::WriteDefinition::assigns/1 predicate

This commit is contained in:
Tom Hvitved
2021-06-18 10:32:18 +02:00
parent 78db1bf045
commit 7cc02e6d00
3 changed files with 19 additions and 17 deletions

View File

@@ -160,15 +160,15 @@ abstract private class ExprChildMapping extends Expr {
/** Provides classes for control-flow nodes that wrap AST expressions. */
module ExprNodes {
// TODO: Add more classes
private class AssignmentExprChildMapping extends ExprChildMapping, Assignment {
private class AssignExprChildMapping extends ExprChildMapping, AssignExpr {
override predicate relevantChild(Expr e) { e = this.getAnOperand() }
}
/** A control-flow node that wraps an `Assignment` AST expression. */
class AssignmentCfgNode extends ExprCfgNode {
override AssignmentExprChildMapping e;
/** A control-flow node that wraps an `AssignExpr` AST expression. */
class AssignExprCfgNode extends ExprCfgNode {
override AssignExprChildMapping e;
final override Assignment getExpr() { result = ExprCfgNode.super.getExpr() }
final override AssignExpr getExpr() { result = ExprCfgNode.super.getExpr() }
/** Gets the LHS of this assignment. */
final ExprCfgNode getLhs() { e.hasCfgChild(e.getLeftOperand(), this, result) }
@@ -177,11 +177,6 @@ module ExprNodes {
final ExprCfgNode getRhs() { e.hasCfgChild(e.getRightOperand(), this, result) }
}
/** A control-flow node that wraps an `AssignExpr` AST expression. */
class AssignExprCfgNode extends AssignmentCfgNode {
AssignExprCfgNode() { this.getExpr() instanceof AssignExpr }
}
private class OperationExprChildMapping extends ExprChildMapping, Operation {
override predicate relevantChild(Expr e) { e = this.getAnOperand() }
}

View File

@@ -203,6 +203,18 @@ module Ssa {
/** Gets the underlying write access. */
final VariableWriteAccess getWriteAccess() { result = write }
/**
* Holds if this SSA definition represents a direct assignment of `value`
* to the underlying variable.
*/
predicate assigns(CfgNodes::ExprCfgNode value) {
exists(CfgNodes::ExprNodes::AssignExprCfgNode a, BasicBlock bb, int i |
this.definesAt(_, bb, i) and
a = bb.getNode(i) and
value = a.getRhs()
)
}
final override string toString() { result = Definition.super.toString() }
final override Location getLocation() { result = this.getControlFlowNode().getLocation() }

View File

@@ -58,13 +58,8 @@ module LocalFlow {
)
or
// Flow from assignment into SSA definition
exists(CfgNodes::ExprNodes::AssignmentCfgNode a, BasicBlock bb, int i |
def.definesAt(_, bb, i) and
a = bb.getNode(i) and
a.getExpr() instanceof AssignExpr and
nodeFrom.asExpr() = a.getRhs() and
nodeTo.(SsaDefinitionNode).getDefinition() = def
)
def.(Ssa::WriteDefinition).assigns(nodeFrom.asExpr()) and
nodeTo.(SsaDefinitionNode).getDefinition() = def
or
// Flow from SSA definition to first read
def = nodeFrom.(SsaDefinitionNode).getDefinition() and