Skip to content

Conversation

@aschackmull
Copy link
Contributor

@aschackmull aschackmull commented Nov 5, 2025

This migrates the Java SSA libraries to use the shared SSA wrapper classes.

Commit-by-commit review is very much encouraged.


import java
private import internal.SsaImpl
import internal.SsaImpl::Ssa as Ssa

Check warning

Code scanning / CodeQL

Names only differing by case Warning

Ssa is only different by casing from SSA that is used elsewhere for modules.
}

private predicate upcastEnhancedForStmtAux(BaseSsaUpdate v, RefType t, RefType t1, RefType t2) {
private predicate upcastEnhancedForStmtAux(

Check warning

Code scanning / CodeQL

Candidate predicate not marked as `nomagic` Warning

Candidate predicate to
upcastEnhancedForStmt
is not marked as nomagic.
i = 0
)
}
module Ssa = Impl::MakeSsa<SsaInput>;

Check warning

Code scanning / CodeQL

Names only differing by case Warning

Ssa is only different by casing from SSA that is used elsewhere for modules.
}
}

module Ssa = Impl::MakeSsa<SsaInput>;

Check warning

Code scanning / CodeQL

Names only differing by case Warning

Ssa is only different by casing from SSA that is used elsewhere for modules.
@aschackmull
Copy link
Contributor Author

I've left several deprecation annotations for a followup PR to avoid having to do a submodule bump here.

@aschackmull aschackmull marked this pull request as ready for review November 7, 2025 11:51
@aschackmull aschackmull requested a review from a team as a code owner November 7, 2025 11:51
Copilot AI review requested due to automatic review settings November 7, 2025 11:51
@aschackmull aschackmull requested a review from a team as a code owner November 7, 2025 11:51
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

This PR modernizes the SSA (Static Single Assignment) API for Java CodeQL by renaming classes and methods to improve clarity and consistency. The changes deprecate old class and method names while introducing clearer alternatives.

  • Renames core SSA classes (e.g., SsaVariableSsaDefinition, SsaPhiNodeSsaPhiDefinition)
  • Renames methods for consistency (e.g., getAUse()getARead(), getCfgNode()getControlFlowNode())
  • Introduces new specialized SSA classes with clearer semantics (SsaCapturedDefinition, SsaImplicitCallDefinition, etc.)

Reviewed Changes

Copilot reviewed 53 out of 53 changed files in this pull request and generated no comments.

Show a summary per file
File Description
shared/ssa/codeql/ssa/Ssa.qll Adds toString methods and renames SsaPhiDefinition class definition
java/ql/lib/semmle/code/java/dataflow/SSA.qll Core SSA API with renamed classes and deprecated old names
java/ql/lib/semmle/code/java/dataflow/internal/BaseSSA.qll Base SSA implementation updated with new class names
java/ql/lib/semmle/code/java/dataflow/internal/SsaImpl.qll Internal SSA implementation restructuring
java/ql/test/**/*.ql Test queries updated to use new API
java/ql/test/**/*.expected Generated test expectations updated with new toString formats
java/ql/lib/**/*.qll Various library files updated to use new API
java/ql/src/**/*.qll Source queries updated to use new API
java/ql/lib/semmle/code/java/Expr.qll Adds new VariableWrite class for SSA integration
java/ql/lib/change-notes/2025-10-07-ssa-api-updates.md Documents the deprecation of old SSA API

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Copy link
Contributor

@hvitved hvitved left a comment

Choose a reason for hiding this comment

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

LGTM; my main concern is about caching.

private import Cached

cached
private module Cached {
Copy link
Contributor

Choose a reason for hiding this comment

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

Did you check that this cached stage is collapsed with the one inside Impl::MakeSsa?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes. See below.

}
}

module Ssa = Impl::MakeSsa<SsaInput>;
Copy link
Contributor

Choose a reason for hiding this comment

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

Same question: Did you check that the cached stages are collapsed?

Comment on lines +110 to +112
result = f.getAnAccess() and
f.isFinal() and
f.getInitializer() = clearlyNotNullExpr(reason) and
Copy link
Contributor

Choose a reason for hiding this comment

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

