mirror of
https://github.com/github/codeql.git
synced 2025-12-16 16:53:25 +01:00
Shared: Use shared SuccessorType in shared Cfg and BasicBlock libs.
This commit is contained in:
@@ -101,14 +101,8 @@ private module Implementation implements CfgShared::InputSig<Location> {
|
||||
last(scope.(CompositeAction), e, c)
|
||||
}
|
||||
|
||||
predicate successorTypeIsSimple(SuccessorType t) { t instanceof DirectSuccessor }
|
||||
|
||||
predicate successorTypeIsCondition(SuccessorType t) { t instanceof BooleanSuccessor }
|
||||
|
||||
SuccessorType getAMatchingSuccessorType(Completion c) { result = c.getAMatchingSuccessorType() }
|
||||
|
||||
predicate isAbnormalExitType(SuccessorType t) { none() }
|
||||
|
||||
int idOfAstNode(AstNode node) { none() }
|
||||
|
||||
int idOfCfgScope(CfgScope scope) { none() }
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
* Provides classes that specify the conditions under which control flows along a given edge.
|
||||
*/
|
||||
|
||||
private import codeql.controlflow.SuccessorType
|
||||
private import internal.EdgeKindInternal
|
||||
|
||||
private newtype TEdgeKind =
|
||||
@@ -28,6 +29,21 @@ abstract private class EdgeKindImpl extends TEdgeKind {
|
||||
|
||||
final class EdgeKind = EdgeKindImpl;
|
||||
|
||||
private SuccessorType getAMatchingSpecificSuccessorType(EdgeKind k) {
|
||||
result.(BooleanSuccessor).getValue() = true and k instanceof TrueEdge
|
||||
or
|
||||
result.(BooleanSuccessor).getValue() = false and k instanceof FalseEdge
|
||||
or
|
||||
result instanceof ExceptionSuccessor and k instanceof ExceptionEdge
|
||||
}
|
||||
|
||||
SuccessorType getAMatchingSuccessorType(EdgeKind k) {
|
||||
result = getAMatchingSpecificSuccessorType(k)
|
||||
or
|
||||
not exists(getAMatchingSpecificSuccessorType(k)) and
|
||||
result instanceof DirectSuccessor
|
||||
}
|
||||
|
||||
/**
|
||||
* A "goto" edge, representing the unconditional successor of an `Instruction`
|
||||
* or `IRBlock`.
|
||||
|
||||
@@ -265,9 +265,9 @@ private predicate isEntryBlock(TIRBlock block) {
|
||||
}
|
||||
|
||||
module IRCfg implements BB::CfgSig<Language::Location> {
|
||||
class ControlFlowNode = Instruction;
|
||||
private import codeql.controlflow.SuccessorType
|
||||
|
||||
class SuccessorType = EdgeKind;
|
||||
class ControlFlowNode = Instruction;
|
||||
|
||||
final private class FinalIRBlock = IRBlock;
|
||||
|
||||
@@ -280,7 +280,12 @@ module IRCfg implements BB::CfgSig<Language::Location> {
|
||||
|
||||
BasicBlock getASuccessor() { result = super.getASuccessor() }
|
||||
|
||||
BasicBlock getASuccessor(SuccessorType t) { result = super.getSuccessor(t) }
|
||||
BasicBlock getASuccessor(SuccessorType t) {
|
||||
exists(EdgeKind k |
|
||||
result = super.getSuccessor(k) and
|
||||
t = getAMatchingSuccessorType(k)
|
||||
)
|
||||
}
|
||||
|
||||
predicate strictlyDominates(BasicBlock bb) { super.strictlyDominates(bb) }
|
||||
|
||||
|
||||
@@ -265,9 +265,9 @@ private predicate isEntryBlock(TIRBlock block) {
|
||||
}
|
||||
|
||||
module IRCfg implements BB::CfgSig<Language::Location> {
|
||||
class ControlFlowNode = Instruction;
|
||||
private import codeql.controlflow.SuccessorType
|
||||
|
||||
class SuccessorType = EdgeKind;
|
||||
class ControlFlowNode = Instruction;
|
||||
|
||||
final private class FinalIRBlock = IRBlock;
|
||||
|
||||
@@ -280,7 +280,12 @@ module IRCfg implements BB::CfgSig<Language::Location> {
|
||||
|
||||
BasicBlock getASuccessor() { result = super.getASuccessor() }
|
||||
|
||||
BasicBlock getASuccessor(SuccessorType t) { result = super.getSuccessor(t) }
|
||||
BasicBlock getASuccessor(SuccessorType t) {
|
||||
exists(EdgeKind k |
|
||||
result = super.getSuccessor(k) and
|
||||
t = getAMatchingSuccessorType(k)
|
||||
)
|
||||
}
|
||||
|
||||
predicate strictlyDominates(BasicBlock bb) { super.strictlyDominates(bb) }
|
||||
|
||||
|
||||
@@ -265,9 +265,9 @@ private predicate isEntryBlock(TIRBlock block) {
|
||||
}
|
||||
|
||||
module IRCfg implements BB::CfgSig<Language::Location> {
|
||||
class ControlFlowNode = Instruction;
|
||||
private import codeql.controlflow.SuccessorType
|
||||
|
||||
class SuccessorType = EdgeKind;
|
||||
class ControlFlowNode = Instruction;
|
||||
|
||||
final private class FinalIRBlock = IRBlock;
|
||||
|
||||
@@ -280,7 +280,12 @@ module IRCfg implements BB::CfgSig<Language::Location> {
|
||||
|
||||
BasicBlock getASuccessor() { result = super.getASuccessor() }
|
||||
|
||||
BasicBlock getASuccessor(SuccessorType t) { result = super.getSuccessor(t) }
|
||||
BasicBlock getASuccessor(SuccessorType t) {
|
||||
exists(EdgeKind k |
|
||||
result = super.getSuccessor(k) and
|
||||
t = getAMatchingSuccessorType(k)
|
||||
)
|
||||
}
|
||||
|
||||
predicate strictlyDominates(BasicBlock bb) { super.strictlyDominates(bb) }
|
||||
|
||||
|
||||
@@ -346,8 +346,6 @@ private class EntryBasicBlockAlias = EntryBasicBlock;
|
||||
module Cfg implements BB::CfgSig<Location> {
|
||||
class ControlFlowNode = ControlFlow::Node;
|
||||
|
||||
class SuccessorType = ControlFlow::SuccessorType;
|
||||
|
||||
class BasicBlock = BasicBlockAlias;
|
||||
|
||||
class EntryBasicBlock = EntryBasicBlockAlias;
|
||||
|
||||
@@ -79,19 +79,10 @@ private module CfgInput implements CfgShared::InputSig<Location> {
|
||||
Impl::scopeLast(scope, last, c)
|
||||
}
|
||||
|
||||
class SuccessorType = ST::SuccessorType;
|
||||
private class SuccessorType = ST::SuccessorType;
|
||||
|
||||
SuccessorType getAMatchingSuccessorType(Completion c) { result = c.getAMatchingSuccessorType() }
|
||||
|
||||
predicate successorTypeIsSimple(SuccessorType t) { t instanceof ST::DirectSuccessor }
|
||||
|
||||
predicate successorTypeIsCondition(SuccessorType t) { t instanceof ST::ConditionalSuccessor }
|
||||
|
||||
predicate isAbnormalExitType(SuccessorType t) {
|
||||
t instanceof ST::ExceptionSuccessor or
|
||||
t instanceof ST::ExitSuccessor
|
||||
}
|
||||
|
||||
int idOfAstNode(AstNode node) { result = node.getId() }
|
||||
|
||||
int idOfCfgScope(CfgScope node) { result = idOfAstNode(node) }
|
||||
|
||||
@@ -163,8 +163,6 @@ class ConditionBlock extends PreBasicBlock {
|
||||
module PreCfg implements BB::CfgSig<Location> {
|
||||
class ControlFlowNode = ControlFlowElement;
|
||||
|
||||
class SuccessorType = Cfg::SuccessorType;
|
||||
|
||||
class BasicBlock = PreBasicBlock;
|
||||
|
||||
class EntryBasicBlock extends BasicBlock {
|
||||
|
||||
@@ -7,10 +7,9 @@ module;
|
||||
import java
|
||||
import Dominance
|
||||
private import codeql.controlflow.BasicBlock as BB
|
||||
private import codeql.controlflow.SuccessorType
|
||||
|
||||
private module Input implements BB::InputSig<Location> {
|
||||
import codeql.controlflow.SuccessorType
|
||||
|
||||
/** Hold if `t` represents a conditional successor type. */
|
||||
predicate successorTypeIsCondition(SuccessorType t) { none() }
|
||||
|
||||
@@ -96,7 +95,7 @@ class BasicBlock extends BbImpl::BasicBlock {
|
||||
predicate strictlyDominates(BasicBlock bb) { super.strictlyDominates(bb) }
|
||||
|
||||
/** Gets an immediate successor of this basic block of a given type, if any. */
|
||||
BasicBlock getASuccessor(Input::SuccessorType t) { result = super.getASuccessor(t) }
|
||||
BasicBlock getASuccessor(SuccessorType t) { result = super.getASuccessor(t) }
|
||||
|
||||
BasicBlock getASuccessor() { result = super.getASuccessor() }
|
||||
|
||||
@@ -161,8 +160,6 @@ private class BasicBlockAlias = BasicBlock;
|
||||
module Cfg implements BB::CfgSig<Location> {
|
||||
class ControlFlowNode = BbImpl::ControlFlowNode;
|
||||
|
||||
class SuccessorType = BbImpl::SuccessorType;
|
||||
|
||||
class BasicBlock = BasicBlockAlias;
|
||||
|
||||
class EntryBasicBlock extends BasicBlock instanceof BbImpl::EntryBasicBlock { }
|
||||
|
||||
@@ -139,7 +139,7 @@ private predicate isNonFallThroughPredecessor(SwitchCase sc, ControlFlowNode pre
|
||||
)
|
||||
}
|
||||
|
||||
private module SuccessorTypes implements SharedGuards::SuccessorTypesSig<SuccessorType> {
|
||||
private module SuccessorTypes implements SharedGuards::SuccessorTypesSig {
|
||||
import codeql.controlflow.SuccessorType
|
||||
}
|
||||
|
||||
|
||||
@@ -372,16 +372,28 @@ module Public {
|
||||
|
||||
module Cfg implements BB::CfgSig<Location> {
|
||||
private import javascript as Js
|
||||
private import codeql.util.Unit
|
||||
private import codeql.controlflow.SuccessorType
|
||||
|
||||
class ControlFlowNode = Js::ControlFlowNode;
|
||||
|
||||
class SuccessorType = Unit;
|
||||
private predicate conditionSucc(BasicBlock bb1, BasicBlock bb2, boolean branch) {
|
||||
exists(ConditionGuardNode g |
|
||||
bb1 = g.getTest().getBasicBlock() and
|
||||
bb2 = g.getBasicBlock() and
|
||||
branch = g.getOutcome()
|
||||
)
|
||||
}
|
||||
|
||||
class BasicBlock extends FinalBasicBlock {
|
||||
BasicBlock getASuccessor() { result = super.getASuccessor() }
|
||||
|
||||
BasicBlock getASuccessor(SuccessorType t) { result = super.getASuccessor() and exists(t) }
|
||||
BasicBlock getASuccessor(SuccessorType t) {
|
||||
conditionSucc(this, result, t.(BooleanSuccessor).getValue())
|
||||
or
|
||||
result = super.getASuccessor() and
|
||||
t instanceof DirectSuccessor and
|
||||
not conditionSucc(this, result, _)
|
||||
}
|
||||
|
||||
predicate strictlyDominates(BasicBlock bb) {
|
||||
this.(ReachableBasicBlock).strictlyDominates(bb)
|
||||
|
||||
@@ -1259,9 +1259,9 @@ private class ControlFlowNodeAlias = ControlFlowNode;
|
||||
final private class FinalBasicBlock = BasicBlock;
|
||||
|
||||
module Cfg implements BB::CfgSig<Location> {
|
||||
class ControlFlowNode = ControlFlowNodeAlias;
|
||||
private import codeql.controlflow.SuccessorType
|
||||
|
||||
class SuccessorType = Unit;
|
||||
class ControlFlowNode = ControlFlowNodeAlias;
|
||||
|
||||
class BasicBlock extends FinalBasicBlock {
|
||||
// Note `PY:BasicBlock` does not have a `getLocation`.
|
||||
@@ -1275,7 +1275,24 @@ module Cfg implements BB::CfgSig<Location> {
|
||||
|
||||
BasicBlock getASuccessor() { result = super.getASuccessor() }
|
||||
|
||||
BasicBlock getASuccessor(SuccessorType t) { result = super.getASuccessor() and exists(t) }
|
||||
private BasicBlock getANonDirectSuccessor(SuccessorType t) {
|
||||
result = this.getATrueSuccessor() and
|
||||
t.(BooleanSuccessor).getValue() = true
|
||||
or
|
||||
result = this.getAFalseSuccessor() and
|
||||
t.(BooleanSuccessor).getValue() = false
|
||||
or
|
||||
result = this.getAnExceptionalSuccessor() and
|
||||
t instanceof ExceptionSuccessor
|
||||
}
|
||||
|
||||
BasicBlock getASuccessor(SuccessorType t) {
|
||||
result = this.getANonDirectSuccessor(t)
|
||||
or
|
||||
result = super.getASuccessor() and
|
||||
t instanceof DirectSuccessor and
|
||||
not result = this.getANonDirectSuccessor(_)
|
||||
}
|
||||
|
||||
predicate strictlyDominates(BasicBlock bb) { super.strictlyDominates(bb) }
|
||||
|
||||
|
||||
@@ -301,13 +301,9 @@ private class BasicBlockAlias = BasicBlock;
|
||||
|
||||
private class EntryBasicBlockAlias = EntryBasicBlock;
|
||||
|
||||
private class SuccessorTypeAlias = SuccessorType;
|
||||
|
||||
module Cfg implements BB::CfgSig<Location> {
|
||||
class ControlFlowNode = CfgNode;
|
||||
|
||||
class SuccessorType = SuccessorTypeAlias;
|
||||
|
||||
class BasicBlock = BasicBlockAlias;
|
||||
|
||||
class EntryBasicBlock = EntryBasicBlockAlias;
|
||||
|
||||
@@ -46,19 +46,10 @@ private module CfgInput implements CfgShared::InputSig<Location> {
|
||||
scope.(Impl::CfgScopeImpl).exit(last, c)
|
||||
}
|
||||
|
||||
class SuccessorType = Cfg::SuccessorType;
|
||||
private class SuccessorType = Cfg::SuccessorType;
|
||||
|
||||
SuccessorType getAMatchingSuccessorType(Completion c) { result = c.getAMatchingSuccessorType() }
|
||||
|
||||
predicate successorTypeIsSimple(SuccessorType t) { t instanceof Cfg::DirectSuccessor }
|
||||
|
||||
predicate successorTypeIsCondition(SuccessorType t) { t instanceof Cfg::ConditionalSuccessor }
|
||||
|
||||
predicate isAbnormalExitType(SuccessorType t) {
|
||||
t instanceof Cfg::ExceptionSuccessor or
|
||||
t instanceof Cfg::ExitSuccessor
|
||||
}
|
||||
|
||||
private predicate id(Ruby::AstNode node1, Ruby::AstNode node2) { node1 = node2 }
|
||||
|
||||
private predicate idOf(Ruby::AstNode node, int id) = equivalenceRelation(id/2)(node, id)
|
||||
|
||||
@@ -21,8 +21,6 @@ final class JoinPredecessorBasicBlock = BasicBlocksImpl::JoinPredecessorBasicBlo
|
||||
module Cfg implements BB::CfgSig<Location> {
|
||||
class ControlFlowNode = ControlFlowGraph::CfgNode;
|
||||
|
||||
class SuccessorType = ControlFlowGraph::SuccessorType;
|
||||
|
||||
class BasicBlock = BasicBlocksImpl::BasicBlock;
|
||||
|
||||
class EntryBasicBlock = BasicBlocksImpl::EntryBasicBlock;
|
||||
|
||||
@@ -29,19 +29,11 @@ private module CfgInput implements InputSig<Location> {
|
||||
Stages::CfgStage::ref()
|
||||
}
|
||||
|
||||
class SuccessorType = Cfg::SuccessorType;
|
||||
private class SuccessorType = Cfg::SuccessorType;
|
||||
|
||||
/** Gets a successor type that matches completion `c`. */
|
||||
SuccessorType getAMatchingSuccessorType(Completion c) { result = c.getAMatchingSuccessorType() }
|
||||
|
||||
/**
|
||||
* Hold if `c` represents simple (normal) evaluation of a statement or an expression.
|
||||
*/
|
||||
predicate successorTypeIsSimple(SuccessorType t) { t instanceof Cfg::DirectSuccessor }
|
||||
|
||||
/** Holds if `t` is an abnormal exit type out of a CFG scope. */
|
||||
predicate isAbnormalExitType(SuccessorType t) { none() }
|
||||
|
||||
/** Hold if `t` represents a conditional successor type. */
|
||||
predicate successorTypeIsCondition(SuccessorType t) { t instanceof Cfg::BooleanSuccessor }
|
||||
|
||||
|
||||
@@ -9,17 +9,12 @@ overlay[local?]
|
||||
module;
|
||||
|
||||
private import codeql.util.Location
|
||||
private import SuccessorType
|
||||
|
||||
/** Provides the language-specific input specification. */
|
||||
signature module InputSig<LocationSig Location> {
|
||||
/** The type of a control flow successor. */
|
||||
class SuccessorType {
|
||||
/** Gets a textual representation of this successor type. */
|
||||
string toString();
|
||||
}
|
||||
|
||||
/** Hold if `t` represents a conditional successor type. */
|
||||
predicate successorTypeIsCondition(SuccessorType t);
|
||||
default predicate successorTypeIsCondition(SuccessorType t) { t instanceof ConditionalSuccessor }
|
||||
|
||||
/** A delineated part of the AST with its own CFG. */
|
||||
class CfgScope;
|
||||
@@ -61,12 +56,6 @@ signature module CfgSig<LocationSig Location> {
|
||||
Location getLocation();
|
||||
}
|
||||
|
||||
/** The type of a control flow successor. */
|
||||
class SuccessorType {
|
||||
/** Gets a textual representation of this successor type. */
|
||||
string toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* A basic block, that is, a maximal straight-line sequence of control flow nodes
|
||||
* without branches or joins.
|
||||
@@ -180,8 +169,6 @@ module Make<LocationSig Location, InputSig<Location> Input> implements CfgSig<Lo
|
||||
|
||||
class ControlFlowNode = Input::Node;
|
||||
|
||||
class SuccessorType = Input::SuccessorType;
|
||||
|
||||
/**
|
||||
* A basic block, that is, a maximal straight-line sequence of control flow nodes
|
||||
* without branches or joins.
|
||||
|
||||
@@ -8,6 +8,7 @@ module;
|
||||
private import codeql.util.Location
|
||||
private import codeql.util.FileSystem
|
||||
private import codeql.util.Void
|
||||
private import SuccessorType
|
||||
|
||||
/** Provides the language-specific input specification. */
|
||||
signature module InputSig<LocationSig Location> {
|
||||
@@ -59,26 +60,11 @@ signature module InputSig<LocationSig Location> {
|
||||
/** Holds if `scope` is exited when `last` finishes with completion `c`. */
|
||||
predicate scopeLast(CfgScope scope, AstNode last, Completion c);
|
||||
|
||||
/** A type of a control flow successor. */
|
||||
class SuccessorType {
|
||||
/** Gets a textual representation of this successor type. */
|
||||
string toString();
|
||||
}
|
||||
|
||||
/** Gets a successor type that matches completion `c`. */
|
||||
SuccessorType getAMatchingSuccessorType(Completion c);
|
||||
|
||||
/**
|
||||
* Hold if `t` represents simple (normal) evaluation of a statement or an
|
||||
* expression.
|
||||
*/
|
||||
predicate successorTypeIsSimple(SuccessorType t);
|
||||
|
||||
/** Hold if `t` represents a conditional successor type. */
|
||||
predicate successorTypeIsCondition(SuccessorType t);
|
||||
|
||||
/** Holds if `t` is an abnormal exit type out of a CFG scope. */
|
||||
predicate isAbnormalExitType(SuccessorType t);
|
||||
default predicate successorTypeIsCondition(SuccessorType t) { t instanceof ConditionalSuccessor }
|
||||
|
||||
/**
|
||||
* Gets an `id` of `node`. This is used to order the predecessors of a join
|
||||
@@ -522,7 +508,7 @@ module MakeWithSplitting<
|
||||
private predicate succEntrySplits(CfgScope pred, AstNode succ, Splits succSplits, SuccessorType t) {
|
||||
exists(int rnk |
|
||||
scopeFirst(pred, succ) and
|
||||
successorTypeIsSimple(t) and
|
||||
t instanceof DirectSuccessor and
|
||||
succEntrySplitsFromRank(pred, succ, succSplits, rnk)
|
||||
|
|
||||
rnk = 0 and
|
||||
@@ -1016,7 +1002,7 @@ module MakeWithSplitting<
|
||||
exists(CfgScope scope |
|
||||
pred = TAnnotatedExitNode(scope, _) and
|
||||
result = TExitNode(scope) and
|
||||
successorTypeIsSimple(t)
|
||||
t instanceof DirectSuccessor
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1320,7 +1306,7 @@ module MakeWithSplitting<
|
||||
label =
|
||||
strictconcat(SuccessorType t, string s |
|
||||
succ = getASuccessor(pred, t) and
|
||||
if successorTypeIsSimple(t) then s = "" else s = t.toString()
|
||||
if t instanceof DirectSuccessor then s = "" else s = t.toString()
|
||||
|
|
||||
s, ", " order by s
|
||||
)
|
||||
@@ -1590,8 +1576,6 @@ module MakeWithSplitting<
|
||||
private class NodeAlias = Node;
|
||||
|
||||
private module BasicBlockInputSig implements BB::InputSig<Location> {
|
||||
class SuccessorType = Input::SuccessorType;
|
||||
|
||||
predicate successorTypeIsCondition = Input::successorTypeIsCondition/1;
|
||||
|
||||
class CfgScope = CfgScopeAlias;
|
||||
|
||||
@@ -51,16 +51,17 @@ overlay[local?]
|
||||
module;
|
||||
|
||||
private import codeql.controlflow.BasicBlock as BB
|
||||
private import codeql.controlflow.SuccessorType as ST
|
||||
private import codeql.util.Boolean
|
||||
private import codeql.util.Location
|
||||
private import codeql.util.Unit
|
||||
|
||||
signature class TypSig;
|
||||
|
||||
signature module SuccessorTypesSig<TypSig SuccessorType> {
|
||||
class ExceptionSuccessor extends SuccessorType;
|
||||
signature module SuccessorTypesSig {
|
||||
class ExceptionSuccessor extends ST::SuccessorType;
|
||||
|
||||
class ConditionalSuccessor extends SuccessorType {
|
||||
class ConditionalSuccessor extends ST::SuccessorType {
|
||||
/** Gets the Boolean value of this successor. */
|
||||
boolean getValue();
|
||||
}
|
||||
@@ -204,8 +205,7 @@ signature module InputSig<LocationSig Location, TypSig ControlFlowNode, TypSig B
|
||||
|
||||
/** Provides guards-related predicates and classes. */
|
||||
module Make<
|
||||
LocationSig Location, BB::CfgSig<Location> Cfg,
|
||||
SuccessorTypesSig<Cfg::SuccessorType> SuccessorTypes,
|
||||
LocationSig Location, BB::CfgSig<Location> Cfg, SuccessorTypesSig SuccessorTypes,
|
||||
InputSig<Location, Cfg::ControlFlowNode, Cfg::BasicBlock> Input>
|
||||
{
|
||||
private module Cfg_ = Cfg;
|
||||
@@ -320,7 +320,7 @@ module Make<
|
||||
}
|
||||
|
||||
private predicate exceptionBranchPoint(BasicBlock bb1, BasicBlock normalSucc, BasicBlock excSucc) {
|
||||
exists(SuccessorType norm, ExceptionSuccessor exc |
|
||||
exists(ST::SuccessorType norm, ExceptionSuccessor exc |
|
||||
bb1.getASuccessor(norm) = normalSucc and
|
||||
bb1.getASuccessor(exc) = excSucc and
|
||||
normalSucc != excSucc and
|
||||
|
||||
@@ -339,3 +339,9 @@ class RetrySuccessor extends JumpSuccessor, TRetrySuccessor {
|
||||
class JavaYieldSuccessor extends JumpSuccessor, TJavaYieldSuccessor {
|
||||
override string toString() { result = "yield" }
|
||||
}
|
||||
|
||||
/** Holds if `t` is an abnormal exit type out of a CFG scope. */
|
||||
predicate isAbnormalExitType(SuccessorType t) {
|
||||
t instanceof ExceptionSuccessor or
|
||||
t instanceof ExitSuccessor
|
||||
}
|
||||
|
||||
@@ -119,13 +119,9 @@ private class EntryBasicBlockAlias = EntryBasicBlock;
|
||||
|
||||
private class ControlFlowNodeAlias = ControlFlowNode;
|
||||
|
||||
private class SuccessorTypeAlias = SuccessorType;
|
||||
|
||||
module Cfg implements BB::CfgSig<Location> {
|
||||
class ControlFlowNode = ControlFlowNodeAlias;
|
||||
|
||||
class SuccessorType = SuccessorTypeAlias;
|
||||
|
||||
class BasicBlock = BasicBlockAlias;
|
||||
|
||||
class EntryBasicBlock = EntryBasicBlockAlias;
|
||||
|
||||
@@ -48,29 +48,11 @@ module CfgInput implements InputSig<Location> {
|
||||
|
||||
CfgScope getCfgScope(AstNode n) { result = scopeOfAst(n.asAstNode()) }
|
||||
|
||||
class SuccessorType = Cfg::SuccessorType;
|
||||
private class SuccessorType = Cfg::SuccessorType;
|
||||
|
||||
/** Gets a successor type that matches completion `c`. */
|
||||
SuccessorType getAMatchingSuccessorType(Completion c) { result = c.getAMatchingSuccessorType() }
|
||||
|
||||
/**
|
||||
* Hold if `c` represents simple (normal) evaluation of a statement or an
|
||||
* expression.
|
||||
*/
|
||||
predicate successorTypeIsSimple(SuccessorType t) { t instanceof Cfg::DirectSuccessor }
|
||||
|
||||
/** Holds if `t` is an abnormal exit type out of a CFG scope. */
|
||||
predicate isAbnormalExitType(SuccessorType t) { t instanceof Cfg::ExceptionSuccessor }
|
||||
|
||||
/** Hold if `t` represents a conditional successor type. */
|
||||
predicate successorTypeIsCondition(SuccessorType t) {
|
||||
t instanceof Cfg::BooleanSuccessor or
|
||||
t instanceof Cfg::BreakSuccessor or
|
||||
t instanceof Cfg::ContinueSuccessor or
|
||||
t instanceof Cfg::MatchingSuccessor or
|
||||
t instanceof Cfg::EmptinessSuccessor
|
||||
}
|
||||
|
||||
/** Holds if `first` is first executed when entering `scope`. */
|
||||
predicate scopeFirst(CfgScope scope, AstNode first) {
|
||||
scope.(Impl::CfgScope::Range_).entry(first)
|
||||
|
||||
Reference in New Issue
Block a user