8000 DataFlow: Run overlay-informed if not diff-informed by jbj · Pull Request #19857 · github/codeql · GitHub
[go: up one dir, main page]

Skip to content

DataFlow: Run overlay-informed if not diff-informed #19857

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

Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
DataFlow:Run overlay-informed if not diff-informed
To ensure good performance, always run data flow overlay-informed unless
the configuration has opted in to being diff-informed. This change
affects only databases with an overlay and therefore has no immediate
production consequences.
  • Loading branch information
jbj committed Jun 24, 2025
commit c1214db5b3c482975035d31183ddb503af1cb04c
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ module;

private import semmle.code.Location
private import codeql.dataflow.DataFlow
private import semmle.code.java.Overlay

module Private {
import DataFlowPrivate
Expand All @@ -29,4 +30,6 @@ module JavaDataFlow implements InputSig<Location> {
predicate mayBenefitFromCallContext = Private::mayBenefitFromCallContext/1;

predicate viableImplInCallContext = Private::viableImplInCallContext/2;

predicate isEvaluatingInOverlay = isOverlay/0;
}
12 changes: 12 additions & 0 deletions shared/dataflow/codeql/dataflow/DataFlow.qll
Original file line number Diff line number Diff line change
Expand Up @@ -349,6 +349,18 @@ signature module InputSig<LocationSig Location> {

/** Holds if `fieldFlowBranchLimit` should be ignored for flow going into/out of `c`. */
default predicate ignoreFieldFlowBranchLimit(DataFlowCallable c) { none() }

/**
* Holds if the evaluator is currently evaluating with an overlay. The
* implementation of this predicate needs to be `overlay[local]`. For a
* language with no overlay support, `none()` is a valid implementation.
*
* When called from a local predicate, this predicate holds if we are in the
* overlay-only local evaluation. When called from a global pre 8000 dicate, this
* predicate holds if we are evaluating globally with overlay and base both
* visible.
*/
Copy link
Preview
Copilot AI Jun 24, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The default isEvaluatingInOverlay predicate lacks the required overlay[local] annotation, so overlay-local evaluations won't see it. Add overlay[local] to its definition.

Suggested change
*/
*/
overlay[local]

Copilot uses AI. Check for mistakes.

default predicate isEvaluatingInOverlay() { none() }
}

module Configs<LocationSig Location, InputSig<Location> Lang> {
Expand Down
37 changes: 34 additions & 3 deletions shared/dataflow/codeql/dataflow/internal/DataFlowImplStage1.qll
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
* Provides an implementation of a fast initial pruning of global
* (interprocedural) data flow reachability (Stage 1).
*/
overlay[local?]
overlay[local?] // when this is removed, put `overlay[local?]` on `isOverlayNode`.
module;

private import codeql.util.Unit
Expand Down Expand Up @@ -129,14 +129,38 @@ module MakeImplStage1<LocationSig Location, InputSig<Location> Lang> {

private module AlertFiltering = AlertFilteringImpl<Location>;

/**
* Holds if the given node is visible in overlay-only local evaluation.
*
* This predicate needs to be `overlay[local?]`, either directly or
* through annotations from an outer scope. If `Node` is global for the
* language under analysis, then every node is considered an overlay
* node, which means there will effectively be no overlay-based
* filtering of sources and sinks.
*/
private predicate isOverlayNode(Node node) {
Comment on lines +135 to +141
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not give this predicate an explicit overlay annotation now?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The compiler gives a warning that it's redundant because the file module is also annotated overlay[local?].

isEvaluatingInOverlay() and
// Any local node is an overlay node if we are evaluating in overlay mode
node = node
Copy link
Preview
Copilot AI Jun 24, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The predicate isOverlayNode uses a tautology (node = node), so it doesn't actually distinguish overlay-visible nodes. Replace it with a predicate that checks the node's overlay locality (e.g., isLocalNode(node)).

Copilot uses AI. Check for mistakes.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The canonical way to write this is exists(node).

}

overlay[global]
pragma[nomagic]
private predicate isFilteredSource(Node source) {
Config::isSource(source, _) and
if Config::observeDiffInformedIncrementalMode()
then AlertFiltering::filterByLocation(Config::getASelectedSourceLocation(source))
else any()
else (
// If we are in base-only global evaluation, do not filter out any sources.
not isEvaluatingInOverlay()
or
// If we are in global evaluation with an overlay present, restrict
// sources to those visible in the overlay.
isOverlayNode(source)
)
}

overlay[global]
pragma[nomagic]
private predicate isFilteredSink(Node sink) {
(
Expand All @@ -145,7 +169,14 @@ module MakeImplStage1<LocationSig Location, InputSig<Location> Lang> {
) and
if Config::observeDiffInformedIncrementalMode()
then AlertFiltering::filterByLocation(Config::getASelectedSinkLocation(sink))
else any()
else (
// If we are in base-only global evaluation, do not filter out any sinks.
not isEvaluatingInOverlay()
or
// If we are in global evaluation with an overlay present, restrict
// sinks to those visible in the overlay.
isOverlayNode(sink)
)
}

private predicate hasFilteredSource() { isFilteredSource(_) }
Expand Down
Loading
0