@@ -514,8 +514,8 @@ private module ReturnNodes {
514514 }
515515
516516 /**
517- * A data-flow node that represents an expression returned by a callable,
518- * 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 .
519519 */
520520 class ExplicitReturnNode extends ReturningNode , ReturningStatementNode {
521521 ExplicitReturnNode ( ) {
@@ -531,11 +531,25 @@ private module ReturnNodes {
531531 }
532532 }
533533
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+ */
534551 class ExprReturnNode extends ReturningNode , ExprNode {
535- ExprReturnNode ( ) {
536- this .getExprNode ( ) .getASuccessor ( ) .( CfgNodes:: AnnotatedExitNode ) .isNormal ( ) and
537- this .( NodeImpl ) .getCfgScope ( ) instanceof Callable
538- }
552+ ExprReturnNode ( ) { exists ( Callable c | implicitReturn ( c , this ) = c .getAStmt ( ) ) }
539553
540554 override ReturnKind getKind ( ) { result instanceof NormalReturnKind }
541555 }
0 commit comments