mirror of
https://github.com/github/codeql.git
synced 2026-02-27 20:33:42 +01:00
Java: Add AnnotatedExitNodes to the CFG.
This commit is contained in:
@@ -82,6 +82,7 @@ module;
|
||||
*/
|
||||
|
||||
import java
|
||||
private import codeql.util.Boolean
|
||||
private import Completion
|
||||
private import controlflow.internal.Preconditions
|
||||
private import controlflow.internal.SwitchCases
|
||||
@@ -102,6 +103,7 @@ module ControlFlow {
|
||||
private newtype TNode =
|
||||
TExprNode(Expr e) { hasControlFlow(e) } or
|
||||
TStmtNode(Stmt s) or
|
||||
TAnnotatedExitNode(Callable c, Boolean normal) { exists(c.getBody()) } or
|
||||
TExitNode(Callable c) { exists(c.getBody()) } or
|
||||
TAssertThrowNode(AssertStmt s)
|
||||
|
||||
@@ -191,6 +193,38 @@ module ControlFlow {
|
||||
override Location getLocation() { result = s.getLocation() }
|
||||
}
|
||||
|
||||
/** A control flow node indicating the normal or exceptional termination of a callable. */
|
||||
class AnnotatedExitNode extends Node, TAnnotatedExitNode {
|
||||
Callable c;
|
||||
boolean normal;
|
||||
|
||||
AnnotatedExitNode() { this = TAnnotatedExitNode(c, normal) }
|
||||
|
||||
override Callable getEnclosingCallable() { result = c }
|
||||
|
||||
override ExprParent getAstNode() { result = c }
|
||||
|
||||
/** Gets a textual representation of this element. */
|
||||
override string toString() {
|
||||
normal = true and result = "Normal Exit"
|
||||
or
|
||||
normal = false and result = "Exceptional Exit"
|
||||
}
|
||||
|
||||
/** Gets the source location for this element. */
|
||||
override Location getLocation() { result = c.getLocation() }
|
||||
}
|
||||
|
||||
/** A control flow node indicating normal termination of a callable. */
|
||||
class NormalExitNode extends AnnotatedExitNode {
|
||||
NormalExitNode() { this = TAnnotatedExitNode(_, true) }
|
||||
}
|
||||
|
||||
/** A control flow node indicating exceptional termination of a callable. */
|
||||
class ExceptionalExitNode extends AnnotatedExitNode {
|
||||
ExceptionalExitNode() { this = TAnnotatedExitNode(_, false) }
|
||||
}
|
||||
|
||||
/** A control flow node indicating the termination of a callable. */
|
||||
class ExitNode extends Node, TExitNode {
|
||||
Callable c;
|
||||
@@ -1266,11 +1300,17 @@ private module ControlFlowGraphImpl {
|
||||
*/
|
||||
cached
|
||||
Node succ(Node n, Completion completion) {
|
||||
// After executing the callable body, the final node is the exit node.
|
||||
// After executing the callable body, the final nodes are first the
|
||||
// annotated exit node and then the final exit node.
|
||||
exists(Callable c | last(c.getBody(), n, completion) |
|
||||
result.(ExitNode).getEnclosingCallable() = c
|
||||
if completion instanceof ThrowCompletion
|
||||
then result.(ExceptionalExitNode).getEnclosingCallable() = c
|
||||
else result.(NormalExitNode).getEnclosingCallable() = c
|
||||
)
|
||||
or
|
||||
completion = NormalCompletion() and
|
||||
n.(AnnotatedExitNode).getEnclosingCallable() = result.(ExitNode).getEnclosingCallable()
|
||||
or
|
||||
// Logic expressions and conditional expressions execute in AST pre-order.
|
||||
completion = NormalCompletion() and
|
||||
(
|
||||
|
||||
Reference in New Issue
Block a user