@@ -176,6 +176,49 @@ private module Cached {
176176 )
177177 }
178178
179+ /**
180+ * Holds if there is flow for a captured variable from the enclosing scope into a block.
181+ * ```rb
182+ * foo = 0
183+ * bar {
184+ * puts foo
185+ * }
186+ * ```
187+ */
188+ cached
189+ predicate captureFlowIn ( Definition def , Definition entry ) {
190+ exists ( LocalVariable v , BasicBlock bb , int i |
191+ ssaDefReachesRead ( v , def , bb , i ) and
192+ capturedCallRead ( bb , i , v ) and
193+ exists ( BasicBlock bb2 , int i2 |
194+ capturedEntryWrite ( bb2 , i2 , v ) and
195+ entry .definesAt ( v , bb2 , i2 )
196+ )
197+ )
198+ }
199+
200+ /**
201+ * Holds if there is outgoinh flow for a captured variable that is updated in a block.
202+ * ```rb
203+ * foo = 0
204+ * bar {
205+ * foo += 10
206+ * }
207+ * puts foo
208+ * ```
209+ */
210+ cached
211+ predicate captureFlowOut ( Definition def , Definition exit ) {
212+ exists ( LocalVariable v , BasicBlock bb , int i |
213+ ssaDefReachesRead ( v , def , bb , i ) and
214+ capturedExitRead ( bb , i , v ) and
215+ exists ( BasicBlock bb2 , int i2 |
216+ capturedCallWrite ( bb2 , i2 , v ) and
217+ exit .definesAt ( v , bb2 , i2 )
218+ )
219+ )
220+ }
221+
179222 cached
180223 Definition phiHasInputFromBlock ( PhiNode phi , BasicBlock bb ) {
181224 phiHasInputFromBlock ( phi , result , bb )
0 commit comments