@@ -46,18 +46,19 @@ module LocalFlow {
4646 )
4747 }
4848
49+ /** Gets the SSA definition node corresponding to parameter `p`. */
50+ SsaDefinitionNode getParameterDefNode ( NamedParameter p ) {
51+ exists ( BasicBlock bb , int i |
52+ bb .getNode ( i ) .getNode ( ) = p .getDefiningAccess ( ) and
53+ result .getDefinition ( ) .definesAt ( _, bb , i )
54+ )
55+ }
56+
4957 /**
5058 * Holds if there is a local flow step from `nodeFrom` to `nodeTo` involving
5159 * SSA definition `def`.
5260 */
5361 predicate localSsaFlowStep ( Ssa:: Definition def , Node nodeFrom , Node nodeTo ) {
54- // Flow from parameter into SSA definition
55- exists ( BasicBlock bb , int i |
56- bb .getNode ( i ) .getNode ( ) =
57- nodeFrom .( ParameterNode ) .getParameter ( ) .( NamedParameter ) .getDefiningAccess ( ) and
58- nodeTo .( SsaDefinitionNode ) .getDefinition ( ) .definesAt ( _, bb , i )
59- )
60- or
6162 // Flow from assignment into SSA definition
6263 def .( Ssa:: WriteDefinition ) .assigns ( nodeFrom .asExpr ( ) ) and
6364 nodeTo .( SsaDefinitionNode ) .getDefinition ( ) = def
@@ -145,19 +146,14 @@ private module Cached {
145146 class TParameterNode =
146147 TNormalParameterNode or TBlockParameterNode or TSelfParameterNode or TSummaryParameterNode ;
147148
148- /**
149- * This is the local flow predicate that is shared between local data flow
150- * and global data flow.
151- */
152- cached
153- predicate simpleLocalFlowStepCommon ( Node nodeFrom , Node nodeTo ) {
154- LocalFlow:: localSsaFlowStep ( _, nodeFrom , nodeTo )
149+ private predicate defaultValueFlow ( NamedParameter p , ExprNode e ) {
150+ p .( OptionalParameter ) .getDefaultValue ( ) = e .getExprNode ( ) .getExpr ( )
155151 or
156- nodeTo . ( ParameterNode ) . getParameter ( ) . ( OptionalParameter ) . getDefaultValue ( ) =
157- nodeFrom . asExpr ( ) . getExpr ( )
158- or
159- nodeTo . ( ParameterNode ) . getParameter ( ) . ( KeywordParameter ) . getDefaultValue ( ) =
160- nodeFrom . asExpr ( ) . getExpr ( )
152+ p . ( KeywordParameter ) . getDefaultValue ( ) = e . getExprNode ( ) . getExpr ( )
153+ }
154+
155+ private predicate localFlowStepCommon ( Node nodeFrom , Node nodeTo ) {
156+ LocalFlow :: localSsaFlowStep ( _ , nodeFrom , nodeTo )
161157 or
162158 nodeFrom .( SelfParameterNode ) .getMethod ( ) = nodeTo .asExpr ( ) .getExpr ( ) .getEnclosingCallable ( ) and
163159 nodeTo .asExpr ( ) .getExpr ( ) instanceof Self
@@ -194,19 +190,46 @@ private module Cached {
194190
195191 /**
196192 * This is the local flow predicate that is used as a building block in global
197- * data flow. It excludes SSA flow through instance fields, as flow through fields
198- * is handled by the global data-flow library, but includes various other steps
199- * that are only relevant for global flow.
193+ * data flow.
200194 */
201195 cached
202196 predicate simpleLocalFlowStep ( Node nodeFrom , Node nodeTo ) {
203- simpleLocalFlowStepCommon ( nodeFrom , nodeTo )
197+ localFlowStepCommon ( nodeFrom , nodeTo )
198+ or
199+ defaultValueFlow ( nodeTo .( ParameterNode ) .getParameter ( ) , nodeFrom )
200+ or
201+ nodeTo = LocalFlow:: getParameterDefNode ( nodeFrom .( ParameterNode ) .getParameter ( ) )
204202 or
205203 nodeTo .( SynthReturnNode ) .getAnInput ( ) = nodeFrom
206204 or
207205 FlowSummaryImpl:: Private:: Steps:: summaryLocalStep ( nodeFrom , nodeTo , true )
208206 }
209207
208+ /** This is the local flow predicate that is exposed. */
209+ cached
210+ predicate localFlowStepImpl ( Node nodeFrom , Node nodeTo ) {
211+ localFlowStepCommon ( nodeFrom , nodeTo )
212+ or
213+ defaultValueFlow ( nodeTo .( ParameterNode ) .getParameter ( ) , nodeFrom )
214+ or
215+ nodeTo = LocalFlow:: getParameterDefNode ( nodeFrom .( ParameterNode ) .getParameter ( ) )
216+ or
217+ // Simple flow through library code is included in the exposed local
218+ // step relation, even though flow is technically inter-procedural
219+ FlowSummaryImpl:: Private:: Steps:: summaryThroughStep ( nodeFrom , nodeTo , true )
220+ }
221+
222+ /** This is the local flow predicate that is used in type tracking. */
223+ cached
224+ predicate localFlowStepTypeTracker ( Node nodeFrom , Node nodeTo ) {
225+ localFlowStepCommon ( nodeFrom , nodeTo )
226+ or
227+ exists ( NamedParameter p |
228+ defaultValueFlow ( p , nodeFrom ) and
229+ nodeTo = LocalFlow:: getParameterDefNode ( p )
230+ )
231+ }
232+
210233 cached
211234 predicate isLocalSourceNode ( Node n ) {
212235 n instanceof ParameterNode
@@ -217,7 +240,7 @@ private module Cached {
217240 // and we can remove this case.
218241 n instanceof SelfArgumentNode
219242 or
220- not simpleLocalFlowStepCommon + ( any ( Node e |
243+ not localFlowStepTypeTracker + ( any ( Node e |
221244 e instanceof ExprNode
222245 or
223246 e instanceof ParameterNode
@@ -538,7 +561,7 @@ private module ReturnNodes {
538561
539562 SynthReturnNode ( ) { this = TSynthReturnNode ( scope , kind ) }
540563
541- /** Get a syntactic return node that flows into this synthetic node. */
564+ /** Gets a syntactic return node that flows into this synthetic node. */
542565 ReturningNode getAnInput ( ) {
543566 result .( NodeImpl ) .getCfgScope ( ) = scope and
544567 result .getKind ( ) = kind
0 commit comments