@@ -5,6 +5,7 @@ private import DataFlowDispatch
55private import semmle.code.java.controlflow.Guards
66private import semmle.code.java.dataflow.SSA
77private import ContainerFlow
8+ private import semmle.code.java.dataflow.FlowSummary
89private import FlowSummaryImpl as FlowSummaryImpl
910import DataFlowNodes:: Private
1011
@@ -24,7 +25,7 @@ class ReturnKind extends TReturnKind {
2425 * `kind`.
2526 */
2627OutNode getAnOutNode ( DataFlowCall call , ReturnKind kind ) {
27- result = call . getNode ( ) and
28+ result . getCall ( ) = call and
2829 kind = TNormalReturnKind ( )
2930}
3031
@@ -214,9 +215,55 @@ class DataFlowExpr = Expr;
214215
215216class DataFlowType = RefType ;
216217
217- class DataFlowCall extends Call {
218- /** Gets the data flow node corresponding to this call. */
219- ExprNode getNode ( ) { result .getExpr ( ) = this }
218+ private newtype TDataFlowCall =
219+ TCall ( Call c ) or
220+ TSummaryCall ( SummarizedCallable c , Node receiver ) {
221+ FlowSummaryImpl:: Private:: summaryCallbackRange ( c , receiver )
222+ }
223+
224+ /** A call relevant for data flow. Includes both source calls and synthesized calls. */
225+ class DataFlowCall extends TDataFlowCall {
226+ /** Gets the source (non-synthesized) call this corresponds to, if any. */
227+ Call asCall ( ) { this = TCall ( result ) }
228+
229+ /** Gets the enclosing callable of this call. */
230+ abstract DataFlowCallable getEnclosingCallable ( ) ;
231+
232+ /** Gets a textual representation of this call. */
233+ abstract string toString ( ) ;
234+
235+ /** Gets the location of this call. */
236+ abstract Location getLocation ( ) ;
237+ }
238+
239+ /** A source call, that is, a `Call`. */
240+ class SrcCall extends DataFlowCall , TCall {
241+ Call call ;
242+
243+ SrcCall ( ) { this = TCall ( call ) }
244+
245+ override DataFlowCallable getEnclosingCallable ( ) { result = call .getEnclosingCallable ( ) }
246+
247+ override string toString ( ) { result = call .toString ( ) }
248+
249+ override Location getLocation ( ) { result = call .getLocation ( ) }
250+ }
251+
252+ /** A synthesized call inside a `SummarizedCallable`. */
253+ class SummaryCall extends DataFlowCall , TSummaryCall {
254+ private SummarizedCallable c ;
255+ private Node receiver ;
256+
257+ SummaryCall ( ) { this = TSummaryCall ( c , receiver ) }
258+
259+ /** Gets the data flow node that this call targets. */
260+ Node getReceiver ( ) { result = receiver }
261+
262+ override DataFlowCallable getEnclosingCallable ( ) { result = c }
263+
264+ override string toString ( ) { result = "[summary] call to " + receiver + " in " + c }
265+
266+ override Location getLocation ( ) { result = c .getLocation ( ) }
220267}
221268
222269/** Holds if `e` is an expression that always has the same Boolean value `val`. */
@@ -275,13 +322,23 @@ predicate isImmutableOrUnobservable(Node n) {
275322/** Holds if `n` should be hidden from path explanations. */
276323predicate nodeIsHidden ( Node n ) { n instanceof SummaryNode }
277324
278- class LambdaCallKind = Unit ;
325+ class LambdaCallKind = Method ; // the "apply" method in the functional interface
279326
280327/** Holds if `creation` is an expression that creates a lambda of kind `kind` for `c`. */
281- predicate lambdaCreation ( Node creation , LambdaCallKind kind , DataFlowCallable c ) { none ( ) }
328+ predicate lambdaCreation ( Node creation , LambdaCallKind kind , DataFlowCallable c ) {
329+ exists ( FunctionalExpr func , FunctionalInterface interface |
330+ creation .asExpr ( ) = func and
331+ func .asMethod ( ) = c and
332+ func .getType ( ) .( RefType ) .getSourceDeclaration ( ) = interface and
333+ kind = interface .getRunMethod ( )
334+ )
335+ }
282336
283337/** Holds if `call` is a lambda call of kind `kind` where `receiver` is the lambda expression. */
284- predicate lambdaCall ( DataFlowCall call , LambdaCallKind kind , Node receiver ) { none ( ) }
338+ predicate lambdaCall ( DataFlowCall call , LambdaCallKind kind , Node receiver ) {
339+ receiver = call .( SummaryCall ) .getReceiver ( ) and
340+ getNodeDataFlowType ( receiver ) .getSourceDeclaration ( ) .( FunctionalInterface ) .getRunMethod ( ) = kind
341+ }
285342
286343/** Extra data-flow steps needed for lambda flow analysis. */
287344predicate additionalLambdaFlowStep ( Node nodeFrom , Node nodeTo , boolean preservesValue ) { none ( ) }
0 commit comments