@@ -91,6 +91,9 @@ newtype TDataFlowNode =
9191 TLocalVariableRefNode ( AstNode repr , LocalVariable var , VariableRefKind kind ) {
9292 performsVariableAccess ( repr , var , kind , _)
9393 } or
94+ TReturnNode ( DataFlowCallable callable ) {
95+ not exists ( callable .asSummarizedCallable ( ) ) // represented by TSummaryNode
96+ } or
9497 TCallableNode ( DataFlowCallable callable ) or
9598 TImplicitParameterNode ( DataFlowCallable callable , ImplicitParameterPosition pos ) {
9699 not exists ( callable .asSummarizedCallable ( ) ) // represented by TSummaryNode
@@ -104,7 +107,7 @@ newtype TDataFlowNode =
104107
105108class TDataFlowNodeStage1 =
106109 TValueNode or TStrictlyIncomingValue or TExprPostUpdateNode or TLocalVariableRefNode or
107- TCallableNode or TImplicitParameterNode or TImplicitArgumentNode ;
110+ TReturnNode or TCallableNode or TImplicitParameterNode or TImplicitArgumentNode ;
108111
109112class TDataFlowNodeStage2 = TDataFlowNodeStage1 or TLocalSsaNode ;
110113
@@ -152,6 +155,16 @@ class BuilderNode extends TDataFlowNodeStage1 {
152155 /** Holds if this represents the updated state of the value returned by `expr` after it has been mutated by the surrounding assignment or call. */
153156 predicate isPostUpdate ( Expr expr ) { this = TExprPostUpdateNode ( expr ) }
154157
158+ /** Holds if this node is the canonical representative for the return value of `callable`. */
159+ predicate isReturnNode ( Callable callable ) { this .isReturnNodeEx ( toDataFlowCallable ( callable ) ) }
160+
161+ /**
162+ * Holds if this node is the canonical representative for the return value of `callable`.
163+ *
164+ * Note that this does not hold for the return node in a summarized callable.
165+ */
166+ predicate isReturnNodeEx ( DataFlowCallable callable ) { this = TReturnNode ( callable ) }
167+
155168 /** Holds if this node represents an implicit parameter of `callable`. */
156169 predicate isImplicitParameter ( DataFlowCallable callable , ImplicitParameterPosition pos ) {
157170 this = TImplicitParameterNode ( callable , pos )
@@ -258,6 +271,11 @@ class BuilderNode extends TDataFlowNodeStage1 {
258271 result = "[callable] " + callable .toString ( )
259272 )
260273 or
274+ exists ( DataFlowCallable callable |
275+ this .isReturnNodeEx ( callable ) and
276+ result = "[return] " + callable .toString ( )
277+ )
278+ or
261279 exists ( DataFlowCall call , ArgumentPosition pos |
262280 this .isImplicitArgument ( call , pos , false ) and
263281 result = "[" + pos + " arg] " + call .toString ( )
@@ -284,6 +302,11 @@ class BuilderNode extends TDataFlowNodeStage1 {
284302 result = callable .getLocation ( )
285303 )
286304 or
305+ exists ( DataFlowCallable callable |
306+ this .isReturnNodeEx ( callable ) and
307+ result = callable .getLocation ( )
308+ )
309+ or
287310 exists ( DataFlowCall call |
288311 this .isImplicitArgument ( call , _, _) and
289312 result = call .getLocation ( )
@@ -371,6 +394,9 @@ class Node extends TDataFlowNode {
371394 /** Holds if this is the canonical representative for the given `callable`. */
372395 predicate isCallable ( Callable callable ) { this .( BuilderNode ) .isCallable ( callable ) }
373396
397+ /** Holds if this node is the canonical representative for the return value of `callable`. */
398+ predicate isReturnNode ( Callable callable ) { this .( BuilderNode ) .isReturnNode ( callable ) }
399+
374400 /**
375401 * Gets the AST node wrapped by this data flow, if any.
376402 */
@@ -419,8 +445,6 @@ class Node extends TDataFlowNode {
419445 result .asSourceCallable ( ) = node .getSourceVariable ( ) .getDeclaringCallable ( )
420446 )
421447 or
422- this .( BuilderNode ) .isImplicitParameter ( result , _)
423- or
424448 exists ( CaptureSsaOutput:: SynthesizedCaptureNode node |
425449 this = TCaptureSsaNode ( node ) and
426450 result .asSourceCallable ( ) = node .getEnclosingCallable ( )
@@ -433,6 +457,8 @@ class Node extends TDataFlowNode {
433457 result = call .getEnclosingCallable ( )
434458 )
435459 or
460+ this .( BuilderNode ) .isReturnNodeEx ( result )
461+ or
436462 exists ( DataFlowCallable callable |
437463 this .isCallableEx ( callable ) and
438464 result .asSourceCallable ( ) = callable .asSourceCallable ( ) .getEnclosingCallable ( )
0 commit comments