@@ -52,6 +52,24 @@ private module Cached {
5252 )
5353 }
5454
55+ /** Gets the summary resulting from prepending `step` to this type-tracking summary. */
56+ cached
57+ TypeBackTracker prepend ( TypeBackTracker tbt , StepSummary step ) {
58+ exists ( Boolean hasReturn , string content | tbt = MkTypeBackTracker ( hasReturn , content ) |
59+ step = LevelStep ( ) and result = tbt
60+ or
61+ step = CallStep ( ) and hasReturn = false and result = tbt
62+ or
63+ step = ReturnStep ( ) and result = MkTypeBackTracker ( true , content )
64+ or
65+ exists ( string p |
66+ step = LoadStep ( p ) and content = "" and result = MkTypeBackTracker ( hasReturn , p )
67+ )
68+ or
69+ step = StoreStep ( content ) and result = MkTypeBackTracker ( hasReturn , "" )
70+ )
71+ }
72+
5573 /**
5674 * Gets the summary that corresponds to having taken a forwards
5775 * heap and/or intra-procedural step from `nodeFrom` to `nodeTo`.
@@ -365,19 +383,7 @@ class TypeBackTracker extends TTypeBackTracker {
365383 TypeBackTracker ( ) { this = MkTypeBackTracker ( hasReturn , content ) }
366384
367385 /** Gets the summary resulting from prepending `step` to this type-tracking summary. */
368- TypeBackTracker prepend ( StepSummary step ) {
369- step = LevelStep ( ) and result = this
370- or
371- step = CallStep ( ) and hasReturn = false and result = this
372- or
373- step = ReturnStep ( ) and result = MkTypeBackTracker ( true , content )
374- or
375- exists ( string p |
376- step = LoadStep ( p ) and content = "" and result = MkTypeBackTracker ( hasReturn , p )
377- )
378- or
379- step = StoreStep ( content ) and result = MkTypeBackTracker ( hasReturn , "" )
380- }
386+ TypeBackTracker prepend ( StepSummary step ) { result = prepend ( this , step ) }
381387
382388 /** Gets a textual representation of this summary. */
383389 string toString ( ) {
@@ -459,6 +465,19 @@ class TypeBackTracker extends TTypeBackTracker {
459465 simpleLocalFlowStep ( nodeFrom , nodeTo ) and
460466 this = result
461467 }
468+
469+ /**
470+ * Gets a forwards summary that is compatible with this backwards summary.
471+ * That is, if this summary describes the steps needed to back-track a value
472+ * from `sink` to `mid`, and the result is a valid summary of the steps needed
473+ * to track a value from `source` to `mid`, then the value from `source` may
474+ * also flow to `sink`.
475+ */
476+ TypeTracker getACompatibleTypeTracker ( ) {
477+ exists ( boolean hasCall | result = MkTypeTracker ( hasCall , content ) |
478+ hasCall = false or this .hasReturn ( ) = false
479+ )
480+ }
462481}
463482
464483/** Provides predicates for implementing custom `TypeBackTracker`s. */
0 commit comments