@@ -52,7 +52,7 @@ private module CfgInput implements CfgShared::InputSig<Location> {
52
52
}
53
53
54
54
predicate isAbnormalExitType ( SuccessorType t ) {
55
- t instanceof Cfg:: SuccessorTypes:: RaiseSuccessor or
55
+ t instanceof Cfg:: SuccessorTypes:: ThrowSuccessor or
56
56
t instanceof Cfg:: SuccessorTypes:: ExitSuccessor
57
57
}
58
58
}
@@ -543,6 +543,79 @@ module Trees {
543
543
override AstNode getChildNode ( int i ) { result = super .getElement ( i ) }
544
544
}
545
545
546
+ class CatchClauseTree extends PreOrderTree instanceof CatchClause {
547
+ final override predicate propagatesAbnormal ( Ast child ) { none ( ) }
548
+
549
+ final override predicate last ( AstNode last , Completion c ) {
550
+ last ( super .getBody ( ) , last , c )
551
+ or
552
+ // The last catch type failed to matchs
553
+ last ( super .getCatchType ( super .getNumberOfCatchTypes ( ) - 1 ) , last , c ) and
554
+ c .( MatchCompletion ) .isNonMatch ( )
555
+ }
556
+
557
+ final override predicate succ ( AstNode pred , AstNode succ , Completion c ) {
558
+ // Preorder: Flow from the catch clause to the first catch type to test,
559
+ // or to the body if this is a catch all
560
+ pred = this and
561
+ completionIsSimple ( c ) and
562
+ (
563
+ first ( super .getCatchType ( 0 ) , succ )
564
+ or
565
+ super .isCatchAll ( ) and
566
+ first ( super .getBody ( ) , succ )
567
+ )
568
+ or
569
+ // Flow from a catch type to the next catch type when it fails to match
570
+ exists ( int i , boolean match |
571
+ last ( super .getCatchType ( i ) , pred , c ) and
572
+ match = c .( MatchCompletion ) .getValue ( )
573
+ |
574
+ match = true and
575
+ first ( super .getBody ( ) , succ )
576
+ or
577
+ match = false and
578
+ first ( super .getCatchType ( i + 1 ) , succ )
579
+ )
580
+ }
581
+ }
582
+
583
+ class TryStmtBlock extends PreOrderTree instanceof TryStmt {
584
+ final override predicate propagatesAbnormal ( AstNode child ) { child = super .getFinally ( ) }
585
+
586
+ final override predicate last ( AstNode last , Completion c ) {
587
+ last ( super .getFinally ( ) , last , c )
588
+ or
589
+ not super .hasFinally ( ) and
590
+ (
591
+ // Body exits without an exception
592
+ last ( super .getBody ( ) , last , c ) and
593
+ completionIsNormal ( c )
594
+ or
595
+ // In case there's an exception we exit by evaluating one of the catch clauses
596
+ // Note that there will always be at least one catch clause if there is no `try`.
597
+ last ( super .getACatchClause ( ) , last , c )
598
+ )
599
+ }
600
+
601
+ final override predicate succ ( AstNode pred , AstNode succ , Completion c ) {
602
+ // Preorder: The try/catch statment flows to the body
603
+ pred = this and
604
+ first ( super .getBody ( ) , succ ) and
605
+ completionIsSimple ( c )
606
+ or
607
+ // Flow from the body to the finally when the body didn't throw
608
+ last ( super .getBody ( ) , pred , c ) and
609
+ if c instanceof ThrowCompletion
610
+ then first ( super .getCatchClause ( 0 ) , succ )
611
+ else first ( super .getFinally ( ) , succ )
612
+ }
613
+ }
614
+
615
+ class ThrowStmtTree extends StandardPreOrderTree instanceof ThrowStmt {
616
+ override AstNode getChildNode ( int i ) { i = 0 and result = super .getPipeline ( ) }
617
+ }
618
+
546
619
class ConstExprTree extends LeafTree instanceof ConstExpr { }
547
620
548
621
class CmdExprTree extends StandardPreOrderTree instanceof CmdExpr {
@@ -577,7 +650,7 @@ private module Cached {
577
650
TReturnSuccessor ( ) or
578
651
TBreakSuccessor ( ) or
579
652
TContinueSuccessor ( ) or
580
- TRaiseSuccessor ( ) or
653
+ TThrowSuccessor ( ) or
581
654
TExitSuccessor ( ) or
582
655
TMatchingSuccessor ( Boolean b )
583
656
}
0 commit comments