Java: IPA the CFG

This commit is contained in:
Owen Mansel-Chan
2024-11-12 17:01:51 +00:00
parent 0f5786e4e6
commit 0f3dd6d8f1
79 changed files with 455 additions and 348 deletions

View File

@@ -1,7 +1,6 @@
import java
import semmle.code.java.ControlFlowGraph
predicate shouldBeDeadEnd(ControlFlowNode n) {
predicate shouldBeDeadEnd(ExprParent n) {
n instanceof BreakStmt and n.getFile().isKotlinSourceFile() // TODO
or
n instanceof Interface // TODO
@@ -55,8 +54,11 @@ predicate shouldBeDeadEnd(ControlFlowNode n) {
n = any(ConstCase c).getValue(_) // TODO
}
from ControlFlowNode n, string s
from ControlFlowNode n, ExprParent astnode, string s
where
// TODO: exists(n.getASuccessor()) and shouldBeDeadEnd(n) and s = "expected dead end"
not exists(n.getASuccessor()) and not shouldBeDeadEnd(n) and s = "unexpected dead end"
select n, n.getPrimaryQlClasses(), s
astnode = n.getAstNode() and
// TODO: exists(n.getASuccessor()) and shouldBeDeadEnd(n.getAstNode()) and s = "expected dead end"
not exists(n.getASuccessor()) and
not shouldBeDeadEnd(astnode) and
s = "unexpected dead end"
select n, astnode.getPrimaryQlClasses(), s

View File

@@ -4,7 +4,7 @@
* The only API exported by this library are the toplevel classes `ControlFlowNode`
* 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
* statement, an expression, or an exit node for a callable, indicating that
* execution of the callable terminates.
*/
@@ -84,45 +84,122 @@ private import Completion
private import controlflow.internal.Preconditions
private import controlflow.internal.SwitchCases
/** 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()
/** Provides the definition of control flow nodes. */
module ControlFlow {
private predicate hasControlFlow(Expr e) {
not exists(ConstCase cc | e = cc.getValue(_)) 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 immediately enclosing callable whose body contains this node. */
Callable getEnclosingCallable() {
result = this or
result = this.(Stmt).getEnclosingCallable() or
result = this.(Expr).getEnclosingCallable()
private newtype TNode =
TExprNode(Expr e) { hasControlFlow(e) } or
TStmtNode(Stmt s) or
TExitNode(Callable c) { exists(c.getBody()) }
/** 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 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 the basic block that contains this node. */
BasicBlock getBasicBlock() { result.getANode() = this }
/** 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 the source location for this element. */
Location getLocation() {
result = this.asExpr().getLocation() or
result = this.asStmt().getLocation() or
result = this.(ExitNode).getEnclosingCallable().getLocation()
}
/**
* Get the most appropriate AST node for this control flow node, if any.
*
* This is needed for the equivalence relation on basic blocks in range
* analysis.
*/
ExprParent getAstNode() {
result = this.asExpr() or
result = this.asStmt() or
this = TExitNode(result)
}
}
/** Gets an immediate successor of this node. */
ControlFlowNode getASuccessor() { result = succ(this) }
/** Gets an immediate predecessor of this node. */
ControlFlowNode getAPredecessor() { this = succ(result) }
/** Gets an exception successor of this node. */
ControlFlowNode getAnExceptionSuccessor() { result = succ(this, ThrowCompletion(_)) }
/** 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())
}
/** Gets the basic block that contains this node. */
BasicBlock getBasicBlock() { result.getANode() = this }
/** A synthetic node for the exit of a callable. */
class ExitNode extends Node, TExitNode { }
}
class ControlFlowNode = ControlFlow::Node;
/** Gets the intra-procedural successor of `n`. */
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.
*/
@@ -167,7 +244,7 @@ private module ControlFlowGraphImpl {
* `ClassCastException` is expected, or because it is a Kotlin not-null check
* and a `NullPointerException` 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 |
@@ -200,7 +277,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().getEnclosingStmt+() = try.getBlock() or
n.(Expr).getParent*() = try.getAResource()
@@ -214,7 +291,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().getEnclosingStmt+() = try.getBlock() or
n.(Expr).getParent*() = try.getAResource()
@@ -229,7 +306,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().getEnclosingStmt+() = try.getBlock() or
n.(Expr).getParent*() = try.getAResource()
)
@@ -287,7 +364,7 @@ private module ControlFlowGraphImpl {
* That is, contexts where the control-flow edges depend on `value` given that `b` ends
* with a `booleanCompletion(value, _)`.
*/
private predicate inBooleanContext(ControlFlowNode b) {
private predicate inBooleanContext(AstNode b) {
exists(LogicExpr logexpr |
logexpr.(BinaryExpr).getLeftOperand() = b
or
@@ -493,9 +570,7 @@ private module ControlFlowGraphImpl {
* immediately before either falling through to execute successor statements or execute a rule body
* if present. `completion` is the completion kind of the last operation.
*/
private predicate lastPatternCaseMatchingOp(
PatternCase pc, ControlFlowNode last, Completion completion
) {
private predicate lastPatternCaseMatchingOp(PatternCase pc, Node last, Completion completion) {
last(pc.getAPattern(), last, completion) and
completion = NormalCompletion() and
not exists(pc.getGuard())
@@ -514,7 +589,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.
@@ -576,7 +651,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
@@ -649,7 +724,7 @@ private module ControlFlowGraphImpl {
}
/** Gets the first child node, if any. */
ControlFlowNode firstChild() {
AstNode firstChild() {
result = this.getChildNode(-1)
or
result = this.getChildNode(0) and not exists(this.getChildNode(-1))
@@ -687,18 +762,18 @@ 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 instanceof WhenExpr
result.asExpr() = n and n instanceof WhenExpr
or
result = n and n instanceof WhenBranch
result.asStmt() = n and n instanceof WhenBranch
or
result = n and n instanceof StmtExpr
result.asExpr() = n and n instanceof StmtExpr
or
result = n and n.(PostOrderNode).isLeafNode()
result = n.getCFGNode() and n.(PostOrderNode).isLeafNode()
or
result = first(n.(PostOrderNode).firstChild())
or
@@ -706,12 +781,11 @@ 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
or
result = n and n instanceof SwitchExpr
result.asExpr() = n and n instanceof SwitchExpr
}
/**
@@ -722,9 +796,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(_)
@@ -737,7 +809,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 |
@@ -767,12 +839,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())
}
@@ -796,7 +868,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.
// As are any break, yield, continue, or return completions.
exists(Expr e | e.getParent() = n |
@@ -853,15 +925,18 @@ private module ControlFlowGraphImpl {
)
or
exists(InstanceOfExpr ioe | ioe.isPattern() and ioe = n |
last = n and completion = basicBooleanCompletion(false)
last.asExpr() = n and completion = basicBooleanCompletion(false)
or
last(ioe.getPattern(), last, NormalCompletion()) and completion = basicBooleanCompletion(true)
)
or
// The last node of a node executed in post-order is the node itself.
n.(PostOrderNode).mayCompleteNormally() and last = n and completion = NormalCompletion()
// 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.
@@ -997,7 +1072,7 @@ private module ControlFlowGraphImpl {
// * On success of its guard test, if it is not a rule (boolean true)
// (the latter two cases are accounted for by lastPatternCaseMatchingOp)
exists(PatternCase pc | n = pc |
last = pc and completion = basicBooleanCompletion(false)
last.asStmt() = pc and completion = basicBooleanCompletion(false)
or
last(pc.getGuard(), last, completion) and
completion = BooleanCompletion(false, _)
@@ -1010,13 +1085,15 @@ 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()
@@ -1031,7 +1108,7 @@ private module ControlFlowGraphImpl {
)
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()
@@ -1067,7 +1144,7 @@ private module ControlFlowGraphImpl {
// the last node of the condition of the last branch in the absence of an else-branch.
exists(WhenExpr whenexpr | whenexpr = n |
// If we have no branches then we are the last node
last = n and
last.asExpr() = n and
completion = NormalCompletion() and
not exists(whenexpr.getBranch(_))
or
@@ -1117,17 +1194,19 @@ private module ControlFlowGraphImpl {
* execution finishes with the given completion.
*/
cached
ControlFlowNode succ(ControlFlowNode n, Completion completion) {
// Callables serve as their own exit nodes.
exists(Callable c | last(c.getBody(), n, completion) | result = c)
Node succ(Node n, Completion completion) {
// The successor of a callable is its exit node.
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.
@@ -1151,9 +1230,11 @@ private module ControlFlowGraphImpl {
)
or
exists(InstanceOfExpr ioe | ioe.isPattern() |
last(ioe.getExpr(), n, completion) and completion = NormalCompletion() and result = ioe
last(ioe.getExpr(), n, completion) and
completion = NormalCompletion() and
result.asExpr() = ioe
or
n = ioe and
n.asExpr() = ioe and
result = first(ioe.getPattern()) and
completion = basicBooleanCompletion(true)
)
@@ -1164,11 +1245,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.(BlockStmt).getStmt(0)) and completion = NormalCompletion()
result = first(n.asStmt().(BlockStmt).getStmt(0)) and completion = NormalCompletion()
or
exists(BlockStmt blk, int i |
last(blk.getStmt(i), n, completion) and
@@ -1178,7 +1259,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
@@ -1190,7 +1271,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
@@ -1198,10 +1279,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()
@@ -1238,27 +1319,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...
@@ -1282,7 +1365,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())
@@ -1310,7 +1393,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())
)
@@ -1321,7 +1404,9 @@ private module ControlFlowGraphImpl {
switchExpr = switch.(SwitchStmt).getExpr() or switchExpr = switch.(SwitchExpr).getExpr()
|
// From the entry point control is transferred first to the expression...
n = switch and result = first(switchExpr) and completion = NormalCompletion()
(n.asStmt() = switch or n.asExpr() = switch) and
result = first(switchExpr) and
completion = NormalCompletion()
or
// ...and then to any case up to and including the first pattern case, if any.
last(switchExpr, n, completion) and
@@ -1345,7 +1430,7 @@ private module ControlFlowGraphImpl {
or
// A pattern case that completes boolean false (type test or guard failure) continues to consider other cases:
exists(PatternCase case | completion = BooleanCompletion(false, _) |
last(case, n, completion) and result = getASuccessorSwitchCase(case, switch)
last(case, n, completion) and result.asStmt() = getASuccessorSwitchCase(case, switch)
)
)
or
@@ -1358,7 +1443,7 @@ private module ControlFlowGraphImpl {
// * Variable declarations -normal-> rule execution (when there is no guard)
// * Guard success -true-> rule execution
exists(PatternCase pc |
n = pc and
n.asStmt() = pc and
completion = basicBooleanCompletion(true) and
result = first(pc.getAPattern())
or
@@ -1375,7 +1460,7 @@ private module ControlFlowGraphImpl {
)
or
// Non-pattern cases have an internal edge leading to their rule body if any when the case matches.
exists(SwitchCase case | n = case |
exists(SwitchCase case | n.asStmt() = case |
not case instanceof PatternCase and
completion = NormalCompletion() and
(
@@ -1387,32 +1472,32 @@ private module ControlFlowGraphImpl {
or
// Yield
exists(YieldStmt yield | completion = NormalCompletion() |
n = yield and result = first(yield.getValue())
n.asStmt() = yield and result = first(yield.getValue())
)
or
// 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.(StmtExpr).getStmt()) and completion = NormalCompletion()
result = first(n.asExpr().(StmtExpr).getStmt()) 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)))
)
or
// When expressions:
exists(WhenExpr whenexpr |
n = whenexpr and
n.asExpr() = whenexpr and
result = first(whenexpr.getBranch(0)) and
completion = NormalCompletion()
or
@@ -1425,7 +1510,7 @@ private module ControlFlowGraphImpl {
or
// When branches:
exists(WhenBranch whenbranch |
n = whenbranch and
n.asStmt() = whenbranch and
completion = NormalCompletion() and
result = first(whenbranch.getCondition())
or
@@ -1463,7 +1548,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()
@@ -1474,9 +1559,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`.
@@ -1487,8 +1570,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)
@@ -1497,7 +1580,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)
}
@@ -1506,18 +1589,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 = this.getABranchSuccessor(true) }
ControlFlow::Node getATrueSuccessor() { result = this.getABranchSuccessor(true) }
/** Gets a false-successor of the `ConditionNode`. */
ControlFlowNode getAFalseSuccessor() { result = this.getABranchSuccessor(false) }
ControlFlow::Node getAFalseSuccessor() { result = this.getABranchSuccessor(false) }
/** Gets the condition of this `ConditionNode`. This is equal to the node itself. */
ExprParent getCondition() { result = this }
ExprParent getCondition() { result = this.asExpr() or result = this.asStmt() }
}

View File

@@ -61,10 +61,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() }

View File

@@ -45,10 +45,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 }

View File

@@ -66,3 +66,8 @@ class BasicBlock extends ControlFlowNode {
/** Holds if this basic block post-dominates `node`. (This is reflexive.) */
predicate bbPostDominates(BasicBlock node) { bbPostDominates(this, node) }
}
/** A basic block that ends in an exit node. */
class ExitBlock extends BasicBlock {
ExitBlock() { this.getLastNode() instanceof ControlFlow::ExitNode }
}

View File

@@ -9,13 +9,15 @@ import java
*/
/** 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 BlockStmt 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 BlockStmt and
not exists(entry.getEnclosingCallable()) and
not entrystmt.getParent() instanceof Stmt
)
}
/** The successor relation for basic blocks. */
@@ -31,11 +33,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() }

View File

@@ -113,7 +113,7 @@ private PatternCase getClosestPrecedingPatternCase(SwitchCase case) {
private predicate isNonFallThroughPredecessor(SwitchCase sc, ControlFlowNode pred) {
pred = sc.getControlFlowNode().getAPredecessor() and
(
pred.(Expr).getParent*() = sc.getSelectorExpr()
pred.asExpr().getParent*() = sc.getSelectorExpr()
or
// Ambiguous: in the case of `case String _ when x: case "SomeConstant":`, the guard `x`
// passing edge will fall through into the constant case, and the guard failing edge
@@ -122,7 +122,7 @@ private predicate isNonFallThroughPredecessor(SwitchCase sc, ControlFlowNode pre
exists(PatternCase previousPatternCase |
previousPatternCase = getClosestPrecedingPatternCase(sc)
|
pred.(Expr).getParent*() = previousPatternCase.getGuard() and
pred.asExpr().getParent*() = previousPatternCase.getGuard() and
// Check there is any statement in between the previous pattern case and this one,
// or the case is a rule, so there is no chance of a fall-through.
(
@@ -133,7 +133,7 @@ private predicate isNonFallThroughPredecessor(SwitchCase sc, ControlFlowNode pre
or
// Unambigious: on the test-passing edge there must be at least one intervening
// declaration node, including anonymous `_` declarations.
pred = getClosestPrecedingPatternCase(sc)
pred.asStmt() = getClosestPrecedingPatternCase(sc)
)
}

View File

@@ -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)
)
}
@@ -45,17 +45,17 @@ private predicate callAlwaysPerformsAction(Call call, ActionConfiguration conf)
/** 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 +80,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)
)
}

View File

@@ -207,14 +207,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 = this.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 this.(Expr).getEnclosingStmt() instanceof AssertStmt and
not this instanceof CatchClause
not exists(Callable c | c.getBody().getControlFlowNode() = this.getFirstNode()) and
not this.getFirstNode().asExpr().getEnclosingStmt() instanceof AssertStmt and
not this.getFirstNode().asStmt() instanceof CatchClause
or
// Switch statements with a constant comparison expression may have unreachable cases.
exists(ConstSwitchStmt constSwitchStmt, BasicBlock unreachableCaseBlock |

View File

@@ -227,12 +227,14 @@ class InstanceAccessExt extends TInstanceAccessExt {
/** Gets the control flow node associated with this instance access. */
ControlFlowNode getCfgNode() {
exists(ExprParent e | e = this.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 VarRead then fa = result else result.(AssignExpr).getDest() = fa
if fa instanceof VarRead
then fa.getControlFlowNode() = result
else result.asExpr().(AssignExpr).getDest() = fa
)
)
}

View File

@@ -130,8 +130,8 @@ predicate dereference(Expr e) {
* The `VarAccess` is included for nicer error reporting.
*/
private ControlFlowNode varDereference(SsaVariable v, VarAccess va) {
dereference(result) and
result = sameValue(v, va)
dereference(result.asExpr()) and
result.asExpr() = sameValue(v, va)
}
/**
@@ -141,16 +141,16 @@ private ControlFlowNode varDereference(SsaVariable v, VarAccess va) {
private ControlFlowNode ensureNotNull(SsaVariable v) {
result = varDereference(v, _)
or
result.(AssertStmt).getExpr() = nullGuard(v, true, false)
result.asStmt().(AssertStmt).getExpr() = nullGuard(v, true, false)
or
exists(AssertTrueMethod m | result = m.getACheck(nullGuard(v, true, false)))
exists(AssertTrueMethod m | result.asCall() = m.getACheck(nullGuard(v, true, false)))
or
exists(AssertFalseMethod m | result = m.getACheck(nullGuard(v, false, false)))
exists(AssertFalseMethod m | result.asCall() = m.getACheck(nullGuard(v, false, false)))
or
exists(AssertNotNullMethod m | result = m.getACheck(v.getAUse()))
exists(AssertNotNullMethod m | result.asCall() = m.getACheck(v.getAUse()))
or
exists(AssertThatMethod m, MethodCall ma |
result = m.getACheck(v.getAUse()) and ma.getControlFlowNode() = result
result.asCall() = m.getACheck(v.getAUse()) and ma.getControlFlowNode() = result
|
ma.getAnArgument().(MethodCall).getMethod().getName() = "notNullValue"
)
@@ -279,10 +279,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().asExpr() = for.getVariable() and
not n2.asExpr() = for.getVariable()
)
}
@@ -343,7 +343,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

View File

@@ -211,9 +211,11 @@ module Sem implements Semantic {
BasicBlock getABasicBlockSuccessor(BasicBlock bb) { result = bb.getABBSuccessor() }
private predicate id(BasicBlock x, BasicBlock y) { x = y }
private predicate id(ExprParent x, ExprParent y) { x = y }
private predicate idOf(BasicBlock x, int y) = equivalenceRelation(id/2)(x, y)
private predicate idOfAst(ExprParent x, int y) = equivalenceRelation(id/2)(x, y)
private predicate idOf(BasicBlock x, int y) { idOfAst(x.getAstNode(), y) }
int getBlockId1(BasicBlock bb) { idOf(bb, result) }

View File

@@ -228,7 +228,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
@@ -237,8 +237,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).getLocalTypeDeclStmt() = result
nc.(AnonymousClass).getClassInstanceExpr().getControlFlowNode() = result or
nc.(LocalClass).getLocalTypeDeclStmt().getControlFlowNode() = result
}
/**
@@ -276,7 +276,7 @@ private module SsaImpl {
/** Holds if `VarAccess` `use` of `v` occurs in `b` at index `i`. */
private predicate variableUse(TrackedVar v, VarRead 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`. */
@@ -423,7 +423,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(), _)
}
@@ -550,7 +550,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
@@ -574,12 +574,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
|
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 and
liveAtEntry(v, b)
}
/**
@@ -882,7 +886,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)
}
/**
@@ -940,7 +944,7 @@ class SsaVariable extends TSsaVariable {
/** Gets an access of this SSA variable. */
VarRead getAUse() {
ssaDefReachesUse(_, this, result) or
this = TSsaUntracked(_, result)
this = TSsaUntracked(_, result.getControlFlowNode())
}
/**
@@ -954,7 +958,7 @@ class SsaVariable extends TSsaVariable {
*/
VarRead getAFirstUse() {
firstUse(this, result) or
this = TSsaUntracked(_, result)
this = TSsaUntracked(_, result.getControlFlowNode())
}
/** Holds if this SSA variable is live at the end of `b`. */
@@ -990,7 +994,7 @@ class SsaUpdate extends SsaVariable {
class SsaExplicitUpdate extends SsaUpdate, TSsaCertainUpdate {
SsaExplicitUpdate() {
exists(VariableUpdate upd |
upd = this.getCfgNode() and getDestVar(upd) = this.getSourceVariable()
upd.getControlFlowNode() = this.getCfgNode() and getDestVar(upd) = this.getSourceVariable()
)
}
@@ -998,7 +1002,8 @@ class SsaExplicitUpdate extends SsaUpdate, TSsaCertainUpdate {
/** Gets the `VariableUpdate` defining the SSA variable. */
VariableUpdate getDefiningExpr() {
result = this.getCfgNode() and getDestVar(result) = this.getSourceVariable()
result.getControlFlowNode() = this.getCfgNode() and
getDestVar(result) = this.getSourceVariable()
}
}
@@ -1038,7 +1043,7 @@ class SsaImplicitUpdate extends SsaUpdate {
exists(SsaSourceField f, Callable setter |
f = this.getSourceVariable() and
relevantFieldUpdate(setter, f.getField(), result) and
updatesNamedField(this.getCfgNode(), f, setter)
updatesNamedField(this.getCfgNode().asCall(), f, setter)
)
}
@@ -1086,7 +1091,7 @@ class SsaImplicitInit extends SsaVariable, TSsaEntryDef {
*/
predicate isParameterDefinition(Parameter p) {
this.getSourceVariable() = TLocalVar(p.getCallable(), p) and
p.getCallable().getBody() = this.getCfgNode()
p.getCallable().getBody().getControlFlowNode() = this.getCfgNode()
}
}

View File

@@ -252,8 +252,8 @@ private module Input implements TypeFlowInput<Location> {
downcastSuccessorAux(pragma[only_bind_into](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())
)
}

View File

@@ -73,15 +73,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).getLocalTypeDeclStmt() = result
nc.(AnonymousClass).getClassInstanceExpr().getControlFlowNode() = result or
nc.(LocalClass).getLocalTypeDeclStmt().getControlFlowNode() = result
}
/**
@@ -121,7 +121,7 @@ private module SsaImpl {
/** Holds if `VarAccess` `use` of `v` occurs in `b` at index `i`. */
private predicate variableUse(BaseSsaSourceVariable v, VarRead 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`. */
@@ -164,7 +164,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
|
l instanceof Parameter or
l.getCallable() != c
)
@@ -537,7 +539,7 @@ class BaseSsaVariable extends TBaseSsaVariable {
class BaseSsaUpdate extends BaseSsaVariable, TSsaUpdate {
BaseSsaUpdate() {
exists(VariableUpdate upd |
upd = this.getCfgNode() and getDestVar(upd) = this.getSourceVariable()
upd.getControlFlowNode() = this.getCfgNode() and getDestVar(upd) = this.getSourceVariable()
)
}
@@ -545,7 +547,8 @@ class BaseSsaUpdate extends BaseSsaVariable, TSsaUpdate {
/** Gets the `VariableUpdate` defining the SSA variable. */
VariableUpdate getDefiningExpr() {
result = this.getCfgNode() and getDestVar(result) = this.getSourceVariable()
result.getControlFlowNode() = this.getCfgNode() and
getDestVar(result) = this.getSourceVariable()
}
}
@@ -566,7 +569,7 @@ class BaseSsaImplicitInit extends BaseSsaVariable, TSsaEntryDef {
*/
predicate isParameterDefinition(Parameter p) {
this.getSourceVariable() = TLocalVar(p.getCallable(), p) and
p.getCallable().getBody() = this.getCfgNode()
p.getCallable().getBody().getControlFlowNode() = this.getCfgNode()
}
}

View File

@@ -112,7 +112,7 @@ private module CaptureInput implements VariableCapture::InputSig<Location> {
Location getLocation() { result = super.getLocation() }
predicate hasCfgNode(BasicBlock bb, int i) { this = bb.(J::BasicBlock).getNode(i) }
predicate hasCfgNode(BasicBlock bb, int i) { this = bb.(J::BasicBlock).getNode(i).asExpr() }
}
class VariableWrite extends Expr instanceof VariableUpdate {

View File

@@ -17,9 +17,11 @@ import DataFlowNodes::Public
/** 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() = cfgnode.asStmt()
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
}

View File

@@ -133,5 +133,5 @@ module Private {
predicate ssaUpdateStep = RU::ssaUpdateStep/3;
Expr getABasicBlockExpr(BasicBlock bb) { result = bb.getANode() }
Expr getABasicBlockExpr(BasicBlock bb) { result = bb.getANode().asExpr() }
}

View File

@@ -340,7 +340,7 @@ private module Impl {
Field getField(FieldAccess fa) { result = fa.getField() }
Expr getAnExpression(SsaReadPositionBlock bb) { result = bb.getBlock().getANode() }
Expr getAnExpression(SsaReadPositionBlock bb) { result = bb.getBlock().getANode().asExpr() }
Guard getComparisonGuard(ComparisonExpr ce) { result = ce }
}

View File

@@ -15,9 +15,11 @@ class BasicBlock = BB::BasicBlock;
/** Gets a basic block in which SSA variable `v` is read. */
BasicBlock getAReadBasicBlock(SsaVariable v) { result = v.getAUse().getBasicBlock() }
private predicate id(BasicBlock x, BasicBlock y) { x = y }
private predicate id(BB::ExprParent x, BB::ExprParent y) { x = y }
private predicate idOf(BasicBlock x, int y) = equivalenceRelation(id/2)(x, y)
private predicate idOfAst(BB::ExprParent x, int y) = equivalenceRelation(id/2)(x, y)
private predicate idOf(BasicBlock x, int y) { idOfAst(x.getAstNode(), y) }
private int getId(BasicBlock bb) { idOf(bb, result) }

View File

@@ -109,12 +109,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().(BooleanLiteral).getBooleanValue() = false
exists(AssertFailMethod m | n.asExpr() = m.getACheck()) or
n.asStmt().(AssertStmt).getExpr().(BooleanLiteral).getBooleanValue() = false
)
}

View File

@@ -73,14 +73,14 @@ 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 SwitchCase and
not sc.getControlFlowNode().getASuccessor().asStmt() instanceof SwitchCase and
not defaultFallThrough(sc)
}
private predicate defaultFallThrough(ConstCase sc) {
exists(DefaultCase default | default.(ControlFlowNode).getASuccessor() = sc)
exists(DefaultCase default | default.getControlFlowNode().getASuccessor().asStmt() = sc)
or
defaultFallThrough(sc.(ControlFlowNode).getAPredecessor())
defaultFallThrough(sc.getControlFlowNode().getAPredecessor().asStmt())
}
/** Holds if `stmt` is a branching statement used for the computation of cyclomatic complexity. */

View File

@@ -29,15 +29,19 @@ private module ValidationMethod<DataFlow::guardChecksSig/3 validationGuard> {
*/
private predicate validationMethod(Method m, int arg) {
exists(
Guard g, SsaImplicitInit var, ControlFlowNode exit, ControlFlowNode normexit, boolean branch
Guard g, SsaImplicitInit var, ControlFlow::ExitNode exit, ControlFlowNode normexit,
boolean branch
|
validationGuard(g, var.getAUse(), branch) 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)
|
g.(ConditionNode).getABranchSuccessor(branch) = exit or
exists(ConditionNode conditionNode |
g = conditionNode.getCondition() and conditionNode.getABranchSuccessor(branch) = exit
)
or
g.controls(normexit.getBasicBlock(), branch)
)
}

View File

@@ -50,7 +50,7 @@ private predicate validatedAccess(VarAccess va) {
bb.getNode(i + 1) = node.getANormalSuccessor()
|
bb.bbStrictlyDominates(va.getBasicBlock()) or
bb.getNode(any(int j | j > i)) = va
bb.getNode(any(int j | j > i)).asExpr() = va
)
)
)

View File

@@ -30,7 +30,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

View File

@@ -36,7 +36,7 @@ where
doubleCheckedLocking(if1, if2, sync, f) and
a.getEnclosingStmt().getEnclosingStmt*() = if2.getThen() and
se.getEnclosingStmt().getEnclosingStmt*() = sync.getBlock() and
a.(ControlFlowNode).getASuccessor+() = se and
a.getControlFlowNode().getASuccessor+().asExpr() = se 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.",

View File

@@ -64,12 +64,12 @@ class ValidSynchStmt extends Stmt {
exists(MethodCall lockAction |
lockAction.getQualifier() = lockField.getAnAccess() and
lockAction.getMethod().getName() = "lock" and
dominates(lockAction, this)
dominates(lockAction.getControlFlowNode(), this.getControlFlowNode())
) and
exists(MethodCall unlockAction |
unlockAction.getQualifier() = lockField.getAnAccess() and
unlockAction.getMethod().getName() = "unlock" and
postDominates(unlockAction, this)
postDominates(unlockAction.getControlFlowNode(), this.getControlFlowNode())
)
)
}

View File

@@ -59,11 +59,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).asExpr() = t.getLockAccess())
}
predicate unlockBlock(LockType t, BasicBlock b, int unlocks) {
unlocks = strictcount(int i | b.getNode(i) = t.getUnlockAccess())
unlocks = strictcount(int i | b.getNode(i).asExpr() = t.getUnlockAccess())
}
/**
@@ -90,11 +90,11 @@ predicate failedLock(LockType t, BasicBlock lockblock, BasicBlock exblock) {
exists(ControlFlowNode lock |
lock = lockblock.getLastNode() and
(
lock = t.getLockAccess()
lock.asExpr() = t.getLockAccess()
or
exists(SsaExplicitUpdate lockbool |
// Using the value of `t.getLockAccess()` ensures that it is a `tryLock` call.
lock = lockbool.getAUse() and
lock.asExpr() = lockbool.getAUse() and
lockbool.getDefiningExpr().(VariableAssign).getSource() = t.getLockAccess()
)
) and
@@ -147,12 +147,12 @@ predicate blockIsLocked(LockType t, BasicBlock src, BasicBlock b, int locks) {
)
}
from Callable c, LockType t, BasicBlock src, BasicBlock exit, MethodCall lock
from Callable c, LockType t, BasicBlock src, ExitBlock exit, MethodCall lock
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.getEnclosingCallable() = c and
lock = src.getANode().asExpr() and
lock = t.getLockAccess()
select lock, "This lock might not be unlocked or might be locked more times than it is unlocked."

View File

@@ -61,7 +61,7 @@ predicate mainLoopCondition(LoopStmt loop, Expr cond) {
else loopReentry = cond
|
last.getEnclosingStmt().getEnclosingStmt*() = 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, VarRead use | ssa.getAUse() = use and use.getParent*() = cond |
not ssa.getCfgNode().getEnclosingStmt().getEnclosingStmt*() = 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(MethodCall ma | ma.getParent*() = cond) and

View File

@@ -80,8 +80,8 @@ predicate badReentrantLockOrder(MethodCall first, MethodCall second, MethodCall
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
)

View File

@@ -17,7 +17,7 @@ import Common
from SwitchStmt s, Stmt c
where
c = s.getACase() and
not c.(ControlFlowNode).getASuccessor() instanceof SwitchCase and
not c.getControlFlowNode().getASuccessor().asStmt() instanceof SwitchCase and
not s.(Annotatable).suppressesWarningsAbout("fallthrough") and
mayDropThroughWithoutComment(s, c)
select c,

View File

@@ -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().asStmt() = switch.getACase()
)
}
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().asStmt() = switchCase and
b2.getFirstNode().asStmt() = other and
switchCaseControlFlowPlus(switch, b1, b2) and
other = switch.getACase() and
not fallThroughCommented(other)

View File

@@ -55,7 +55,7 @@ module SpringViewManipulationConfig implements DataFlow::ConfigSig {
// a = "redirect:" + taint`
// ```
exists(AddExpr e, StringLiteral sl |
node.asExpr() = e.getControlFlowNode().getASuccessor*() and
node.asExpr() = e.getControlFlowNode().getASuccessor*().asExpr() and
sl = e.getLeftOperand*() and
sl.getValue().matches(["redirect:%", "ajaxredirect:%", "forward:%"])
)

View File

@@ -1,7 +1,7 @@
| Test.java:3:14:3:17 | { ... } | 0 | Test.java:3:14:3:17 | { ... } |
| Test.java:3:14:3:17 | { ... } | 1 | Test.java:3:14:3:17 | super(...) |
| Test.java:3:14:3:17 | { ... } | 2 | Test.java:3:14:3:17 | Test |
| Test.java:4:14:4:17 | test | 0 | Test.java:4:14:4:17 | test |
| Test.java:3:14:3:17 | { ... } | 2 | Test.java:3:14:3:17 | Exit |
| Test.java:4:14:4:17 | Exit | 0 | Test.java:4:14:4:17 | Exit |
| Test.java:4:21:76:2 | { ... } | 0 | Test.java:4:21:76:2 | { ... } |
| Test.java:4:21:76:2 | { ... } | 1 | Test.java:5:3:5:12 | var ...; |
| Test.java:4:21:76:2 | { ... } | 2 | Test.java:5:11:5:11 | 0 |

View File

@@ -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, i, n

View File

@@ -1,4 +1,4 @@
| Test.java:4:21:76:2 | { ... } | Test.java:4:14:4:17 | test |
| Test.java:4:21:76:2 | { ... } | Test.java:4:14:4:17 | Exit |
| Test.java:4:21:76:2 | { ... } | Test.java:11:14:14:3 | { ... } |
| Test.java:4:21:76:2 | { ... } | Test.java:14:10:16:3 | { ... } |
| Test.java:4:21:76:2 | { ... } | Test.java:18:3:18:8 | <Expr>; |
@@ -20,7 +20,7 @@
| Test.java:4:21:76:2 | { ... } | Test.java:60:12:62:5 | { ... } |
| Test.java:4:21:76:2 | { ... } | Test.java:63:9:66:4 | { ... } |
| Test.java:4:21:76:2 | { ... } | Test.java:70:3:70:9 | <Expr>; |
| Test.java:18:3:18:8 | <Expr>; | Test.java:4:14:4:17 | test |
| Test.java:18:3:18:8 | <Expr>; | Test.java:4:14:4:17 | Exit |
| Test.java:18:3:18:8 | <Expr>; | Test.java:22:4:22:10 | <Expr>; |
| Test.java:18:3:18:8 | <Expr>; | Test.java:24:4:24:10 | return ... |
| Test.java:18:3:18:8 | <Expr>; | Test.java:30:15:33:3 | { ... } |

View File

@@ -6,7 +6,7 @@
| Test.java:18:3:18:8 | <Expr>; | Test.java:24:4:24:10 | return ... |
| Test.java:22:4:22:10 | <Expr>; | Test.java:30:15:33:3 | { ... } |
| Test.java:22:4:22:10 | <Expr>; | Test.java:35:3:35:9 | <Expr>; |
| Test.java:24:4:24:10 | return ... | Test.java:4:14:4:17 | test |
| Test.java:24:4:24:10 | return ... | Test.java:4:14:4:17 | Exit |
| Test.java:30:15:33:3 | { ... } | Test.java:35:3:35:9 | <Expr>; |
| Test.java:35:3:35:9 | <Expr>; | Test.java:38:9:38:9 | x |
| Test.java:38:9:38:9 | x | Test.java:38:16:41:3 | { ... } |
@@ -27,4 +27,4 @@
| Test.java:57:15:60:5 | { ... } | Test.java:70:3:70:9 | <Expr>; |
| Test.java:60:12:62:5 | { ... } | Test.java:54:26:54:26 | j |
| Test.java:63:9:66:4 | { ... } | Test.java:54:26:54:26 | j |
| Test.java:70:3:70:9 | <Expr>; | Test.java:4:14:4:17 | test |
| Test.java:70:3:70:9 | <Expr>; | Test.java:4:14:4:17 | Exit |

View File

@@ -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

View File

@@ -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

View File

@@ -4,6 +4,6 @@ import semmle.code.java.controlflow.Dominance
from IfStmt i, BlockStmt 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

View File

@@ -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

View File

@@ -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

View File

@@ -27,7 +27,7 @@
| Test.java:14:18:14:18 | y | Test.java:14:14:14:18 | ... + ... |
| Test.java:17:3:17:12 | if (...) | 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 | <Expr>; |
| 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 | if (...) | 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 | break |
| Test.java:85:8:85:14 | ... == ... | Test.java:87:4:87:15 | if (...) |
| Test.java:85:13:85:14 | 10 | Test.java:85:8:85:14 | ... == ... |

View File

@@ -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

View File

@@ -5,7 +5,7 @@ class PathTestConf extends ActionConfiguration {
PathTestConf() { this = "PathTestConf" }
override predicate isAction(ControlFlowNode node) {
node.(MethodCall).getMethod().hasName("action")
node.asExpr().(MethodCall).getMethod().hasName("action")
}
}

View File

@@ -1,4 +1,4 @@
| 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:6:14:6:23 | { ... } | MultiCatch.java:6:14:6:23 | super(...) |
| MultiCatch.java:8:2:20:2 | { ... } | MultiCatch.java:9:3:19:3 | try ... |
| MultiCatch.java:9:3:19:3 | try ... | MultiCatch.java:10:3:15:3 | { ... } |
@@ -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 | <Expr>; | MultiCatch.java:17:4:17:4 | e |
| MultiCatch.java:18:4:18:11 | throw ... | MultiCatch.java:7:14:7:23 | multiCatch |
| MultiCatch.java:18:4:18:11 | throw ... | MultiCatch.java:7:14:7:23 | Exit |
| MultiCatch.java:18:10:18:10 | e | MultiCatch.java:18:4:18:11 | throw ... |
| MultiCatch.java:23:2:33:2 | { ... } | MultiCatch.java:24:3:32:4 | try ... |
| MultiCatch.java:24:3:32:4 | try ... | MultiCatch.java:25:3:31:3 | { ... } |
@@ -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 | throw ... | MultiCatch.java:31:5:31:37 | catch (...) |
| MultiCatch.java:29:11:29:28 | new SQLException(...) | MultiCatch.java:29:5:29:29 | throw ... |
| MultiCatch.java:30:4:30:25 | throw ... | MultiCatch.java:22:14:22:24 | multiCatch2 |
| MultiCatch.java:30:4:30:25 | throw ... | MultiCatch.java:22:14:22:24 | Exit |
| MultiCatch.java:30:4:30:25 | throw ... | MultiCatch.java:31:5:31:37 | catch (...) |
| MultiCatch.java:30:10:30:24 | new Exception(...) | MultiCatch.java:30:4:30:25 | throw ... |
| MultiCatch.java:31:5:31:37 | catch (...) | MultiCatch.java:31:36:31:36 | e |
| MultiCatch.java:31:36:31:36 | e | MultiCatch.java:32:3:32:4 | { ... } |
| MultiCatch.java:32:3:32:4 | { ... } | MultiCatch.java:22:14:22:24 | multiCatch2 |
| MultiCatch.java:32:3:32:4 | { ... } | MultiCatch.java:22:14:22:24 | Exit |
| MultiCatch.java:36:2:42:2 | { ... } | MultiCatch.java:37:3:41:4 | try ... |
| MultiCatch.java:37:3:41:4 | try ... | MultiCatch.java:38:3:40:3 | { ... } |
| MultiCatch.java:38:3:40:3 | { ... } | 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 | catch (...) |
| MultiCatch.java:40:5:40:22 | catch (...) | MultiCatch.java:40:21:40:21 | e |
| MultiCatch.java:40:21:40:21 | e | MultiCatch.java:41:3:41:4 | { ... } |
| MultiCatch.java:41:3:41:4 | { ... } | MultiCatch.java:35:14:35:26 | ordinaryCatch |
| MultiCatch.java:41:3:41:4 | { ... } | MultiCatch.java:35:14:35:26 | Exit |

View File

@@ -1,4 +1,4 @@
| Test.java:1:14:1:17 | super(...) | Test.java:1:14:1:17 | Test |
| Test.java:1:14:1:17 | super(...) | Test.java:1:14:1:17 | Exit |
| Test.java:1:14:1:17 | { ... } | Test.java:1:14:1:17 | super(...) |
| Test.java:3:40:20:3 | { ... } | Test.java:5:5:5:34 | var ...; |
| Test.java:5:5:5:34 | var ...; | Test.java:5:26:5:33 | source(...) |
@@ -29,7 +29,7 @@
| Test.java:11:12:11:12 | s | Test.java:11:7:11:13 | sink(...) |
| Test.java:14:5:14:92 | if (...) | Test.java:14:9:14:9 | o |
| Test.java:14:9:14:9 | o | Test.java:14:9:14:91 | ...instanceof... |
| Test.java:14:9:14:91 | ...instanceof... | Test.java:3:22:3:25 | test |
| Test.java:14:9:14:91 | ...instanceof... | Test.java:3:22:3:25 | Exit |
| Test.java:14:9:14:91 | ...instanceof... | Test.java:14:41:14:47 | tainted |
| Test.java:14:22:14:91 | Outer(...) | Test.java:14:94:18:5 | { ... } |
| Test.java:14:28:14:67 | Inner(...) | Test.java:14:77:14:90 | alsoNotTainted |
@@ -43,15 +43,15 @@
| Test.java:16:7:16:22 | sink(...) | Test.java:17:7:17:27 | <Expr>; |
| Test.java:16:7:16:23 | <Expr>; | Test.java:16:12:16:21 | notTainted |
| Test.java:16:12:16:21 | notTainted | Test.java:16:7:16:22 | sink(...) |
| Test.java:17:7:17:26 | sink(...) | Test.java:3:22:3:25 | test |
| Test.java:17:7:17:26 | sink(...) | Test.java:3:22:3:25 | Exit |
| Test.java:17:7:17:27 | <Expr>; | Test.java:17:12:17:25 | alsoNotTainted |
| Test.java:17:12:17:25 | alsoNotTainted | Test.java:17:7:17:26 | sink(...) |
| Test.java:22:33:22:53 | { ... } | Test.java:22:42:22:50 | "tainted" |
| Test.java:22:35:22:51 | return ... | Test.java:22:24:22:29 | source |
| Test.java:22:35:22:51 | return ... | Test.java:22:24:22:29 | Exit |
| Test.java:22:42:22:50 | "tainted" | Test.java:22:35:22:51 | return ... |
| Test.java:23:40:23:42 | { ... } | Test.java:23:22:23:25 | sink |
| Test.java:23:40:23:42 | { ... } | Test.java:23:22:23:25 | Exit |
| Test.java:27:8:27:12 | ...=... | Test.java:27:8:27:12 | <Expr>; |
| Test.java:27:8:27:12 | ...=... | Test.java:27:8:27:12 | Outer |
| Test.java:27:8:27:12 | ...=... | Test.java:27:8:27:12 | Exit |
| Test.java:27:8:27:12 | <Expr>; | Test.java:27:8:27:12 | this |
| Test.java:27:8:27:12 | <Expr>; | Test.java:27:8:27:12 | this |
| Test.java:27:8:27:12 | i | Test.java:27:8:27:12 | ...=... |
@@ -61,7 +61,7 @@
| Test.java:27:8:27:12 | this | Test.java:27:8:27:12 | otherField |
| Test.java:27:8:27:12 | { ... } | Test.java:27:8:27:12 | super(...) |
| Test.java:28:8:28:12 | ...=... | Test.java:28:8:28:12 | <Expr>; |
| Test.java:28:8:28:12 | ...=... | Test.java:28:8:28:12 | Inner |
| Test.java:28:8:28:12 | ...=... | Test.java:28:8:28:12 | Exit |
| Test.java:28:8:28:12 | <Expr>; | Test.java:28:8:28:12 | this |
| Test.java:28:8:28:12 | <Expr>; | Test.java:28:8:28:12 | this |
| Test.java:28:8:28:12 | nonTaintedField | Test.java:28:8:28:12 | ...=... |

View File

@@ -1,5 +1,5 @@
import java
from ControlFlowNode cn
where cn.getFile().getBaseName() = "Test.java"
where cn.getLocation().getFile().getBaseName() = "Test.java"
select cn, cn.getASuccessor()

View File

@@ -1,6 +1,6 @@
| Exhaustive.java:1:14:1:23 | super(...) | Exhaustive.java:1:14:1:23 | Exhaustive |
| Exhaustive.java:1:14:1:23 | super(...) | Exhaustive.java:1:14:1:23 | Exit |
| Exhaustive.java:1:14:1:23 | { ... } | Exhaustive.java:1:14:1:23 | super(...) |
| Exhaustive.java:3:8:3:8 | super(...) | Exhaustive.java:3:8:3:8 | E |
| Exhaustive.java:3:8:3:8 | super(...) | Exhaustive.java:3:8:3:8 | Exit |
| Exhaustive.java:3:8:3:8 | { ... } | Exhaustive.java:3:8:3:8 | super(...) |
| Exhaustive.java:3:8:3:8 | { ... } | Exhaustive.java:3:12:3:12 | <Expr>; |
| Exhaustive.java:3:12:3:12 | ...=... | Exhaustive.java:3:15:3:15 | <Expr>; |
@@ -9,12 +9,12 @@
| Exhaustive.java:3:15:3:15 | ...=... | Exhaustive.java:3:18:3:18 | <Expr>; |
| Exhaustive.java:3:15:3:15 | <Expr>; | Exhaustive.java:3:15:3:15 | new E(...) |
| Exhaustive.java:3:15:3:15 | new E(...) | Exhaustive.java:3:15:3:15 | ...=... |
| Exhaustive.java:3:18:3:18 | ...=... | Exhaustive.java:3:8:3:8 | <clinit> |
| Exhaustive.java:3:18:3:18 | ...=... | Exhaustive.java:3:8:3:8 | Exit |
| Exhaustive.java:3:18:3:18 | <Expr>; | Exhaustive.java:3:18:3:18 | new E(...) |
| Exhaustive.java:3:18:3:18 | new E(...) | Exhaustive.java:3:18:3:18 | ...=... |
| Exhaustive.java:5:15:5:15 | super(...) | Exhaustive.java:5:15:5:15 | X |
| Exhaustive.java:5:15:5:15 | super(...) | Exhaustive.java:5:15:5:15 | Exit |
| Exhaustive.java:5:15:5:15 | { ... } | Exhaustive.java:5:15:5:15 | super(...) |
| Exhaustive.java:6:15:6:15 | super(...) | Exhaustive.java:6:15:6:15 | Y |
| Exhaustive.java:6:15:6:15 | super(...) | Exhaustive.java:6:15:6:15 | Exit |
| Exhaustive.java:6:15:6:15 | { ... } | Exhaustive.java:6:15:6:15 | super(...) |
| Exhaustive.java:8:47:35:3 | { ... } | Exhaustive.java:11:5:11:14 | switch (...) |
| Exhaustive.java:11:5:11:14 | switch (...) | Exhaustive.java:11:13:11:13 | o |
@@ -50,10 +50,10 @@
| Exhaustive.java:30:13:30:13 | i | Exhaustive.java:31:7:31:15 | case <Pattern> |
| Exhaustive.java:31:7:31:15 | case <Pattern> | Exhaustive.java:31:14:31:14 | <anonymous local variable> |
| Exhaustive.java:31:7:31:15 | case <Pattern> | Exhaustive.java:32:7:32:15 | case <Pattern> |
| Exhaustive.java:31:14:31:14 | <anonymous local variable> | Exhaustive.java:8:22:8:25 | test |
| Exhaustive.java:31:14:31:14 | <anonymous local variable> | Exhaustive.java:8:22:8:25 | Exit |
| Exhaustive.java:32:7:32:15 | case <Pattern> | Exhaustive.java:32:14:32:14 | <anonymous local variable> |
| Exhaustive.java:32:14:32:14 | <anonymous local variable> | Exhaustive.java:8:22:8:25 | test |
| Test.java:1:14:1:17 | super(...) | Test.java:1:14:1:17 | Test |
| Exhaustive.java:32:14:32:14 | <anonymous local variable> | Exhaustive.java:8:22:8:25 | Exit |
| Test.java:1:14:1:17 | super(...) | Test.java:1:14:1:17 | Exit |
| Test.java:1:14:1:17 | { ... } | Test.java:1:14:1:17 | super(...) |
| Test.java:3:41:134:3 | { ... } | Test.java:5:6:5:19 | switch (...) |
| Test.java:5:6:5:19 | switch (...) | Test.java:5:14:5:18 | thing |
@@ -380,9 +380,9 @@
| Test.java:130:8:130:21 | case <Pattern> | Test.java:130:20:130:20 | <anonymous local variable> |
| Test.java:130:8:130:21 | case <Pattern> | Test.java:131:8:131:15 | default |
| Test.java:130:20:130:20 | <anonymous local variable> | Test.java:131:8:131:15 | default |
| Test.java:131:8:131:15 | default | Test.java:3:22:3:25 | test |
| Test.java:131:8:131:15 | default | Test.java:3:22:3:25 | Exit |
| Test.java:138:8:138:8 | ...=... | Test.java:138:8:138:8 | <Expr>; |
| Test.java:138:8:138:8 | ...=... | Test.java:138:8:138:8 | A |
| Test.java:138:8:138:8 | ...=... | Test.java:138:8:138:8 | Exit |
| Test.java:138:8:138:8 | <Expr>; | Test.java:138:8:138:8 | this |
| Test.java:138:8:138:8 | <Expr>; | Test.java:138:8:138:8 | this |
| Test.java:138:8:138:8 | b | Test.java:138:8:138:8 | ...=... |
@@ -392,7 +392,7 @@
| Test.java:138:8:138:8 | this | Test.java:138:8:138:8 | field3 |
| Test.java:138:8:138:8 | { ... } | Test.java:138:8:138:8 | super(...) |
| Test.java:139:8:139:8 | ...=... | Test.java:139:8:139:8 | <Expr>; |
| Test.java:139:8:139:8 | ...=... | Test.java:139:8:139:8 | B |
| Test.java:139:8:139:8 | ...=... | Test.java:139:8:139:8 | Exit |
| Test.java:139:8:139:8 | <Expr>; | Test.java:139:8:139:8 | this |
| Test.java:139:8:139:8 | <Expr>; | Test.java:139:8:139:8 | this |
| Test.java:139:8:139:8 | field1 | Test.java:139:8:139:8 | ...=... |

View File

@@ -1,5 +1,5 @@
import java
from ControlFlowNode cn
where cn.getFile().getBaseName() = ["Test.java", "Exhaustive.java"]
where cn.getLocation().getFile().getBaseName() = ["Test.java", "Exhaustive.java"]
select cn, cn.getASuccessor()

View File

@@ -1,4 +1,4 @@
| 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:8:14:8:28 | { ... } | CloseReaderTest.java:8:14:8:28 | super(...) |
| CloseReaderTest.java:10:2:24:2 | { ... } | CloseReaderTest.java:12:3:13:42 | <Expr>; |
| CloseReaderTest.java:12:3:12:12 | System.out | CloseReaderTest.java:12:20:12:40 | "Enter password for " |
@@ -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 | try ... | CloseReaderTest.java:18:3:20:3 | { ... } |
| CloseReaderTest.java:18:3:20:3 | { ... } | CloseReaderTest.java:19:11:19:15 | stdin |
| CloseReaderTest.java:19:4:19:27 | return ... | CloseReaderTest.java:9:23:9:34 | readPassword |
| CloseReaderTest.java:19:4:19:27 | return ... | 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 | return ... |
| CloseReaderTest.java:19:11:19:26 | readLine(...) | CloseReaderTest.java:20:5:20:26 | catch (...) |
| CloseReaderTest.java:20:5:20:26 | catch (...) | CloseReaderTest.java:20:24:20:25 | ex |
| CloseReaderTest.java:20:24:20:25 | ex | CloseReaderTest.java:21:3:23:3 | { ... } |
| CloseReaderTest.java:21:3:23:3 | { ... } | CloseReaderTest.java:22:11:22:14 | null |
| CloseReaderTest.java:22:4:22:15 | return ... | CloseReaderTest.java:9:23:9:34 | readPassword |
| CloseReaderTest.java:22:4:22:15 | return ... | CloseReaderTest.java:9:23:9:34 | Exit |
| CloseReaderTest.java:22:11:22:14 | null | CloseReaderTest.java:22:4:22:15 | return ... |

View File

@@ -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.getLocation().getFile().getStem() = "PopulateRuntimeException"
select n, succ

View File

@@ -1,4 +1,4 @@
| 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:3:14:3:28 | { ... } | LoopVarReadTest.java:3:14:3:28 | super(...) |
| LoopVarReadTest.java:5:2:15:2 | { ... } | LoopVarReadTest.java:6:3:6:12 | var ...; |
| LoopVarReadTest.java:6:3:6:12 | var ...; | LoopVarReadTest.java:6:11:6:11 | 2 |
@@ -23,6 +23,6 @@
| LoopVarReadTest.java:12:7:12:12 | q | LoopVarReadTest.java:14:3:14:28 | <Expr>; |
| 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 | <Expr>; | LoopVarReadTest.java:14:3:14:12 | System.out |
| LoopVarReadTest.java:14:22:14:26 | "foo" | LoopVarReadTest.java:14:3:14:27 | println(...) |

View File

@@ -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.getLocation().getFile().getStem() = "PopulateRuntimeException"
select n, succ

View File

@@ -1,4 +1,4 @@
| 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:11:14:11:25 | { ... } | SaveFileTest.java:11:14:11:25 | super(...) |
| SaveFileTest.java:15:2:55:2 | { ... } | SaveFileTest.java:17:3:17:25 | var ...; |
| SaveFileTest.java:17:3:17:25 | var ...; | SaveFileTest.java:17:21:17:24 | path |
@@ -95,9 +95,9 @@
| SaveFileTest.java:48:5:48:15 | flush(...) | SaveFileTest.java:50:6:50:30 | catch (...) |
| SaveFileTest.java:48:5:48:16 | <Expr>; | 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 | catch (...) |
| SaveFileTest.java:49:5:49:16 | <Expr>; | SaveFileTest.java:49:5:49:7 | bos |
| SaveFileTest.java:50:6:50:30 | catch (...) | SaveFileTest.java:50:23:50:29 | ignored |
| SaveFileTest.java:50:23:50:29 | ignored | SaveFileTest.java:51:4:52:4 | { ... } |
| SaveFileTest.java:51:4:52:4 | { ... } | SaveFileTest.java:12:14:12:21 | saveFile |
| SaveFileTest.java:51:4:52:4 | { ... } | SaveFileTest.java:12:14:12:21 | Exit |

View File

@@ -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.getLocation().getFile().getStem() = "PopulateRuntimeException"
select n, succ

View File

@@ -1,8 +1,8 @@
| 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:1:14:1:23 | { ... } | SchackTest.java:1:14:1:23 | 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:2:8:2:10 | { ... } | SchackTest.java:2:8:2: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:3:8:3:10 | { ... } | SchackTest.java:3:8:3:10 | super(...) |
| SchackTest.java:5:18:24:2 | { ... } | SchackTest.java:6:3:23:3 | try ... |
| SchackTest.java:6:3:23:3 | try ... | SchackTest.java:6:7:17:3 | { ... } |
@@ -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 | { ... } | SchackTest.java:22:4:22:41 | <Expr>; |
| 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 | <Expr>; | 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 | { ... } | SchackTest.java:27:3:27:25 | if (...) |
@@ -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 | throw ... | SchackTest.java:26:18:26:20 | bar |
| SchackTest.java:28:4:28:19 | throw ... | SchackTest.java:26:18:26:20 | Exit |
| SchackTest.java:28:10:28:18 | new ExB(...) | SchackTest.java:28:4:28:19 | throw ... |
| SchackTest.java:29:3:29:28 | return ... | SchackTest.java:26:18:26:20 | bar |
| SchackTest.java:29:3:29:28 | return ... | 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 | return ... |
| SchackTest.java:29:26:29:27 | .3 | SchackTest.java:29:10:29:27 | ... > ... |

View File

@@ -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.getLocation().getFile().getStem() = "PopulateRuntimeException"
select n, succ

View File

@@ -1,4 +1,4 @@
| 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:3:14:3:22 | { ... } | TestBreak.java:3:14:3:22 | super(...) |
| TestBreak.java:5:2:85:2 | { ... } | TestBreak.java:7:3:8:11 | <Label>: ... |
| TestBreak.java:7:3:8:11 | <Label>: ... | TestBreak.java:8:4:8:11 | for (...;...;...) |
@@ -140,16 +140,16 @@
| TestBreak.java:72:4:72:9 | <Expr>; | 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 | switch (...) | 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 | case ... |
| TestBreak.java:76:10:76:10 | x | TestBreak.java:81:3:81:9 | case ... |
| TestBreak.java:78:3:78:9 | case ... | TestBreak.java:79:4:79:9 | <Expr>; |
| TestBreak.java:79:4:79:8 | ...=... | TestBreak.java:80:4:80:9 | break |
| TestBreak.java:79:4:79:9 | <Expr>; | 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 | break | TestBreak.java:4:14:4:14 | f |
| TestBreak.java:80:4:80:9 | break | TestBreak.java:4:14:4:14 | Exit |
| TestBreak.java:81:3:81:9 | case ... | TestBreak.java:82:4:82:9 | <Expr>; |
| TestBreak.java:82:4:82:8 | ...=... | TestBreak.java:83:4:83:9 | break |
| TestBreak.java:82:4:82:9 | <Expr>; | 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 | break | TestBreak.java:4:14:4:14 | f |
| TestBreak.java:83:4:83:9 | break | TestBreak.java:4:14:4:14 | Exit |

View File

@@ -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.getLocation().getFile().getStem() = "PopulateRuntimeException"
select n, succ

View File

@@ -6,5 +6,5 @@
| TestContinue.java:33:8:33:13 | ... == ... | TestContinue.java:37:4:47:4 | { ... } |
| TestContinue.java:40:10:40:15 | ... == ... | TestContinue.java:44:6:44:15 | <Expr>; |
| TestContinue.java:45:14:45:19 | ... == ... | TestContinue.java:46:5:46:11 | <Expr>; |
| 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 | break |

View File

@@ -1,4 +1,4 @@
| 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:3:14:3:25 | { ... } | TestContinue.java:3:14:3:25 | super(...) |
| TestContinue.java:5:2:58:2 | { ... } | TestContinue.java:7:3:8:27 | <Label>: ... |
| TestContinue.java:7:3:8:27 | <Label>: ... | TestContinue.java:8:4:8:27 | for (...;...;...) |
@@ -97,7 +97,7 @@
| TestContinue.java:50:7:50:8 | 13 | TestContinue.java:50:3:50:8 | ...=... |
| TestContinue.java:51:3:51:17 | while (...) | 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 | { ... } |
| TestContinue.java:51:15:51:16 | 12 | TestContinue.java:51:10:51:16 | ... != ... |
| TestContinue.java:52:3:57:3 | { ... } | TestContinue.java:53:4:53:14 | if (...) |
@@ -107,4 +107,4 @@
| TestContinue.java:53:8:53:13 | ... != ... | TestContinue.java:56:5:56:10 | break |
| TestContinue.java:53:13:53:13 | 6 | TestContinue.java:53:8:53:13 | ... != ... |
| TestContinue.java:54:5:54:13 | continue | TestContinue.java:51:10:51:10 | y |
| TestContinue.java:56:5:56:10 | break | TestContinue.java:4:14:4:14 | f |
| TestContinue.java:56:5:56:10 | break | TestContinue.java:4:14:4:14 | Exit |

View File

@@ -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.getLocation().getFile().getStem() = "PopulateRuntimeException"
select n, succ

View File

@@ -1,4 +1,4 @@
| 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:1:7:1:22 | { ... } | TestDeclarations.java:1:7:1:22 | super(...) |
| TestDeclarations.java:2:30:24:2 | { ... } | TestDeclarations.java:4:3:4:11 | var ...; |
| TestDeclarations.java:4:3:4:11 | var ...; | TestDeclarations.java:4:7:4:7 | b |
@@ -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 | return ... | TestDeclarations.java:2:6:2:21 | declarationTests |
| TestDeclarations.java:18:5:18:13 | return ... | TestDeclarations.java:2:6:2:21 | Exit |
| TestDeclarations.java:18:12:18:12 | c | TestDeclarations.java:18:5:18:13 | return ... |
| TestDeclarations.java:20:3:20:10 | var ...; | 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 | <Expr>; | 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 | return ... | TestDeclarations.java:2:6:2:21 | declarationTests |
| TestDeclarations.java:23:3:23:11 | return ... | TestDeclarations.java:2:6:2:21 | Exit |
| TestDeclarations.java:23:10:23:10 | b | TestDeclarations.java:23:3:23:11 | return ... |

View File

@@ -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.getLocation().getFile().getStem() = "PopulateRuntimeException"
select n, succ

View File

@@ -1,4 +1,4 @@
| 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:3:14:3:24 | { ... } | TestFinally.java:3:14:3:24 | super(...) |
| TestFinally.java:5:2:149:2 | { ... } | TestFinally.java:6:3:6:13 | var ...; |
| TestFinally.java:6:3:6:13 | var ...; | TestFinally.java:6:11:6:12 | 12 |
@@ -268,7 +268,7 @@
| TestFinally.java:118:4:118:32 | println(...) | TestFinally.java:119:4:119:13 | <Expr>; |
| TestFinally.java:118:4:118:33 | <Expr>; | 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 | <Expr>; |
| TestFinally.java:119:4:119:13 | <Expr>; | 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 | <Expr>; |
| TestFinally.java:141:13:141:13 | 1 | TestFinally.java:141:8:141:13 | ... == ... |
| TestFinally.java:142:4:144:4 | { ... } | TestFinally.java:143:5:143:11 | return ... |
| TestFinally.java:143:5:143:11 | return ... | TestFinally.java:4:14:4:14 | f |
| TestFinally.java:143:5:143:11 | return ... | 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 | <Expr>; |
| TestFinally.java:145:4:145:34 | <Expr>; | 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 | <Expr>; | 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 | ...=... |

View File

@@ -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.getLocation().getFile().getStem() = "PopulateRuntimeException"
select n, succ

View File

@@ -1,4 +1,4 @@
| 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:3:14:3:37 | { ... } | TestFinallyBreakContinue.java:3:14:3:37 | super(...) |
| TestFinallyBreakContinue.java:5:2:107:2 | { ... } | TestFinallyBreakContinue.java:6:3:6:12 | var ...; |
| TestFinallyBreakContinue.java:6:3:6:12 | var ...; | TestFinallyBreakContinue.java:6:11:6:11 | 1 |
@@ -79,7 +79,7 @@
| TestFinallyBreakContinue.java:62:24:62:34 | "Exception" | TestFinallyBreakContinue.java:62:5:62:35 | println(...) |
| TestFinallyBreakContinue.java:64:4:66:4 | { ... } | TestFinallyBreakContinue.java:65:5:65:34 | <Expr>; |
| 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 | <Label>: ... |
| TestFinallyBreakContinue.java:65:5:65:34 | <Expr>; | 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 | { ... } | TestFinallyBreakContinue.java:104:5:104:34 | <Expr>; |
| 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 | <Expr>; | TestFinallyBreakContinue.java:104:5:104:14 | System.out |
| TestFinallyBreakContinue.java:104:24:104:32 | "finally" | TestFinallyBreakContinue.java:104:5:104:33 | println(...) |

View File

@@ -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.getLocation().getFile().getStem() = "PopulateRuntimeException"
select n, succ

View File

@@ -2,7 +2,7 @@
| TestLoopBranch.java:4:2:4:13 | ...=... | TestLoopBranch.java:5:2:5:13 | <Expr>; |
| TestLoopBranch.java:4:2:4:13 | <Expr>; | 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 | <obinit> |
| TestLoopBranch.java:5:2:5:13 | ...=... | TestLoopBranch.java:3:14:3:27 | Exit |
| TestLoopBranch.java:5:2:5:13 | <Expr>; | 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 | { ... } | TestLoopBranch.java:9:3:9:12 | var ...; |
@@ -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 | return ... | TestLoopBranch.java:7:14:7:14 | f |
| TestLoopBranch.java:59:4:59:10 | return ... | TestLoopBranch.java:7:14:7:14 | Exit |
| TestLoopBranch.java:62:3:62:12 | switch (...) | TestLoopBranch.java:62:11:62:11 | x |
| TestLoopBranch.java:62:11:62:11 | x | TestLoopBranch.java:64:3:64:9 | case ... |
| TestLoopBranch.java:62:11:62:11 | x | TestLoopBranch.java:67:3:67:9 | case ... |
@@ -214,10 +214,10 @@
| TestLoopBranch.java:96:3:102:4 | var ...; | TestLoopBranch.java:96:26:102:3 | new (...) |
| TestLoopBranch.java:96:22:102:3 | b | TestLoopBranch.java:103:3:103:21 | <Expr>; |
| TestLoopBranch.java:96:26:102:3 | new (...) | TestLoopBranch.java:96:22:102:3 | b |
| 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:96:30:96:47 | { ... } | TestLoopBranch.java:96:30:96:47 | super(...) |
| TestLoopBranch.java:99:4:101:4 | { ... } | TestLoopBranch.java:100:12:100:12 | 0 |
| TestLoopBranch.java:100:5:100:13 | return ... | TestLoopBranch.java:98:15:98:23 | compareTo |
| TestLoopBranch.java:100:5:100:13 | return ... | TestLoopBranch.java:98:15:98:23 | Exit |
| TestLoopBranch.java:100:12:100:12 | 0 | TestLoopBranch.java:100:5:100:13 | return ... |
| 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 | <Expr>; |
@@ -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 | return ... | TestLoopBranch.java:7:14:7:14 | f |
| TestLoopBranch.java:106:3:106:9 | return ... | TestLoopBranch.java:7:14:7:14 | Exit |
| TestLoopBranch.java:109:9:109:22 | <Expr>; | TestLoopBranch.java:109:9:109:22 | <obinit>(...) |
| TestLoopBranch.java:109:9:109:22 | <obinit>(...) | TestLoopBranch.java:111:3:111:10 | <Expr>; |
| TestLoopBranch.java:109:9:109:22 | super(...) | TestLoopBranch.java:109:9:109:22 | <Expr>; |
@@ -236,7 +236,7 @@
| TestLoopBranch.java:111:3:111:9 | ...=... | TestLoopBranch.java:112:3:112:10 | <Expr>; |
| TestLoopBranch.java:111:3:111:10 | <Expr>; | 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 | <Expr>; | 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 | <Expr>; | TestLoopBranch.java:115:9:115:22 | <obinit>(...) |
@@ -246,6 +246,6 @@
| TestLoopBranch.java:117:3:117:8 | ...=... | TestLoopBranch.java:118:3:118:9 | <Expr>; |
| TestLoopBranch.java:117:3:117:9 | <Expr>; | 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 | <Expr>; | TestLoopBranch.java:118:8:118:8 | i |
| TestLoopBranch.java:118:8:118:8 | i | TestLoopBranch.java:118:3:118:8 | ...=... |

View File

@@ -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.getLocation().getFile().getStem() = "PopulateRuntimeException"
select n, succ

View File

@@ -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 | { ... } | TestThrow.java:7:10:7:18 | super(...) |
| TestThrow.java:12:2:13:2 | { ... } | TestThrow.java:11:15:11:21 | thrower |
| TestThrow.java:12:2:13:2 | { ... } | TestThrow.java:11:15:11:21 | Exit |
| TestThrow.java:16:2:134:2 | { ... } | TestThrow.java:17:3:17:12 | var ...; |
| TestThrow.java:17:3:17:12 | var ...; | TestThrow.java:17:11:17:11 | 0 |
| TestThrow.java:17:7:17:11 | z | TestThrow.java:18:3:27:3 | try ... |
@@ -69,7 +69,7 @@
| TestThrow.java:48:4:48:9 | <Expr>; | 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 | { ... } | TestThrow.java:51:4:51:9 | <Expr>; |
| 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 | <Expr>; |
| TestThrow.java:51:4:51:9 | <Expr>; | 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 | if (...) |
| TestThrow.java:58:13:58:13 | 1 | TestThrow.java:58:8:58:13 | ... == ... |
| TestThrow.java:59:4:61:4 | { ... } | TestThrow.java:60:11:60:25 | new Exception(...) |
| TestThrow.java:60:5:60:26 | throw ... | TestThrow.java:15:14:15:14 | f |
| TestThrow.java:60:5:60:26 | throw ... | TestThrow.java:15:14:15:14 | Exit |
| TestThrow.java:60:5:60:26 | throw ... | TestThrow.java:69:5:69:30 | catch (...) |
| TestThrow.java:60:11:60:25 | new Exception(...) | TestThrow.java:60:5:60:26 | throw ... |
| TestThrow.java:60:11:60:25 | new Exception(...) | TestThrow.java:69:5:69:30 | catch (...) |
@@ -95,7 +95,7 @@
| TestThrow.java:62:13:62:18 | ... == ... | TestThrow.java:66:4:68:4 | { ... } |
| TestThrow.java:62:18:62:18 | 2 | TestThrow.java:62:13:62:18 | ... == ... |
| TestThrow.java:63:4:65:4 | { ... } | TestThrow.java:64:5:64:20 | <Expr>; |
| 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 | catch (...) |
| TestThrow.java:64:5:64:19 | new TestThrow(...) | TestThrow.java:74:3:74:9 | <Expr>; |
| TestThrow.java:64:5:64:20 | <Expr>; | 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 | throw ... |
| TestThrow.java:79:11:79:25 | new Exception(...) | TestThrow.java:81:3:83:3 | { ... } |
| TestThrow.java:81:3:83:3 | { ... } | TestThrow.java:82:4:82:9 | <Expr>; |
| 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 | try ... |
| TestThrow.java:82:4:82:9 | <Expr>; | 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 | <Expr>; | 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 | { ... } | TestThrow.java:125:4:125:9 | <Expr>; |
| 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 | if (...) |
| TestThrow.java:125:4:125:9 | <Expr>; | 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 | <Expr>; |
| TestThrow.java:128:12:128:12 | 1 | TestThrow.java:128:7:128:12 | ... == ... |
| TestThrow.java:129:3:131:3 | { ... } | TestThrow.java:130:10:130:24 | new Exception(...) |
| TestThrow.java:130:4:130:25 | throw ... | TestThrow.java:15:14:15:14 | f |
| TestThrow.java:130:4:130:25 | throw ... | TestThrow.java:15:14:15:14 | Exit |
| TestThrow.java:130:10:130:24 | new Exception(...) | TestThrow.java:130:4:130:25 | throw ... |
| 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 | <Expr>; | 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 | -... |

View File

@@ -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.getLocation().getFile().getStem() = "PopulateRuntimeException"
select n, succ

View File

@@ -1,15 +1,15 @@
| TestThrow2.java:3:7:3:16 | <Expr>; | TestThrow2.java:3:7:3:16 | <obinit>(...) |
| TestThrow2.java:3:7:3:16 | <obinit>(...) | TestThrow2.java:3:7:3:16 | TestThrow2 |
| TestThrow2.java:3:7:3:16 | <obinit>(...) | TestThrow2.java:3:7:3:16 | Exit |
| TestThrow2.java:3:7:3:16 | super(...) | TestThrow2.java:3:7:3:16 | <Expr>; |
| TestThrow2.java:3:7:3:16 | { ... } | TestThrow2.java:3:7:3:16 | super(...) |
| TestThrow2.java:3:7:3:16 | { ... } | TestThrow2.java:5:2:11:2 | { ... } |
| TestThrow2.java:5:2:11:2 | { ... } | TestThrow2.java:6:3:10:3 | try ... |
| TestThrow2.java:6:3:10:3 | try ... | TestThrow2.java:6:7:8:3 | { ... } |
| TestThrow2.java:6:7:8:3 | { ... } | TestThrow2.java:7:4:7:13 | <Expr>; |
| TestThrow2.java:7:4:7:12 | thrower(...) | TestThrow2.java:3:7:3:16 | <obinit> |
| 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 | catch (...) |
| TestThrow2.java:7:4:7:13 | <Expr>; | TestThrow2.java:7:4:7:12 | thrower(...) |
| TestThrow2.java:8:5:8:23 | catch (...) | TestThrow2.java:8:22:8:22 | e |
| TestThrow2.java:8:22:8:22 | e | TestThrow2.java:8:25:10:3 | { ... } |
| TestThrow2.java:8:25:10:3 | { ... } | TestThrow2.java:9:4:9:4 | ; |
| TestThrow2.java:9:4:9:4 | ; | TestThrow2.java:3:7:3:16 | <obinit> |
| TestThrow2.java:9:4:9:4 | ; | TestThrow2.java:3:7:3:16 | Exit |

View File

@@ -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.getLocation().getFile().getStem() = "PopulateRuntimeException"
select n, succ

View File

@@ -1,4 +1,4 @@
| 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:3:14:3:25 | { ... } | TestTryCatch.java:3:14:3:25 | super(...) |
| TestTryCatch.java:5:2:43:2 | { ... } | TestTryCatch.java:6:3:23:3 | try ... |
| TestTryCatch.java:6:3:23:3 | try ... | TestTryCatch.java:7:3:12:3 | { ... } |
@@ -51,7 +51,7 @@
| TestTryCatch.java:21:4:21:32 | println(...) | TestTryCatch.java:22:4:22:13 | <Expr>; |
| TestTryCatch.java:21:4:21:33 | <Expr>; | 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 | var ...; |
| TestTryCatch.java:22:4:22:13 | <Expr>; | 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 | <Expr>; | 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 | ...=... |

View File

@@ -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.getLocation().getFile().getStem() = "PopulateRuntimeException"
select n, succ

View File

@@ -1,4 +1,4 @@
| 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:6:14:6:33 | { ... } | TestTryWithResources.java:6:14:6:33 | super(...) |
| TestTryWithResources.java:7:60:16:2 | { ... } | TestTryWithResources.java:8:3:15:3 | try ... |
| TestTryWithResources.java:8:3:15:3 | try ... | TestTryWithResources.java:8:8:8:58 | var ...; |
@@ -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 | { ... } | TestTryWithResources.java:14:4:14:33 | <Expr>; |
| 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 | <Expr>; | TestTryWithResources.java:14:4:14:13 | System.out |
| TestTryWithResources.java:14:23:14:31 | "finally" | TestTryWithResources.java:14:4:14:32 | println(...) |

View File

@@ -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.getLocation().getFile().getStem() = "PopulateRuntimeException"
select n, succ