|
2 | 2 |
|
3 | 3 | private import codeql.actions.Cfg as Cfg |
4 | 4 |
|
5 | | -class BasicBlock = Cfg::BasicBlock; |
| 5 | +/** |
| 6 | + * A basic block, that is, a maximal straight-line sequence of control flow nodes |
| 7 | + * without branches or joins. |
| 8 | + */ |
| 9 | +class BasicBlock extends Cfg::BasicBlock { |
| 10 | + /** Gets an immediate successor of this basic block, if any. */ |
| 11 | + BasicBlock getASuccessor() { result = super.getASuccessor() } |
6 | 12 |
|
7 | | -class EntryBasicBlock = Cfg::EntryBasicBlock; |
| 13 | + /** Gets an immediate successor of this basic block of a given type, if any. */ |
| 14 | + BasicBlock getASuccessor(Cfg::SuccessorType t) { result = super.getASuccessor(t) } |
| 15 | + |
| 16 | + /** Gets an immediate predecessor of this basic block, if any. */ |
| 17 | + BasicBlock getAPredecessor() { result = super.getAPredecessor() } |
| 18 | + |
| 19 | + /** Gets an immediate predecessor of this basic block of a given type, if any. */ |
| 20 | + BasicBlock getAPredecessor(Cfg::SuccessorType t) { result = super.getAPredecessor(t) } |
| 21 | + |
| 22 | + /** Gets the control flow node at a specific (zero-indexed) position in this basic block. */ |
| 23 | + Cfg::Node getNode(int pos) { result = super.getNode(pos) } |
| 24 | + |
| 25 | + /** Gets a control flow node in this basic block. */ |
| 26 | + Cfg::Node getANode() { result = super.getANode() } |
| 27 | + |
| 28 | + /** Gets the first control flow node in this basic block. */ |
| 29 | + Cfg::Node getFirstNode() { result = super.getFirstNode() } |
| 30 | + |
| 31 | + /** Gets the last control flow node in this basic block. */ |
| 32 | + Cfg::Node getLastNode() { result = super.getLastNode() } |
| 33 | + |
| 34 | + predicate immediatelyDominates(BasicBlock bb) { super.immediatelyDominates(bb) } |
| 35 | + |
| 36 | + predicate strictlyDominates(BasicBlock bb) { super.strictlyDominates(bb) } |
| 37 | + |
| 38 | + predicate dominates(BasicBlock bb) { super.dominates(bb) } |
| 39 | + |
| 40 | + predicate inDominanceFrontier(BasicBlock df) { super.inDominanceFrontier(df) } |
| 41 | + |
| 42 | + BasicBlock getImmediateDominator() { result = super.getImmediateDominator() } |
| 43 | + |
| 44 | + predicate strictlyPostDominates(BasicBlock bb) { super.strictlyPostDominates(bb) } |
| 45 | + |
| 46 | + predicate postDominates(BasicBlock bb) { super.postDominates(bb) } |
| 47 | +} |
| 48 | + |
| 49 | +/** |
| 50 | + * An entry basic block, that is, a basic block whose first node is |
| 51 | + * an entry node. |
| 52 | + */ |
| 53 | +class EntryBasicBlock extends BasicBlock, Cfg::EntryBasicBlock { } |
| 54 | + |
| 55 | +/** |
| 56 | + * An annotated exit basic block, that is, a basic block that contains an |
| 57 | + * annotated exit node. |
| 58 | + */ |
| 59 | +class AnnotatedExitBasicBlock extends BasicBlock { |
| 60 | + AnnotatedExitBasicBlock() { this.getANode() instanceof Cfg::AnnotatedExitNode } |
| 61 | + |
| 62 | + /** Holds if this block represents a normal exit. */ |
| 63 | + final predicate isNormal() { this.getANode() instanceof Cfg::NormalExitNode } |
| 64 | +} |
| 65 | + |
| 66 | +/** |
| 67 | + * An exit basic block, that is, a basic block whose last node is |
| 68 | + * an exit node. |
| 69 | + */ |
| 70 | +class ExitBasicBlock extends BasicBlock { |
| 71 | + ExitBasicBlock() { this.getLastNode() instanceof Cfg::ExitNode } |
| 72 | +} |
| 73 | + |
| 74 | +/** A basic block with more than one predecessor. */ |
| 75 | +class JoinBlock extends BasicBlock { |
| 76 | + JoinBlock() { strictcount(this.getFirstNode().getAPredecessor()) > 1 } |
| 77 | + |
| 78 | + /** |
| 79 | + * Gets the `i`th predecessor of this join block, with respect to some |
| 80 | + * arbitrary order. |
| 81 | + */ |
| 82 | + JoinBlockPredecessor getJoinBlockPredecessor(int i) { none() } |
| 83 | +} |
| 84 | + |
| 85 | +/** A basic block that is an immediate predecessor of a join block. */ |
| 86 | +class JoinBlockPredecessor extends BasicBlock { |
| 87 | + JoinBlockPredecessor() { this.getASuccessor() instanceof JoinBlock } |
| 88 | +} |
| 89 | + |
| 90 | +/** A basic block that terminates in a condition, splitting the subsequent control flow. */ |
| 91 | +class ConditionBlock extends BasicBlock { |
| 92 | + ConditionBlock() { |
| 93 | + exists(this.getLastNode().getASuccessor(any(Cfg::BooleanSuccessor successor))) |
| 94 | + } |
| 95 | + |
| 96 | + /** |
| 97 | + * Holds if basic block `succ` is immediately controlled by this basic |
| 98 | + * block with conditional value `s`. |
| 99 | + */ |
| 100 | + predicate immediatelyControls(BasicBlock succ, Cfg::BooleanSuccessor s) { |
| 101 | + succ = this.getASuccessor(s) and |
| 102 | + forall(BasicBlock pred | pred = succ.getAPredecessor() and pred != this | succ.dominates(pred)) |
| 103 | + } |
| 104 | + |
| 105 | + /** |
| 106 | + * Holds if basic block `controlled` is controlled by this basic block with |
| 107 | + * conditional value `s`. |
| 108 | + */ |
| 109 | + predicate controls(BasicBlock controlled, Cfg::BooleanSuccessor s) { |
| 110 | + exists(BasicBlock succ | this.immediatelyControls(succ, s) and succ.dominates(controlled)) |
| 111 | + } |
| 112 | +} |
0 commit comments