@@ -126,39 +126,47 @@ class ControlFlowElement extends ExprOrStmtParent, @control_flow_element {
126126 * ```
127127 *
128128 * does not work.
129+ *
130+ * `cb` records all of the possible condition blocks for this control flow element
131+ * that a path from the callable entry point to `succ` may go through.
129132 */
130133 pragma [ nomagic]
131- private predicate immediatelyControlsBlockSplit ( BasicBlock succ , ConditionalSuccessor s ) {
132- exists ( ConditionBlock cb | this .immediatelyControlsBlockSplit0 ( cb , succ , s ) |
133- forall ( BasicBlock pred , SuccessorType t |
134- this .immediatelyControlsBlockSplit1 ( cb , succ , s , pred , t )
135- |
136- this .immediatelyControlsBlockSplit2 ( cb , succ , s , pred , t )
137- )
134+ private predicate immediatelyControlsBlockSplit (
135+ BasicBlock succ , ConditionalSuccessor s , ConditionBlock cb
136+ ) {
137+ this .immediatelyControlsBlockSplit0 ( cb , succ , s ) and
138+ forall ( BasicBlock pred , SuccessorType t |
139+ this .immediatelyControlsBlockSplit1 ( cb , succ , s , pred , t )
140+ |
141+ this .immediatelyControlsBlockSplit2 ( cb , succ , s , pred , t )
138142 )
139143 }
140144
141145 pragma [ noinline]
142- private predicate controlsJoinBlockPredecessor ( JoinBlock controlled , ConditionalSuccessor s , int i ) {
143- this .controlsBlockSplit ( controlled .getJoinBlockPredecessor ( i ) , s )
146+ private predicate controlsJoinBlockPredecessor (
147+ JoinBlock controlled , ConditionalSuccessor s , int i , ConditionBlock cb
148+ ) {
149+ this .controlsBlockSplit ( controlled .getJoinBlockPredecessor ( i ) , s , cb )
144150 }
145151
146152 private predicate controlsJoinBlockSplit ( JoinBlock controlled , ConditionalSuccessor s , int i ) {
147153 i = - 1 and
148- this .controlsJoinBlockPredecessor ( controlled , s , _)
154+ this .controlsJoinBlockPredecessor ( controlled , s , _, _ )
149155 or
150156 this .controlsJoinBlockSplit ( controlled , s , i - 1 ) and
151157 (
152- this .controlsJoinBlockPredecessor ( controlled , s , i )
158+ this .controlsJoinBlockPredecessor ( controlled , s , i , _ )
153159 or
154160 controlled .dominates ( controlled .getJoinBlockPredecessor ( i ) )
155161 )
156162 }
157163
158164 cached
159- private predicate controlsBlockSplit ( BasicBlock controlled , ConditionalSuccessor s ) {
165+ private predicate controlsBlockSplit (
166+ BasicBlock controlled , ConditionalSuccessor s , ConditionBlock cb
167+ ) {
160168 Stages:: GuardsStage:: forceCachingInSameStage ( ) and
161- this .immediatelyControlsBlockSplit ( controlled , s )
169+ this .immediatelyControlsBlockSplit ( controlled , s , cb )
162170 or
163171 // Equivalent with
164172 //
@@ -178,10 +186,11 @@ class ControlFlowElement extends ExprOrStmtParent, @control_flow_element {
178186 last = max ( int i | exists ( controlled .( JoinBlock ) .getJoinBlockPredecessor ( i ) ) )
179187 |
180188 this .controlsJoinBlockSplit ( controlled , s , last )
181- )
189+ ) and
190+ this .controlsJoinBlockPredecessor ( controlled , s , _, cb )
182191 or
183192 not controlled instanceof JoinBlock and
184- this .controlsBlockSplit ( controlled .getAPredecessor ( ) , s )
193+ this .controlsBlockSplit ( controlled .getAPredecessor ( ) , s , cb )
185194 }
186195
187196 /**
@@ -200,16 +209,25 @@ class ControlFlowElement extends ExprOrStmtParent, @control_flow_element {
200209 * ```
201210 *
202211 * as control flow splitting is taken into account.
212+ *
213+ * `cb` records all of the possible condition blocks for this control flow element
214+ * that a path from the callable entry point to `controlled` may go through.
203215 */
204- predicate controlsBlock ( BasicBlock controlled , ConditionalSuccessor s ) {
205- this .controlsBlockSplit ( controlled , s )
216+ predicate controlsBlock ( BasicBlock controlled , ConditionalSuccessor s , ConditionBlock cb ) {
217+ this .controlsBlockSplit ( controlled , s , cb )
206218 or
207- exists ( ConditionBlock cb | cb .getLastNode ( ) = this .getAControlFlowNode ( ) |
208- cb .controls ( controlled , s )
209- )
219+ cb .getLastNode ( ) = this .getAControlFlowNode ( ) and
220+ cb .controls ( controlled , s )
221+ }
222+
223+ /** DEPRECATED: Use `controlsBlock/3` instead. */
224+ deprecated predicate controlsBlock ( BasicBlock controlled , ConditionalSuccessor s ) {
225+ this .controlsBlock ( controlled , s , _)
210226 }
211227
212228 /**
229+ * DEPRECATED.
230+ *
213231 * Holds if control flow element `controlled` is controlled by this control flow
214232 * element with conditional value `s`. That is, `controlled` can only be reached
215233 * from the callable entry point by going via the `s` edge out of this element.
@@ -227,7 +245,7 @@ class ControlFlowElement extends ExprOrStmtParent, @control_flow_element {
227245 */
228246 // potentially very large predicate, so must be inlined
229247 pragma [ inline]
230- predicate controlsElement ( ControlFlowElement controlled , ConditionalSuccessor s ) {
248+ deprecated predicate controlsElement ( ControlFlowElement controlled , ConditionalSuccessor s ) {
231249 forex ( BasicBlock bb | bb = controlled .getAControlFlowNode ( ) .getBasicBlock ( ) |
232250 this .controlsBlock ( bb , s )
233251 )
0 commit comments