@@ -34,7 +34,7 @@ module ControlFlow {
3434
3535 /** Holds if this control flow node has conditional successors. */
3636 predicate isCondition ( ) {
37- exists ( getASuccessorByType ( any ( SuccessorTypes :: ConditionalSuccessor e ) ) )
37+ exists ( getASuccessorByType ( any ( ConditionalSuccessor e ) ) )
3838 }
3939
4040 /** Gets the basic block that this control flow node belongs to. */
@@ -216,7 +216,7 @@ module ControlFlow {
216216 * on line 1.
217217 */
218218 Node getATrueSuccessor ( ) {
219- result = getASuccessorByType ( any ( SuccessorTypes :: BooleanSuccessor t | t .getValue ( ) = true ) )
219+ result = getASuccessorByType ( any ( BooleanSuccessor t | t .getValue ( ) = true ) )
220220 }
221221
222222 /**
@@ -236,7 +236,7 @@ module ControlFlow {
236236 * on line 1.
237237 */
238238 Node getAFalseSuccessor ( ) {
239- result = getASuccessorByType ( any ( SuccessorTypes :: BooleanSuccessor t | t .getValue ( ) = false ) )
239+ result = getASuccessorByType ( any ( BooleanSuccessor t | t .getValue ( ) = false ) )
240240 }
241241
242242 /**
@@ -256,7 +256,7 @@ module ControlFlow {
256256 * `x` on line 1.
257257 */
258258 Node getANullSuccessor ( ) {
259- result = getASuccessorByType ( any ( SuccessorTypes :: NullnessSuccessor t | t .isNull ( ) ) )
259+ result = getASuccessorByType ( any ( NullnessSuccessor t | t .isNull ( ) ) )
260260 }
261261
262262 /**
@@ -275,7 +275,7 @@ module ControlFlow {
275275 * of the node `x`.
276276 */
277277 Node getANonNullSuccessor ( ) {
278- result = getASuccessorByType ( any ( SuccessorTypes :: NullnessSuccessor t | not t .isNull ( ) ) )
278+ result = getASuccessorByType ( any ( NullnessSuccessor t | not t .isNull ( ) ) )
279279 }
280280
281281 /** Holds if this node has more than one predecessor. */
@@ -775,6 +775,7 @@ module ControlFlow {
775775 }
776776 }
777777 }
778+ private import SuccessorTypes
778779
779780 /**
780781 * INTERNAL: Do not use.
@@ -2382,6 +2383,118 @@ module ControlFlow {
23822383 }
23832384 import Successor
23842385
2386+ /**
2387+ * Provides a basic block implementation on control flow elements. That is,
2388+ * a "pre-CFG" where the nodes are (unsplit) control flow elements and the
2389+ * successor releation is `succ = succ(pred, _)`.
2390+ *
2391+ * The logic is duplicated from the implementation in `BasicBlocks.qll`, and
2392+ * being an internal class, all predicate documentation has been removed.
2393+ */
2394+ module PreBasicBlocks {
2395+ private predicate startsBB ( ControlFlowElement cfe ) {
2396+ not cfe = succ ( _, _) and
2397+ (
2398+ exists ( succ ( cfe , _) )
2399+ or
2400+ exists ( succExit ( cfe , _) )
2401+ )
2402+ or
2403+ strictcount ( ControlFlowElement pred , Completion c | cfe = succ ( pred , c ) ) > 1
2404+ or
2405+ exists ( ControlFlowElement pred , int i |
2406+ cfe = succ ( pred , _) and
2407+ i = count ( ControlFlowElement succ , Completion c | succ = succ ( pred , c ) ) |
2408+ i > 1
2409+ or
2410+ i = 1 and
2411+ exists ( succExit ( pred , _) )
2412+ )
2413+ }
2414+
2415+ private predicate intraBBSucc ( ControlFlowElement pred , ControlFlowElement succ ) {
2416+ succ = succ ( pred , _) and
2417+ not startsBB ( succ )
2418+ }
2419+
2420+ predicate bbIndex ( ControlFlowElement bbStart , ControlFlowElement cfe , int i ) =
2421+ shortestDistances( startsBB / 1 , intraBBSucc / 2 ) ( bbStart , cfe , i )
2422+
2423+ private predicate succBB ( PreBasicBlock pred , PreBasicBlock succ ) {
2424+ succ = pred .getASuccessor ( )
2425+ }
2426+
2427+ private predicate entryBB ( PreBasicBlock bb ) {
2428+ bb = succEntry ( _)
2429+ }
2430+
2431+ private predicate bbIDominates ( PreBasicBlock dom , PreBasicBlock bb ) =
2432+ idominance( entryBB / 1 , succBB / 2 ) ( _, dom , bb )
2433+
2434+ class PreBasicBlock extends ControlFlowElement {
2435+ PreBasicBlock ( ) {
2436+ startsBB ( this )
2437+ }
2438+
2439+ PreBasicBlock getASuccessor ( ) {
2440+ result = succ ( this .getLastElement ( ) , _)
2441+ }
2442+
2443+ PreBasicBlock getAPredecessor ( ) {
2444+ result .getASuccessor ( ) = this
2445+ }
2446+
2447+ ControlFlowElement getElement ( int pos ) {
2448+ bbIndex ( this , result , pos )
2449+ }
2450+
2451+ ControlFlowElement getAnElement ( ) {
2452+ result = this .getElement ( _)
2453+ }
2454+
2455+ ControlFlowElement getFirstElement ( ) {
2456+ result = this
2457+ }
2458+
2459+ ControlFlowElement getLastElement ( ) {
2460+ result = this .getElement ( length ( ) - 1 )
2461+ }
2462+
2463+ int length ( ) {
2464+ result = strictcount ( getAnElement ( ) )
2465+ }
2466+
2467+ predicate strictlyDominates ( PreBasicBlock bb ) {
2468+ bbIDominates + ( this , bb )
2469+ }
2470+
2471+ predicate dominates ( PreBasicBlock bb ) {
2472+ bb = this
2473+ or
2474+ this .strictlyDominates ( bb )
2475+ }
2476+
2477+ predicate inDominanceFrontier ( PreBasicBlock df ) {
2478+ this .dominatesPredecessor ( df ) and
2479+ not this .strictlyDominates ( df )
2480+ }
2481+
2482+ private predicate dominatesPredecessor ( PreBasicBlock df ) {
2483+ this .dominates ( df .getAPredecessor ( ) )
2484+ }
2485+ }
2486+
2487+ class ConditionBlock extends PreBasicBlock {
2488+ ConditionBlock ( ) {
2489+ strictcount ( ConditionalCompletion c |
2490+ exists ( succ ( this .getLastElement ( ) , c ) )
2491+ or
2492+ exists ( succExit ( this .getLastElement ( ) , c ) )
2493+ ) > 1
2494+ }
2495+ }
2496+ }
2497+
23852498 /**
23862499 * Provides classes and predicates relevant for splitting the control flow graph.
23872500 */
@@ -2464,15 +2577,15 @@ module ControlFlow {
24642577 */
24652578 class FinallySplitType extends SuccessorType {
24662579 FinallySplitType ( ) {
2467- not this instanceof SuccessorTypes :: ConditionalSuccessor
2580+ not this instanceof ConditionalSuccessor
24682581 }
24692582
24702583 /** Holds if this split type matches entry into a `finally` block with completion `c`. */
24712584 predicate isSplitForEntryCompletion ( Completion c ) {
24722585 if c instanceof NormalCompletion then
24732586 // If the entry into the `finally` block completes with any normal completion,
24742587 // it simply means normal execution after the `finally` block
2475- this instanceof SuccessorTypes :: NormalSuccessor
2588+ this instanceof NormalSuccessor
24762589 else
24772590 this .matchesCompletion ( c )
24782591 }
@@ -2561,7 +2674,7 @@ module ControlFlow {
25612674 }
25622675
25632676 override string toString ( ) {
2564- if type instanceof SuccessorTypes :: NormalSuccessor then
2677+ if type instanceof NormalSuccessor then
25652678 result = ""
25662679 else
25672680 result = "finally: " + type .toString ( )
@@ -2603,12 +2716,12 @@ module ControlFlow {
26032716 or
26042717 not c instanceof NormalCompletion
26052718 or
2606- type instanceof SuccessorTypes :: NormalSuccessor
2719+ type instanceof NormalSuccessor
26072720 ) else (
26082721 // Finally block can exit with completion `c` derived from try/catch
26092722 // block: must match this split
26102723 type .matchesCompletion ( c ) and
2611- not type instanceof SuccessorTypes :: NormalSuccessor
2724+ not type instanceof NormalSuccessor
26122725 )
26132726 )
26142727 }
@@ -2895,7 +3008,7 @@ module ControlFlow {
28953008 pragma [ noinline]
28963009 predicate succEntrySplits ( Callable pred , ControlFlowElement succ , Splits succSplits , SuccessorType t ) {
28973010 succ = succEntry ( pred ) and
2898- t instanceof SuccessorTypes :: NormalSuccessor and
3011+ t instanceof NormalSuccessor and
28993012 succSplits = TSplitsNil ( ) // initially no splits
29003013 }
29013014
0 commit comments