mirror of
https://github.com/github/codeql.git
synced 2026-04-23 07:45:17 +02:00
Rust: Add a few control flow tree classes
This commit is contained in:
@@ -1,11 +1,12 @@
|
||||
private import rust
|
||||
private import codeql.util.Boolean
|
||||
private import codeql.rust.controlflow.ControlFlowGraph
|
||||
private import rust
|
||||
private import SuccessorType
|
||||
private import SuccessorTypes
|
||||
|
||||
private newtype TCompletion =
|
||||
TSimpleCompletion() or
|
||||
TBooleanCompletion(boolean b) { b in [false, true] } or
|
||||
TBooleanCompletion(Boolean b) or
|
||||
TReturnCompletion()
|
||||
|
||||
/** A completion of a statement or an expression. */
|
||||
@@ -82,3 +83,12 @@ class ReturnCompletion extends TReturnCompletion, Completion {
|
||||
|
||||
override string toString() { result = "return" }
|
||||
}
|
||||
|
||||
/** Hold if `c` represents normal evaluation of a statement or an expression. */
|
||||
predicate completionIsNormal(Completion c) { c instanceof NormalCompletion }
|
||||
|
||||
/** Hold if `c` represents simple and normal evaluation of a statement or an expression. */
|
||||
predicate completionIsSimple(Completion c) { c instanceof SimpleCompletion }
|
||||
|
||||
/** Holds if `c` is a valid completion for `n`. */
|
||||
predicate completionIsValidFor(Completion c, AstNode n) { c.isValidFor(n) }
|
||||
|
||||
@@ -1 +1,47 @@
|
||||
private import rust
|
||||
import ControlFlowGraphImplSpecific::CfgImpl
|
||||
import Completion
|
||||
|
||||
class CallTree extends StandardPostOrderTree instanceof Call {
|
||||
override ControlFlowTree getChildNode(int i) { result = super.getArg(i) }
|
||||
}
|
||||
|
||||
class BinaryOpTree extends StandardPostOrderTree instanceof BinaryOp {
|
||||
override ControlFlowTree getChildNode(int i) {
|
||||
i = 0 and result = super.getLhs()
|
||||
or
|
||||
i = 1 and result = super.getRhs()
|
||||
}
|
||||
}
|
||||
|
||||
class IfTree extends PostOrderTree instanceof If {
|
||||
override predicate first(AstNode node) { first(super.getCondition(), node) }
|
||||
|
||||
override predicate propagatesAbnormal(AstNode child) { none() }
|
||||
|
||||
override predicate succ(AstNode pred, AstNode succ, Completion c) {
|
||||
// Edges from the condition to each branch
|
||||
last(super.getCondition(), pred, c) and
|
||||
(
|
||||
first(super.getThen(), succ) and c.(BooleanCompletion).getValue() = true
|
||||
or
|
||||
first(super.getElse(), succ) and c.(BooleanCompletion).getValue() = false
|
||||
)
|
||||
or
|
||||
// An edge from the then branch to the last node
|
||||
last(super.getThen(), pred, c) and
|
||||
succ = this and
|
||||
completionIsSimple(c)
|
||||
or
|
||||
// An edge from the else branch to the last node
|
||||
last(super.getElse(), pred, c) and
|
||||
succ = this and
|
||||
completionIsSimple(c)
|
||||
}
|
||||
}
|
||||
|
||||
class LetTree extends StandardPostOrderTree instanceof Let {
|
||||
override ControlFlowTree getChildNode(int i) { i = 0 and result = super.getExpr() }
|
||||
}
|
||||
|
||||
class LiteralTree extends LeafTree instanceof Literal { }
|
||||
|
||||
@@ -11,11 +11,11 @@ module CfgInput implements InputSig<Rust::Location> {
|
||||
|
||||
class Completion = C::Completion;
|
||||
|
||||
predicate completionIsNormal(Completion c) { c instanceof C::NormalCompletion }
|
||||
predicate completionIsNormal = C::completionIsNormal/1;
|
||||
|
||||
predicate completionIsSimple(Completion c) { c instanceof C::SimpleCompletion }
|
||||
predicate completionIsSimple = C::completionIsSimple/1;
|
||||
|
||||
predicate completionIsValidFor(Completion c, AstNode e) { c.isValidFor(e) }
|
||||
predicate completionIsValidFor = C::completionIsValidFor/2;
|
||||
|
||||
/** An AST node with an associated control-flow graph. */
|
||||
class CfgScope = Scope::CfgScope;
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
private import codeql.util.Boolean
|
||||
|
||||
cached
|
||||
newtype TSuccessorType =
|
||||
TSuccessorSuccessor() or
|
||||
TBooleanSuccessor(boolean b) { b in [false, true] } or
|
||||
TBooleanSuccessor(Boolean b) or
|
||||
TReturnSuccessor()
|
||||
|
||||
/** The type of a control flow successor. */
|
||||
|
||||
Reference in New Issue
Block a user