@@ -746,6 +746,10 @@ module ControlFlow {
746746 result = TSelf ( any ( Completion c | c .isValidFor ( cfe ) ) )
747747 }
748748
749+ private TRec specificBoolean ( boolean value ) {
750+ result = TRec ( TLastRecSpecificCompletion ( any ( BooleanCompletion bc | bc .getValue ( ) = value ) ) )
751+ }
752+
749753 /**
750754 * Gets an element from which the last element of `cfe` can be computed
751755 * (recursively) based on computation specification `c`. The predicate
@@ -788,7 +792,7 @@ module ControlFlow {
788792 cfe = any ( LogicalAndExpr lae |
789793 // Left operand exits with a false completion
790794 result = lae .getLeftOperand ( ) and
791- c = TRec ( TLastRecSpecificCompletion ( any ( FalseCompletion fc ) ) )
795+ c = specificBoolean ( false )
792796 or
793797 // Left operand exits abnormally
794798 result = lae .getLeftOperand ( ) and
@@ -802,7 +806,7 @@ module ControlFlow {
802806 cfe = any ( LogicalOrExpr loe |
803807 // Left operand exits with a true completion
804808 result = loe .getLeftOperand ( ) and
805- c = TRec ( TLastRecSpecificCompletion ( any ( TrueCompletion tc ) ) )
809+ c = specificBoolean ( true )
806810 or
807811 // Left operand exits abnormally
808812 result = loe .getLeftOperand ( ) and
@@ -887,7 +891,7 @@ module ControlFlow {
887891 cfe = any ( IfStmt is |
888892 // Condition exits with a false completion and there is no `else` branch
889893 result = is .getCondition ( ) and
890- c = TRec ( TLastRecSpecificCompletion ( any ( FalseCompletion fc ) ) ) and
894+ c = specificBoolean ( false ) and
891895 not exists ( is .getElse ( ) )
892896 or
893897 // Condition exits abnormally
@@ -936,7 +940,7 @@ module ControlFlow {
936940 c = TRec ( TLastRecSpecificNegCompletion ( any ( MatchingCompletion mc | mc .isMatch ( ) ) ) )
937941 or
938942 result = cs .getCondition ( ) and
939- c = TRec ( TLastRecSpecificCompletion ( any ( FalseCompletion fc ) ) )
943+ c = specificBoolean ( false )
940944 )
941945 or
942946 // Last statement exits with any non-break completion
@@ -966,7 +970,7 @@ module ControlFlow {
966970 cfe = any ( Case case |
967971 // Condition exists with a `false` completion
968972 result = case .getCondition ( ) and
969- c = TRec ( TLastRecSpecificCompletion ( any ( FalseCompletion fc ) ) )
973+ c = specificBoolean ( false )
970974 or
971975 // Condition exists abnormally
972976 result = case .getCondition ( ) and
@@ -987,7 +991,7 @@ module ControlFlow {
987991 |
988992 // Condition exits with a false completion
989993 result = ls .getCondition ( ) and
990- c = TRec ( TLastRecSpecificCompletion ( any ( FalseCompletion fc ) ) )
994+ c = specificBoolean ( false )
991995 or
992996 // Condition exits abnormally
993997 result = ls .getCondition ( ) and
@@ -1046,7 +1050,7 @@ module ControlFlow {
10461050 or
10471051 // Incompatible filter
10481052 result = scc .getFilterClause ( ) and
1049- c = TRec ( TLastRecSpecificCompletion ( any ( FalseCompletion fc ) ) )
1053+ c = specificBoolean ( false )
10501054 )
10511055 )
10521056 or
@@ -1087,6 +1091,12 @@ module ControlFlow {
10871091 )
10881092 }
10891093
1094+ pragma [ noinline]
1095+ private LabeledStmt getLabledStmt ( string label , Callable c ) {
1096+ result .getEnclosingCallable ( ) = c and
1097+ label = result .getLabel ( )
1098+ }
1099+
10901100 /**
10911101 * Gets a potential last element executed within control flow element `cfe`,
10921102 * as well as its completion.
@@ -1148,8 +1158,8 @@ module ControlFlow {
11481158 rec = TLastRecSwitchAbnormalCompletion ( ) and
11491159 not c instanceof BreakCompletion and
11501160 not c instanceof NormalCompletion and
1151- not c instanceof GotoDefaultCompletion and
1152- not c instanceof GotoCaseCompletion and
1161+ not getLabledStmt ( c . ( GotoCompletion ) . getLabel ( ) , cfe . getEnclosingCallable ( ) ) instanceof
1162+ CaseStmt and
11531163 c = c0
11541164 or
11551165 rec = TLastRecInvalidOperationException ( ) and
@@ -1515,24 +1525,6 @@ module ControlFlow {
15151525 c instanceof NormalCompletion and
15161526 result = first ( ss .getStmt ( i + 1 ) )
15171527 )
1518- or
1519- exists ( GotoCompletion gc |
1520- cfe = last ( ss .getAStmt ( ) , gc ) and
1521- gc = c
1522- |
1523- // Flow from last element of a statement with a `goto default` completion
1524- // to first element `default` statement
1525- gc instanceof GotoDefaultCompletion and
1526- result = first ( ss .getDefaultCase ( ) )
1527- or
1528- // Flow from last element of a statement with a `goto case` completion
1529- // to first element of relevant case
1530- exists ( ConstCase cc |
1531- cc = ss .getAConstCase ( ) and
1532- cc .getLabel ( ) = gc .( GotoCaseCompletion ) .getLabel ( ) and
1533- result = first ( cc .getBody ( ) )
1534- )
1535- )
15361528 )
15371529 or
15381530 exists ( Case case |
@@ -1766,13 +1758,13 @@ module ControlFlow {
17661758 or
17671759 // Flow from element with `goto` completion to first element of relevant
17681760 // target
1769- c = any ( GotoLabelCompletion glc |
1770- cfe = last ( _, glc ) and
1761+ c = any ( GotoCompletion gc |
1762+ cfe = last ( _, gc ) and
17711763 // Special case: when a `goto` happens inside a `try` statement with a
17721764 // `finally` block, flow does not go directly to the target, but instead
17731765 // to the `finally` block (and from there possibly to the target)
17741766 not cfe = getBlockOrCatchFinallyPred ( any ( TryStmt ts | ts .hasFinally ( ) ) , _) and
1775- result = first ( glc . getGotoStmt ( ) . getTarget ( ) )
1767+ result = first ( getLabledStmt ( gc . getLabel ( ) , cfe . getEnclosingCallable ( ) ) )
17761768 )
17771769 or
17781770 // Standard left-to-right evaluation
0 commit comments