mirror of
https://github.com/github/codeql.git
synced 2026-04-18 13:34:02 +02:00
Rust: Use Callable to define CfgScope
This commit is contained in:
@@ -40,10 +40,12 @@ private module CfgInput implements InputSig<Location> {
|
||||
predicate successorTypeIsCondition(SuccessorType t) { t instanceof Cfg::BooleanSuccessor }
|
||||
|
||||
/** Holds if `first` is first executed when entering `scope`. */
|
||||
predicate scopeFirst(CfgScope scope, AstNode first) { scope.scopeFirst(first) }
|
||||
predicate scopeFirst(CfgScope scope, AstNode first) {
|
||||
first(scope.(CfgScopeTree).getFirstChildNode(), first)
|
||||
}
|
||||
|
||||
/** Holds if `scope` is exited when `last` finishes with completion `c`. */
|
||||
predicate scopeLast(CfgScope scope, AstNode last, Completion c) { scope.scopeLast(last, c) }
|
||||
predicate scopeLast(CfgScope scope, AstNode last, Completion c) { last(scope.getBody(), last, c) }
|
||||
}
|
||||
|
||||
private module CfgSplittingInput implements SplittingInputSig<Location, CfgInput> {
|
||||
@@ -65,7 +67,7 @@ private module CfgImpl =
|
||||
|
||||
import CfgImpl
|
||||
|
||||
class FunctionTree extends StandardTree, Function {
|
||||
class CfgScopeTree extends StandardTree, Scope::CfgScope {
|
||||
override predicate first(AstNode first) { first = this }
|
||||
|
||||
override predicate last(AstNode last, Completion c) {
|
||||
@@ -319,24 +321,6 @@ module ExprTrees {
|
||||
override AstNode getChildNode(int i) { i = 0 and result = super.getExpr() }
|
||||
}
|
||||
|
||||
class ClosureExprTree extends StandardTree, ClosureExpr {
|
||||
override predicate first(AstNode first) { first = this }
|
||||
|
||||
override predicate last(AstNode last, Completion c) {
|
||||
last = this and
|
||||
completionIsValidFor(c, this)
|
||||
}
|
||||
|
||||
override predicate propagatesAbnormal(AstNode child) { none() }
|
||||
|
||||
override AstNode getChildNode(int i) {
|
||||
result = this.getParamList().getParam(i)
|
||||
or
|
||||
i = this.getParamList().getNumberOfParams() and
|
||||
result = this.getBody()
|
||||
}
|
||||
}
|
||||
|
||||
class ContinueExprTree extends LeafTree, ContinueExpr {
|
||||
override predicate last(AstNode last, Completion c) { none() }
|
||||
|
||||
|
||||
@@ -3,34 +3,26 @@ private import Completion
|
||||
private import ControlFlowGraphImpl
|
||||
private import codeql.rust.elements.internal.generated.ParentChild
|
||||
|
||||
abstract class CfgScope extends AstNode {
|
||||
/** Holds if `first` is executed first when entering scope. */
|
||||
abstract predicate scopeFirst(AstNode first);
|
||||
|
||||
/** Holds if scope is exited when `last` finishes with completion `c`. */
|
||||
abstract predicate scopeLast(AstNode last, Completion c);
|
||||
}
|
||||
|
||||
final class FunctionScope extends CfgScope, Function {
|
||||
FunctionScope() {
|
||||
/**
|
||||
* A control-flow graph (CFG) scope.
|
||||
*
|
||||
* A CFG scope is a callable with a body.
|
||||
*/
|
||||
class CfgScope extends Callable {
|
||||
CfgScope() {
|
||||
// A function without a body corresponds to a trait method signature and
|
||||
// should not have a CFG scope.
|
||||
this.hasBody()
|
||||
this.(Function).hasBody()
|
||||
or
|
||||
this instanceof ClosureExpr
|
||||
}
|
||||
|
||||
override predicate scopeFirst(AstNode node) {
|
||||
first(this.(FunctionTree).getFirstChildNode(), node)
|
||||
/** Gets the body of this callable. */
|
||||
AstNode getBody() {
|
||||
result = this.(Function).getBody()
|
||||
or
|
||||
result = this.(ClosureExpr).getBody()
|
||||
}
|
||||
|
||||
override predicate scopeLast(AstNode node, Completion c) { last(this.getBody(), node, c) }
|
||||
}
|
||||
|
||||
final class ClosureScope extends CfgScope, ClosureExpr {
|
||||
override predicate scopeFirst(AstNode node) {
|
||||
first(this.(ExprTrees::ClosureExprTree).getFirstChildNode(), node)
|
||||
}
|
||||
|
||||
override predicate scopeLast(AstNode node, Completion c) { last(this.getBody(), node, c) }
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user