@@ -303,6 +303,13 @@ private module ControlFlowGraphImpl {
303303 )
304304 or
305305 exists ( ConditionalStmt condstmt | condstmt .getCondition ( ) = b )
306+ or
307+ exists ( WhenBranch whenbranch |
308+ whenbranch .getCondition ( ) = b )
309+ or
310+ exists ( WhenExpr whenexpr |
311+ inBooleanContext ( whenexpr ) and
312+ whenexpr .getBranch ( _) .getResult ( ) = b )
306313 }
307314
308315 /**
@@ -386,7 +393,7 @@ private module ControlFlowGraphImpl {
386393 private Stmt nonReturningStmt ( ) {
387394 result instanceof ThrowStmt
388395 or
389- result .( ExprStmt ) .getExpr ( ) = nonReturningMethodAccess ( )
396+ result .( ExprStmt ) .getExpr ( ) = nonReturningExpr ( )
390397 or
391398 result .( BlockStmt ) .getLastStmt ( ) = nonReturningStmt ( )
392399 or
@@ -401,6 +408,20 @@ private module ControlFlowGraphImpl {
401408 )
402409 }
403410
411+ /**
412+ * Gets an expression that always throws an exception or calls `exit`.
413+ */
414+ private Expr nonReturningExpr ( ) {
415+ result = nonReturningMethodAccess ( )
416+ or
417+ exists ( WhenExpr whenexpr | whenexpr = result |
418+ whenexpr .getBranch ( _) .isElseBranch ( ) and
419+ forex ( WhenBranch whenbranch | whenbranch = whenexpr .getBranch ( _) |
420+ whenbranch .getResult ( ) = nonReturningExpr ( )
421+ or
422+ whenbranch .getResult ( ) = nonReturningStmt ( ) ) )
423+ }
424+
404425 /**
405426 * Expressions and statements with CFG edges in post-order AST traversal.
406427 *
@@ -459,6 +480,8 @@ private module ControlFlowGraphImpl {
459480 this instanceof LocalTypeDeclStmt
460481 or
461482 this instanceof AssertStmt
483+ or
484+ this instanceof WhenBranch
462485 }
463486
464487 /** Gets child nodes in their order of execution. Indexing starts at either -1 or 0. */
@@ -570,6 +593,8 @@ private module ControlFlowGraphImpl {
570593 or
571594 result = n and n instanceof ConditionalExpr
572595 or
596+ result = n and n instanceof WhenExpr
597+ or
573598 result = n and n .( PostOrderNode ) .isLeafNode ( )
574599 or
575600 result = first ( n .( PostOrderNode ) .firstChild ( ) )
@@ -880,6 +905,23 @@ private module ControlFlowGraphImpl {
880905 last ( s .getVariable ( count ( s .getAVariable ( ) ) ) , last , completion ) and
881906 completion = NormalCompletion ( )
882907 )
908+ or
909+ // The last node in a `when` expression is the last node in any of its branches or
910+ // the last node of the condition in the absence of an else-branch.
911+ exists ( WhenExpr whenexpr | whenexpr = n |
912+ last = n and
913+ completion = NormalCompletion ( ) and
914+ not whenexpr .getBranch ( _) .isElseBranch ( )
915+ or
916+ last ( whenexpr .getBranch ( _) .getResult ( ) , last , completion )
917+ )
918+ or
919+ exists ( WhenBranch whenbranch | whenbranch = n |
920+ last ( whenbranch .getCondition ( ) , last , BooleanCompletion ( false , _) ) and
921+ completion = NormalCompletion ( )
922+ or
923+ last ( whenbranch .getResult ( ) , last , completion )
924+ )
883925 }
884926
885927 /**
@@ -1142,6 +1184,27 @@ private module ControlFlowGraphImpl {
11421184 or
11431185 exists ( int i | last ( s .getVariable ( i ) , n , completion ) and result = first ( s .getVariable ( i + 1 ) ) )
11441186 )
1187+ or
1188+ // When expressions:
1189+ exists ( WhenExpr whenexpr | n = whenexpr |
1190+ n = whenexpr and result = first ( whenexpr .getBranch ( 0 ) ) and
1191+ completion = NormalCompletion ( )
1192+ or
1193+ exists ( int i |
1194+ last ( whenexpr .getBranch ( i ) .getCondition ( ) , n , completion ) and
1195+ completion = BooleanCompletion ( false , _) and
1196+ result = first ( whenexpr .getBranch ( i + 1 ) ) )
1197+ )
1198+ or
1199+ // When branches:
1200+ exists ( WhenBranch whenbranch | n = whenbranch |
1201+ completion = NormalCompletion ( ) and
1202+ result = first ( whenbranch .getCondition ( ) )
1203+ or
1204+ last ( whenbranch .getCondition ( ) , n , completion ) and
1205+ completion = BooleanCompletion ( true , _) and
1206+ result = first ( whenbranch .getResult ( ) )
1207+ )
11451208 }
11461209
11471210 /*
0 commit comments