Skip to content

Commit 321a4af

Browse files
authored
Merge pull request #19883 from aschackmull/java/fix-assert-cfg
Java: Fix assert CFG by properly tagging the false successor.
2 parents 7750f12 + c091fc5 commit 321a4af

File tree

5 files changed

+44
-15
lines changed

5 files changed

+44
-15
lines changed

java/ql/lib/semmle/code/java/ControlFlowGraph.qll

Lines changed: 42 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,8 @@ module ControlFlow {
100100
private newtype TNode =
101101
TExprNode(Expr e) { hasControlFlow(e) } or
102102
TStmtNode(Stmt s) or
103-
TExitNode(Callable c) { exists(c.getBody()) }
103+
TExitNode(Callable c) { exists(c.getBody()) } or
104+
TAssertThrowNode(AssertStmt s)
104105

105106
/** A node in the expression-level control-flow graph. */
106107
class Node extends TNode {
@@ -204,6 +205,25 @@ module ControlFlow {
204205
/** Gets the source location for this element. */
205206
override Location getLocation() { result = c.getLocation() }
206207
}
208+
209+
/** A control flow node indicating a failing assertion. */
210+
class AssertThrowNode extends Node, TAssertThrowNode {
211+
AssertStmt s;
212+
213+
AssertThrowNode() { this = TAssertThrowNode(s) }
214+
215+
override Stmt getEnclosingStmt() { result = s }
216+
217+
override Callable getEnclosingCallable() { result = s.getEnclosingCallable() }
218+
219+
override ExprParent getAstNode() { result = s }
220+
221+
/** Gets a textual representation of this element. */
222+
override string toString() { result = "Assert Throw" }
223+
224+
/** Gets the source location for this element. */
225+
override Location getLocation() { result = s.getLocation() }
226+
}
207227
}
208228

209229
class ControlFlowNode = ControlFlow::Node;
@@ -327,7 +347,17 @@ private module ControlFlowGraphImpl {
327347
)
328348
}
329349

330-
private ThrowableType assertionError() { result.hasQualifiedName("java.lang", "AssertionError") }
350+
private ThrowableType actualAssertionError() {
351+
result.hasQualifiedName("java.lang", "AssertionError")
352+
}
353+
354+
private ThrowableType assertionError() {
355+
result = actualAssertionError()
356+
or
357+
// In case `AssertionError` is not extracted, we use `Error` as a fallback.
358+
not exists(actualAssertionError()) and
359+
result.hasQualifiedName("java.lang", "Error")
360+
}
331361

332362
/**
333363
* Gets an exception type that may be thrown during execution of the
@@ -1123,12 +1153,7 @@ private module ControlFlowGraphImpl {
11231153
or
11241154
// `assert` statements may throw
11251155
completion = ThrowCompletion(assertionError()) and
1126-
(
1127-
last(assertstmt.getMessage(), last, NormalCompletion())
1128-
or
1129-
not exists(assertstmt.getMessage()) and
1130-
last(assertstmt.getExpr(), last, BooleanCompletion(false, _))
1131-
)
1156+
last.(AssertThrowNode).getAstNode() = assertstmt
11321157
)
11331158
or
11341159
// `throw` statements or throwing calls give rise to `Throw` completion
@@ -1547,7 +1572,15 @@ private module ControlFlowGraphImpl {
15471572
or
15481573
last(assertstmt.getExpr(), n, completion) and
15491574
completion = BooleanCompletion(false, _) and
1550-
result = first(assertstmt.getMessage())
1575+
(
1576+
result = first(assertstmt.getMessage())
1577+
or
1578+
not exists(assertstmt.getMessage()) and
1579+
result.(AssertThrowNode).getAstNode() = assertstmt
1580+
)
1581+
or
1582+
last(assertstmt.getMessage(), n, NormalCompletion()) and
1583+
result.(AssertThrowNode).getAstNode() = assertstmt
15511584
)
15521585
or
15531586
// When expressions:

java/ql/test/query-tests/Nullness/C.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -251,7 +251,7 @@ public void ex18(boolean b, int[] xs, Object related) {
251251
(b && xs == null && related == null);
252252
if (b) {
253253
if (related == null) { return; }
254-
xs[0] = 42; // FP - correlated conditions fails to recognize assert edges
254+
xs[0] = 42; // OK
255255
}
256256
}
257257
}

java/ql/test/query-tests/Nullness/NullMaybe.expected

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,9 +32,6 @@
3232
| C.java:207:9:207:11 | obj | Variable $@ may be null at this access because of $@ assignment. | C.java:201:5:201:22 | Object obj | obj | C.java:201:12:201:21 | obj | this |
3333
| C.java:219:9:219:10 | o1 | Variable $@ may be null at this access as suggested by $@ null guard. | C.java:212:20:212:28 | o1 | o1 | C.java:213:9:213:18 | ... == ... | this |
3434
| C.java:233:7:233:8 | xs | Variable $@ may be null at this access because of $@ assignment. | C.java:231:5:231:56 | int[] xs | xs | C.java:231:11:231:55 | xs | this |
35-
| C.java:254:7:254:8 | xs | Variable $@ may be null at this access as suggested by $@ null guard. | C.java:248:31:248:38 | xs | xs | C.java:249:19:249:28 | ... == ... | this |
36-
| C.java:254:7:254:8 | xs | Variable $@ may be null at this access as suggested by $@ null guard. | C.java:248:31:248:38 | xs | xs | C.java:250:18:250:27 | ... != ... | this |
37-
| C.java:254:7:254:8 | xs | Variable $@ may be null at this access as suggested by $@ null guard. | C.java:248:31:248:38 | xs | xs | C.java:251:18:251:27 | ... == ... | this |
3835
| F.java:11:5:11:7 | obj | Variable $@ may be null at this access as suggested by $@ null guard. | F.java:8:18:8:27 | obj | obj | F.java:9:9:9:19 | ... == ... | this |
3936
| F.java:17:5:17:7 | obj | Variable $@ may be null at this access as suggested by $@ null guard. | F.java:14:18:14:27 | obj | obj | F.java:15:9:15:19 | ... == ... | this |
4037
| G.java:20:12:20:12 | s | Variable $@ may be null at this access as suggested by $@ null guard. | G.java:3:27:3:34 | s | s | G.java:5:9:5:17 | ... == ... | this |

java/ql/test/query-tests/RangeAnalysis/A.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ void m4(int[] a, int[] b) {
6464
int sum = 0;
6565
for (int i = 0; i < a.length; ) {
6666
sum += a[i++]; // OK
67-
sum += a[i++]; // OK - FP
67+
sum += a[i++]; // OK
6868
}
6969
int len = b.length;
7070
if ((len & 1) != 0)

java/ql/test/query-tests/RangeAnalysis/ArrayIndexOutOfBounds.expected

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
| A.java:45:14:45:22 | ...[...] | This array access might be out of bounds, as the index might be equal to the array length. |
44
| A.java:49:14:49:22 | ...[...] | This array access might be out of bounds, as the index might be equal to the array length. |
55
| A.java:58:14:58:19 | ...[...] | This array access might be out of bounds, as the index might be equal to the array length. |
6-
| A.java:67:14:67:19 | ...[...] | This array access might be out of bounds, as the index might be equal to the array length. |
76
| A.java:89:12:89:16 | ...[...] | This array access might be out of bounds, as the index might be equal to the array length. |
87
| A.java:100:18:100:31 | ...[...] | This array access might be out of bounds, as the index might be equal to the array length + 8. |
98
| A.java:113:14:113:21 | ...[...] | This array access might be out of bounds, as the index might be equal to the array length. |

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy