-
Notifications
You must be signed in to change notification settings - Fork 1.7k
Java: Use the shared BasicBlocks library. #19505
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
Migration to the shared BasicBlock library and deprecation of legacy bb*
methods and predicates, updating call sites to use the new BasicBlock
API.
- Replaced legacy dominance and successor/predecessor methods (
bbDominates
,getABBSuccessor
, etc.) with the shared-library methods (dominates
,getASuccessor
, etc.). - Updated imports, removed unused
Dominance
imports, and augmentedqlpack.yml
to depend oncodeql/controlflow
. - Introduced
SuccessorType
definitions, updatedBasicBlocks.qll
to use the sharedBasicBlock
implementation, and added change notes.
Reviewed Changes
Copilot reviewed 39 out of 39 changed files in this pull request and generated no comments.
Show a summary per file
File | Description |
---|---|
java/ql/lib/semmle/code/java/security/PathSanitizer.qll | Swapped bbDominates for dominates . |
java/ql/lib/semmle/code/java/security/AndroidWebViewCertificateValidationQuery.qll | Swapped bbPostDominates for postDominates . |
java/ql/lib/semmle/code/java/dataflow/internal/rangeanalysis/SsaReadPositionSpecific.qll | Updated idOf to use getFirstNode().getAstNode() . |
java/ql/lib/semmle/code/java/dataflow/internal/SsaImpl.qll | Removed Dom import; switched to immediatelyDominates and getASuccessor . |
java/ql/lib/semmle/code/java/dataflow/internal/DataFlowUtil.qll | Replaced getABBSuccessor calls with getASuccessor . |
java/ql/lib/semmle/code/java/dataflow/internal/DataFlowPrivate.qll | Swapped bbIDominates and getABBSuccessor for shared APIs. |
java/ql/lib/semmle/code/java/dataflow/internal/BaseSSA.qll | Removed Dom import; switched to shared dominator/successor APIs. |
java/ql/lib/semmle/code/java/dataflow/TypeFlow.qll | Replaced getABBPredecessor and bbDominates with new methods. |
java/ql/lib/semmle/code/java/dataflow/RangeAnalysis.qll | Updated idOf and successor calls to use getFirstNode /getASuccessor . |
java/ql/lib/semmle/code/java/dataflow/Nullness.qll | Replaced all getABBSuccessor /getAST* with new basic-block methods. |
java/ql/lib/semmle/code/java/controlflow/internal/GuardsLogic.qll | Updated dominance checks to use dominates and new successor logic. |
java/ql/lib/semmle/code/java/controlflow/UnreachableBlocks.qll | Replaced predecessor and dominance calls with shared methods. |
java/ql/lib/semmle/code/java/controlflow/SuccessorType.qll | Added new SuccessorType hierarchy. |
java/ql/lib/semmle/code/java/controlflow/Paths.qll | Swapped legacy bb* calls for shared successor/dominance methods. |
java/ql/lib/semmle/code/java/controlflow/Guards.qll | Updated getTestSuccessor , dominance checks to new form. |
java/ql/lib/semmle/code/java/controlflow/Dominance.qll | Deprecated old predicates, forwarding to new methods. |
java/ql/lib/semmle/code/java/controlflow/BasicBlocks.qll | Imported and extended shared BasicBlock implementation. |
java/ql/lib/qlpack.yml | Added codeql/controlflow dependency. |
java/ql/lib/change-notes/2025-05-16-shared-basicblocks.md | Documented deprecation and migration to shared BasicBlock . |
cpp/ql/lib/semmle/code/cpp/rangeanalysis/new/internal/semantic/SemanticCFG.qll | Renamed bbDominates to dominates . |
Comments suppressed due to low confidence (3)
java/ql/lib/semmle/code/java/controlflow/BasicBlocks.qll:6
- [nitpick] The
Dominance
import is now redundant since the sharedBasicBlock
API provides dominance predicates; consider removing this import to clean up unused dependencies.
import Dominance
java/ql/lib/semmle/code/java/controlflow/SuccessorType.qll:1
- The new
SuccessorType
hierarchy introduced here doesn’t appear to have dedicated tests; consider adding unit tests to coverNormalSuccessor
,ConditionalSuccessor
, andExceptionSuccessor
handling.
import java
java/ql/lib/semmle/code/java/dataflow/internal/DataFlowPrivate.qll:86
- The
BasicBlock
type isn’t aliased in this module; you should addprivate import java as J
andclass BasicBlock = J::BasicBlock;
at the top to ensure the correct type is used.
BasicBlock getImmediateBasicBlockDominator(BasicBlock bb) {
} | ||
|
||
/** Exit points for basic-block control-flow. */ | ||
private predicate bbSink(BasicBlock exit) { exit.getLastNode() instanceof ControlFlow::ExitNode } | ||
|
||
/** Reversed `bbSucc`. */ | ||
private predicate bbPred(BasicBlock post, BasicBlock pre) { post = pre.getABBSuccessor() } | ||
private predicate bbPred(BasicBlock post, BasicBlock pre) { post = pre.getASuccessor() } |
Check warning
Code scanning / CodeQL
Missing QLDoc for parameter Warning
5c50666
to
719bbe4
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Really awesome to get Java onto to the shared basic block library 😃
I've left a few minor comments and ideas.
/** Holds if this basic block post-dominates `node`. (This is reflexive.) */ | ||
predicate bbPostDominates(BasicBlock node) { bbPostDominates(this, node) } | ||
/** | ||
* A control-flow node that represents the start of a basic block. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This comment seems outdated as BasicBlock
is no longer also a ControlFlowNode
.
What about using the exact same QLDoc as for BasicBlock
in the other languages (which we could modify if needed)?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed.
--- | ||
category: deprecated | ||
--- | ||
* Java now uses the shared `BasicBlock` library. This means that several member predicates now use the preferred names. The old predicates have been deprecated. The `BasicBlock` class itself no longer extends `ControlFlowNode` - the predicate `getFirstNode` can be used to fix any QL code that somehow relied on this. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure if it's clear for end users what "the preferred names" refer to? Maybe mention that the naming of the member predicates are now aligned with other languages, which also gives it a positive spin.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed.
* ``` | ||
*/ | ||
predicate dominanceFrontier(BasicBlock x, BasicBlock w) { | ||
x = w.getABBPredecessor() and not bbIDominates(x, w) | ||
x = w.getAPredecessor() and not x.immediatelyDominates(w) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What about deprecating this in favor of inDominanceFrontier
from the shared library?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think dominance frontier is used for anything else than SSA construction, and the shared SSA lib does its own calculation, so perhaps we should deprecate both. In any case, I think that's fine to postpone for now.
|
||
/** The immediate post-dominance relation on basic blocks. */ | ||
cached | ||
predicate bbIPostDominates(BasicBlock dominator, BasicBlock node) = | ||
deprecated predicate bbIPostDominates(BasicBlock dominator, BasicBlock node) = |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should this have a DEPRECATED: Use ...
doc like the other deprecated predicates?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Immediate post-dominance is not exposed in the shared lib - I'm not sure we've ever seen any use-cases for it, though, so adding it is probably of little value - hence why I simply opted to discretely deprecate this single public instance.
* This is a necessary and sufficient condition for an edge to dominate anything, | ||
* and in particular `dominatingEdge(bb1, bb2) and bb2.dominates(bb3)` means | ||
* that the edge `(bb1, bb2)` dominates `bb3`. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
* This is a necessary and sufficient condition for an edge to dominate anything, | |
* and in particular `dominatingEdge(bb1, bb2) and bb2.dominates(bb3)` means | |
* that the edge `(bb1, bb2)` dominates `bb3`. | |
* This is a necessary and sufficient condition for an edge to dominate some | |
* node, and `dominatingEdge(bb1, bb2) and bb2.dominates(bb3)` implies that | |
* the edge `(bb1, bb2)` dominates `bb3`. |
It might just be me, but I find "anything" here to be a bit unclear.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've adopted the s/anything/some node/
, but I don't want to change the second sentence from "means" to "implies", as that weakens the statement - it really is the semantic meaning of the QL snippet that's being explained.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Or how about "something" instead? Or at the very least "some block"?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've gone with "some block" for now.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"Some block" is also great 👍
I don't really understand the "in particular" though. What follows doesn't seem like a special case of the preceding statement? "This" in the first part refers to dominatingEdge(bb1, bb2)
and the second part talks about a situration where, in addition, bb2.dominates(bb3)
holds as well?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Right, I guess "in particular" ought to be "therefore". Does that sound better to you?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, I think "therefore" would be great :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed.
@@ -16,6 +16,6 @@ predicate dominanceCounterExample(ControlFlowNode entry, ControlFlowNode dom, Co | |||
|
|||
from Callable c, ControlFlowNode dom, ControlFlowNode node | |||
where | |||
(strictlyDominates(dom, node) or bbStrictlyDominates(dom, node)) and | |||
strictlyDominates(dom, node) and |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is in a file that includes "wrong" in the name, so I'm guessing it doesn't matter, but it's not clear to me why the previous code had the two conjuncts.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Once upon a time dominance for individual cfg nodes was computed independently of basic blocks, which I believe is the historical reason for this double check. Now, when translating basic block dominance via getFirstNode, one implies the other trivially, so we can simplify the test.
*/ | ||
class BasicBlock extends BbImpl::BasicBlock { | ||
/** Gets the immediately enclosing callable whose body contains this node. */ | ||
Callable getEnclosingCallable() { result = this.getScope() } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As discussed offline it might be nice to agree on a name for this predicate that every language can use. Right now Java's basic block will have both getScope
and getEnclosingCallable
that does the exact same thing.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, but I think that's best left as a follow-up.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, absolutely :)
@paldepind I've pushed review fixes now. |
0514624
to
00073b3
Compare
00073b3
to
10efea1
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for addressing my nitpicks. Looks great to me 👍
What the title says. Also, since
BasicBlock
is now no longer cast-compatible withControlFlowNode
there's no reason to use all thebb
-prefixed names, so I've deprecated those and switched to the defaults provided by the shared library.