@@ -97,15 +97,20 @@ module LocalFlow {
97
97
}
98
98
}
99
99
100
- /** An argument of a call (including qualifier arguments). */
101
- private class Argument extends Expr {
102
- private Call call ;
100
+ /** An argument of a call (including qualifier arguments, excluding block arguments ). */
101
+ private class Argument extends CfgNodes :: ExprCfgNode {
102
+ private CfgNodes :: ExprNodes :: CallCfgNode call ;
103
103
private int arg ;
104
104
105
- Argument ( ) { this = call .getArgument ( arg ) }
105
+ Argument ( ) {
106
+ this = call .getArgument ( arg ) and
107
+ not this .getExpr ( ) instanceof BlockArgument
108
+ or
109
+ this = call .getReceiver ( ) and arg = - 1
110
+ }
106
111
107
112
/** Holds if this expression is the `i`th argument of `c`. */
108
- predicate isArgumentOf ( Expr c , int i ) { c = call and i = arg }
113
+ predicate isArgumentOf ( CfgNodes :: ExprNodes :: CallCfgNode c , int i ) { c = call and i = arg }
109
114
}
110
115
111
116
/** A collection of cached types and predicates to be evaluated in the same stage. */
@@ -125,14 +130,7 @@ private module Cached {
125
130
TNormalParameterNode ( Parameter p ) { not p instanceof BlockParameter } or
126
131
TSelfParameterNode ( MethodBase m ) or
127
132
TBlockParameterNode ( MethodBase m ) or
128
- TExprPostUpdateNode ( CfgNodes:: ExprCfgNode n ) {
129
- exists ( AstNode node | node = n .getNode ( ) |
130
- node instanceof Argument and
131
- not node instanceof BlockArgument
132
- or
133
- n = any ( CfgNodes:: ExprNodes:: CallCfgNode call ) .getReceiver ( )
134
- )
135
- } or
133
+ TExprPostUpdateNode ( CfgNodes:: ExprCfgNode n ) { n instanceof Argument } or
136
134
TSummaryNode (
137
135
FlowSummaryImpl:: Public:: SummarizedCallable c ,
138
136
FlowSummaryImpl:: Private:: SummaryNodeState state
@@ -438,24 +436,18 @@ abstract class ArgumentNode extends Node {
438
436
private module ArgumentNodes {
439
437
/** A data-flow node that represents an explicit call argument. */
440
438
class ExplicitArgumentNode extends ArgumentNode {
441
- ExplicitArgumentNode ( ) {
442
- this .asExpr ( ) .getExpr ( ) instanceof Argument and
443
- not this .asExpr ( ) .getExpr ( ) instanceof BlockArgument
444
- }
439
+ Argument arg ;
440
+
441
+ ExplicitArgumentNode ( ) { this .asExpr ( ) = arg }
445
442
446
443
override predicate sourceArgumentOf ( CfgNodes:: ExprNodes:: CallCfgNode call , int pos ) {
447
- this . asExpr ( ) = call . getArgument ( pos )
444
+ arg . isArgumentOf ( call , pos )
448
445
}
449
446
}
450
447
451
448
/** A data-flow node that represents the `self` argument of a call. */
452
- class SelfArgumentNode extends ArgumentNode {
453
- SelfArgumentNode ( ) { this .asExpr ( ) = any ( CfgNodes:: ExprNodes:: CallCfgNode call ) .getReceiver ( ) }
454
-
455
- override predicate sourceArgumentOf ( CfgNodes:: ExprNodes:: CallCfgNode call , int pos ) {
456
- this .asExpr ( ) = call .getReceiver ( ) and
457
- pos = - 1
458
- }
449
+ class SelfArgumentNode extends ExplicitArgumentNode {
450
+ SelfArgumentNode ( ) { arg .isArgumentOf ( _, - 1 ) }
459
451
}
460
452
461
453
/** A data-flow node that represents a block argument. */
@@ -522,8 +514,8 @@ private module ReturnNodes {
522
514
}
523
515
524
516
/**
525
- * A data-flow node that represents an expression returned by a callable,
526
- * either using an explict `return` statement or as the expression of a method body .
517
+ * A data-flow node that represents an expression explicitly returned by
518
+ * a callable .
527
519
*/
528
520
class ExplicitReturnNode extends ReturningNode , ReturningStatementNode {
529
521
ExplicitReturnNode ( ) {
@@ -539,11 +531,25 @@ private module ReturnNodes {
539
531
}
540
532
}
541
533
534
+ pragma [ noinline]
535
+ private AstNode implicitReturn ( Callable c , ExprNode n ) {
536
+ exists ( CfgNodes:: ExprCfgNode en |
537
+ en = n .getExprNode ( ) and
538
+ en .getASuccessor ( ) .( CfgNodes:: AnnotatedExitNode ) .isNormal ( ) and
539
+ n .( NodeImpl ) .getCfgScope ( ) = c and
540
+ result = en .getExpr ( )
541
+ )
542
+ or
543
+ result = implicitReturn ( c , n ) .getParent ( )
544
+ }
545
+
546
+ /**
547
+ * A data-flow node that represents an expression implicitly returned by
548
+ * a callable. An implicit return happens when an expression can be the
549
+ * last thing that is evaluated in the body of the callable.
550
+ */
542
551
class ExprReturnNode extends ReturningNode , ExprNode {
543
- ExprReturnNode ( ) {
544
- this .getExprNode ( ) .getASuccessor ( ) .( CfgNodes:: AnnotatedExitNode ) .isNormal ( ) and
545
- this .( NodeImpl ) .getCfgScope ( ) instanceof Callable
546
- }
552
+ ExprReturnNode ( ) { exists ( Callable c | implicitReturn ( c , this ) = c .getAStmt ( ) ) }
547
553
548
554
override ReturnKind getKind ( ) { result instanceof NormalReturnKind }
549
555
}
0 commit comments