@@ -104,67 +104,67 @@ class LocalSourceNode extends Node {
104104 }
105105
106106 /**
107- * DEPRECATED. Use `TypeTrackingNode::track` instead.
108- *
109107 * Gets a node that this node may flow to using one heap and/or interprocedural step.
110108 *
111109 * See `TypeTracker` for more details about how to use this.
112110 */
113111 pragma [ inline]
114- deprecated LocalSourceNode track ( TypeTracker t2 , TypeTracker t ) { t = t2 .step ( this , result ) }
112+ LocalSourceNode track ( TypeTracker t2 , TypeTracker t ) { t = t2 .step ( this , result ) }
115113
116114 /**
117- * DEPRECATED. Use `TypeTrackingNode::backtrack` instead.
118- *
119115 * Gets a node that may flow into this one using one heap and/or interprocedural step.
120116 *
121117 * See `TypeBackTracker` for more details about how to use this.
122118 */
123119 pragma [ inline]
124- deprecated LocalSourceNode backtrack ( TypeBackTracker t2 , TypeBackTracker t ) {
125- t2 = t .step ( result , this )
126- }
120+ LocalSourceNode backtrack ( TypeBackTracker t2 , TypeBackTracker t ) { t2 = t .step ( result , this ) }
127121}
128122
129123/**
130124 * A node that can be used for type tracking or type back-tracking.
131125 *
132126 * All steps made during type tracking should be between instances of this class.
133127 */
134- class TypeTrackingNode extends Node {
135- TypeTrackingNode ( ) {
136- this instanceof LocalSourceNode
137- or
138- this instanceof ModuleVariableNode
128+ class TypeTrackingNode = LocalSourceNode ;
129+
130+ /** Temporary holding ground for the `TypeTrackingNode` class. */
131+ private module FutureWork {
132+ class FutureTypeTrackingNode extends Node {
133+ FutureTypeTrackingNode ( ) {
134+ this instanceof LocalSourceNode
135+ or
136+ this instanceof ModuleVariableNode
137+ }
138+
139+ /**
140+ * Holds if this node can flow to `nodeTo` in one or more local flow steps.
141+ *
142+ * For `ModuleVariableNode`s, the only "local" step is to the node itself.
143+ * For `LocalSourceNode`s, this is the usual notion of local flow.
144+ */
145+ pragma [ inline]
146+ predicate flowsTo ( Node node ) {
147+ this instanceof ModuleVariableNode and this = node
148+ or
149+ this .( LocalSourceNode ) .flowsTo ( node )
150+ }
151+
152+ /**
153+ * Gets a node that this node may flow to using one heap and/or interprocedural step.
154+ *
155+ * See `TypeTracker` for more details about how to use this.
156+ */
157+ pragma [ inline]
158+ TypeTrackingNode track ( TypeTracker t2 , TypeTracker t ) { t = t2 .step ( this , result ) }
159+
160+ /**
161+ * Gets a node that may flow into this one using one heap and/or interprocedural step.
162+ *
163+ * See `TypeBackTracker` for more details about how to use this.
164+ */
165+ pragma [ inline]
166+ TypeTrackingNode backtrack ( TypeBackTracker t2 , TypeBackTracker t ) { t2 = t .step ( result , this ) }
139167 }
140-
141- /**
142- * Holds if this node can flow to `nodeTo` in one or more local flow steps.
143- *
144- * For `ModuleVariableNode`s, the only "local" step is to the node itself.
145- * For `LocalSourceNode`s, this is the usual notion of local flow.
146- */
147- predicate flowsTo ( Node node ) {
148- this instanceof ModuleVariableNode and this = node
149- or
150- this .( LocalSourceNode ) .flowsTo ( node )
151- }
152-
153- /**
154- * Gets a node that this node may flow to using one heap and/or interprocedural step.
155- *
156- * See `TypeTracker` for more details about how to use this.
157- */
158- pragma [ inline]
159- TypeTrackingNode track ( TypeTracker t2 , TypeTracker t ) { t = t2 .step ( this , result ) }
160-
161- /**
162- * Gets a node that may flow into this one using one heap and/or interprocedural step.
163- *
164- * See `TypeBackTracker` for more details about how to use this.
165- */
166- pragma [ inline]
167- TypeTrackingNode backtrack ( TypeBackTracker t2 , TypeBackTracker t ) { t2 = t .step ( result , this ) }
168168}
169169
170170cached
@@ -179,11 +179,21 @@ private module Cached {
179179 source = sink
180180 or
181181 exists ( Node second |
182- simpleLocalFlowStep ( source , second ) and
183- simpleLocalFlowStep * ( second , sink )
182+ localSourceFlowStep ( source , second ) and
183+ localSourceFlowStep * ( second , sink )
184184 )
185185 }
186186
187+ /**
188+ * Helper predicate for `hasLocalSource`. Removes any steps go to module variable reads, as these
189+ * are already local source nodes in their own right.
190+ */
191+ cached
192+ private predicate localSourceFlowStep ( Node nodeFrom , Node nodeTo ) {
193+ simpleLocalFlowStep ( nodeFrom , nodeTo ) and
194+ not nodeTo = any ( ModuleVariableNode v ) .getARead ( )
195+ }
196+
187197 /**
188198 * Holds if `base` flows to the base of `ref` and `ref` has attribute name `attr`.
189199 */
0 commit comments