@@ -210,23 +210,22 @@ module Ssa {
210210 final CfgNode getWriteAccess ( ) { result = write }
211211
212212 /**
213- * Holds if this SSA definition assigns `value` to the underlying variable.
213+ * Holds if this SSA definition assigns `value` to the underlying
214+ * variable.
214215 *
215- * This is either a direct assignment, `x = value`, or an assignment via
216- * simple pattern matching
217- *
218- * ```rb
219- * case value
220- * in Foo => x then ...
221- * in y => then ...
222- * end
223- * ```
216+ * This is either the value in a direct assignment, `x = value`, or in a
217+ * `let` statement, `let x = value`. Note that patterns on the lhs. are
218+ * currently not supported.
224219 */
225220 predicate assigns ( ExprCfgNode value ) {
226- exists ( AssignmentExprCfgNode ae , BasicBlock bb , int i |
227- this .definesAt ( _, bb , i ) and
228- ae .getLhs ( ) = bb .getNode ( i ) and
229- value = ae .getRhs ( )
221+ exists ( AssignmentExprCfgNode ae |
222+ ae .getLhs ( ) = write and
223+ ae .getRhs ( ) = value
224+ )
225+ or
226+ exists ( LetStmtCfgNode ls |
227+ ls .getPat ( ) = write and
228+ ls .getInitializer ( ) = value
230229 )
231230 }
232231
@@ -338,4 +337,37 @@ module Ssa {
338337
339338 override Location getLocation ( ) { result = this .getBasicBlock ( ) .getLocation ( ) }
340339 }
340+
341+ /**
342+ * An SSA definition inserted at a call that may update the value of a captured
343+ * variable. For example, in
344+ *
345+ * ```rust
346+ * fn capture_mut() {
347+ * let mut y = 0;
348+ * (0..5).for_each(|x| {
349+ * y += x
350+ * });
351+ * y
352+ * }
353+ * ```
354+ *
355+ * a definition for `y` is inserted at the call to `for_each`.
356+ */
357+ private class CapturedCallDefinition extends Definition , SsaImpl:: UncertainWriteDefinition {
358+ CapturedCallDefinition ( ) {
359+ exists ( Variable v , BasicBlock bb , int i |
360+ this .definesAt ( v , bb , i ) and
361+ SsaImpl:: capturedCallWrite ( _, bb , i , v )
362+ )
363+ }
364+
365+ /**
366+ * Gets the immediately preceding definition. Since this update is uncertain,
367+ * the value from the preceding definition might still be valid.
368+ */
369+ final Definition getPriorDefinition ( ) { result = SsaImpl:: uncertainWriteDefinitionInput ( this ) }
370+
371+ override string toString ( ) { result = "<captured exit> " + this .getSourceVariable ( ) }
372+ }
341373}
0 commit comments