diff --git a/change-notes/1.20/analysis-java.md b/change-notes/1.20/analysis-java.md index e8271cb20aa2..105face9414a 100644 --- a/change-notes/1.20/analysis-java.md +++ b/change-notes/1.20/analysis-java.md @@ -17,4 +17,14 @@ ## Changes to QL libraries +* The class `ControlFlowNode` (and by extension `BasicBlock`) is no longer + directly equatable to `Expr` and `Stmt`. Any queries that exploit these + equalities, for example by using casts, will now report compilation errors. + You can fix these errors by making minor changes to the affected queries. + The conversions can be inserted in either direction depending on what is most + convenient. Available conversions include `Expr.getControlFlowNode()`, + `Stmt.getControlFlowNode()`, `ControlFlowNode.asExpr()`, + `ControlFlowNode.asStmt()`, and `ControlFlowNode.asCall()`. + Exit nodes were until now modeled as a `ControlFlowNode` equal to its + enclosing `Callable`; these are now modeled by the class `ControlFlow::ExitNode`. diff --git a/java/ql/src/Likely Bugs/Comparison/UselessComparisonTest.qll b/java/ql/src/Likely Bugs/Comparison/UselessComparisonTest.qll index ea01b89deb3c..081bfa179d4c 100644 --- a/java/ql/src/Likely Bugs/Comparison/UselessComparisonTest.qll +++ b/java/ql/src/Likely Bugs/Comparison/UselessComparisonTest.qll @@ -35,7 +35,7 @@ predicate uselessTest(ConditionNode s1, BinaryExpr test, boolean testIsTrue) { ConditionBlock cb, SsaVariable v, BinaryExpr cond, boolean condIsTrue, int k1, int k2, CompileTimeConstantExpr c1, CompileTimeConstantExpr c2 | - s1 = cond and + s1.getCondition() = cond and cb.getCondition() = cond and cond.hasOperands(v.getAUse(), c1) and c1.getIntValue() = k1 and diff --git a/java/ql/src/Likely Bugs/Concurrency/DoubleCheckedLockingWithInitRace.ql b/java/ql/src/Likely Bugs/Concurrency/DoubleCheckedLockingWithInitRace.ql index 6992898bf84f..485b3a5d2ab7 100644 --- a/java/ql/src/Likely Bugs/Concurrency/DoubleCheckedLockingWithInitRace.ql +++ b/java/ql/src/Likely Bugs/Concurrency/DoubleCheckedLockingWithInitRace.ql @@ -36,7 +36,7 @@ where doubleCheckedLocking(if1, if2, sync, f) and a.getEnclosingStmt().getParent*() = if2.getThen() and se.getEnclosingStmt().getParent*() = sync.getBlock() and - a.(ControlFlowNode).getASuccessor+() = se and + a.getControlFlowNode().getASuccessor+() = se.getControlFlowNode() and a.getDest().(FieldAccess).getField() = f select a, "Potential race condition. This assignment to $@ is visible to other threads before the subsequent statements are executed.", diff --git a/java/ql/src/Likely Bugs/Concurrency/LazyInitStaticField.ql b/java/ql/src/Likely Bugs/Concurrency/LazyInitStaticField.ql index 89aacbfcdf57..3133c1321111 100644 --- a/java/ql/src/Likely Bugs/Concurrency/LazyInitStaticField.ql +++ b/java/ql/src/Likely Bugs/Concurrency/LazyInitStaticField.ql @@ -63,12 +63,12 @@ class ValidSynchStmt extends Stmt { exists(MethodAccess lockAction | lockAction.getQualifier() = lockField.getAnAccess() and lockAction.getMethod().getName() = "lock" and - dominates(lockAction, this) + dominates(lockAction.getControlFlowNode(), this.getControlFlowNode()) ) and exists(MethodAccess unlockAction | unlockAction.getQualifier() = lockField.getAnAccess() and unlockAction.getMethod().getName() = "unlock" and - postDominates(unlockAction, this) + postDominates(unlockAction.getControlFlowNode(), this.getControlFlowNode()) ) ) } diff --git a/java/ql/src/Likely Bugs/Concurrency/UnreleasedLock.ql b/java/ql/src/Likely Bugs/Concurrency/UnreleasedLock.ql index 40fb18543d19..b787c38881e5 100644 --- a/java/ql/src/Likely Bugs/Concurrency/UnreleasedLock.ql +++ b/java/ql/src/Likely Bugs/Concurrency/UnreleasedLock.ql @@ -58,11 +58,11 @@ class LockType extends RefType { } predicate lockBlock(LockType t, BasicBlock b, int locks) { - locks = strictcount(int i | b.getNode(i) = t.getLockAccess()) + locks = strictcount(int i | b.getNode(i) = t.getLockAccess().getControlFlowNode()) } predicate unlockBlock(LockType t, BasicBlock b, int unlocks) { - unlocks = strictcount(int i | b.getNode(i) = t.getUnlockAccess()) + unlocks = strictcount(int i | b.getNode(i) = t.getUnlockAccess().getControlFlowNode()) } /** @@ -89,11 +89,11 @@ predicate failedLock(LockType t, BasicBlock lockblock, BasicBlock exblock) { exists(ControlFlowNode lock | lock = lockblock.getLastNode() and ( - lock = t.getLockAccess() + lock = t.getLockAccess().getControlFlowNode() or exists(SsaExplicitUpdate lockbool | // Using the value of `t.getLockAccess()` ensures that it is a `tryLock` call. - lock = lockbool.getAUse() and + lock = lockbool.getAUse().getControlFlowNode() and lockbool.getDefiningExpr().(VariableAssign).getSource() = t.getLockAccess() ) ) and @@ -151,7 +151,7 @@ where // Restrict results to those methods that actually attempt to unlock. t.getUnlockAccess().getEnclosingCallable() = c and blockIsLocked(t, src, exit, _) and - exit.getLastNode() = c and - lock = src.getANode() and + exit.getLastNode().(ControlFlow::ExitNode).getEnclosingCallable() = c and + lock.getControlFlowNode() = src.getANode() and lock = t.getLockAccess() select lock, "This lock might not be unlocked or might be locked more times than it is unlocked." diff --git a/java/ql/src/Likely Bugs/Termination/ConstantLoopCondition.ql b/java/ql/src/Likely Bugs/Termination/ConstantLoopCondition.ql index d39591798214..199bb4b1aa70 100644 --- a/java/ql/src/Likely Bugs/Termination/ConstantLoopCondition.ql +++ b/java/ql/src/Likely Bugs/Termination/ConstantLoopCondition.ql @@ -61,7 +61,7 @@ predicate mainLoopCondition(LoopStmt loop, Expr cond) { else loopReentry = cond | last.getEnclosingStmt().getParent*() = loop.getBody() and - last.getASuccessor().(Expr).getParent*() = loopReentry + last.getASuccessor().asExpr().getParent*() = loopReentry ) } @@ -75,7 +75,7 @@ where // None of the ssa variables in `cond` are updated inside the loop. forex(SsaVariable ssa, RValue use | ssa.getAUse() = use and use.getParent*() = cond | not ssa.getCFGNode().getEnclosingStmt().getParent*() = loop or - ssa.getCFGNode().(Expr).getParent*() = loop.(ForStmt).getAnInit() + ssa.getCFGNode().asExpr().getParent*() = loop.(ForStmt).getAnInit() ) and // And `cond` does not use method calls, field reads, or array reads. not exists(MethodAccess ma | ma.getParent*() = cond) and diff --git a/java/ql/src/Security/CWE/CWE-022/ZipSlip.ql b/java/ql/src/Security/CWE/CWE-022/ZipSlip.ql index f23167eed24e..5e95ce926261 100644 --- a/java/ql/src/Security/CWE/CWE-022/ZipSlip.ql +++ b/java/ql/src/Security/CWE/CWE-022/ZipSlip.ql @@ -130,14 +130,14 @@ predicate validateFilePath(SsaVariable var, Guard check) { * Holds if `m` validates its `arg`th parameter. */ predicate validationMethod(Method m, int arg) { - exists(Guard check, SsaImplicitInit var, ControlFlowNode exit, ControlFlowNode normexit | + exists(Guard check, SsaImplicitInit var, ControlFlow::ExitNode exit, ControlFlowNode normexit | validateFilePath(var, check) and var.isParameterDefinition(m.getParameter(arg)) and - exit = m and + exit.getEnclosingCallable() = m and normexit.getANormalSuccessor() = exit and 1 = strictcount(ControlFlowNode n | n.getANormalSuccessor() = exit) | - check.(ConditionNode).getATrueSuccessor() = exit or + check.hasBranchEdge(_, exit.getBasicBlock(), true) or check.controls(normexit.getBasicBlock(), true) ) } diff --git a/java/ql/src/Security/CWE/CWE-833/LockOrderInconsistency.ql b/java/ql/src/Security/CWE/CWE-833/LockOrderInconsistency.ql index be73ae83eeb2..8e3dcee7a09a 100644 --- a/java/ql/src/Security/CWE/CWE-833/LockOrderInconsistency.ql +++ b/java/ql/src/Security/CWE/CWE-833/LockOrderInconsistency.ql @@ -77,8 +77,8 @@ predicate badReentrantLockOrder(MethodAccess first, MethodAccess second, MethodA otherSecond = v1.getLockAction() and second = v2.getLockAction() and otherFirst = v2.getLockAction() and - first.(ControlFlowNode).getASuccessor+() = second and - otherFirst.(ControlFlowNode).getASuccessor+() = otherSecond + first.getControlFlowNode().getASuccessor+() = second.getControlFlowNode() and + otherFirst.getControlFlowNode().getASuccessor+() = otherSecond.getControlFlowNode() | v1 != v2 ) diff --git a/java/ql/src/Violations of Best Practice/Declarations/BreakInSwitchCase.ql b/java/ql/src/Violations of Best Practice/Declarations/BreakInSwitchCase.ql index bfcd7bdaf716..87a8d1bd2dbd 100644 --- a/java/ql/src/Violations of Best Practice/Declarations/BreakInSwitchCase.ql +++ b/java/ql/src/Violations of Best Practice/Declarations/BreakInSwitchCase.ql @@ -17,8 +17,8 @@ import Common from SwitchStmt s, Stmt c where c = s.getACase() and - not c.(ControlFlowNode).getASuccessor() instanceof ConstCase and - not c.(ControlFlowNode).getASuccessor() instanceof DefaultCase and + not c.getControlFlowNode().getASuccessor().asStmt() instanceof ConstCase and + not c.getControlFlowNode().getASuccessor().asStmt() instanceof DefaultCase and not s.(Annotatable).suppressesWarningsAbout("fallthrough") and mayDropThroughWithoutComment(s, c) select c, diff --git a/java/ql/src/Violations of Best Practice/Declarations/Common.qll b/java/ql/src/Violations of Best Practice/Declarations/Common.qll index 0f95df4b5c40..ea5ca9d3a030 100644 --- a/java/ql/src/Violations of Best Practice/Declarations/Common.qll +++ b/java/ql/src/Violations of Best Practice/Declarations/Common.qll @@ -24,15 +24,15 @@ predicate switchCaseControlFlowPlus(SwitchStmt switch, BasicBlock b1, BasicBlock exists(BasicBlock mid | switchCaseControlFlowPlus(switch, mid, b2) and switchCaseControlFlow(switch, b1, mid) and - not mid.getFirstNode() = switch.getACase() + not mid.getFirstNode() = switch.getACase().getControlFlowNode() ) } predicate mayDropThroughWithoutComment(SwitchStmt switch, Stmt switchCase) { switchCase = switch.getACase() and exists(Stmt other, BasicBlock b1, BasicBlock b2 | - b1.getFirstNode() = switchCase and - b2.getFirstNode() = other and + b1.getFirstNode() = switchCase.getControlFlowNode() and + b2.getFirstNode() = other.getControlFlowNode() and switchCaseControlFlowPlus(switch, b1, b2) and other = switch.getACase() and not fallThroughCommented(other) diff --git a/java/ql/src/semmle/code/java/ControlFlowGraph.qll b/java/ql/src/semmle/code/java/ControlFlowGraph.qll index 8a7c2c85123e..93d0e016272f 100644 --- a/java/ql/src/semmle/code/java/ControlFlowGraph.qll +++ b/java/ql/src/semmle/code/java/ControlFlowGraph.qll @@ -1,7 +1,7 @@ /** * Provides classes and predicates for computing expression-level intra-procedural control flow graphs. * - * The only API exported by this library are the toplevel classes `ControlFlowNode` + * The only API exported by this library are the toplevel classes `ControlFlow::Node` * and its subclass `ConditionNode`, which wrap the successor relation and the * concept of true- and false-successors of conditions. A cfg node may either be a * statement, an expression, or the enclosing callable, indicating that @@ -82,37 +82,87 @@ import java private import Completion -/** A node in the expression-level control-flow graph. */ -class ControlFlowNode extends Top, @exprparent { - /** Gets the statement containing this node, if any. */ - Stmt getEnclosingStmt() { - result = this or - result = this.(Expr).getEnclosingStmt() - } +module ControlFlow { + private newtype TNode = + TExprNode(Expr e) { hasControlFlow(e) } or + TStmtNode(Stmt s) or + TExitNode(Callable c) { exists(c.getBody()) } - /** Gets the immediately enclosing callable whose body contains this node. */ - Callable getEnclosingCallable() { - result = this or - result = this.(Stmt).getEnclosingCallable() or - result = this.(Expr).getEnclosingCallable() - } + /** A node in the expression-level control-flow graph. */ + class Node extends TNode { + /** Gets the statement containing this node, if any. */ + Stmt getEnclosingStmt() { + result = this.asStmt() or + result = this.asExpr().getEnclosingStmt() + } + + /** Gets the immediately enclosing callable whose body contains this node. */ + Callable getEnclosingCallable() { + this = TExitNode(result) or + result = this.asStmt().getEnclosingCallable() or + result = this.asExpr().getEnclosingCallable() + } + + /** Gets the statement this `Node` corresponds to, if any. */ + Stmt asStmt() { this = TStmtNode(result) } + + /** Gets the expression this `Node` corresponds to, if any. */ + Expr asExpr() { this = TExprNode(result) } + + /** Gets the call this `Node` corresponds to, if any. */ + Call asCall() { + result = this.asExpr() or + result = this.asStmt() + } + + /** Gets an immediate successor of this node. */ + Node getASuccessor() { result = succ(this) } + + /** Gets an immediate predecessor of this node. */ + Node getAPredecessor() { this = succ(result) } + + /** Gets an exception successor of this node. */ + Node getAnExceptionSuccessor() { result = succ(this, ThrowCompletion(_)) } - /** Gets an immediate successor of this node. */ - ControlFlowNode getASuccessor() { result = succ(this) } + /** Gets a successor of this node that is neither an exception successor nor a jump (break, continue, return). */ + Node getANormalSuccessor() { + result = succ(this, BooleanCompletion(_, _)) or + result = succ(this, NormalCompletion()) + } - /** Gets an immediate predecessor of this node. */ - ControlFlowNode getAPredecessor() { this = succ(result) } + BasicBlock getBasicBlock() { result.getANode() = this } - /** Gets an exception successor of this node. */ - ControlFlowNode getAnExceptionSuccessor() { result = succ(this, ThrowCompletion(_)) } + /** Gets a textual representation of this element. */ + string toString() { + result = this.asExpr().toString() + or + result = this.asStmt().toString() + or + result = "Exit" and this instanceof ExitNode + } - /** Gets a successor of this node that is neither an exception successor nor a jump (break, continue, return). */ - ControlFlowNode getANormalSuccessor() { - result = succ(this, BooleanCompletion(_, _)) or - result = succ(this, NormalCompletion()) + Location getLocation() { + result = this.asExpr().getLocation() or + result = this.asStmt().getLocation() or + result = this.(ExitNode).getEnclosingCallable().getLocation() + } } - BasicBlock getBasicBlock() { result.getANode() = this } + class ExitNode extends Node, TExitNode { } +} + +class ControlFlowNode = ControlFlow::Node; + +private predicate hasControlFlow(Expr e) { + not e instanceof ParExpr and + not e.getEnclosingStmt() instanceof ConstCase and + not e.getParent*() instanceof Annotation and + not e instanceof TypeAccess and + not e instanceof ArrayTypeAccess and + not e instanceof UnionTypeAccess and + not e instanceof IntersectionTypeAccess and + not e instanceof WildcardTypeAccess and + not exists(AssignExpr ae | ae.getDest() = e) } /** Gets the intra-procedural successor of `n`. */ @@ -120,6 +170,19 @@ private ControlFlowNode succ(ControlFlowNode n) { result = succ(n, _) } cached private module ControlFlowGraphImpl { + private import ControlFlow + + private class AstNode extends ExprParent { + AstNode() { this instanceof Expr or this instanceof Stmt } + + Stmt getEnclosingStmt() { + result = this or + result = this.(Expr).getEnclosingStmt() + } + + Node getCFGNode() { result.asExpr() = this or result.asStmt() = this } + } + /** * Gets a label that applies to this statement. */ @@ -163,7 +226,7 @@ private module ControlFlowGraphImpl { * that may throw an exception, or because it is a cast and a * `ClassCastException` is expected. */ - private predicate mayThrow(ControlFlowNode n, ThrowableType t) { + private predicate mayThrow(AstNode n, ThrowableType t) { t = n.(ThrowStmt).getThrownExceptionType() or exists(Call c | c = n | @@ -182,7 +245,7 @@ private module ControlFlowGraphImpl { * Bind `t` to an unchecked exception that may transfer control to a finally * block inside which `n` is nested. */ - private predicate uncheckedExceptionFromFinally(ControlFlowNode n, ThrowableType t) { + private predicate uncheckedExceptionFromFinally(AstNode n, ThrowableType t) { exists(TryStmt try | n.getEnclosingStmt().getParent+() = try.getBlock() or n.(Expr).getParent*() = try.getAResource() @@ -196,7 +259,7 @@ private module ControlFlowGraphImpl { * Bind `t` to all unchecked exceptions that may be caught by some * `try-catch` inside which `n` is nested. */ - private predicate uncheckedExceptionFromCatch(ControlFlowNode n, ThrowableType t) { + private predicate uncheckedExceptionFromCatch(AstNode n, ThrowableType t) { exists(TryStmt try, UncheckedThrowableSuperType caught | n.getEnclosingStmt().getParent+() = try.getBlock() or n.(Expr).getParent*() = try.getAResource() @@ -211,7 +274,7 @@ private module ControlFlowGraphImpl { * body or the resources (if any) of `try`. */ private ThrowableType thrownInBody(TryStmt try) { - exists(ControlFlowNode n | mayThrow(n, result) | + exists(AstNode n | mayThrow(n, result) | n.getEnclosingStmt().getParent+() = try.getBlock() or n.(Expr).getParent*() = try.getAResource() ) @@ -397,7 +460,7 @@ private module ControlFlowGraphImpl { * and `ThrowStmt`. CFG nodes without child nodes in the CFG that may complete * normally are also included. */ - private class PostOrderNode extends ControlFlowNode { + private class PostOrderNode extends AstNode { PostOrderNode() { // For VarAccess and ArrayAccess only read accesses (r-values) are included, // as write accesses aren't included in the CFG. @@ -447,7 +510,7 @@ private module ControlFlowGraphImpl { } /** Gets child nodes in their order of execution. Indexing starts at either -1 or 0. */ - ControlFlowNode getChildNode(int index) { + AstNode getChildNode(int index) { exists(ArrayAccess e | e = this | index = 0 and result = e.getArray() or @@ -512,7 +575,7 @@ private module ControlFlowGraphImpl { } /** Gets the first child node, if any. */ - ControlFlowNode firstChild() { + AstNode firstChild() { result = getChildNode(-1) or result = getChildNode(0) and not exists(getChildNode(-1)) @@ -550,12 +613,12 @@ private module ControlFlowGraphImpl { /** * Determine the part of the AST node `n` that will be executed first. */ - private ControlFlowNode first(ControlFlowNode n) { - result = n and n instanceof LogicExpr + private Node first(AstNode n) { + result.asExpr() = n and n instanceof LogicExpr or - result = n and n instanceof ConditionalExpr + result.asExpr() = n and n instanceof ConditionalExpr or - result = n and n.(PostOrderNode).isLeafNode() + exists(PostOrderNode p | p = n | result = p.getCFGNode() and p.isLeafNode()) or result = first(n.(PostOrderNode).firstChild()) or @@ -563,8 +626,7 @@ private module ControlFlowGraphImpl { or result = first(n.(SynchronizedStmt).getExpr()) or - result = n and - n instanceof Stmt and + result.asStmt() = n and not n instanceof PostOrderNode and not n instanceof SynchronizedStmt } @@ -577,9 +639,7 @@ private module ControlFlowGraphImpl { * node in the `try` block that may not complete normally, or a node in * the `try` block that has no control flow successors inside the block. */ - private predicate catchOrFinallyCompletion( - TryStmt try, ControlFlowNode last, Completion completion - ) { + private predicate catchOrFinallyCompletion(TryStmt try, Node last, Completion completion) { last(try.getBlock(), last, completion) or last(try.getAResource(), last, completion) and completion = ThrowCompletion(_) @@ -592,7 +652,7 @@ private module ControlFlowGraphImpl { * In other words, if `last` throws an exception it is possibly not caught by any * of the catch clauses. */ - private predicate uncaught(TryStmt try, ControlFlowNode last, Completion completion) { + private predicate uncaught(TryStmt try, Node last, Completion completion) { catchOrFinallyCompletion(try, last, completion) and ( exists(ThrowableType thrown | @@ -622,12 +682,12 @@ private module ControlFlowGraphImpl { * This is similar to `uncaught`, but also includes final statements of `catch` * clauses. */ - private predicate finallyPred(TryStmt try, ControlFlowNode last, Completion completion) { + private predicate finallyPred(TryStmt try, Node last, Completion completion) { uncaught(try, last, completion) or last(try.getACatchClause(), last, completion) } - private predicate lastInFinally(TryStmt try, ControlFlowNode last) { + private predicate lastInFinally(TryStmt try, Node last) { last(try.getFinally(), last, NormalCompletion()) } @@ -639,7 +699,7 @@ private module ControlFlowGraphImpl { * A `booleanCompletion` implies that `n` is an `Expr`. Any abnormal * completion besides `throwCompletion` implies that `n` is a `Stmt`. */ - private predicate last(ControlFlowNode n, ControlFlowNode last, Completion completion) { + private predicate last(AstNode n, Node last, Completion completion) { // Exceptions are propagated from any sub-expression. exists(Expr e | e.getParent() = n | last(e, last, completion) and completion = ThrowCompletion(_) @@ -696,9 +756,11 @@ private module ControlFlowGraphImpl { last(n.(ParExpr).getExpr(), last, completion) or // The last node of a node executed in post-order is the node itself. - n.(PostOrderNode).mayCompleteNormally() and last = n and completion = NormalCompletion() + exists(PostOrderNode p | p = n | + p.mayCompleteNormally() and last = p.getCFGNode() and completion = NormalCompletion() + ) or - last = n and completion = basicBooleanCompletion(n.(BooleanLiteral).getBooleanValue()) + last.asExpr() = n and completion = basicBooleanCompletion(n.(BooleanLiteral).getBooleanValue()) or // The last statement in a block is any statement that does not complete normally, // or the last statement. @@ -790,20 +852,22 @@ private module ControlFlowGraphImpl { last(n.(SynchronizedStmt).getBlock(), last, completion) or // `return` statements give rise to a `Return` completion - last = n.(ReturnStmt) and completion = ReturnCompletion() + last.asStmt() = n.(ReturnStmt) and completion = ReturnCompletion() or // `throw` statements or throwing calls give rise to ` Throw` completion - exists(ThrowableType tt | mayThrow(n, tt) | last = n and completion = ThrowCompletion(tt)) + exists(ThrowableType tt | mayThrow(n, tt) | + last = n.getCFGNode() and completion = ThrowCompletion(tt) + ) or // `break` statements give rise to a `Break` completion - exists(BreakStmt break | break = n and last = n | + exists(BreakStmt break | break = n and last.asStmt() = n | completion = labelledBreakCompletion(MkLabel(break.getLabel())) or not exists(break.getLabel()) and completion = anonymousBreakCompletion() ) or // `continue` statements give rise to a `Continue` completion - exists(ContinueStmt cont | cont = n and last = n | + exists(ContinueStmt cont | cont = n and last.asStmt() = n | completion = labelledContinueCompletion(MkLabel(cont.getLabel())) or not exists(cont.getLabel()) and completion = anonymousContinueCompletion() @@ -837,17 +901,19 @@ private module ControlFlowGraphImpl { * execution finishes with the given completion. */ cached - ControlFlowNode succ(ControlFlowNode n, Completion completion) { + Node succ(Node n, Completion completion) { // Callables serve as their own exit nodes. - exists(Callable c | last(c.getBody(), n, completion) | result = c) + exists(Callable c | last(c.getBody(), n, completion) | + result.(ExitNode).getEnclosingCallable() = c + ) or // Logic expressions and conditional expressions execute in AST pre-order. completion = NormalCompletion() and ( - result = first(n.(AndLogicalExpr).getLeftOperand()) or - result = first(n.(OrLogicalExpr).getLeftOperand()) or - result = first(n.(LogNotExpr).getExpr()) or - result = first(n.(ConditionalExpr).getCondition()) + result = first(n.asExpr().(AndLogicalExpr).getLeftOperand()) or + result = first(n.asExpr().(OrLogicalExpr).getLeftOperand()) or + result = first(n.asExpr().(LogNotExpr).getExpr()) or + result = first(n.asExpr().(ConditionalExpr).getCondition()) ) or // If a logic expression doesn't short-circuit then control flows from its left operand to its right. @@ -880,11 +946,11 @@ private module ControlFlowGraphImpl { | result = first(p.getChildNode(i + 1)) or - not exists(p.getChildNode(i + 1)) and result = p + not exists(p.getChildNode(i + 1)) and result = p.getCFGNode() ) or // Statements within a block execute sequentially. - result = first(n.(Block).getStmt(0)) and completion = NormalCompletion() + result = first(n.asStmt().(Block).getStmt(0)) and completion = NormalCompletion() or exists(Block blk, int i | last(blk.getStmt(i), n, completion) and @@ -894,7 +960,7 @@ private module ControlFlowGraphImpl { or // Control flows to the corresponding branch depending on the boolean completion of the condition. exists(IfStmt s | - n = s and result = first(s.getCondition()) and completion = NormalCompletion() + n.asStmt() = s and result = first(s.getCondition()) and completion = NormalCompletion() or last(s.getCondition(), n, completion) and completion = BooleanCompletion(true, _) and @@ -906,7 +972,7 @@ private module ControlFlowGraphImpl { ) or // For statements: - exists(ForStmt for, ControlFlowNode condentry | + exists(ForStmt for, Node condentry | // Any part of the control flow that aims for the condition needs to hit either the condition... condentry = first(for.getCondition()) or @@ -914,10 +980,10 @@ private module ControlFlowGraphImpl { not exists(for.getCondition()) and condentry = first(for.getStmt()) | // From the entry point, which is the for statement itself, control goes to either the first init expression... - n = for and result = first(for.getInit(0)) and completion = NormalCompletion() + n.asStmt() = for and result = first(for.getInit(0)) and completion = NormalCompletion() or // ...or the condition if the for doesn't include init expressions. - n = for and + n.asStmt() = for and not exists(for.getAnInit()) and result = condentry and completion = NormalCompletion() @@ -954,27 +1020,29 @@ private module ControlFlowGraphImpl { // Enhanced for statements: exists(EnhancedForStmt for | // First the expression gets evaluated... - n = for and result = first(for.getExpr()) and completion = NormalCompletion() + n.asStmt() = for and result = first(for.getExpr()) and completion = NormalCompletion() or // ...then the variable gets assigned... last(for.getExpr(), n, completion) and completion = NormalCompletion() and - result = for.getVariable() + result.asExpr() = for.getVariable() or // ...and then control goes to the body of the loop. - n = for.getVariable() and result = first(for.getStmt()) and completion = NormalCompletion() + n.asExpr() = for.getVariable() and + result = first(for.getStmt()) and + completion = NormalCompletion() or // Finally, the back edge of the loop goes to reassign the variable. last(for.getStmt(), n, completion) and continues(completion, for) and - result = for.getVariable() + result.asExpr() = for.getVariable() ) or // While loops start at the condition... - result = first(n.(WhileStmt).getCondition()) and completion = NormalCompletion() + result = first(n.asStmt().(WhileStmt).getCondition()) and completion = NormalCompletion() or // ...and do-while loops start at the body. - result = first(n.(DoStmt).getStmt()) and completion = NormalCompletion() + result = first(n.asStmt().(DoStmt).getStmt()) and completion = NormalCompletion() or exists(LoopStmt loop | loop instanceof WhileStmt or loop instanceof DoStmt | // Control goes from the condition via a true-completion to the body... @@ -998,7 +1066,7 @@ private module ControlFlowGraphImpl { ) or // After the last resource declaration, control transfers to the body. - exists(TryStmt try | n = try and completion = NormalCompletion() | + exists(TryStmt try | n.asStmt() = try and completion = NormalCompletion() | result = first(try.getResource(0)) or not exists(try.getAResource()) and result = first(try.getBlock()) @@ -1026,7 +1094,7 @@ private module ControlFlowGraphImpl { or // Catch clauses first assign their variable and then execute their block exists(CatchClause cc | completion = NormalCompletion() | - n = cc and result = first(cc.getVariable()) + n.asStmt() = cc and result = first(cc.getVariable()) or last(cc.getVariable(), n, completion) and result = first(cc.getBlock()) ) @@ -1034,7 +1102,7 @@ private module ControlFlowGraphImpl { // Switch statements exists(SwitchStmt switch | completion = NormalCompletion() | // From the entry point control is transferred first to the expression... - n = switch and result = first(switch.getExpr()) + n.asStmt() = switch and result = first(switch.getExpr()) or // ...and then to one of the cases. last(switch.getExpr(), n, completion) and result = first(switch.getACase()) @@ -1048,18 +1116,18 @@ private module ControlFlowGraphImpl { // No edges in a SwitchCase - the constant expression in a ConstCase isn't included in the CFG. // Synchronized statements execute their expression _before_ synchronization, so the CFG reflects that. exists(SynchronizedStmt synch | completion = NormalCompletion() | - last(synch.getExpr(), n, completion) and result = synch + last(synch.getExpr(), n, completion) and result.asStmt() = synch or - n = synch and result = first(synch.getBlock()) + n.asStmt() = synch and result = first(synch.getBlock()) ) or - result = first(n.(ExprStmt).getExpr()) and completion = NormalCompletion() + result = first(n.asStmt().(ExprStmt).getExpr()) and completion = NormalCompletion() or - result = first(n.(LabeledStmt).getStmt()) and completion = NormalCompletion() + result = first(n.asStmt().(LabeledStmt).getStmt()) and completion = NormalCompletion() or // Variable declarations in a variable declaration statement are executed sequentially. exists(LocalVariableDeclStmt s | completion = NormalCompletion() | - n = s and result = first(s.getVariable(1)) + n.asStmt() = s and result = first(s.getVariable(1)) or exists(int i | last(s.getVariable(i), n, completion) and result = first(s.getVariable(i + 1))) ) @@ -1093,7 +1161,7 @@ private module ControlFlowGraphImpl { * predicate `finallyPred`, since their completion is resumed after normal * completion of the `finally`. */ - private Completion resumption(ControlFlowNode n) { + private Completion resumption(Node n) { exists(TryStmt try | lastInFinally(try, n) and finallyPred(try, _, result)) or not lastInFinally(_, n) and result = NormalCompletion() @@ -1104,9 +1172,7 @@ private module ControlFlowGraphImpl { * * That is, the `booleanCompletion` is the label of the edge in the CFG. */ - private ControlFlowNode mainBranchSucc(ControlFlowNode n, boolean b) { - result = succ(n, BooleanCompletion(_, b)) - } + private Node mainBranchSucc(Node n, boolean b) { result = succ(n, BooleanCompletion(_, b)) } /** * A true- or false-successor that is not tagged with a `booleanCompletion`. @@ -1117,8 +1183,8 @@ private module ControlFlowGraphImpl { * In the latter case, when `n` occurs as the last node in a finally block, there might be * multiple different such successors. */ - private ControlFlowNode otherBranchSucc(ControlFlowNode n, boolean b) { - exists(ControlFlowNode main | main = mainBranchSucc(n, b.booleanNot()) | + private Node otherBranchSucc(Node n, boolean b) { + exists(Node main | main = mainBranchSucc(n, b.booleanNot()) | result = succ(n, resumption(n)) and not result = main and (b = true or b = false) @@ -1127,7 +1193,7 @@ private module ControlFlowGraphImpl { /** Gets a true- or false-successor of `n`. */ cached - ControlFlowNode branchSuccessor(ControlFlowNode n, boolean branch) { + Node branchSuccessor(Node n, boolean branch) { result = mainBranchSucc(n, branch) or result = otherBranchSucc(n, branch) } @@ -1135,18 +1201,18 @@ private module ControlFlowGraphImpl { private import ControlFlowGraphImpl /** A control-flow node that branches based on a condition. */ -class ConditionNode extends ControlFlowNode { +class ConditionNode extends ControlFlow::Node { ConditionNode() { exists(branchSuccessor(this, _)) } /** Gets a true- or false-successor of the `ConditionNode`. */ - ControlFlowNode getABranchSuccessor(boolean branch) { result = branchSuccessor(this, branch) } + ControlFlow::Node getABranchSuccessor(boolean branch) { result = branchSuccessor(this, branch) } /** Gets a true-successor of the `ConditionNode`. */ - ControlFlowNode getATrueSuccessor() { result = getABranchSuccessor(true) } + ControlFlow::Node getATrueSuccessor() { result = getABranchSuccessor(true) } /** Gets a false-successor of the `ConditionNode`. */ - ControlFlowNode getAFalseSuccessor() { result = getABranchSuccessor(false) } + ControlFlow::Node getAFalseSuccessor() { result = getABranchSuccessor(false) } - /** Gets the condition of this `ConditionNode`. This is equal to the node itself. */ - Expr getCondition() { result = this } + /** Gets the condition of this `ConditionNode`. */ + Expr getCondition() { result = this.asExpr() } } diff --git a/java/ql/src/semmle/code/java/Expr.qll b/java/ql/src/semmle/code/java/Expr.qll index 195e3aa68947..56bcc7ccc76c 100755 --- a/java/ql/src/semmle/code/java/Expr.qll +++ b/java/ql/src/semmle/code/java/Expr.qll @@ -60,10 +60,10 @@ class Expr extends ExprParent, @expr { Expr getAChildExpr() { exprs(result, _, _, this, _) } /** Gets the basic block in which this expression occurs, if any. */ - BasicBlock getBasicBlock() { result.getANode() = this } + BasicBlock getBasicBlock() { result.getANode().asExpr() = this } /** Gets the `ControlFlowNode` corresponding to this expression. */ - ControlFlowNode getControlFlowNode() { result = this } + ControlFlowNode getControlFlowNode() { result.asExpr() = this } /** This statement's Halstead ID (used to compute Halstead metrics). */ string getHalsteadID() { result = this.toString() } diff --git a/java/ql/src/semmle/code/java/Statement.qll b/java/ql/src/semmle/code/java/Statement.qll index 29411cd26177..857e5534e794 100755 --- a/java/ql/src/semmle/code/java/Statement.qll +++ b/java/ql/src/semmle/code/java/Statement.qll @@ -36,10 +36,10 @@ class Stmt extends StmtParent, ExprParent, @stmt { Stmt getAChild() { result.getParent() = this } /** Gets the basic block in which this statement occurs. */ - BasicBlock getBasicBlock() { result.getANode() = this } + BasicBlock getBasicBlock() { result.getANode().asStmt() = this } /** Gets the `ControlFlowNode` corresponding to this statement. */ - ControlFlowNode getControlFlowNode() { result = this } + ControlFlowNode getControlFlowNode() { result.asStmt() = this } /** Cast this statement to a class that provides access to metrics information. */ MetricStmt getMetrics() { result = this } diff --git a/java/ql/src/semmle/code/java/controlflow/Dominance.qll b/java/ql/src/semmle/code/java/controlflow/Dominance.qll index d9ca3914ec73..62e8d2740afa 100644 --- a/java/ql/src/semmle/code/java/controlflow/Dominance.qll +++ b/java/ql/src/semmle/code/java/controlflow/Dominance.qll @@ -10,13 +10,15 @@ private import semmle.code.java.ControlFlowGraph */ /** Entry points for control-flow. */ -private predicate flowEntry(Stmt entry) { - exists(Callable c | entry = c.getBody()) - or - // This disjunct is technically superfluous, but safeguards against extractor problems. - entry instanceof Block and - not exists(entry.getEnclosingCallable()) and - not entry.getParent() instanceof Stmt +private predicate flowEntry(BasicBlock entry) { + exists(Stmt entrystmt | entrystmt = entry.getFirstNode().asStmt() | + exists(Callable c | entrystmt = c.getBody()) + or + // This disjunct is technically superfluous, but safeguards against extractor problems. + entrystmt instanceof Block and + not exists(entry.getEnclosingCallable()) and + not entrystmt.getParent() instanceof Stmt + ) } /** The successor relation for basic blocks. */ @@ -32,11 +34,8 @@ predicate hasDominanceInformation(BasicBlock bb) { exists(BasicBlock entry | flowEntry(entry) and bbSucc*(entry, bb)) } -/** Exit points for control-flow. */ -private predicate flowExit(Callable exit) { exists(ControlFlowNode s | s.getASuccessor() = exit) } - /** Exit points for basic-block control-flow. */ -private predicate bbSink(BasicBlock exit) { flowExit(exit.getLastNode()) } +private predicate bbSink(BasicBlock exit) { exit.getLastNode() instanceof ControlFlow::ExitNode } /** Reversed `bbSucc`. */ private predicate bbPred(BasicBlock post, BasicBlock pre) { post = pre.getABBSuccessor() } diff --git a/java/ql/src/semmle/code/java/controlflow/Guards.qll b/java/ql/src/semmle/code/java/controlflow/Guards.qll index ae164a5b0c8c..f3b7c500ca36 100644 --- a/java/ql/src/semmle/code/java/controlflow/Guards.qll +++ b/java/ql/src/semmle/code/java/controlflow/Guards.qll @@ -125,7 +125,7 @@ class Guard extends ExprParent { branch = true and bb2.getFirstNode() = sc.getControlFlowNode() and pred = sc.getControlFlowNode().getAPredecessor() and - pred.(Expr).getParent*() = sc.getSwitch().getExpr() and + pred.asExpr().getParent*() = sc.getSwitch().getExpr() and bb1 = pred.getBasicBlock() ) } @@ -160,7 +160,7 @@ private predicate switchCaseControls(SwitchCase sc, BasicBlock bb) { caseblock.getFirstNode() = sc.getControlFlowNode() and caseblock.bbDominates(bb) and forall(ControlFlowNode pred | pred = sc.getControlFlowNode().getAPredecessor() | - pred.(Expr).getParent*() = ss.getExpr() + pred.asExpr().getParent*() = ss.getExpr() ) ) } diff --git a/java/ql/src/semmle/code/java/controlflow/Paths.qll b/java/ql/src/semmle/code/java/controlflow/Paths.qll index b4e9a68b280e..1fb36b9be369 100644 --- a/java/ql/src/semmle/code/java/controlflow/Paths.qll +++ b/java/ql/src/semmle/code/java/controlflow/Paths.qll @@ -32,7 +32,7 @@ abstract class ActionConfiguration extends string { private BasicBlock actionBlock(ActionConfiguration conf) { exists(ControlFlowNode node | result = node.getBasicBlock() | conf.isAction(node) or - callAlwaysPerformsAction(node, conf) + callAlwaysPerformsAction(node.asCall(), conf) ) } @@ -43,19 +43,23 @@ private predicate callAlwaysPerformsAction(Call call, ActionConfiguration conf) ) } +private class ExitBlock extends BasicBlock { + ExitBlock() { this.getLastNode() instanceof ControlFlow::ExitNode } +} + /** Holds if an action dominates the exit of the callable. */ private predicate actionDominatesExit(Callable callable, ActionConfiguration conf) { - exists(BasicBlock exit | - exit.getLastNode() = callable and + exists(ExitBlock exit | + exit.getEnclosingCallable() = callable and actionBlock(conf).bbDominates(exit) ) } /** Gets a `BasicBlock` that contains an action that does not dominate the exit. */ private BasicBlock nonDominatingActionBlock(ActionConfiguration conf) { - exists(BasicBlock exit | + exists(ExitBlock exit | result = actionBlock(conf) and - exit.getLastNode() = result.getEnclosingCallable() and + exit.getEnclosingCallable() = result.getEnclosingCallable() and not result.bbDominates(exit) ) } @@ -80,8 +84,8 @@ private predicate postActionBlock(BasicBlock bb, ActionConfiguration conf) { private predicate callableAlwaysPerformsAction(Callable callable, ActionConfiguration conf) { actionDominatesExit(callable, conf) or - exists(BasicBlock exit | - exit.getLastNode() = callable and + exists(ExitBlock exit | + exit.getEnclosingCallable() = callable and postActionBlock(exit, conf) ) } diff --git a/java/ql/src/semmle/code/java/controlflow/UnreachableBlocks.qll b/java/ql/src/semmle/code/java/controlflow/UnreachableBlocks.qll index c7be6d2494dc..e445d578d0c4 100644 --- a/java/ql/src/semmle/code/java/controlflow/UnreachableBlocks.qll +++ b/java/ql/src/semmle/code/java/controlflow/UnreachableBlocks.qll @@ -210,14 +210,12 @@ class UnreachableBasicBlock extends BasicBlock { conditionBlock.controls(this, constant.booleanNot()) ) or - // This block is not reachable in the CFG, and is not a callable, a body of a callable, an - // expression in an annotation, an expression in an assert statement, or a catch clause. + // This block is not reachable in the CFG, and is not the entrypoint in a callable, an + // expression in an assert statement, or a catch clause. forall(BasicBlock bb | bb = getABBPredecessor() | bb instanceof UnreachableBasicBlock) and - not exists(Callable c | c.getBody() = this) and - not this instanceof Callable and - not exists(Annotation a | a.getAChildExpr*() = this) and - not exists(AssertStmt a | a = this.(Expr).getEnclosingStmt()) and - not this instanceof CatchClause + not exists(Callable c | c.getBody().getControlFlowNode() = this.getFirstNode()) and + not exists(AssertStmt a | a = this.getFirstNode().asExpr().getEnclosingStmt()) and + not this.getFirstNode().asStmt() instanceof CatchClause or // Switch statements with a constant comparison expression may have unreachable cases. exists(ConstSwitchStmt constSwitchStmt, BasicBlock failingCaseBlock | @@ -226,7 +224,7 @@ class UnreachableBasicBlock extends BasicBlock { // Not accessible from the successful case not constSwitchStmt.getMatchingCase().getBasicBlock().getABBSuccessor*() = failingCaseBlock and // Blocks dominated by the failing case block are unreachable - constSwitchStmt.getAFailingCase().getBasicBlock().bbDominates(this) + failingCaseBlock.bbDominates(this) ) } } diff --git a/java/ql/src/semmle/code/java/dataflow/Guards.qll b/java/ql/src/semmle/code/java/dataflow/Guards.qll index 474c0d1c8368..54f823a0f664 100644 --- a/java/ql/src/semmle/code/java/dataflow/Guards.qll +++ b/java/ql/src/semmle/code/java/dataflow/Guards.qll @@ -11,7 +11,7 @@ deprecated class ConditionBlock = Guards::ConditionBlock; /** Holds if `n` updates the locally scoped variable `v`. */ deprecated predicate variableUpdate(ControlFlowNode n, LocalScopeVariable v) { - exists(VariableUpdate a | a = n | a.getDestVar() = v) + exists(VariableUpdate a | a.getControlFlowNode() = n | a.getDestVar() = v) } /** Holds if `bb` updates the locally scoped variable `v`. */ diff --git a/java/ql/src/semmle/code/java/dataflow/InstanceAccess.qll b/java/ql/src/semmle/code/java/dataflow/InstanceAccess.qll index 0fa167ffe32c..29781ffa99ef 100644 --- a/java/ql/src/semmle/code/java/dataflow/InstanceAccess.qll +++ b/java/ql/src/semmle/code/java/dataflow/InstanceAccess.qll @@ -229,12 +229,14 @@ class InstanceAccessExt extends TInstanceAccessExt { /** Gets the control flow node associated with this instance access. */ ControlFlowNode getCfgNode() { exists(ExprParent e | e = getAssociatedExprOrStmt() | - e instanceof Call and result = e + result.asCall() = e or - e instanceof InstanceAccess and result = e + e.(InstanceAccess).getControlFlowNode() = result or exists(FieldAccess fa | fa = e | - if fa instanceof RValue then fa = result else result.(AssignExpr).getDest() = fa + if fa instanceof RValue + then fa.getControlFlowNode() = result + else result.asExpr().(AssignExpr).getDest() = fa ) ) } diff --git a/java/ql/src/semmle/code/java/dataflow/ModulusAnalysis.qll b/java/ql/src/semmle/code/java/dataflow/ModulusAnalysis.qll index e0e3b7ea4ba4..5c19e56d40a7 100644 --- a/java/ql/src/semmle/code/java/dataflow/ModulusAnalysis.qll +++ b/java/ql/src/semmle/code/java/dataflow/ModulusAnalysis.qll @@ -135,11 +135,17 @@ private predicate evenlyDivisibleExpr(Expr e, int factor) { ) } -private predicate id(BasicBlock x, BasicBlock y) { x = y } +private ExprParent getAst(BasicBlock bb) { + exists(ControlFlowNode n | bb.getFirstNode() = n | n.asExpr() = result or n.asStmt() = result) +} + +private class AstAtBasicBlock extends ExprParent { AstAtBasicBlock() { this = getAst(_) } } + +private predicate id(AstAtBasicBlock x, AstAtBasicBlock y) { x = y } -private predicate idOf(BasicBlock x, int y) = equivalenceRelation(id/2)(x, y) +private predicate idOf(AstAtBasicBlock x, int y) = equivalenceRelation(id/2)(x, y) -private int getId(BasicBlock bb) { idOf(bb, result) } +private int getId(BasicBlock bb) { idOf(getAst(bb), result) } /** * Holds if `inp` is an input to `phi` along `edge` and this input has index `r` diff --git a/java/ql/src/semmle/code/java/dataflow/Nullness.qll b/java/ql/src/semmle/code/java/dataflow/Nullness.qll index 34557f9075ef..51612fd36293 100644 --- a/java/ql/src/semmle/code/java/dataflow/Nullness.qll +++ b/java/ql/src/semmle/code/java/dataflow/Nullness.qll @@ -132,7 +132,7 @@ private ControlFlowNode varDereference(SsaVariable v, VarAccess va) { exists(Expr e | dereference(e) and e = sameValue(v, va) and - result = e.getProperExpr() + result = e.getProperExpr().getControlFlowNode() ) } @@ -142,10 +142,10 @@ private ControlFlowNode varDereference(SsaVariable v, VarAccess va) { */ private ControlFlowNode ensureNotNull(SsaVariable v) { result = varDereference(v, _) or - result.(AssertStmt).getExpr() = nullGuard(v, true, false) or - exists(AssertTrueMethod m | result = m.getACheck(nullGuard(v, true, false))) or - exists(AssertFalseMethod m | result = m.getACheck(nullGuard(v, false, false))) or - exists(AssertNotNullMethod m | result = m.getACheck(v.getAUse())) + result.asStmt().(AssertStmt).getExpr() = nullGuard(v, true, false) or + exists(AssertTrueMethod m | result.asExpr() = m.getACheck(nullGuard(v, true, false))) or + exists(AssertFalseMethod m | result.asExpr() = m.getACheck(nullGuard(v, false, false))) or + exists(AssertNotNullMethod m | result.asExpr() = m.getACheck(v.getAUse())) } /** @@ -271,10 +271,10 @@ private predicate enhancedForEarlyExit(EnhancedForStmt for, ControlFlowNode n1, exists(Expr forExpr | n1.getANormalSuccessor() = n2 and for.getExpr() = forExpr and - forExpr.getAChildExpr*() = n1 and - not forExpr.getAChildExpr*() = n2 and - n1.getANormalSuccessor() = for.getVariable() and - not n2 = for.getVariable() + forExpr.getAChildExpr*() = n1.asExpr() and + not forExpr.getAChildExpr*() = n2.asExpr() and + n1.getANormalSuccessor() = for.getVariable().getControlFlowNode() and + not n2 = for.getVariable().getControlFlowNode() ) } @@ -335,7 +335,7 @@ private predicate nullVarStep( not impossibleEdge(mid, bb) and not exists(boolean branch | nullGuard(midssa, branch, false).hasBranchEdge(mid, bb, branch)) and not (leavingFinally(mid, bb, true) and midstoredcompletion = true) and - if bb.getFirstNode() = any(TryStmt try | | try.getFinally()) + if bb.getFirstNode().asStmt() = any(TryStmt try | | try.getFinally()) then if bb.getFirstNode() = mid.getLastNode().getANormalSuccessor() then storedcompletion = false diff --git a/java/ql/src/semmle/code/java/dataflow/SSA.qll b/java/ql/src/semmle/code/java/dataflow/SSA.qll index 484fe0c82e16..bb1a30062a54 100644 --- a/java/ql/src/semmle/code/java/dataflow/SSA.qll +++ b/java/ql/src/semmle/code/java/dataflow/SSA.qll @@ -224,7 +224,7 @@ private module SsaImpl { /** Holds if `n` must update the locally tracked variable `v`. */ cached predicate certainVariableUpdate(TrackedVar v, ControlFlowNode n, BasicBlock b, int i) { - exists(VariableUpdate a | a = n | getDestVar(a) = v) and + exists(VariableUpdate a | a.getControlFlowNode() = n | getDestVar(a) = v) and b.getNode(i) = n and hasDominanceInformation(b) or @@ -233,8 +233,8 @@ private module SsaImpl { /** Gets the definition point of a nested class in the parent scope. */ private ControlFlowNode parentDef(NestedClass nc) { - nc.(AnonymousClass).getClassInstanceExpr() = result or - nc.(LocalClass).getLocalClassDeclStmt() = result + nc.(AnonymousClass).getClassInstanceExpr().getControlFlowNode() = result or + nc.(LocalClass).getLocalClassDeclStmt().getControlFlowNode() = result } /** @@ -272,7 +272,7 @@ private module SsaImpl { /** Holds if `VarAccess` `use` of `v` occurs in `b` at index `i`. */ private predicate variableUse(TrackedVar v, RValue use, BasicBlock b, int i) { - v.getAnAccess() = use and b.getNode(i) = use + v.getAnAccess() = use and b.getNode(i) = use.getControlFlowNode() } /** Holds if the value of `v` is captured in `b` at index `i`. */ @@ -434,7 +434,7 @@ private module SsaImpl { * `f` has an update somewhere. */ private predicate updateCandidate(TrackedField f, Call call, BasicBlock b, int i) { - b.getNode(i) = call and + b.getNode(i).asCall() = call and call.getEnclosingCallable() = f.getEnclosingCallable() and relevantFieldUpdate(_, f.getField(), _) } @@ -559,7 +559,7 @@ private module SsaImpl { /** Holds if `n` might update the locally tracked variable `v`. */ cached predicate uncertainVariableUpdate(TrackedVar v, ControlFlowNode n, BasicBlock b, int i) { - exists(Call c | c = n | updatesNamedField(c, v, _)) and + exists(Call c | c = n.asCall() | updatesNamedField(c, v, _)) and b.getNode(i) = n and hasDominanceInformation(b) or @@ -583,12 +583,16 @@ private module SsaImpl { /** Holds if `v` has an implicit definition at the entry, `b`, of the callable. */ cached predicate hasEntryDef(TrackedVar v, BasicBlock b) { - exists(LocalScopeVariable l, Callable c | v = TLocalVar(c, l) and c.getBody() = b | + exists(LocalScopeVariable l, Callable c | + v = TLocalVar(c, l) and c.getBody().getControlFlowNode() = b.getFirstNode() + | l instanceof Parameter or l.getCallable() != c ) or - v instanceof SsaSourceField and v.getEnclosingCallable().getBody() = b and liveAtEntry(v, b) + v instanceof SsaSourceField and + v.getEnclosingCallable().getBody().getControlFlowNode() = b.getFirstNode() and + liveAtEntry(v, b) } /** @@ -883,7 +887,7 @@ private newtype TSsaVariable = } or TSsaEntryDef(TrackedVar v, BasicBlock b) { hasEntryDef(v, b) } or TSsaUntracked(SsaSourceField nf, ControlFlowNode n) { - n = nf.getAnAccess().(FieldRead) and not trackField(nf) + n = nf.getAnAccess().(FieldRead).getControlFlowNode() and not trackField(nf) } /** @@ -939,7 +943,7 @@ class SsaVariable extends TSsaVariable { /** Gets an access of this SSA variable. */ RValue getAUse() { ssaDefReachesUse(_, this, result) or - this = TSsaUntracked(_, result) + this = TSsaUntracked(_, result.getControlFlowNode()) } /** @@ -953,7 +957,7 @@ class SsaVariable extends TSsaVariable { */ RValue getAFirstUse() { firstUse(this, result) or - this = TSsaUntracked(_, result) + this = TSsaUntracked(_, result.getControlFlowNode()) } /** Holds if this SSA variable is live at the end of `b`. */ @@ -988,14 +992,16 @@ class SsaUpdate extends SsaVariable { /** An SSA variable that is defined by a `VariableUpdate`. */ class SsaExplicitUpdate extends SsaUpdate, TSsaCertainUpdate { SsaExplicitUpdate() { - exists(VariableUpdate upd | upd = this.getCFGNode() and getDestVar(upd) = getSourceVariable()) + exists(VariableUpdate upd | + upd.getControlFlowNode() = this.getCFGNode() and getDestVar(upd) = getSourceVariable() + ) } override string toString() { result = "SSA def(" + getSourceVariable() + ")" } /** Gets the `VariableUpdate` defining the SSA variable. */ VariableUpdate getDefiningExpr() { - result = this.getCFGNode() and getDestVar(result) = getSourceVariable() + result.getControlFlowNode() = this.getCFGNode() and getDestVar(result) = getSourceVariable() } } @@ -1035,7 +1041,7 @@ class SsaImplicitUpdate extends SsaUpdate { exists(SsaSourceField f, Callable setter | f = getSourceVariable() and relevantFieldUpdate(setter, f.getField(), result) and - updatesNamedField(getCFGNode(), f, setter) + updatesNamedField(getCFGNode().asCall(), f, setter) ) } @@ -1082,7 +1088,8 @@ class SsaImplicitInit extends SsaVariable, TSsaEntryDef { * Holds if the SSA variable is a parameter defined by its initial value in the callable. */ predicate isParameterDefinition(Parameter p) { - getSourceVariable() = TLocalVar(p.getCallable(), p) and p.getCallable().getBody() = getCFGNode() + getSourceVariable() = TLocalVar(p.getCallable(), p) and + p.getCallable().getBody().getControlFlowNode() = getCFGNode() } } diff --git a/java/ql/src/semmle/code/java/dataflow/TypeFlow.qll b/java/ql/src/semmle/code/java/dataflow/TypeFlow.qll index 731681add97d..fd00e8b2f5d5 100644 --- a/java/ql/src/semmle/code/java/dataflow/TypeFlow.qll +++ b/java/ql/src/semmle/code/java/dataflow/TypeFlow.qll @@ -270,8 +270,8 @@ private predicate downcastSuccessor(VarAccess va, RefType t) { downcastSuccessorAux(cast, v, t, t1, t2) and t1.getASourceSupertype+() = t2 and va = v.getAUse() and - dominates(cast, va) and - dominates(cast.(ControlFlowNode).getANormalSuccessor(), va) + dominates(cast.getControlFlowNode(), va.getControlFlowNode()) and + dominates(cast.getControlFlowNode().getANormalSuccessor(), va.getControlFlowNode()) ) } diff --git a/java/ql/src/semmle/code/java/dataflow/internal/BaseSSA.qll b/java/ql/src/semmle/code/java/dataflow/internal/BaseSSA.qll index 0e4060d09260..949bf8d2901f 100644 --- a/java/ql/src/semmle/code/java/dataflow/internal/BaseSSA.qll +++ b/java/ql/src/semmle/code/java/dataflow/internal/BaseSSA.qll @@ -71,15 +71,15 @@ private module SsaImpl { /** Holds if `n` updates the local variable `v`. */ cached predicate variableUpdate(BaseSsaSourceVariable v, ControlFlowNode n, BasicBlock b, int i) { - exists(VariableUpdate a | a = n | getDestVar(a) = v) and + exists(VariableUpdate a | a.getControlFlowNode() = n | getDestVar(a) = v) and b.getNode(i) = n and hasDominanceInformation(b) } /** Gets the definition point of a nested class in the parent scope. */ private ControlFlowNode parentDef(NestedClass nc) { - nc.(AnonymousClass).getClassInstanceExpr() = result or - nc.(LocalClass).getLocalClassDeclStmt() = result + nc.(AnonymousClass).getClassInstanceExpr().getControlFlowNode() = result or + nc.(LocalClass).getLocalClassDeclStmt().getControlFlowNode() = result } /** @@ -119,7 +119,7 @@ private module SsaImpl { /** Holds if `VarAccess` `use` of `v` occurs in `b` at index `i`. */ private predicate variableUse(BaseSsaSourceVariable v, RValue use, BasicBlock b, int i) { - v.getAnAccess() = use and b.getNode(i) = use + v.getAnAccess() = use and b.getNode(i) = use.getControlFlowNode() } /** Holds if the value of `v` is captured in `b` at index `i`. */ @@ -162,7 +162,9 @@ private module SsaImpl { /** Holds if `v` has an implicit definition at the entry, `b`, of the callable. */ cached predicate hasEntryDef(BaseSsaSourceVariable v, BasicBlock b) { - exists(LocalScopeVariable l, Callable c | v = TLocalVar(c, l) and c.getBody() = b | + exists(LocalScopeVariable l, Callable c | + v = TLocalVar(c, l) and c.getBody().getControlFlowNode() = b.getFirstNode() + | l instanceof Parameter or l.getCallable() != c ) @@ -384,14 +386,16 @@ class BaseSsaVariable extends TBaseSsaVariable { /** An SSA variable that is defined by a `VariableUpdate`. */ class BaseSsaUpdate extends BaseSsaVariable, TSsaUpdate { BaseSsaUpdate() { - exists(VariableUpdate upd | upd = this.getCFGNode() and getDestVar(upd) = getSourceVariable()) + exists(VariableUpdate upd | + upd.getControlFlowNode() = this.getCFGNode() and getDestVar(upd) = getSourceVariable() + ) } override string toString() { result = "SSA def(" + getSourceVariable() + ")" } /** Gets the `VariableUpdate` defining the SSA variable. */ VariableUpdate getDefiningExpr() { - result = this.getCFGNode() and getDestVar(result) = getSourceVariable() + result.getControlFlowNode() = this.getCFGNode() and getDestVar(result) = getSourceVariable() } } @@ -411,7 +415,8 @@ class BaseSsaImplicitInit extends BaseSsaVariable, TSsaEntryDef { * Holds if the SSA variable is a parameter defined by its initial value in the callable. */ predicate isParameterDefinition(Parameter p) { - getSourceVariable() = TLocalVar(p.getCallable(), p) and p.getCallable().getBody() = getCFGNode() + getSourceVariable() = TLocalVar(p.getCallable(), p) and + p.getCallable().getBody().getControlFlowNode() = getCFGNode() } } diff --git a/java/ql/src/semmle/code/java/dataflow/internal/DataFlowUtil.qll b/java/ql/src/semmle/code/java/dataflow/internal/DataFlowUtil.qll index 7fab84a10e2e..dc8a470b9410 100644 --- a/java/ql/src/semmle/code/java/dataflow/internal/DataFlowUtil.qll +++ b/java/ql/src/semmle/code/java/dataflow/internal/DataFlowUtil.qll @@ -265,9 +265,11 @@ private class ImplicitStoreTarget extends ImplicitPostUpdateNode, TImplicitStore /** Holds if `n` is an access to an unqualified `this` at `cfgnode`. */ private predicate thisAccess(Node n, ControlFlowNode cfgnode) { - n.(InstanceParameterNode).getCallable().getBody() = cfgnode + n.(InstanceParameterNode).getCallable().getBody().getControlFlowNode() = cfgnode or - exists(InstanceAccess ia | ia = n.asExpr() and ia = cfgnode and ia.isOwnInstanceAccess()) + exists(InstanceAccess ia | + ia = n.asExpr() and ia.getControlFlowNode() = cfgnode and ia.isOwnInstanceAccess() + ) or n.(ImplicitInstanceAccess).getInstanceAccess().(OwnInstanceAccess).getCfgNode() = cfgnode } diff --git a/java/ql/src/semmle/code/java/frameworks/Assertions.qll b/java/ql/src/semmle/code/java/frameworks/Assertions.qll index 2fb6a3d82256..75ca2a51b704 100644 --- a/java/ql/src/semmle/code/java/frameworks/Assertions.qll +++ b/java/ql/src/semmle/code/java/frameworks/Assertions.qll @@ -91,12 +91,12 @@ predicate assertFail(BasicBlock bb, ControlFlowNode n) { bb = n.getBasicBlock() and ( exists(AssertTrueMethod m | - n = m.getACheck(any(BooleanLiteral b | b.getBooleanValue() = false)) + n.asExpr() = m.getACheck(any(BooleanLiteral b | b.getBooleanValue() = false)) ) or exists(AssertFalseMethod m | - n = m.getACheck(any(BooleanLiteral b | b.getBooleanValue() = true)) + n.asExpr() = m.getACheck(any(BooleanLiteral b | b.getBooleanValue() = true)) ) or - exists(AssertFailMethod m | n = m.getACheck()) or - n.(AssertStmt).getExpr().getProperExpr().(BooleanLiteral).getBooleanValue() = false + exists(AssertFailMethod m | n.asExpr() = m.getACheck()) or + n.asStmt().(AssertStmt).getExpr().getProperExpr().(BooleanLiteral).getBooleanValue() = false ) } diff --git a/java/ql/src/semmle/code/java/metrics/MetricCallable.qll b/java/ql/src/semmle/code/java/metrics/MetricCallable.qll index b59330b879f5..33e25f2ff159 100755 --- a/java/ql/src/semmle/code/java/metrics/MetricCallable.qll +++ b/java/ql/src/semmle/code/java/metrics/MetricCallable.qll @@ -70,14 +70,16 @@ class MetricCallable extends Callable { // so there should be a branching point for each non-default switch // case (ignoring those that just fall through to the next case). private predicate branchingSwitchCase(ConstCase sc) { - not sc.(ControlFlowNode).getASuccessor() instanceof ConstCase and - not sc.(ControlFlowNode).getASuccessor() instanceof DefaultCase and + not sc.getControlFlowNode().getASuccessor().asStmt() instanceof ConstCase and + not sc.getControlFlowNode().getASuccessor().asStmt() instanceof DefaultCase and not defaultFallThrough(sc) } private predicate defaultFallThrough(ConstCase sc) { - exists(DefaultCase default | default.(ControlFlowNode).getASuccessor() = sc) or - defaultFallThrough(sc.(ControlFlowNode).getAPredecessor()) + exists(DefaultCase default | + default.getControlFlowNode().getASuccessor() = sc.getControlFlowNode() + ) or + defaultFallThrough(sc.getControlFlowNode().getAPredecessor().asStmt()) } /** Holds if `stmt` is a branching statement used for the computation of cyclomatic complexity. */ diff --git a/java/ql/test/library-tests/controlflow/basic/bbStmts.expected b/java/ql/test/library-tests/controlflow/basic/bbStmts.expected index 1b239e1dd29f..f92601b612d6 100644 --- a/java/ql/test/library-tests/controlflow/basic/bbStmts.expected +++ b/java/ql/test/library-tests/controlflow/basic/bbStmts.expected @@ -1,7 +1,7 @@ -| Test.java:3:14:3:17 | stmt | Test.java:3:14:3:17 | Test | 2 | +| Test.java:3:14:3:17 | stmt | Test.java:3:14:3:17 | Exit | 2 | | Test.java:3:14:3:17 | stmt | Test.java:3:14:3:17 | stmt | 0 | | Test.java:3:14:3:17 | stmt | Test.java:3:14:3:17 | super(...) | 1 | -| Test.java:4:14:4:17 | test | Test.java:4:14:4:17 | test | 0 | +| Test.java:4:14:4:17 | Exit | Test.java:4:14:4:17 | Exit | 0 | | Test.java:4:21:76:2 | stmt | Test.java:4:21:76:2 | stmt | 0 | | Test.java:4:21:76:2 | stmt | Test.java:5:3:5:12 | stmt | 1 | | Test.java:4:21:76:2 | stmt | Test.java:5:7:5:11 | x | 3 | diff --git a/java/ql/test/library-tests/controlflow/basic/bbStmts.ql b/java/ql/test/library-tests/controlflow/basic/bbStmts.ql index 52c95e13650d..b4cd05975967 100644 --- a/java/ql/test/library-tests/controlflow/basic/bbStmts.ql +++ b/java/ql/test/library-tests/controlflow/basic/bbStmts.ql @@ -3,5 +3,5 @@ import default from BasicBlock b, ControlFlowNode n, int i where b.getNode(i) = n and - b.getFile().(CompilationUnit).fromSource() + b.getEnclosingCallable().getFile().(CompilationUnit).fromSource() select b, n, i diff --git a/java/ql/test/library-tests/controlflow/basic/bbStrictDominance.expected b/java/ql/test/library-tests/controlflow/basic/bbStrictDominance.expected index db3694335274..b6b323510aba 100644 --- a/java/ql/test/library-tests/controlflow/basic/bbStrictDominance.expected +++ b/java/ql/test/library-tests/controlflow/basic/bbStrictDominance.expected @@ -1,4 +1,4 @@ -| Test.java:4:21:76:2 | stmt | Test.java:4:14:4:17 | test | +| Test.java:4:21:76:2 | stmt | Test.java:4:14:4:17 | Exit | | Test.java:4:21:76:2 | stmt | Test.java:11:14:14:3 | stmt | | Test.java:4:21:76:2 | stmt | Test.java:14:10:16:3 | stmt | | Test.java:4:21:76:2 | stmt | Test.java:18:3:18:8 | stmt | @@ -20,7 +20,7 @@ | Test.java:4:21:76:2 | stmt | Test.java:60:12:62:5 | stmt | | Test.java:4:21:76:2 | stmt | Test.java:63:9:66:4 | stmt | | Test.java:4:21:76:2 | stmt | Test.java:70:3:70:9 | stmt | -| Test.java:18:3:18:8 | stmt | Test.java:4:14:4:17 | test | +| Test.java:18:3:18:8 | stmt | Test.java:4:14:4:17 | Exit | | Test.java:18:3:18:8 | stmt | Test.java:22:4:22:10 | stmt | | Test.java:18:3:18:8 | stmt | Test.java:24:4:24:10 | stmt | | Test.java:18:3:18:8 | stmt | Test.java:30:15:33:3 | stmt | diff --git a/java/ql/test/library-tests/controlflow/basic/bbSuccessor.expected b/java/ql/test/library-tests/controlflow/basic/bbSuccessor.expected index 3aeb7b5553d3..17ad2c861a26 100644 --- a/java/ql/test/library-tests/controlflow/basic/bbSuccessor.expected +++ b/java/ql/test/library-tests/controlflow/basic/bbSuccessor.expected @@ -6,7 +6,7 @@ | Test.java:18:3:18:8 | stmt | Test.java:24:4:24:10 | stmt | | Test.java:22:4:22:10 | stmt | Test.java:30:15:33:3 | stmt | | Test.java:22:4:22:10 | stmt | Test.java:35:3:35:9 | stmt | -| Test.java:24:4:24:10 | stmt | Test.java:4:14:4:17 | test | +| Test.java:24:4:24:10 | stmt | Test.java:4:14:4:17 | Exit | | Test.java:30:15:33:3 | stmt | Test.java:35:3:35:9 | stmt | | Test.java:35:3:35:9 | stmt | Test.java:38:9:38:9 | x | | Test.java:38:9:38:9 | x | Test.java:38:16:41:3 | stmt | @@ -27,4 +27,4 @@ | Test.java:57:15:60:5 | stmt | Test.java:70:3:70:9 | stmt | | Test.java:60:12:62:5 | stmt | Test.java:54:26:54:26 | j | | Test.java:63:9:66:4 | stmt | Test.java:54:26:54:26 | j | -| Test.java:70:3:70:9 | stmt | Test.java:4:14:4:17 | test | +| Test.java:70:3:70:9 | stmt | Test.java:4:14:4:17 | Exit | diff --git a/java/ql/test/library-tests/controlflow/basic/strictDominance.ql b/java/ql/test/library-tests/controlflow/basic/strictDominance.ql index 2d366a4f3727..10529b6d5c86 100644 --- a/java/ql/test/library-tests/controlflow/basic/strictDominance.ql +++ b/java/ql/test/library-tests/controlflow/basic/strictDominance.ql @@ -2,5 +2,5 @@ import default import semmle.code.java.controlflow.Dominance from Stmt pre, Stmt post -where strictlyDominates(pre, post) +where strictlyDominates(pre.getControlFlowNode(), post.getControlFlowNode()) select pre, post diff --git a/java/ql/test/library-tests/controlflow/basic/strictPostDominance.ql b/java/ql/test/library-tests/controlflow/basic/strictPostDominance.ql index 9948718fc83b..99268a03c4be 100644 --- a/java/ql/test/library-tests/controlflow/basic/strictPostDominance.ql +++ b/java/ql/test/library-tests/controlflow/basic/strictPostDominance.ql @@ -2,5 +2,5 @@ import default import semmle.code.java.controlflow.Dominance from Stmt pre, Stmt post -where strictlyPostDominates(post, pre) +where strictlyPostDominates(post.getControlFlowNode(), pre.getControlFlowNode()) select post, pre diff --git a/java/ql/test/library-tests/controlflow/dominance/dominanceBad.ql b/java/ql/test/library-tests/controlflow/dominance/dominanceBad.ql index 847b0347d373..c3deaf16851e 100644 --- a/java/ql/test/library-tests/controlflow/dominance/dominanceBad.ql +++ b/java/ql/test/library-tests/controlflow/dominance/dominanceBad.ql @@ -4,6 +4,6 @@ import semmle.code.java.controlflow.Dominance from IfStmt i, Block b where b = i.getThen() and - dominates(i.getThen(), b) and - dominates(i.getElse(), b) + dominates(i.getThen().getControlFlowNode(), b.getControlFlowNode()) and + dominates(i.getElse().getControlFlowNode(), b.getControlFlowNode()) select i, b diff --git a/java/ql/test/library-tests/controlflow/dominance/dominanceWrong.ql b/java/ql/test/library-tests/controlflow/dominance/dominanceWrong.ql index 298e0752ee41..5ee23224d5f9 100644 --- a/java/ql/test/library-tests/controlflow/dominance/dominanceWrong.ql +++ b/java/ql/test/library-tests/controlflow/dominance/dominanceWrong.ql @@ -17,5 +17,5 @@ predicate dominanceCounterExample(ControlFlowNode entry, ControlFlowNode dom, Co from Callable c, ControlFlowNode dom, ControlFlowNode node where (strictlyDominates(dom, node) or bbStrictlyDominates(dom, node)) and - dominanceCounterExample(c.getBody(), dom, node) + dominanceCounterExample(c.getBody().getControlFlowNode(), dom, node) select c, dom, node diff --git a/java/ql/test/library-tests/controlflow/dominance/dominatedByStart.ql b/java/ql/test/library-tests/controlflow/dominance/dominatedByStart.ql index b5bdf6889967..9a0d1b0c4bba 100644 --- a/java/ql/test/library-tests/controlflow/dominance/dominatedByStart.ql +++ b/java/ql/test/library-tests/controlflow/dominance/dominatedByStart.ql @@ -3,14 +3,14 @@ import default import semmle.code.java.controlflow.Dominance ControlFlowNode reachableIn(Method func) { - result = func.getBody() or + result = func.getBody().getControlFlowNode() or result = reachableIn(func).getASuccessor() } from Method func, ControlFlowNode entry, ControlFlowNode node where - func.getBody() = entry and + func.getBody().getControlFlowNode() = entry and reachableIn(func) = node and entry != node and - not strictlyDominates(func.getBody(), node) + not strictlyDominates(func.getBody().getControlFlowNode(), node) select func, node diff --git a/java/ql/test/library-tests/controlflow/dominance/dominator.expected b/java/ql/test/library-tests/controlflow/dominance/dominator.expected index 36d5a3f38db3..c88bbdb172ec 100644 --- a/java/ql/test/library-tests/controlflow/dominance/dominator.expected +++ b/java/ql/test/library-tests/controlflow/dominance/dominator.expected @@ -27,7 +27,7 @@ | Test.java:14:18:14:18 | y | Test.java:14:14:14:18 | ... + ... | | Test.java:17:3:17:12 | stmt | Test.java:17:7:17:7 | x | | Test.java:17:7:17:7 | x | Test.java:17:11:17:11 | 0 | -| Test.java:17:7:17:11 | ... < ... | Test.java:2:6:2:9 | test | +| Test.java:17:7:17:11 | ... < ... | Test.java:2:6:2:9 | Exit | | Test.java:17:7:17:11 | ... < ... | Test.java:18:4:18:10 | stmt | | Test.java:17:7:17:11 | ... < ... | Test.java:20:11:20:11 | z | | Test.java:17:11:17:11 | 0 | Test.java:17:7:17:11 | ... < ... | @@ -163,7 +163,7 @@ | Test.java:83:9:83:9 | c | Test.java:83:5:83:9 | ...=... | | Test.java:85:4:85:15 | stmt | Test.java:85:8:85:8 | a | | Test.java:85:8:85:8 | a | Test.java:85:13:85:14 | 10 | -| Test.java:85:8:85:14 | ... == ... | Test.java:74:6:74:10 | test2 | +| Test.java:85:8:85:14 | ... == ... | Test.java:74:6:74:10 | Exit | | Test.java:85:8:85:14 | ... == ... | Test.java:86:5:86:10 | stmt | | Test.java:85:8:85:14 | ... == ... | Test.java:87:4:87:15 | stmt | | Test.java:85:13:85:14 | 10 | Test.java:85:8:85:14 | ... == ... | diff --git a/java/ql/test/library-tests/controlflow/dominance/dominatorExists.ql b/java/ql/test/library-tests/controlflow/dominance/dominatorExists.ql index 34469a686b14..220e4f275d54 100644 --- a/java/ql/test/library-tests/controlflow/dominance/dominatorExists.ql +++ b/java/ql/test/library-tests/controlflow/dominance/dominatorExists.ql @@ -4,13 +4,13 @@ import semmle.code.java.controlflow.Dominance /** transitive dominance */ ControlFlowNode reachableIn(Method func) { - result = func.getBody() or + result = func.getBody().getControlFlowNode() or result = reachableIn(func).getASuccessor() } from Method func, ControlFlowNode node where node = reachableIn(func) and - node != func.getBody() and + node != func.getBody().getControlFlowNode() and not iDominates(_, node) select func, node diff --git a/java/ql/test/library-tests/controlflow/paths/paths.ql b/java/ql/test/library-tests/controlflow/paths/paths.ql index 7216b8e829a7..20d268963b47 100644 --- a/java/ql/test/library-tests/controlflow/paths/paths.ql +++ b/java/ql/test/library-tests/controlflow/paths/paths.ql @@ -5,7 +5,7 @@ class PathTestConf extends ActionConfiguration { PathTestConf() { this = "PathTestConf" } override predicate isAction(ControlFlowNode node) { - node.(MethodAccess).getMethod().hasName("action") + node.asExpr().(MethodAccess).getMethod().hasName("action") } } diff --git a/java/ql/test/library-tests/java7/MultiCatch/MultiCatchControlFlow.expected b/java/ql/test/library-tests/java7/MultiCatch/MultiCatchControlFlow.expected index 624f3a90f7aa..7741deceb3ba 100644 --- a/java/ql/test/library-tests/java7/MultiCatch/MultiCatchControlFlow.expected +++ b/java/ql/test/library-tests/java7/MultiCatch/MultiCatchControlFlow.expected @@ -1,5 +1,5 @@ | MultiCatch.java:6:14:6:23 | stmt | MultiCatch.java:6:14:6:23 | super(...) | -| MultiCatch.java:6:14:6:23 | super(...) | MultiCatch.java:6:14:6:23 | MultiCatch | +| MultiCatch.java:6:14:6:23 | super(...) | MultiCatch.java:6:14:6:23 | Exit | | MultiCatch.java:8:2:20:2 | stmt | MultiCatch.java:9:3:19:3 | stmt | | MultiCatch.java:9:3:19:3 | stmt | MultiCatch.java:10:3:15:3 | stmt | | MultiCatch.java:10:3:15:3 | stmt | MultiCatch.java:11:4:11:8 | stmt | @@ -16,7 +16,7 @@ | MultiCatch.java:17:4:17:4 | e | MultiCatch.java:17:4:17:22 | printStackTrace(...) | | MultiCatch.java:17:4:17:22 | printStackTrace(...) | MultiCatch.java:18:10:18:10 | e | | MultiCatch.java:17:4:17:23 | stmt | MultiCatch.java:17:4:17:4 | e | -| MultiCatch.java:18:4:18:11 | stmt | MultiCatch.java:7:14:7:23 | multiCatch | +| MultiCatch.java:18:4:18:11 | stmt | MultiCatch.java:7:14:7:23 | Exit | | MultiCatch.java:18:10:18:10 | e | MultiCatch.java:18:4:18:11 | stmt | | MultiCatch.java:23:2:33:2 | stmt | MultiCatch.java:24:3:32:4 | stmt | | MultiCatch.java:24:3:32:4 | stmt | MultiCatch.java:25:3:31:3 | stmt | @@ -31,12 +31,12 @@ | MultiCatch.java:28:12:28:12 | c | MultiCatch.java:30:10:30:24 | new Exception(...) | | MultiCatch.java:29:5:29:29 | stmt | MultiCatch.java:31:5:31:37 | stmt | | MultiCatch.java:29:11:29:28 | new SQLException(...) | MultiCatch.java:29:5:29:29 | stmt | -| MultiCatch.java:30:4:30:25 | stmt | MultiCatch.java:22:14:22:24 | multiCatch2 | +| MultiCatch.java:30:4:30:25 | stmt | MultiCatch.java:22:14:22:24 | Exit | | MultiCatch.java:30:4:30:25 | stmt | MultiCatch.java:31:5:31:37 | stmt | | MultiCatch.java:30:10:30:24 | new Exception(...) | MultiCatch.java:30:4:30:25 | stmt | | MultiCatch.java:31:5:31:37 | stmt | MultiCatch.java:31:36:31:36 | e | | MultiCatch.java:31:36:31:36 | e | MultiCatch.java:32:3:32:4 | stmt | -| MultiCatch.java:32:3:32:4 | stmt | MultiCatch.java:22:14:22:24 | multiCatch2 | +| MultiCatch.java:32:3:32:4 | stmt | MultiCatch.java:22:14:22:24 | Exit | | MultiCatch.java:36:2:42:2 | stmt | MultiCatch.java:37:3:41:4 | stmt | | MultiCatch.java:37:3:41:4 | stmt | MultiCatch.java:38:3:40:3 | stmt | | MultiCatch.java:38:3:40:3 | stmt | MultiCatch.java:39:10:39:26 | new IOException(...) | @@ -45,4 +45,4 @@ | MultiCatch.java:39:10:39:26 | new IOException(...) | MultiCatch.java:40:5:40:22 | stmt | | MultiCatch.java:40:5:40:22 | stmt | MultiCatch.java:40:21:40:21 | e | | MultiCatch.java:40:21:40:21 | e | MultiCatch.java:41:3:41:4 | stmt | -| MultiCatch.java:41:3:41:4 | stmt | MultiCatch.java:35:14:35:26 | ordinaryCatch | +| MultiCatch.java:41:3:41:4 | stmt | MultiCatch.java:35:14:35:26 | Exit | diff --git a/java/ql/test/library-tests/successors/CloseReaderTest/TestSucc.expected b/java/ql/test/library-tests/successors/CloseReaderTest/TestSucc.expected index b5b5f262f47d..e3d1f04c8e77 100644 --- a/java/ql/test/library-tests/successors/CloseReaderTest/TestSucc.expected +++ b/java/ql/test/library-tests/successors/CloseReaderTest/TestSucc.expected @@ -1,5 +1,5 @@ | CloseReaderTest.java:8:14:8:28 | stmt | CloseReaderTest.java:8:14:8:28 | super(...) | -| CloseReaderTest.java:8:14:8:28 | super(...) | CloseReaderTest.java:8:14:8:28 | CloseReaderTest | +| CloseReaderTest.java:8:14:8:28 | super(...) | CloseReaderTest.java:8:14:8:28 | Exit | | CloseReaderTest.java:10:2:24:2 | stmt | CloseReaderTest.java:12:3:13:42 | stmt | | CloseReaderTest.java:12:3:12:12 | System.out | CloseReaderTest.java:12:20:12:40 | "Enter password for " | | CloseReaderTest.java:12:3:13:41 | print(...) | CloseReaderTest.java:14:3:14:21 | stmt | @@ -19,12 +19,12 @@ | CloseReaderTest.java:16:5:16:13 | System.in | CloseReaderTest.java:15:45:16:14 | new InputStreamReader(...) | | CloseReaderTest.java:17:3:23:3 | stmt | CloseReaderTest.java:18:3:20:3 | stmt | | CloseReaderTest.java:18:3:20:3 | stmt | CloseReaderTest.java:19:11:19:15 | stdin | -| CloseReaderTest.java:19:4:19:27 | stmt | CloseReaderTest.java:9:23:9:34 | readPassword | +| CloseReaderTest.java:19:4:19:27 | stmt | CloseReaderTest.java:9:23:9:34 | Exit | | CloseReaderTest.java:19:11:19:15 | stdin | CloseReaderTest.java:19:11:19:26 | readLine(...) | | CloseReaderTest.java:19:11:19:26 | readLine(...) | CloseReaderTest.java:19:4:19:27 | stmt | | CloseReaderTest.java:19:11:19:26 | readLine(...) | CloseReaderTest.java:20:5:20:26 | stmt | | CloseReaderTest.java:20:5:20:26 | stmt | CloseReaderTest.java:20:24:20:25 | ex | | CloseReaderTest.java:20:24:20:25 | ex | CloseReaderTest.java:21:3:23:3 | stmt | | CloseReaderTest.java:21:3:23:3 | stmt | CloseReaderTest.java:22:11:22:14 | null | -| CloseReaderTest.java:22:4:22:15 | stmt | CloseReaderTest.java:9:23:9:34 | readPassword | +| CloseReaderTest.java:22:4:22:15 | stmt | CloseReaderTest.java:9:23:9:34 | Exit | | CloseReaderTest.java:22:11:22:14 | null | CloseReaderTest.java:22:4:22:15 | stmt | diff --git a/java/ql/test/library-tests/successors/CloseReaderTest/TestSucc.ql b/java/ql/test/library-tests/successors/CloseReaderTest/TestSucc.ql index 9de77b3c42b6..d09b7c865fd1 100644 --- a/java/ql/test/library-tests/successors/CloseReaderTest/TestSucc.ql +++ b/java/ql/test/library-tests/successors/CloseReaderTest/TestSucc.ql @@ -4,5 +4,5 @@ from ControlFlowNode n, ControlFlowNode succ where succ = n.getASuccessor() and n.getLocation().getFile().getExtension() = "java" and - not n.getFile().getStem() = "PopulateRuntimeException" + not n.getEnclosingCallable().getFile().getStem() = "PopulateRuntimeException" select n, succ diff --git a/java/ql/test/library-tests/successors/LoopVarReadTest/TestSucc.expected b/java/ql/test/library-tests/successors/LoopVarReadTest/TestSucc.expected index f03586c25e80..2116be512f60 100644 --- a/java/ql/test/library-tests/successors/LoopVarReadTest/TestSucc.expected +++ b/java/ql/test/library-tests/successors/LoopVarReadTest/TestSucc.expected @@ -1,5 +1,5 @@ | LoopVarReadTest.java:3:14:3:28 | stmt | LoopVarReadTest.java:3:14:3:28 | super(...) | -| LoopVarReadTest.java:3:14:3:28 | super(...) | LoopVarReadTest.java:3:14:3:28 | LoopVarReadTest | +| LoopVarReadTest.java:3:14:3:28 | super(...) | LoopVarReadTest.java:3:14:3:28 | Exit | | LoopVarReadTest.java:5:2:15:2 | stmt | LoopVarReadTest.java:6:3:6:12 | stmt | | LoopVarReadTest.java:6:3:6:12 | stmt | LoopVarReadTest.java:6:11:6:11 | 2 | | LoopVarReadTest.java:6:7:6:11 | x | LoopVarReadTest.java:7:3:7:33 | stmt | @@ -23,6 +23,6 @@ | LoopVarReadTest.java:12:7:12:12 | q | LoopVarReadTest.java:14:3:14:28 | stmt | | LoopVarReadTest.java:12:11:12:12 | 10 | LoopVarReadTest.java:12:7:12:12 | q | | LoopVarReadTest.java:14:3:14:12 | System.out | LoopVarReadTest.java:14:22:14:26 | "foo" | -| LoopVarReadTest.java:14:3:14:27 | println(...) | LoopVarReadTest.java:4:21:4:28 | testLoop | +| LoopVarReadTest.java:14:3:14:27 | println(...) | LoopVarReadTest.java:4:21:4:28 | Exit | | LoopVarReadTest.java:14:3:14:28 | stmt | LoopVarReadTest.java:14:3:14:12 | System.out | | LoopVarReadTest.java:14:22:14:26 | "foo" | LoopVarReadTest.java:14:3:14:27 | println(...) | diff --git a/java/ql/test/library-tests/successors/LoopVarReadTest/TestSucc.ql b/java/ql/test/library-tests/successors/LoopVarReadTest/TestSucc.ql index 9de77b3c42b6..d09b7c865fd1 100644 --- a/java/ql/test/library-tests/successors/LoopVarReadTest/TestSucc.ql +++ b/java/ql/test/library-tests/successors/LoopVarReadTest/TestSucc.ql @@ -4,5 +4,5 @@ from ControlFlowNode n, ControlFlowNode succ where succ = n.getASuccessor() and n.getLocation().getFile().getExtension() = "java" and - not n.getFile().getStem() = "PopulateRuntimeException" + not n.getEnclosingCallable().getFile().getStem() = "PopulateRuntimeException" select n, succ diff --git a/java/ql/test/library-tests/successors/SaveFileTest/TestSucc.expected b/java/ql/test/library-tests/successors/SaveFileTest/TestSucc.expected index fe6dc51a0c9e..9621ff156149 100644 --- a/java/ql/test/library-tests/successors/SaveFileTest/TestSucc.expected +++ b/java/ql/test/library-tests/successors/SaveFileTest/TestSucc.expected @@ -1,5 +1,5 @@ | SaveFileTest.java:11:14:11:25 | stmt | SaveFileTest.java:11:14:11:25 | super(...) | -| SaveFileTest.java:11:14:11:25 | super(...) | SaveFileTest.java:11:14:11:25 | SaveFileTest | +| SaveFileTest.java:11:14:11:25 | super(...) | SaveFileTest.java:11:14:11:25 | Exit | | SaveFileTest.java:15:2:55:2 | stmt | SaveFileTest.java:17:3:17:25 | stmt | | SaveFileTest.java:17:3:17:25 | stmt | SaveFileTest.java:17:21:17:24 | path | | SaveFileTest.java:17:10:17:24 | savePath | SaveFileTest.java:18:3:18:27 | stmt | @@ -95,9 +95,9 @@ | SaveFileTest.java:48:5:48:15 | flush(...) | SaveFileTest.java:50:6:50:30 | stmt | | SaveFileTest.java:48:5:48:16 | stmt | SaveFileTest.java:48:5:48:7 | bos | | SaveFileTest.java:49:5:49:7 | bos | SaveFileTest.java:49:5:49:15 | close(...) | -| SaveFileTest.java:49:5:49:15 | close(...) | SaveFileTest.java:12:14:12:21 | saveFile | +| SaveFileTest.java:49:5:49:15 | close(...) | SaveFileTest.java:12:14:12:21 | Exit | | SaveFileTest.java:49:5:49:15 | close(...) | SaveFileTest.java:50:6:50:30 | stmt | | SaveFileTest.java:49:5:49:16 | stmt | SaveFileTest.java:49:5:49:7 | bos | | SaveFileTest.java:50:6:50:30 | stmt | SaveFileTest.java:50:23:50:29 | ignored | | SaveFileTest.java:50:23:50:29 | ignored | SaveFileTest.java:51:4:52:4 | stmt | -| SaveFileTest.java:51:4:52:4 | stmt | SaveFileTest.java:12:14:12:21 | saveFile | +| SaveFileTest.java:51:4:52:4 | stmt | SaveFileTest.java:12:14:12:21 | Exit | diff --git a/java/ql/test/library-tests/successors/SaveFileTest/TestSucc.ql b/java/ql/test/library-tests/successors/SaveFileTest/TestSucc.ql index 9de77b3c42b6..d09b7c865fd1 100644 --- a/java/ql/test/library-tests/successors/SaveFileTest/TestSucc.ql +++ b/java/ql/test/library-tests/successors/SaveFileTest/TestSucc.ql @@ -4,5 +4,5 @@ from ControlFlowNode n, ControlFlowNode succ where succ = n.getASuccessor() and n.getLocation().getFile().getExtension() = "java" and - not n.getFile().getStem() = "PopulateRuntimeException" + not n.getEnclosingCallable().getFile().getStem() = "PopulateRuntimeException" select n, succ diff --git a/java/ql/test/library-tests/successors/SchackTest/TestSucc.expected b/java/ql/test/library-tests/successors/SchackTest/TestSucc.expected index 9cd1d76f24fb..6df54dd5d9e0 100644 --- a/java/ql/test/library-tests/successors/SchackTest/TestSucc.expected +++ b/java/ql/test/library-tests/successors/SchackTest/TestSucc.expected @@ -1,9 +1,9 @@ | SchackTest.java:1:14:1:23 | stmt | SchackTest.java:1:14:1:23 | super(...) | -| SchackTest.java:1:14:1:23 | super(...) | SchackTest.java:1:14:1:23 | SchackTest | +| SchackTest.java:1:14:1:23 | super(...) | SchackTest.java:1:14:1:23 | Exit | | SchackTest.java:2:8:2:10 | stmt | SchackTest.java:2:8:2:10 | super(...) | -| SchackTest.java:2:8:2:10 | super(...) | SchackTest.java:2:8:2:10 | ExA | +| SchackTest.java:2:8:2:10 | super(...) | SchackTest.java:2:8:2:10 | Exit | | SchackTest.java:3:8:3:10 | stmt | SchackTest.java:3:8:3:10 | super(...) | -| SchackTest.java:3:8:3:10 | super(...) | SchackTest.java:3:8:3:10 | ExB | +| SchackTest.java:3:8:3:10 | super(...) | SchackTest.java:3:8:3:10 | Exit | | SchackTest.java:5:18:24:2 | stmt | SchackTest.java:6:3:23:3 | stmt | | SchackTest.java:6:3:23:3 | stmt | SchackTest.java:6:7:17:3 | stmt | | SchackTest.java:6:7:17:3 | stmt | SchackTest.java:7:4:15:4 | stmt | @@ -56,7 +56,7 @@ | SchackTest.java:20:23:20:72 | "successor (but neither true nor false successor)" | SchackTest.java:20:4:20:73 | println(...) | | SchackTest.java:21:13:23:3 | stmt | SchackTest.java:22:4:22:41 | stmt | | SchackTest.java:22:4:22:13 | System.out | SchackTest.java:22:23:22:39 | "false successor" | -| SchackTest.java:22:4:22:40 | println(...) | SchackTest.java:5:7:5:9 | foo | +| SchackTest.java:22:4:22:40 | println(...) | SchackTest.java:5:7:5:9 | Exit | | SchackTest.java:22:4:22:41 | stmt | SchackTest.java:22:4:22:13 | System.out | | SchackTest.java:22:23:22:39 | "false successor" | SchackTest.java:22:4:22:40 | println(...) | | SchackTest.java:26:35:30:2 | stmt | SchackTest.java:27:3:27:25 | stmt | @@ -65,9 +65,9 @@ | SchackTest.java:27:7:27:24 | ... > ... | SchackTest.java:28:10:28:18 | new ExB(...) | | SchackTest.java:27:7:27:24 | ... > ... | SchackTest.java:29:10:29:22 | random(...) | | SchackTest.java:27:23:27:24 | .5 | SchackTest.java:27:7:27:24 | ... > ... | -| SchackTest.java:28:4:28:19 | stmt | SchackTest.java:26:18:26:20 | bar | +| SchackTest.java:28:4:28:19 | stmt | SchackTest.java:26:18:26:20 | Exit | | SchackTest.java:28:10:28:18 | new ExB(...) | SchackTest.java:28:4:28:19 | stmt | -| SchackTest.java:29:3:29:28 | stmt | SchackTest.java:26:18:26:20 | bar | +| SchackTest.java:29:3:29:28 | stmt | SchackTest.java:26:18:26:20 | Exit | | SchackTest.java:29:10:29:22 | random(...) | SchackTest.java:29:26:29:27 | .3 | | SchackTest.java:29:10:29:27 | ... > ... | SchackTest.java:29:3:29:28 | stmt | | SchackTest.java:29:26:29:27 | .3 | SchackTest.java:29:10:29:27 | ... > ... | diff --git a/java/ql/test/library-tests/successors/SchackTest/TestSucc.ql b/java/ql/test/library-tests/successors/SchackTest/TestSucc.ql index 9de77b3c42b6..d09b7c865fd1 100644 --- a/java/ql/test/library-tests/successors/SchackTest/TestSucc.ql +++ b/java/ql/test/library-tests/successors/SchackTest/TestSucc.ql @@ -4,5 +4,5 @@ from ControlFlowNode n, ControlFlowNode succ where succ = n.getASuccessor() and n.getLocation().getFile().getExtension() = "java" and - not n.getFile().getStem() = "PopulateRuntimeException" + not n.getEnclosingCallable().getFile().getStem() = "PopulateRuntimeException" select n, succ diff --git a/java/ql/test/library-tests/successors/TestBreak/TestSucc.expected b/java/ql/test/library-tests/successors/TestBreak/TestSucc.expected index bfc016640426..129d1c6958a1 100644 --- a/java/ql/test/library-tests/successors/TestBreak/TestSucc.expected +++ b/java/ql/test/library-tests/successors/TestBreak/TestSucc.expected @@ -1,5 +1,5 @@ | TestBreak.java:3:14:3:22 | stmt | TestBreak.java:3:14:3:22 | super(...) | -| TestBreak.java:3:14:3:22 | super(...) | TestBreak.java:3:14:3:22 | TestBreak | +| TestBreak.java:3:14:3:22 | super(...) | TestBreak.java:3:14:3:22 | Exit | | TestBreak.java:5:2:85:2 | stmt | TestBreak.java:7:3:8:11 | stmt | | TestBreak.java:7:3:8:11 | stmt | TestBreak.java:8:4:8:11 | stmt | | TestBreak.java:8:4:8:11 | stmt | TestBreak.java:9:4:28:4 | stmt | @@ -140,16 +140,16 @@ | TestBreak.java:72:4:72:9 | stmt | TestBreak.java:72:8:72:8 | x | | TestBreak.java:72:8:72:8 | x | TestBreak.java:72:4:72:8 | ...=... | | TestBreak.java:76:3:76:11 | stmt | TestBreak.java:76:10:76:10 | x | -| TestBreak.java:76:10:76:10 | x | TestBreak.java:4:14:4:14 | f | +| TestBreak.java:76:10:76:10 | x | TestBreak.java:4:14:4:14 | Exit | | TestBreak.java:76:10:76:10 | x | TestBreak.java:78:3:78:9 | stmt | | TestBreak.java:76:10:76:10 | x | TestBreak.java:81:3:81:9 | stmt | | TestBreak.java:78:3:78:9 | stmt | TestBreak.java:79:4:79:9 | stmt | | TestBreak.java:79:4:79:8 | ...=... | TestBreak.java:80:4:80:9 | stmt | | TestBreak.java:79:4:79:9 | stmt | TestBreak.java:79:8:79:8 | 1 | | TestBreak.java:79:8:79:8 | 1 | TestBreak.java:79:4:79:8 | ...=... | -| TestBreak.java:80:4:80:9 | stmt | TestBreak.java:4:14:4:14 | f | +| TestBreak.java:80:4:80:9 | stmt | TestBreak.java:4:14:4:14 | Exit | | TestBreak.java:81:3:81:9 | stmt | TestBreak.java:82:4:82:9 | stmt | | TestBreak.java:82:4:82:8 | ...=... | TestBreak.java:83:4:83:9 | stmt | | TestBreak.java:82:4:82:9 | stmt | TestBreak.java:82:8:82:8 | 2 | | TestBreak.java:82:8:82:8 | 2 | TestBreak.java:82:4:82:8 | ...=... | -| TestBreak.java:83:4:83:9 | stmt | TestBreak.java:4:14:4:14 | f | +| TestBreak.java:83:4:83:9 | stmt | TestBreak.java:4:14:4:14 | Exit | diff --git a/java/ql/test/library-tests/successors/TestBreak/TestSucc.ql b/java/ql/test/library-tests/successors/TestBreak/TestSucc.ql index 9de77b3c42b6..d09b7c865fd1 100644 --- a/java/ql/test/library-tests/successors/TestBreak/TestSucc.ql +++ b/java/ql/test/library-tests/successors/TestBreak/TestSucc.ql @@ -4,5 +4,5 @@ from ControlFlowNode n, ControlFlowNode succ where succ = n.getASuccessor() and n.getLocation().getFile().getExtension() = "java" and - not n.getFile().getStem() = "PopulateRuntimeException" + not n.getEnclosingCallable().getFile().getStem() = "PopulateRuntimeException" select n, succ diff --git a/java/ql/test/library-tests/successors/TestContinue/FalseSuccessors.expected b/java/ql/test/library-tests/successors/TestContinue/FalseSuccessors.expected index 046cece6f7fd..173823385dc4 100644 --- a/java/ql/test/library-tests/successors/TestContinue/FalseSuccessors.expected +++ b/java/ql/test/library-tests/successors/TestContinue/FalseSuccessors.expected @@ -6,5 +6,5 @@ | TestContinue.java:33:8:33:13 | ... == ... | TestContinue.java:37:4:47:4 | stmt | | TestContinue.java:40:10:40:15 | ... == ... | TestContinue.java:44:6:44:15 | stmt | | TestContinue.java:45:14:45:19 | ... == ... | TestContinue.java:46:5:46:11 | stmt | -| TestContinue.java:51:10:51:16 | ... != ... | TestContinue.java:4:14:4:14 | f | +| TestContinue.java:51:10:51:16 | ... != ... | TestContinue.java:4:14:4:14 | Exit | | TestContinue.java:53:8:53:13 | ... != ... | TestContinue.java:56:5:56:10 | stmt | diff --git a/java/ql/test/library-tests/successors/TestContinue/TestSucc.expected b/java/ql/test/library-tests/successors/TestContinue/TestSucc.expected index c12e88e7080c..84bb1e633e51 100644 --- a/java/ql/test/library-tests/successors/TestContinue/TestSucc.expected +++ b/java/ql/test/library-tests/successors/TestContinue/TestSucc.expected @@ -1,5 +1,5 @@ | TestContinue.java:3:14:3:25 | stmt | TestContinue.java:3:14:3:25 | super(...) | -| TestContinue.java:3:14:3:25 | super(...) | TestContinue.java:3:14:3:25 | TestContinue | +| TestContinue.java:3:14:3:25 | super(...) | TestContinue.java:3:14:3:25 | Exit | | TestContinue.java:5:2:58:2 | stmt | TestContinue.java:7:3:8:27 | stmt | | TestContinue.java:7:3:8:27 | stmt | TestContinue.java:8:4:8:27 | stmt | | TestContinue.java:8:4:8:27 | stmt | TestContinue.java:8:17:8:17 | 0 | @@ -97,7 +97,7 @@ | TestContinue.java:50:7:50:8 | 13 | TestContinue.java:50:3:50:8 | ...=... | | TestContinue.java:51:3:51:17 | stmt | TestContinue.java:51:10:51:10 | y | | TestContinue.java:51:10:51:10 | y | TestContinue.java:51:15:51:16 | 12 | -| TestContinue.java:51:10:51:16 | ... != ... | TestContinue.java:4:14:4:14 | f | +| TestContinue.java:51:10:51:16 | ... != ... | TestContinue.java:4:14:4:14 | Exit | | TestContinue.java:51:10:51:16 | ... != ... | TestContinue.java:52:3:57:3 | stmt | | TestContinue.java:51:15:51:16 | 12 | TestContinue.java:51:10:51:16 | ... != ... | | TestContinue.java:52:3:57:3 | stmt | TestContinue.java:53:4:53:14 | stmt | @@ -107,4 +107,4 @@ | TestContinue.java:53:8:53:13 | ... != ... | TestContinue.java:56:5:56:10 | stmt | | TestContinue.java:53:13:53:13 | 6 | TestContinue.java:53:8:53:13 | ... != ... | | TestContinue.java:54:5:54:13 | stmt | TestContinue.java:51:10:51:10 | y | -| TestContinue.java:56:5:56:10 | stmt | TestContinue.java:4:14:4:14 | f | +| TestContinue.java:56:5:56:10 | stmt | TestContinue.java:4:14:4:14 | Exit | diff --git a/java/ql/test/library-tests/successors/TestContinue/TestSucc.ql b/java/ql/test/library-tests/successors/TestContinue/TestSucc.ql index 9de77b3c42b6..d09b7c865fd1 100644 --- a/java/ql/test/library-tests/successors/TestContinue/TestSucc.ql +++ b/java/ql/test/library-tests/successors/TestContinue/TestSucc.ql @@ -4,5 +4,5 @@ from ControlFlowNode n, ControlFlowNode succ where succ = n.getASuccessor() and n.getLocation().getFile().getExtension() = "java" and - not n.getFile().getStem() = "PopulateRuntimeException" + not n.getEnclosingCallable().getFile().getStem() = "PopulateRuntimeException" select n, succ diff --git a/java/ql/test/library-tests/successors/TestDeclarations/TestSucc.expected b/java/ql/test/library-tests/successors/TestDeclarations/TestSucc.expected index 73b0df6ab8a5..ae2293965466 100644 --- a/java/ql/test/library-tests/successors/TestDeclarations/TestSucc.expected +++ b/java/ql/test/library-tests/successors/TestDeclarations/TestSucc.expected @@ -1,5 +1,5 @@ | TestDeclarations.java:1:7:1:22 | stmt | TestDeclarations.java:1:7:1:22 | super(...) | -| TestDeclarations.java:1:7:1:22 | super(...) | TestDeclarations.java:1:7:1:22 | TestDeclarations | +| TestDeclarations.java:1:7:1:22 | super(...) | TestDeclarations.java:1:7:1:22 | Exit | | TestDeclarations.java:2:30:24:2 | stmt | TestDeclarations.java:4:3:4:11 | stmt | | TestDeclarations.java:4:3:4:11 | stmt | TestDeclarations.java:4:7:4:7 | b | | TestDeclarations.java:4:7:4:7 | b | TestDeclarations.java:4:10:4:10 | c | @@ -39,7 +39,7 @@ | TestDeclarations.java:17:8:17:14 | ... == ... | TestDeclarations.java:7:9:7:12 | true | | TestDeclarations.java:17:8:17:14 | ... == ... | TestDeclarations.java:18:12:18:12 | c | | TestDeclarations.java:17:13:17:14 | 20 | TestDeclarations.java:17:8:17:14 | ... == ... | -| TestDeclarations.java:18:5:18:13 | stmt | TestDeclarations.java:2:6:2:21 | declarationTests | +| TestDeclarations.java:18:5:18:13 | stmt | TestDeclarations.java:2:6:2:21 | Exit | | TestDeclarations.java:18:12:18:12 | c | TestDeclarations.java:18:5:18:13 | stmt | | TestDeclarations.java:20:3:20:10 | stmt | TestDeclarations.java:20:7:20:7 | x | | TestDeclarations.java:20:7:20:7 | x | TestDeclarations.java:20:9:20:9 | y | @@ -50,5 +50,5 @@ | TestDeclarations.java:22:3:22:7 | ...=... | TestDeclarations.java:23:10:23:10 | b | | TestDeclarations.java:22:3:22:8 | stmt | TestDeclarations.java:22:7:22:7 | 4 | | TestDeclarations.java:22:7:22:7 | 4 | TestDeclarations.java:22:3:22:7 | ...=... | -| TestDeclarations.java:23:3:23:11 | stmt | TestDeclarations.java:2:6:2:21 | declarationTests | +| TestDeclarations.java:23:3:23:11 | stmt | TestDeclarations.java:2:6:2:21 | Exit | | TestDeclarations.java:23:10:23:10 | b | TestDeclarations.java:23:3:23:11 | stmt | diff --git a/java/ql/test/library-tests/successors/TestDeclarations/TestSucc.ql b/java/ql/test/library-tests/successors/TestDeclarations/TestSucc.ql index 9de77b3c42b6..d09b7c865fd1 100644 --- a/java/ql/test/library-tests/successors/TestDeclarations/TestSucc.ql +++ b/java/ql/test/library-tests/successors/TestDeclarations/TestSucc.ql @@ -4,5 +4,5 @@ from ControlFlowNode n, ControlFlowNode succ where succ = n.getASuccessor() and n.getLocation().getFile().getExtension() = "java" and - not n.getFile().getStem() = "PopulateRuntimeException" + not n.getEnclosingCallable().getFile().getStem() = "PopulateRuntimeException" select n, succ diff --git a/java/ql/test/library-tests/successors/TestFinally/TestSucc.expected b/java/ql/test/library-tests/successors/TestFinally/TestSucc.expected index df7b4e57ebf4..1a468b301ad5 100644 --- a/java/ql/test/library-tests/successors/TestFinally/TestSucc.expected +++ b/java/ql/test/library-tests/successors/TestFinally/TestSucc.expected @@ -1,5 +1,5 @@ | TestFinally.java:3:14:3:24 | stmt | TestFinally.java:3:14:3:24 | super(...) | -| TestFinally.java:3:14:3:24 | super(...) | TestFinally.java:3:14:3:24 | TestFinally | +| TestFinally.java:3:14:3:24 | super(...) | TestFinally.java:3:14:3:24 | Exit | | TestFinally.java:5:2:149:2 | stmt | TestFinally.java:6:3:6:13 | stmt | | TestFinally.java:6:3:6:13 | stmt | TestFinally.java:6:11:6:12 | 12 | | TestFinally.java:6:7:6:12 | z | TestFinally.java:7:3:120:3 | stmt | @@ -268,7 +268,7 @@ | TestFinally.java:118:4:118:32 | println(...) | TestFinally.java:119:4:119:13 | stmt | | TestFinally.java:118:4:118:33 | stmt | TestFinally.java:118:4:118:13 | System.out | | TestFinally.java:118:23:118:31 | "Finally" | TestFinally.java:118:4:118:32 | println(...) | -| TestFinally.java:119:4:119:12 | ...=... | TestFinally.java:4:14:4:14 | f | +| TestFinally.java:119:4:119:12 | ...=... | TestFinally.java:4:14:4:14 | Exit | | TestFinally.java:119:4:119:12 | ...=... | TestFinally.java:121:3:121:12 | stmt | | TestFinally.java:119:4:119:13 | stmt | TestFinally.java:119:8:119:8 | y | | TestFinally.java:119:8:119:8 | y | TestFinally.java:119:12:119:12 | 1 | @@ -324,13 +324,13 @@ | TestFinally.java:141:8:141:13 | ... == ... | TestFinally.java:145:4:145:34 | stmt | | TestFinally.java:141:13:141:13 | 1 | TestFinally.java:141:8:141:13 | ... == ... | | TestFinally.java:142:4:144:4 | stmt | TestFinally.java:143:5:143:11 | stmt | -| TestFinally.java:143:5:143:11 | stmt | TestFinally.java:4:14:4:14 | f | +| TestFinally.java:143:5:143:11 | stmt | TestFinally.java:4:14:4:14 | Exit | | TestFinally.java:145:4:145:13 | System.out | TestFinally.java:145:23:145:32 | "Finally2" | -| TestFinally.java:145:4:145:33 | println(...) | TestFinally.java:4:14:4:14 | f | +| TestFinally.java:145:4:145:33 | println(...) | TestFinally.java:4:14:4:14 | Exit | | TestFinally.java:145:4:145:33 | println(...) | TestFinally.java:148:3:148:12 | stmt | | TestFinally.java:145:4:145:34 | stmt | TestFinally.java:145:4:145:13 | System.out | | TestFinally.java:145:23:145:32 | "Finally2" | TestFinally.java:145:4:145:33 | println(...) | -| TestFinally.java:148:3:148:11 | ...=... | TestFinally.java:4:14:4:14 | f | +| TestFinally.java:148:3:148:11 | ...=... | TestFinally.java:4:14:4:14 | Exit | | TestFinally.java:148:3:148:12 | stmt | TestFinally.java:148:7:148:7 | z | | TestFinally.java:148:7:148:7 | z | TestFinally.java:148:11:148:11 | 2 | | TestFinally.java:148:7:148:11 | ... + ... | TestFinally.java:148:3:148:11 | ...=... | diff --git a/java/ql/test/library-tests/successors/TestFinally/TestSucc.ql b/java/ql/test/library-tests/successors/TestFinally/TestSucc.ql index 9de77b3c42b6..d09b7c865fd1 100644 --- a/java/ql/test/library-tests/successors/TestFinally/TestSucc.ql +++ b/java/ql/test/library-tests/successors/TestFinally/TestSucc.ql @@ -4,5 +4,5 @@ from ControlFlowNode n, ControlFlowNode succ where succ = n.getASuccessor() and n.getLocation().getFile().getExtension() = "java" and - not n.getFile().getStem() = "PopulateRuntimeException" + not n.getEnclosingCallable().getFile().getStem() = "PopulateRuntimeException" select n, succ diff --git a/java/ql/test/library-tests/successors/TestFinallyBreakContinue/TestSucc.expected b/java/ql/test/library-tests/successors/TestFinallyBreakContinue/TestSucc.expected index 9ef9bab41721..43a0299833cc 100644 --- a/java/ql/test/library-tests/successors/TestFinallyBreakContinue/TestSucc.expected +++ b/java/ql/test/library-tests/successors/TestFinallyBreakContinue/TestSucc.expected @@ -1,5 +1,5 @@ | TestFinallyBreakContinue.java:3:14:3:37 | stmt | TestFinallyBreakContinue.java:3:14:3:37 | super(...) | -| TestFinallyBreakContinue.java:3:14:3:37 | super(...) | TestFinallyBreakContinue.java:3:14:3:37 | TestFinallyBreakContinue | +| TestFinallyBreakContinue.java:3:14:3:37 | super(...) | TestFinallyBreakContinue.java:3:14:3:37 | Exit | | TestFinallyBreakContinue.java:5:2:107:2 | stmt | TestFinallyBreakContinue.java:6:3:6:12 | stmt | | TestFinallyBreakContinue.java:6:3:6:12 | stmt | TestFinallyBreakContinue.java:6:11:6:11 | 1 | | TestFinallyBreakContinue.java:6:7:6:11 | x | TestFinallyBreakContinue.java:7:3:8:10 | stmt | @@ -79,7 +79,7 @@ | TestFinallyBreakContinue.java:62:24:62:34 | "Exception" | TestFinallyBreakContinue.java:62:5:62:35 | println(...) | | TestFinallyBreakContinue.java:64:4:66:4 | stmt | TestFinallyBreakContinue.java:65:5:65:34 | stmt | | TestFinallyBreakContinue.java:65:5:65:14 | System.out | TestFinallyBreakContinue.java:65:24:65:32 | "finally" | -| TestFinallyBreakContinue.java:65:5:65:33 | println(...) | TestFinallyBreakContinue.java:4:14:4:14 | f | +| TestFinallyBreakContinue.java:65:5:65:33 | println(...) | TestFinallyBreakContinue.java:4:14:4:14 | Exit | | TestFinallyBreakContinue.java:65:5:65:33 | println(...) | TestFinallyBreakContinue.java:34:10:34:13 | true | | TestFinallyBreakContinue.java:65:5:65:33 | println(...) | TestFinallyBreakContinue.java:69:3:106:17 | stmt | | TestFinallyBreakContinue.java:65:5:65:34 | stmt | TestFinallyBreakContinue.java:65:5:65:14 | System.out | @@ -134,7 +134,7 @@ | TestFinallyBreakContinue.java:101:24:101:34 | "Exception" | TestFinallyBreakContinue.java:101:5:101:35 | println(...) | | TestFinallyBreakContinue.java:103:4:105:4 | stmt | TestFinallyBreakContinue.java:104:5:104:34 | stmt | | TestFinallyBreakContinue.java:104:5:104:14 | System.out | TestFinallyBreakContinue.java:104:24:104:32 | "finally" | -| TestFinallyBreakContinue.java:104:5:104:33 | println(...) | TestFinallyBreakContinue.java:4:14:4:14 | f | +| TestFinallyBreakContinue.java:104:5:104:33 | println(...) | TestFinallyBreakContinue.java:4:14:4:14 | Exit | | TestFinallyBreakContinue.java:104:5:104:33 | println(...) | TestFinallyBreakContinue.java:106:12:106:15 | true | | TestFinallyBreakContinue.java:104:5:104:34 | stmt | TestFinallyBreakContinue.java:104:5:104:14 | System.out | | TestFinallyBreakContinue.java:104:24:104:32 | "finally" | TestFinallyBreakContinue.java:104:5:104:33 | println(...) | diff --git a/java/ql/test/library-tests/successors/TestFinallyBreakContinue/TestSucc.ql b/java/ql/test/library-tests/successors/TestFinallyBreakContinue/TestSucc.ql index 9de77b3c42b6..d09b7c865fd1 100644 --- a/java/ql/test/library-tests/successors/TestFinallyBreakContinue/TestSucc.ql +++ b/java/ql/test/library-tests/successors/TestFinallyBreakContinue/TestSucc.ql @@ -4,5 +4,5 @@ from ControlFlowNode n, ControlFlowNode succ where succ = n.getASuccessor() and n.getLocation().getFile().getExtension() = "java" and - not n.getFile().getStem() = "PopulateRuntimeException" + not n.getEnclosingCallable().getFile().getStem() = "PopulateRuntimeException" select n, succ diff --git a/java/ql/test/library-tests/successors/TestLoopBranch/TestSucc.expected b/java/ql/test/library-tests/successors/TestLoopBranch/TestSucc.expected index d487429aff1d..c649af27c02f 100644 --- a/java/ql/test/library-tests/successors/TestLoopBranch/TestSucc.expected +++ b/java/ql/test/library-tests/successors/TestLoopBranch/TestSucc.expected @@ -2,7 +2,7 @@ | TestLoopBranch.java:4:2:4:13 | ...=... | TestLoopBranch.java:5:2:5:13 | stmt | | TestLoopBranch.java:4:2:4:13 | stmt | TestLoopBranch.java:4:11:4:12 | 12 | | TestLoopBranch.java:4:11:4:12 | 12 | TestLoopBranch.java:4:2:4:13 | ...=... | -| TestLoopBranch.java:5:2:5:13 | ...=... | TestLoopBranch.java:3:14:3:27 | | +| TestLoopBranch.java:5:2:5:13 | ...=... | TestLoopBranch.java:3:14:3:27 | Exit | | TestLoopBranch.java:5:2:5:13 | stmt | TestLoopBranch.java:5:11:5:12 | 13 | | TestLoopBranch.java:5:11:5:12 | 13 | TestLoopBranch.java:5:2:5:13 | ...=... | | TestLoopBranch.java:8:2:107:2 | stmt | TestLoopBranch.java:9:3:9:12 | stmt | @@ -133,7 +133,7 @@ | TestLoopBranch.java:58:8:58:8 | y | TestLoopBranch.java:58:12:58:12 | x | | TestLoopBranch.java:58:8:58:12 | ... * ... | TestLoopBranch.java:58:4:58:12 | ...=... | | TestLoopBranch.java:58:12:58:12 | x | TestLoopBranch.java:58:8:58:12 | ... * ... | -| TestLoopBranch.java:59:4:59:10 | stmt | TestLoopBranch.java:7:14:7:14 | f | +| TestLoopBranch.java:59:4:59:10 | stmt | TestLoopBranch.java:7:14:7:14 | Exit | | TestLoopBranch.java:62:3:62:12 | stmt | TestLoopBranch.java:62:11:62:11 | x | | TestLoopBranch.java:62:11:62:11 | x | TestLoopBranch.java:64:3:64:9 | stmt | | TestLoopBranch.java:62:11:62:11 | x | TestLoopBranch.java:67:3:67:9 | stmt | @@ -215,9 +215,9 @@ | TestLoopBranch.java:96:22:102:3 | b | TestLoopBranch.java:103:3:103:21 | stmt | | TestLoopBranch.java:96:26:102:3 | new (...) | TestLoopBranch.java:96:22:102:3 | b | | TestLoopBranch.java:96:30:96:47 | stmt | TestLoopBranch.java:96:30:96:47 | super(...) | -| TestLoopBranch.java:96:30:96:47 | super(...) | TestLoopBranch.java:96:30:96:47 | | +| TestLoopBranch.java:96:30:96:47 | super(...) | TestLoopBranch.java:96:30:96:47 | Exit | | TestLoopBranch.java:99:4:101:4 | stmt | TestLoopBranch.java:100:12:100:12 | 0 | -| TestLoopBranch.java:100:5:100:13 | stmt | TestLoopBranch.java:98:15:98:23 | compareTo | +| TestLoopBranch.java:100:5:100:13 | stmt | TestLoopBranch.java:98:15:98:23 | Exit | | TestLoopBranch.java:100:12:100:12 | 0 | TestLoopBranch.java:100:5:100:13 | stmt | | TestLoopBranch.java:103:3:103:3 | b | TestLoopBranch.java:103:15:103:19 | "Foo" | | TestLoopBranch.java:103:3:103:20 | compareTo(...) | TestLoopBranch.java:105:3:105:12 | stmt | @@ -228,7 +228,7 @@ | TestLoopBranch.java:105:7:105:7 | x | TestLoopBranch.java:105:11:105:11 | y | | TestLoopBranch.java:105:7:105:11 | ... + ... | TestLoopBranch.java:105:3:105:11 | ...=... | | TestLoopBranch.java:105:11:105:11 | y | TestLoopBranch.java:105:7:105:11 | ... + ... | -| TestLoopBranch.java:106:3:106:9 | stmt | TestLoopBranch.java:7:14:7:14 | f | +| TestLoopBranch.java:106:3:106:9 | stmt | TestLoopBranch.java:7:14:7:14 | Exit | | TestLoopBranch.java:109:9:109:22 | (...) | TestLoopBranch.java:111:3:111:10 | stmt | | TestLoopBranch.java:109:9:109:22 | stmt | TestLoopBranch.java:109:9:109:22 | (...) | | TestLoopBranch.java:109:9:109:22 | super(...) | TestLoopBranch.java:109:9:109:22 | stmt | @@ -236,7 +236,7 @@ | TestLoopBranch.java:111:3:111:9 | ...=... | TestLoopBranch.java:112:3:112:10 | stmt | | TestLoopBranch.java:111:3:111:10 | stmt | TestLoopBranch.java:111:8:111:9 | 33 | | TestLoopBranch.java:111:8:111:9 | 33 | TestLoopBranch.java:111:3:111:9 | ...=... | -| TestLoopBranch.java:112:3:112:9 | ...=... | TestLoopBranch.java:109:9:109:22 | TestLoopBranch | +| TestLoopBranch.java:112:3:112:9 | ...=... | TestLoopBranch.java:109:9:109:22 | Exit | | TestLoopBranch.java:112:3:112:10 | stmt | TestLoopBranch.java:112:8:112:9 | 44 | | TestLoopBranch.java:112:8:112:9 | 44 | TestLoopBranch.java:112:3:112:9 | ...=... | | TestLoopBranch.java:115:9:115:22 | (...) | TestLoopBranch.java:117:3:117:9 | stmt | @@ -246,6 +246,6 @@ | TestLoopBranch.java:117:3:117:8 | ...=... | TestLoopBranch.java:118:3:118:9 | stmt | | TestLoopBranch.java:117:3:117:9 | stmt | TestLoopBranch.java:117:8:117:8 | i | | TestLoopBranch.java:117:8:117:8 | i | TestLoopBranch.java:117:3:117:8 | ...=... | -| TestLoopBranch.java:118:3:118:8 | ...=... | TestLoopBranch.java:115:9:115:22 | TestLoopBranch | +| TestLoopBranch.java:118:3:118:8 | ...=... | TestLoopBranch.java:115:9:115:22 | Exit | | TestLoopBranch.java:118:3:118:9 | stmt | TestLoopBranch.java:118:8:118:8 | i | | TestLoopBranch.java:118:8:118:8 | i | TestLoopBranch.java:118:3:118:8 | ...=... | diff --git a/java/ql/test/library-tests/successors/TestLoopBranch/TestSucc.ql b/java/ql/test/library-tests/successors/TestLoopBranch/TestSucc.ql index 9de77b3c42b6..d09b7c865fd1 100644 --- a/java/ql/test/library-tests/successors/TestLoopBranch/TestSucc.ql +++ b/java/ql/test/library-tests/successors/TestLoopBranch/TestSucc.ql @@ -4,5 +4,5 @@ from ControlFlowNode n, ControlFlowNode succ where succ = n.getASuccessor() and n.getLocation().getFile().getExtension() = "java" and - not n.getFile().getStem() = "PopulateRuntimeException" + not n.getEnclosingCallable().getFile().getStem() = "PopulateRuntimeException" select n, succ diff --git a/java/ql/test/library-tests/successors/TestThrow/TestSucc.expected b/java/ql/test/library-tests/successors/TestThrow/TestSucc.expected index e9d360286d4b..32e79ed055dd 100644 --- a/java/ql/test/library-tests/successors/TestThrow/TestSucc.expected +++ b/java/ql/test/library-tests/successors/TestThrow/TestSucc.expected @@ -1,6 +1,6 @@ -| TestThrow.java:7:10:7:18 | super(...) | TestThrow.java:7:10:7:18 | TestThrow | +| TestThrow.java:7:10:7:18 | super(...) | TestThrow.java:7:10:7:18 | Exit | | TestThrow.java:8:2:9:2 | stmt | TestThrow.java:7:10:7:18 | super(...) | -| TestThrow.java:12:2:13:2 | stmt | TestThrow.java:11:15:11:21 | thrower | +| TestThrow.java:12:2:13:2 | stmt | TestThrow.java:11:15:11:21 | Exit | | TestThrow.java:16:2:134:2 | stmt | TestThrow.java:17:3:17:12 | stmt | | TestThrow.java:17:3:17:12 | stmt | TestThrow.java:17:11:17:11 | 0 | | TestThrow.java:17:7:17:11 | z | TestThrow.java:18:3:27:3 | stmt | @@ -69,7 +69,7 @@ | TestThrow.java:48:4:48:9 | stmt | TestThrow.java:48:8:48:8 | 1 | | TestThrow.java:48:8:48:8 | 1 | TestThrow.java:48:4:48:8 | ...=... | | TestThrow.java:50:3:52:3 | stmt | TestThrow.java:51:4:51:9 | stmt | -| TestThrow.java:51:4:51:8 | ...=... | TestThrow.java:15:14:15:14 | f | +| TestThrow.java:51:4:51:8 | ...=... | TestThrow.java:15:14:15:14 | Exit | | TestThrow.java:51:4:51:8 | ...=... | TestThrow.java:54:3:54:9 | stmt | | TestThrow.java:51:4:51:9 | stmt | TestThrow.java:51:8:51:8 | 2 | | TestThrow.java:51:8:51:8 | 2 | TestThrow.java:51:4:51:8 | ...=... | @@ -85,7 +85,7 @@ | TestThrow.java:58:8:58:13 | ... == ... | TestThrow.java:62:9:62:19 | stmt | | TestThrow.java:58:13:58:13 | 1 | TestThrow.java:58:8:58:13 | ... == ... | | TestThrow.java:59:4:61:4 | stmt | TestThrow.java:60:11:60:25 | new Exception(...) | -| TestThrow.java:60:5:60:26 | stmt | TestThrow.java:15:14:15:14 | f | +| TestThrow.java:60:5:60:26 | stmt | TestThrow.java:15:14:15:14 | Exit | | TestThrow.java:60:5:60:26 | stmt | TestThrow.java:69:5:69:30 | stmt | | TestThrow.java:60:11:60:25 | new Exception(...) | TestThrow.java:60:5:60:26 | stmt | | TestThrow.java:60:11:60:25 | new Exception(...) | TestThrow.java:69:5:69:30 | stmt | @@ -95,7 +95,7 @@ | TestThrow.java:62:13:62:18 | ... == ... | TestThrow.java:66:4:68:4 | stmt | | TestThrow.java:62:18:62:18 | 2 | TestThrow.java:62:13:62:18 | ... == ... | | TestThrow.java:63:4:65:4 | stmt | TestThrow.java:64:5:64:20 | stmt | -| TestThrow.java:64:5:64:19 | new TestThrow(...) | TestThrow.java:15:14:15:14 | f | +| TestThrow.java:64:5:64:19 | new TestThrow(...) | TestThrow.java:15:14:15:14 | Exit | | TestThrow.java:64:5:64:19 | new TestThrow(...) | TestThrow.java:69:5:69:30 | stmt | | TestThrow.java:64:5:64:19 | new TestThrow(...) | TestThrow.java:74:3:74:9 | stmt | | TestThrow.java:64:5:64:20 | stmt | TestThrow.java:64:5:64:19 | new TestThrow(...) | @@ -124,7 +124,7 @@ | TestThrow.java:79:11:79:25 | new Exception(...) | TestThrow.java:79:5:79:26 | stmt | | TestThrow.java:79:11:79:25 | new Exception(...) | TestThrow.java:81:3:83:3 | stmt | | TestThrow.java:81:3:83:3 | stmt | TestThrow.java:82:4:82:9 | stmt | -| TestThrow.java:82:4:82:8 | ...=... | TestThrow.java:15:14:15:14 | f | +| TestThrow.java:82:4:82:8 | ...=... | TestThrow.java:15:14:15:14 | Exit | | TestThrow.java:82:4:82:8 | ...=... | TestThrow.java:85:3:126:3 | stmt | | TestThrow.java:82:4:82:9 | stmt | TestThrow.java:82:8:82:8 | 1 | | TestThrow.java:82:8:82:8 | 1 | TestThrow.java:82:4:82:8 | ...=... | @@ -211,7 +211,7 @@ | TestThrow.java:121:4:121:9 | stmt | TestThrow.java:121:8:121:8 | 2 | | TestThrow.java:121:8:121:8 | 2 | TestThrow.java:121:4:121:8 | ...=... | | TestThrow.java:124:3:126:3 | stmt | TestThrow.java:125:4:125:9 | stmt | -| TestThrow.java:125:4:125:8 | ...=... | TestThrow.java:15:14:15:14 | f | +| TestThrow.java:125:4:125:8 | ...=... | TestThrow.java:15:14:15:14 | Exit | | TestThrow.java:125:4:125:8 | ...=... | TestThrow.java:128:3:128:13 | stmt | | TestThrow.java:125:4:125:9 | stmt | TestThrow.java:125:8:125:8 | 3 | | TestThrow.java:125:8:125:8 | 3 | TestThrow.java:125:4:125:8 | ...=... | @@ -221,9 +221,9 @@ | TestThrow.java:128:7:128:12 | ... == ... | TestThrow.java:133:3:133:9 | stmt | | TestThrow.java:128:12:128:12 | 1 | TestThrow.java:128:7:128:12 | ... == ... | | TestThrow.java:129:3:131:3 | stmt | TestThrow.java:130:10:130:24 | new Exception(...) | -| TestThrow.java:130:4:130:25 | stmt | TestThrow.java:15:14:15:14 | f | +| TestThrow.java:130:4:130:25 | stmt | TestThrow.java:15:14:15:14 | Exit | | TestThrow.java:130:10:130:24 | new Exception(...) | TestThrow.java:130:4:130:25 | stmt | -| TestThrow.java:133:3:133:8 | ...=... | TestThrow.java:15:14:15:14 | f | +| TestThrow.java:133:3:133:8 | ...=... | TestThrow.java:15:14:15:14 | Exit | | TestThrow.java:133:3:133:9 | stmt | TestThrow.java:133:8:133:8 | 1 | | TestThrow.java:133:7:133:8 | -... | TestThrow.java:133:3:133:8 | ...=... | | TestThrow.java:133:8:133:8 | 1 | TestThrow.java:133:7:133:8 | -... | diff --git a/java/ql/test/library-tests/successors/TestThrow/TestSucc.ql b/java/ql/test/library-tests/successors/TestThrow/TestSucc.ql index 9de77b3c42b6..d09b7c865fd1 100644 --- a/java/ql/test/library-tests/successors/TestThrow/TestSucc.ql +++ b/java/ql/test/library-tests/successors/TestThrow/TestSucc.ql @@ -4,5 +4,5 @@ from ControlFlowNode n, ControlFlowNode succ where succ = n.getASuccessor() and n.getLocation().getFile().getExtension() = "java" and - not n.getFile().getStem() = "PopulateRuntimeException" + not n.getEnclosingCallable().getFile().getStem() = "PopulateRuntimeException" select n, succ diff --git a/java/ql/test/library-tests/successors/TestThrow2/TestSucc.expected b/java/ql/test/library-tests/successors/TestThrow2/TestSucc.expected index 6f8efd945d6d..32888dde1ecb 100644 --- a/java/ql/test/library-tests/successors/TestThrow2/TestSucc.expected +++ b/java/ql/test/library-tests/successors/TestThrow2/TestSucc.expected @@ -1,4 +1,4 @@ -| TestThrow2.java:3:7:3:16 | (...) | TestThrow2.java:3:7:3:16 | TestThrow2 | +| TestThrow2.java:3:7:3:16 | (...) | TestThrow2.java:3:7:3:16 | Exit | | TestThrow2.java:3:7:3:16 | stmt | TestThrow2.java:3:7:3:16 | (...) | | TestThrow2.java:3:7:3:16 | stmt | TestThrow2.java:3:7:3:16 | super(...) | | TestThrow2.java:3:7:3:16 | stmt | TestThrow2.java:5:2:11:2 | stmt | @@ -6,10 +6,10 @@ | TestThrow2.java:5:2:11:2 | stmt | TestThrow2.java:6:3:10:3 | stmt | | TestThrow2.java:6:3:10:3 | stmt | TestThrow2.java:6:7:8:3 | stmt | | TestThrow2.java:6:7:8:3 | stmt | TestThrow2.java:7:4:7:13 | stmt | -| TestThrow2.java:7:4:7:12 | thrower(...) | TestThrow2.java:3:7:3:16 | | +| TestThrow2.java:7:4:7:12 | thrower(...) | TestThrow2.java:3:7:3:16 | Exit | | TestThrow2.java:7:4:7:12 | thrower(...) | TestThrow2.java:8:5:8:23 | stmt | | TestThrow2.java:7:4:7:13 | stmt | TestThrow2.java:7:4:7:12 | thrower(...) | | TestThrow2.java:8:5:8:23 | stmt | TestThrow2.java:8:22:8:22 | e | | TestThrow2.java:8:22:8:22 | e | TestThrow2.java:8:25:10:3 | stmt | | TestThrow2.java:8:25:10:3 | stmt | TestThrow2.java:9:4:9:4 | stmt | -| TestThrow2.java:9:4:9:4 | stmt | TestThrow2.java:3:7:3:16 | | +| TestThrow2.java:9:4:9:4 | stmt | TestThrow2.java:3:7:3:16 | Exit | diff --git a/java/ql/test/library-tests/successors/TestThrow2/TestSucc.ql b/java/ql/test/library-tests/successors/TestThrow2/TestSucc.ql index 9de77b3c42b6..d09b7c865fd1 100644 --- a/java/ql/test/library-tests/successors/TestThrow2/TestSucc.ql +++ b/java/ql/test/library-tests/successors/TestThrow2/TestSucc.ql @@ -4,5 +4,5 @@ from ControlFlowNode n, ControlFlowNode succ where succ = n.getASuccessor() and n.getLocation().getFile().getExtension() = "java" and - not n.getFile().getStem() = "PopulateRuntimeException" + not n.getEnclosingCallable().getFile().getStem() = "PopulateRuntimeException" select n, succ diff --git a/java/ql/test/library-tests/successors/TestTryCatch/TestSucc.expected b/java/ql/test/library-tests/successors/TestTryCatch/TestSucc.expected index db1f8d15d833..5f2d16d768e3 100644 --- a/java/ql/test/library-tests/successors/TestTryCatch/TestSucc.expected +++ b/java/ql/test/library-tests/successors/TestTryCatch/TestSucc.expected @@ -1,5 +1,5 @@ | TestTryCatch.java:3:14:3:25 | stmt | TestTryCatch.java:3:14:3:25 | super(...) | -| TestTryCatch.java:3:14:3:25 | super(...) | TestTryCatch.java:3:14:3:25 | TestTryCatch | +| TestTryCatch.java:3:14:3:25 | super(...) | TestTryCatch.java:3:14:3:25 | Exit | | TestTryCatch.java:5:2:43:2 | stmt | TestTryCatch.java:6:3:23:3 | stmt | | TestTryCatch.java:6:3:23:3 | stmt | TestTryCatch.java:7:3:12:3 | stmt | | TestTryCatch.java:7:3:12:3 | stmt | TestTryCatch.java:8:4:8:29 | stmt | @@ -51,7 +51,7 @@ | TestTryCatch.java:21:4:21:32 | println(...) | TestTryCatch.java:22:4:22:13 | stmt | | TestTryCatch.java:21:4:21:33 | stmt | TestTryCatch.java:21:4:21:13 | System.out | | TestTryCatch.java:21:23:21:31 | "Finally" | TestTryCatch.java:21:4:21:32 | println(...) | -| TestTryCatch.java:22:4:22:12 | ...=... | TestTryCatch.java:4:14:4:14 | f | +| TestTryCatch.java:22:4:22:12 | ...=... | TestTryCatch.java:4:14:4:14 | Exit | | TestTryCatch.java:22:4:22:12 | ...=... | TestTryCatch.java:24:3:24:13 | stmt | | TestTryCatch.java:22:4:22:13 | stmt | TestTryCatch.java:22:8:22:8 | y | | TestTryCatch.java:22:8:22:8 | y | TestTryCatch.java:22:12:22:12 | 1 | @@ -114,7 +114,7 @@ | TestTryCatch.java:39:9:39:9 | x | TestTryCatch.java:39:13:39:13 | 1 | | TestTryCatch.java:39:9:39:13 | ... + ... | TestTryCatch.java:39:5:39:13 | ...=... | | TestTryCatch.java:39:13:39:13 | 1 | TestTryCatch.java:39:9:39:13 | ... + ... | -| TestTryCatch.java:42:3:42:11 | ...=... | TestTryCatch.java:4:14:4:14 | f | +| TestTryCatch.java:42:3:42:11 | ...=... | TestTryCatch.java:4:14:4:14 | Exit | | TestTryCatch.java:42:3:42:12 | stmt | TestTryCatch.java:42:7:42:7 | z | | TestTryCatch.java:42:7:42:7 | z | TestTryCatch.java:42:11:42:11 | 2 | | TestTryCatch.java:42:7:42:11 | ... + ... | TestTryCatch.java:42:3:42:11 | ...=... | diff --git a/java/ql/test/library-tests/successors/TestTryCatch/TestSucc.ql b/java/ql/test/library-tests/successors/TestTryCatch/TestSucc.ql index 9de77b3c42b6..d09b7c865fd1 100644 --- a/java/ql/test/library-tests/successors/TestTryCatch/TestSucc.ql +++ b/java/ql/test/library-tests/successors/TestTryCatch/TestSucc.ql @@ -4,5 +4,5 @@ from ControlFlowNode n, ControlFlowNode succ where succ = n.getASuccessor() and n.getLocation().getFile().getExtension() = "java" and - not n.getFile().getStem() = "PopulateRuntimeException" + not n.getEnclosingCallable().getFile().getStem() = "PopulateRuntimeException" select n, succ diff --git a/java/ql/test/library-tests/successors/TestTryWithResources/TestSucc.expected b/java/ql/test/library-tests/successors/TestTryWithResources/TestSucc.expected index 86c3f054f155..39a301a4c628 100644 --- a/java/ql/test/library-tests/successors/TestTryWithResources/TestSucc.expected +++ b/java/ql/test/library-tests/successors/TestTryWithResources/TestSucc.expected @@ -1,5 +1,5 @@ | TestTryWithResources.java:6:14:6:33 | stmt | TestTryWithResources.java:6:14:6:33 | super(...) | -| TestTryWithResources.java:6:14:6:33 | super(...) | TestTryWithResources.java:6:14:6:33 | TestTryWithResources | +| TestTryWithResources.java:6:14:6:33 | super(...) | TestTryWithResources.java:6:14:6:33 | Exit | | TestTryWithResources.java:7:60:16:2 | stmt | TestTryWithResources.java:8:3:15:3 | stmt | | TestTryWithResources.java:8:3:15:3 | stmt | TestTryWithResources.java:8:8:8:58 | stmt | | TestTryWithResources.java:8:8:8:58 | stmt | TestTryWithResources.java:8:50:8:53 | args | @@ -32,6 +32,6 @@ | TestTryWithResources.java:12:23:12:38 | "file not found" | TestTryWithResources.java:12:4:12:39 | println(...) | | TestTryWithResources.java:13:13:15:3 | stmt | TestTryWithResources.java:14:4:14:33 | stmt | | TestTryWithResources.java:14:4:14:13 | System.out | TestTryWithResources.java:14:23:14:31 | "finally" | -| TestTryWithResources.java:14:4:14:32 | println(...) | TestTryWithResources.java:7:21:7:24 | main | +| TestTryWithResources.java:14:4:14:32 | println(...) | TestTryWithResources.java:7:21:7:24 | Exit | | TestTryWithResources.java:14:4:14:33 | stmt | TestTryWithResources.java:14:4:14:13 | System.out | | TestTryWithResources.java:14:23:14:31 | "finally" | TestTryWithResources.java:14:4:14:32 | println(...) | diff --git a/java/ql/test/library-tests/successors/TestTryWithResources/TestSucc.ql b/java/ql/test/library-tests/successors/TestTryWithResources/TestSucc.ql index 9de77b3c42b6..d09b7c865fd1 100644 --- a/java/ql/test/library-tests/successors/TestTryWithResources/TestSucc.ql +++ b/java/ql/test/library-tests/successors/TestTryWithResources/TestSucc.ql @@ -4,5 +4,5 @@ from ControlFlowNode n, ControlFlowNode succ where succ = n.getASuccessor() and n.getLocation().getFile().getExtension() = "java" and - not n.getFile().getStem() = "PopulateRuntimeException" + not n.getEnclosingCallable().getFile().getStem() = "PopulateRuntimeException" select n, succ diff --git a/java/ql/test/library-tests/unreachableblocks/UnreachableBlocks.expected b/java/ql/test/library-tests/unreachableblocks/UnreachableBlocks.expected index 2592d8fe1db5..5c02d64c2ffe 100644 --- a/java/ql/test/library-tests/unreachableblocks/UnreachableBlocks.expected +++ b/java/ql/test/library-tests/unreachableblocks/UnreachableBlocks.expected @@ -3,7 +3,6 @@ | unreachableblocks/Unreachable.java:12:22:14:3 | stmt | | unreachableblocks/Unreachable.java:17:3:17:9 | stmt | | unreachableblocks/Unreachable.java:19:3:19:9 | stmt | -| unreachableblocks/Unreachable.java:22:3:22:9 | stmt | | unreachableblocks/Unreachable.java:24:3:24:9 | stmt | | unreachableblocks/Unreachable.java:26:3:26:10 | stmt | | unreachableblocks/Unreachable.java:27:3:27:10 | stmt |