diff --git a/java/ql/src/semmle/code/java/ControlFlowGraph.qll b/java/ql/src/semmle/code/java/ControlFlowGraph.qll index c14c3d7749d..b5905b240f6 100644 --- a/java/ql/src/semmle/code/java/ControlFlowGraph.qll +++ b/java/ql/src/semmle/code/java/ControlFlowGraph.qll @@ -405,7 +405,7 @@ private module ControlFlowGraphImpl { * Expressions and statements with CFG edges in post-order AST traversal. * * This includes most expressions, except those that initiate or propagate branching control - * flow (`LogicExpr`, `ConditionalExpr`), and parentheses, which aren't in the CFG. + * flow (`LogicExpr`, `ConditionalExpr`). * Only a few statements are included; those with specific side-effects * occurring after the evaluation of their children, that is, `Call`, `ReturnStmt`, * and `ThrowStmt`. CFG nodes without child nodes in the CFG that may complete @@ -429,9 +429,10 @@ private module ControlFlowGraphImpl { or this instanceof CastExpr or - this instanceof InstanceOfExpr + this instanceof InstanceOfExpr and not this.(InstanceOfExpr).isPattern() or - this instanceof LocalVariableDeclExpr + this instanceof LocalVariableDeclExpr and + not this = any(InstanceOfExpr ioe).getLocalVariableDeclExpr() or this instanceof RValue or @@ -573,6 +574,8 @@ private module ControlFlowGraphImpl { or result = first(n.(PostOrderNode).firstChild()) or + result = first(n.(InstanceOfExpr).getExpr()) + or result = first(n.(SynchronizedStmt).getExpr()) or result = n and @@ -707,6 +710,11 @@ private module ControlFlowGraphImpl { last(condexpr.getTrueExpr(), last, completion) ) or + exists(InstanceOfExpr ioe | ioe.isPattern() and ioe = n | + last = n and completion = basicBooleanCompletion(false) or + last = ioe.getLocalVariableDeclExpr() and completion = basicBooleanCompletion(true) + ) + or // The last node of a node executed in post-order is the node itself. n.(PostOrderNode).mayCompleteNormally() and last = n and completion = NormalCompletion() or @@ -916,6 +924,14 @@ private module ControlFlowGraphImpl { result = first(e.getFalseExpr()) ) or + exists(InstanceOfExpr ioe | ioe.isPattern() | + last(ioe.getExpr(), n, completion) and completion = NormalCompletion() and result = ioe + or + n = ioe and + result = ioe.getLocalVariableDeclExpr() and + completion = basicBooleanCompletion(true) + ) + or // In other expressions control flows from left to right and ends in the node itself. exists(PostOrderNode p, int i | last(p.getChildNode(i), n, completion) and completion = NormalCompletion()