Java: Update the CFG for assert statements to make them proper guards.#19733
Java: Update the CFG for assert statements to make them proper guards.#19733aschackmull merged 4 commits intogithub:mainfrom
Conversation
There was a problem hiding this comment.
Pull Request Overview
This PR refines how Java assert statements are represented in the control‐flow graph, treating them as true guards and incorporating the optional message expression into the flow.
- Expanded the assertion framework predicates to include
AssertStmtnodes. - Removed direct handling of
AssertStmtin nullness flow in favor of the updated CFG. - Enhanced
ControlFlowGraph.qllto generate throw and normal edges for asserts, update boolean contexts, and record thrown types.
Reviewed Changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
| java/ql/lib/semmle/code/java/frameworks/Assertions.qll | Added AssertStmt cases to the assert‐failure guard |
| java/ql/lib/semmle/code/java/dataflow/Nullness.qll | Removed direct AssertStmt null‐guard branch |
| java/ql/lib/semmle/code/java/ControlFlowGraph.qll | Integrated assert into CFG edges and completions |
| java/ql/lib/change-notes/2025-06-12-assert-cfg.md | Documented CFG change for assert analysis |
Comments suppressed due to low confidence (2)
java/ql/lib/semmle/code/java/dataflow/Nullness.qll:143
- Removing the direct
AssertStmtnull‐guard branch may break nullness inference for plainassertstatements. Ensure that the new CFG paths fully cover this case or reintroduce null‐guard logic forAssertStmt.
result.asStmt().(AssertStmt).getExpr() = nullGuard(v, true, false)
java/ql/lib/semmle/code/java/ControlFlowGraph.qll:1119
- It would be beneficial to add unit tests that verify both normal and exceptional CFG edges for
assertstatements (with and without messages), to ensure the new logic behaves as expected.
exists(AssertStmt assertstmt | assertstmt = n |
|
I've spot-checked a bunch of the changed results. The removed results were FPs, and the new results were typically redundant checks - e.g. both asserting a condition and then also checking it in an |
hvitved
left a comment
There was a problem hiding this comment.
One suggestion, otherwise LGTM.
Co-authored-by: Tom Hvitved <hvitved@github.com>
Isn't it the other way around in Java? |
Right, so my parenthesized remark ought to have been worded slightly different. Nevertheless, for the purpose of bug-finding, assuming that assertions succeed (which is what we get by unconditionally including them in the CFG) gives us good information about non-local invariants and helps us avoid reporting FPs. |
This upgrades the CFG for Java assert statements to be proper guards and includes the message part, which was previously a CFG orphan, in the CFG. That is, the false edge of the condition now leads to an exception edge rather than simply ignoring the value.
For things like nullness, this is definitely what we want, and in general it's probably fine to assume that asserts are evaluated (even though they technically can be disabled).