Rust: Use Callable to define CfgScope

This commit is contained in:
Tom Hvitved
2024-10-21 14:04:50 +02:00
parent e9adbf231f
commit f72af4f1f3
2 changed files with 20 additions and 44 deletions

View File

@@ -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() }

View File

@@ -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) }
}
/**