Some of this logic is duplicated inside clearlyNotNull(SsaDefinition v, Expr reason), so perhaps factor out?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

True, but we want to cover the case in both predicates, so we can't quite eliminate either of the cases. We could factor out another mutually recursive predicate clearlyNotNullField(Field f, Expr reason) and refer to that twice, but it's a bit borderline whether there's actually enough common code for that, so I'm leaning slightly towards keeping it as-is.

@aschackmull
Copy link
Contributor Author

Regarding caching: I've compared the outputs of the stageoverlap script and the number of stages is unchanged. Two stages change as expected:
BaseSSA stage before:

STAGE 11:
18 cached predicate(s)
  BaseSSA::Impl::TPhiReadNode#aebc7af2
  `BaseSSA::Cached::captures/2#8a9d4eca`
  `BaseSSA::baseSsaAdjacentUseUseSameVar/2#705c4532`
  `BaseSSA::baseSsaAdjacentUseUse/2#c9616c05`
  `BaseSSA::Cached::ssaUpdate/2#862a1ebc`
  `BaseSSA::Cached::ssaDefReachesEndOfBlock/2#78b18ca2`
  `BaseSSA::Cached::phiHasInputFromBlock/3#c7e7d002`
  `BaseSSA::Cached::firstUse/2#bd1a5768`
  `BaseSSA::Cached::ssaImplicitInit/1#4eea6057`
  `BaseSSA::Cached::getAUse/1#757edc8c`
  `BaseSSA::BaseSsaSourceVariable.getAnAccess/0#dispred#63a9bea2`
  `BaseSSA::BaseSsaStage::backref/0#74f67f6e`
  `BaseSSA::BaseSsaStage::ref/0#98b08ed3`
  BaseSSA::TLocalVar#427c4922
  BaseSSA::TBaseSsaSourceVariable#97b3067c
  BaseSSA::Impl::TPhiNode#d7813977
  BaseSSA::Impl::TDefinitionExt#51480cc1
  BaseSSA::Impl::TWriteDef#87bef8d1

BaseSSA stage after:

19 cached predicate(s)
  BaseSSA::Impl::TPhiReadNode#cf0be3af
  `BaseSSA::Cached::captures/2#8a9d4eca`
  `BaseSSA::baseSsaAdjacentUseUseSameVar/2#705c4532`
  `BaseSSA::baseSsaAdjacentUseUse/2#c9616c05`
  `BaseSSA::Ssa::Cached::uncertainWriteDefinitionInputCached/2#814503bc`
  `BaseSSA::Ssa::ssaDefReachesUncertainRead/4#076b6de1`
  `BaseSSA::Ssa::Cached::phiHasInputFromBlockCached/3#29383672`
  `BaseSSA::Ssa::Cached::parameterInit/2#8fc0e46e`
  `BaseSSA::Ssa::Cached::isLiveAtEndOfBlock/2#f8ebed08`
  `BaseSSA::Ssa::Cached::explicitWrite/2#1b6c0012`
  `BaseSSA::Ssa::Cached::ssaDefReachesCertainRead/2#c11820eb`
  `BaseSSA::BaseSsaSourceVariable.getAnAccess/0#dispred#63a9bea2`
  `BaseSSA::BaseSsaStage::backref/0#74f67f6e`
  `BaseSSA::BaseSsaStage::ref/0#98b08ed3`
  BaseSSA::TLocalVar#427c4922
  BaseSSA::TBaseSsaSourceVariable#97b3067c
  BaseSSA::Impl::TPhiNode#1a14f911
  BaseSSA::Impl::TDefinitionExt#130e8dc7
  BaseSSA::Impl::TWriteDef#0bf8b8b7

SSA stage before:

