Skip to content

Commit

Permalink
Merge pull request #17817 from hvitved/rust/cfg-scope-callable
Browse files Browse the repository at this point in the history
Rust: Use `Callable` to define `CfgScope`
  • Loading branch information
hvitved authored Oct 23, 2024
2 parents 24ae548 + f72af4f commit 086e0c6
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 44 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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> {
Expand All @@ -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) {
Expand Down Expand Up @@ -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() }

Expand Down
38 changes: 15 additions & 23 deletions rust/ql/lib/codeql/rust/controlflow/internal/Scope.qll
Original file line number Diff line number Diff line change
Expand Up @@ -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) }
}

/**
Expand Down

0 comments on commit 086e0c6

Please sign in to comment.