@@ -550,100 +550,45 @@ abstract class ReturnNode extends Node {
550550 abstract ReturnKind getKind ( ) ;
551551}
552552
553- private module ReturnNodes {
554- /** An AST element that may produce return values when evaluated. */
555- abstract private class ReturnContainer extends Ast {
556- /**
557- * Gets a direct node that will may be returned when evaluating this node.
558- */
559- CfgNode getANode ( ) { none ( ) }
560-
561- /** Gets a child that may produce more nodes that may be returned. */
562- abstract ReturnContainer getAChild ( ) ;
563-
564- /**
565- * Gets a (possibly transitive) node that may be returned when evaluating
566- * this node.
567- */
568- final CfgNode getAReturnedNode ( ) {
569- result = this .getANode ( )
553+ private module EscapeContainer {
554+ private import semmle.code.powershell.internal.AstEscape:: Private
555+
556+ private module ReturnContainerInterpreter implements InterpretAstInputSig {
557+ class T = CfgNodes:: AstCfgNode ;
558+
559+ T interpret ( Ast a ) {
560+ result .( CfgNodes:: ExprCfgNode ) .getExpr ( ) = a
570561 or
571- result = this . getAChild ( ) . getAReturnedNode ( )
562+ result . ( CfgNodes :: StmtCfgNode ) . getStmt ( ) = a . ( Cmd )
572563 }
564+ }
573565
566+ class EscapeContainer extends AstEscape< ReturnContainerInterpreter > :: Element {
574567 /** Holds if `n` may be returned multiples times. */
575568 predicate mayBeMultiReturned ( CfgNode n ) {
576569 n = this .getANode ( ) and
577570 n .getASuccessor + ( ) = n
578571 or
579- this .getAChild ( ) .mayBeMultiReturned ( n )
572+ this .getAChild ( ) .( EscapeContainer ) . mayBeMultiReturned ( n )
580573 }
581574 }
575+ }
582576
583- class ScriptBlockReturnContainer extends ReturnContainer , ScriptBlock {
584- final override ReturnContainer getAChild ( ) { result = this .getEndBlock ( ) }
585- }
586-
587- class NamedBlockReturnContainer extends ReturnContainer , NamedBlock {
588- final override ReturnContainer getAChild ( ) { result = this .getAStmt ( ) }
589- }
590-
591- class CmdExprReturnContainer extends ReturnContainer , CmdExpr {
592- final override CfgNodes:: ExprCfgNode getANode ( ) { result .getExpr ( ) = this .getExpr ( ) }
593-
594- final override ReturnContainer getAChild ( ) { none ( ) }
595- }
596-
597- class LoopStmtReturnContainer extends ReturnContainer , LoopStmt {
598- final override ReturnContainer getAChild ( ) { result = this .getBody ( ) }
599- }
600-
601- class StmtBlockReturnConainer extends ReturnContainer , StmtBlock {
602- final override ReturnContainer getAChild ( ) { result = this .getAStmt ( ) }
603- }
604-
605- class TryStmtReturnContainer extends ReturnContainer , TryStmt {
606- final override ReturnContainer getAChild ( ) {
607- result = this .getBody ( ) or result = this .getACatchClause ( ) or result = this .getFinally ( )
608- }
609- }
610-
611- class ReturnStmtReturnContainer extends ReturnContainer , ReturnStmt {
612- final override ReturnContainer getAChild ( ) { result = this .getPipeline ( ) }
613- }
614-
615- class CatchClausReturnContainer extends ReturnContainer , CatchClause {
616- final override ReturnContainer getAChild ( ) { result = this .getBody ( ) }
617- }
618-
619- class SwitchStmtReturnContainer extends ReturnContainer , SwitchStmt {
620- final override ReturnContainer getAChild ( ) { result = this .getACase ( ) }
621- }
622-
623- class CmdBaseReturnContainer extends ReturnContainer , CmdExpr {
624- final override CfgNodes:: ExprCfgNode getANode ( ) { result .getExpr ( ) = this .getExpr ( ) }
625-
626- final override ReturnContainer getAChild ( ) { none ( ) }
627- }
628-
629- class CmdReturnContainer extends ReturnContainer , Cmd {
630- final override CfgNodes:: StmtCfgNode getANode ( ) { result .getStmt ( ) = this }
631-
632- final override ReturnContainer getAChild ( ) { none ( ) }
633- }
577+ private module ReturnNodes {
578+ private import EscapeContainer
634579
635- private predicate isReturnedImpl ( CfgNodes:: AstCfgNode n , ReturnContainer container ) {
580+ private predicate isReturnedImpl ( CfgNodes:: AstCfgNode n , EscapeContainer container ) {
636581 container = n .getScope ( ) and
637- n = container .getAReturnedNode ( )
582+ n = container .getAnEscapingElement ( )
638583 }
639584
640585 /**
641586 * Holds if `n` may be returned, and there are possibly
642587 * more than one return value from the function.
643588 */
644589 predicate isMultiReturned ( CfgNodes:: AstCfgNode n ) {
645- exists ( ReturnContainer container | isReturnedImpl ( n , container ) |
646- strictcount ( container .getAReturnedNode ( ) ) > 1
590+ exists ( EscapeContainer container | isReturnedImpl ( n , container ) |
591+ strictcount ( container .getAnEscapingElement ( ) ) > 1
647592 or
648593 container .mayBeMultiReturned ( n )
649594 )
0 commit comments