@@ -64,7 +64,13 @@ private module Cached {
6464 TExprNode ( CfgNode n , Expr e ) { hasExprNode ( n , e ) } or
6565 TSsaDefinitionNode ( Ssa:: Definition def ) or
6666 TInoutReturnNode ( ParamDecl param ) { modifiableParam ( param ) } or
67- TSummaryNode ( FlowSummary:: SummarizedCallable c , FlowSummaryImpl:: Private:: SummaryNodeState state ) or
67+ TSummaryNode ( FlowSummary:: SummarizedCallable c , FlowSummaryImpl:: Private:: SummaryNodeState state ) {
68+ FlowSummaryImpl:: Private:: summaryNodeRange ( c , state )
69+ } or
70+ TSourceParameterNode ( ParamDecl param ) or
71+ TSummaryParameterNode ( FlowSummary:: SummarizedCallable c , ParameterPosition pos ) {
72+ FlowSummaryImpl:: Private:: summaryParameterNodeRange ( c , pos )
73+ } or
6874 TExprPostUpdateNode ( CfgNode n ) {
6975 // Obviously, the base of setters needs a post-update node
7076 n = any ( PropertySetterCfgNode setter ) .getBase ( )
@@ -93,6 +99,20 @@ private module Cached {
9399 )
94100 }
95101
102+ private SsaDefinitionNode getParameterDefNode ( ParamDecl p ) {
103+ exists ( BasicBlock bb , int i |
104+ bb .getNode ( i ) .getNode ( ) .asAstNode ( ) = p and
105+ result .asDefinition ( ) .definesAt ( _, bb , i )
106+ )
107+ }
108+
109+ /**
110+ * Holds if `nodeFrom` is a parameter node, and `nodeTo` is a corresponding SSA node.
111+ */
112+ private predicate localFlowSsaParamInput ( Node nodeFrom , Node nodeTo ) {
113+ nodeTo = getParameterDefNode ( nodeFrom .( ParameterNode ) .getParameter ( ) )
114+ }
115+
96116 private predicate localFlowStepCommon ( Node nodeFrom , Node nodeTo ) {
97117 exists ( Ssa:: Definition def |
98118 // Step from assignment RHS to def
@@ -117,6 +137,8 @@ private module Cached {
117137 localFlowSsaInput ( nodeFrom , def , nodeTo .asDefinition ( ) )
118138 )
119139 or
140+ localFlowSsaParamInput ( nodeFrom , nodeTo )
141+ or
120142 // flow through `&` (inout argument)
121143 nodeFrom .asExpr ( ) = nodeTo .asExpr ( ) .( InOutExpr ) .getSubExpr ( )
122144 or
@@ -125,6 +147,9 @@ private module Cached {
125147 or
126148 // flow through `!`
127149 nodeFrom .asExpr ( ) = nodeTo .asExpr ( ) .( ForceValueExpr ) .getSubExpr ( )
150+ or
151+ // flow through a flow summary (extension of `SummaryModelCsv`)
152+ FlowSummaryImpl:: Private:: Steps:: summaryLocalStep ( nodeFrom , nodeTo , true )
128153 }
129154
130155 /**
@@ -138,7 +163,10 @@ private module Cached {
138163
139164 /** This is the local flow predicate that is exposed. */
140165 cached
141- predicate localFlowStepImpl ( Node nodeFrom , Node nodeTo ) { localFlowStepCommon ( nodeFrom , nodeTo ) }
166+ predicate localFlowStepImpl ( Node nodeFrom , Node nodeTo ) {
167+ localFlowStepCommon ( nodeFrom , nodeTo ) or
168+ FlowSummaryImpl:: Private:: Steps:: summaryThroughStepValue ( nodeFrom , nodeTo , _)
169+ }
142170
143171 cached
144172 newtype TContentSet = TSingletonContent ( Content c )
@@ -181,17 +209,15 @@ predicate nodeIsHidden(Node n) { none() }
181209private module ParameterNodes {
182210 abstract class ParameterNodeImpl extends NodeImpl {
183211 predicate isParameterOf ( DataFlowCallable c , ParameterPosition pos ) { none ( ) }
212+
213+ /** Gets the parameter associated with this node, if any. */
214+ ParamDecl getParameter ( ) { none ( ) }
184215 }
185216
186- class NormalParameterNode extends ParameterNodeImpl , SsaDefinitionNodeImpl {
217+ class SourceParameterNode extends ParameterNodeImpl , TSourceParameterNode {
187218 ParamDecl param ;
188219
189- NormalParameterNode ( ) {
190- exists ( BasicBlock bb , int i |
191- super .asDefinition ( ) .definesAt ( param , bb , i ) and
192- bb .getNode ( i ) .getNode ( ) .asAstNode ( ) = param
193- )
194- }
220+ SourceParameterNode ( ) { this = TSourceParameterNode ( param ) }
195221
196222 override Location getLocationImpl ( ) { result = param .getLocation ( ) }
197223
@@ -206,6 +232,26 @@ private module ParameterNodes {
206232 }
207233
208234 override DataFlowCallable getEnclosingCallable ( ) { this .isParameterOf ( result , _) }
235+
236+ override ParamDecl getParameter ( ) { result = param }
237+ }
238+
239+ class SummaryParameterNode extends ParameterNodeImpl , TSummaryParameterNode {
240+ FlowSummary:: SummarizedCallable sc ;
241+ ParameterPosition pos ;
242+
243+ SummaryParameterNode ( ) { this = TSummaryParameterNode ( sc , pos ) }
244+
245+ override predicate isParameterOf ( DataFlowCallable c , ParameterPosition p ) {
246+ c .getUnderlyingCallable ( ) = sc and
247+ p = pos
248+ }
249+
250+ override Location getLocationImpl ( ) { result = sc .getLocation ( ) }
251+
252+ override string toStringImpl ( ) { result = "[summary param] " + pos + " in " + sc }
253+
254+ override DataFlowCallable getEnclosingCallable ( ) { this .isParameterOf ( result , _) }
209255 }
210256}
211257
@@ -300,6 +346,14 @@ private module ArgumentNodes {
300346 )
301347 }
302348 }
349+
350+ class SummaryArgumentNode extends SummaryNode , ArgumentNode {
351+ SummaryArgumentNode ( ) { FlowSummaryImpl:: Private:: summaryArgumentNode ( _, this , _) }
352+
353+ override predicate argumentOf ( DataFlowCall call , ArgumentPosition pos ) {
354+ FlowSummaryImpl:: Private:: summaryArgumentNode ( call , this , pos )
355+ }
356+ }
303357}
304358
305359import ArgumentNodes
@@ -370,6 +424,12 @@ private module OutNodes {
370424 }
371425 }
372426
427+ class SummaryOutNode extends OutNode , SummaryNode {
428+ override DataFlowCall getCall ( ReturnKind kind ) {
429+ FlowSummaryImpl:: Private:: summaryOutNode ( result , this , kind )
430+ }
431+ }
432+
373433 class InOutUpdateArgNode extends OutNode , ExprPostUpdateNode {
374434 Argument arg ;
375435
@@ -435,6 +495,8 @@ predicate storeStep(Node node1, ContentSet c, Node node2) {
435495 node2 .( PostUpdateNode ) .getPreUpdateNode ( ) .asExpr ( ) = ref .getBase ( ) and
436496 c .isSingleton ( any ( Content:: FieldContent ct | ct .getField ( ) = ref .getMember ( ) ) )
437497 )
498+ or
499+ FlowSummaryImpl:: Private:: Steps:: summaryStoreStep ( node1 , c , node2 )
438500}
439501
440502predicate isLValue ( Expr e ) { any ( AssignExpr assign ) .getDest ( ) = e }
@@ -556,6 +618,9 @@ predicate lambdaCreation(Node creation, LambdaCallKind kind, DataFlowCallable c)
556618predicate lambdaCall ( DataFlowCall call , LambdaCallKind kind , Node receiver ) {
557619 kind = TLambdaCallKind ( ) and
558620 receiver .asExpr ( ) = call .asCall ( ) .getExpr ( ) .( ApplyExpr ) .getFunction ( )
621+ or
622+ kind = TLambdaCallKind ( ) and
623+ receiver = call .( SummaryCall ) .getReceiver ( )
559624}
560625
561626/** Extra data-flow steps needed for lambda flow analysis. */
0 commit comments