STAGE 21:
27 cached predicate(s)
  `SsaImpl::firstUse/2#e5f95b1c`
  `SsaImpl::relevantFieldUpdate/3#175bdda3`
  `SsaImpl::defUpdatesNamedField/3#b177d49b`
  `SsaImpl::captures/2#ebc1b8ae`
  `SSA::adjacentUseUseSameVar/2#68cf25c3`
  `SSA::adjacentUseUse/2#c9086f2d`
  SsaImpl::DataFlowIntegrationImpl::TSsaInputNode#8f227fe5
  `SsaImpl::ssaUntrackedDef/2#51aeffed`
  `SsaImpl::ssaDefReachesUncertainDef/2#1e11fc24`
  `SsaImpl::ssaDefReachesEndOfBlock/2#ea5b1b02`
  `SsaImpl::phiHasInputFromBlock/3#89518051`
  `SsaImpl::ssaImplicitInit/1#e06df881`
  `SsaImpl::ssaExplicitUpdate/2#d4539208`
  `SsaImpl::ssaUncertainImplicitUpdate/1#11315a30`
  `SsaImpl::getAUse/1#ca5d2675`
  SsaImpl::Impl::TPhiReadNode#357c6989
  `SsaImpl::DataFlowIntegrationImpl::getAPhiInputDef/2#6c94e4b7`
  SsaImpl::DataFlowIntegrationImpl::TSsaDefinitionNode#4e3b9ed8
  SsaImpl::DataFlowIntegrationImpl::TNode#d672eac3
  SsaImpl::DataFlowIntegrationImpl::TExprNode#60cb727e
  SsaImpl::DataFlowIntegrationImpl::TWriteDefSource#5e63c235
  `SsaImpl::DataFlowIntegration::localMustFlowStep/3#b7be827d`
  `SsaImpl::DataFlowIntegration::localFlowStep/4#3d967e2f`
  `SsaImpl::getDestVar/1#25a31530`
  SsaImpl::Impl::TPhiNode#428e419d
  SsaImpl::Impl::TDefinitionExt#672b6ca5
  SsaImpl::Impl::TWriteDef#3b2d2270

SSA stage after:

STAGE 21:
26 cached predicate(s)
  `SsaImpl::firstUse/2#e5f95b1c`
  `SsaImpl::relevantFieldUpdate/3#175bdda3`
  `SsaImpl::defUpdatesNamedField/3#b177d49b`
  `SsaImpl::captures/2#ebc1b8ae`
  `SSA::adjacentUseUseSameVar/2#68cf25c3`
  `SSA::adjacentUseUse/2#c9086f2d`
  SsaImpl::DataFlowIntegrationImpl::TSsaInputNode#2de8f875
  `SSA::Ssa::Cached::uncertainWriteDefinitionInputCached/2#5657081b`
  `SSA::Ssa::ssaDefReachesUncertainRead/4#b539c176`
  `SSA::Ssa::Cached::phiHasInputFromBlockCached/3#19163e7b`
  `SSA::Ssa::Cached::parameterInit/2#6aae25ba`
  `SSA::Ssa::Cached::isLiveAtEndOfBlock/2#6431964a`
  `SSA::Ssa::Cached::explicitWrite/2#6c9f09cd`
  `SSA::Ssa::Cached::ssaDefReachesCertainRead/2#cda75555`
  SsaImpl::Impl::TPhiReadNode#9d9a39b2
  `SsaImpl::DataFlowIntegrationImpl::getAPhiInputDef/2#eb9fec7a`
  SsaImpl::DataFlowIntegrationImpl::TSsaDefinitionNode#c0ad6d68
  SsaImpl::DataFlowIntegrationImpl::TNode#c0ec5eed
  SsaImpl::DataFlowIntegrationImpl::TExprNode#00fd7dbc
  SsaImpl::DataFlowIntegrationImpl::TWriteDefSource#2c42c1d0
  `SsaImpl::DataFlowIntegration::localMustFlowStep/3#b7be827d`
  `SsaImpl::DataFlowIntegration::localFlowStep/4#3d967e2f`
  `SsaImpl::getDestVar/1#25a31530`
  SsaImpl::Impl::TPhiNode#4eb75855
  SsaImpl::Impl::TDefinitionExt#27006a88
  SsaImpl::Impl::TWriteDef#edb3bd92

Copy link
Contributor

@hvitved hvitved left a comment

Choose a reason for hiding this comment

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

Thanks for verifying that caching works as expected.

@aschackmull aschackmull merged commit fe7be22 into github:main Nov 18, 2025
52 of 53 checks passed
@aschackmull aschackmull deleted the java/ssa-shared branch November 18, 2025 12:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants