mirror of
https://github.com/github/codeql.git
synced 2026-08-02 16:32:58 +02:00
Preparatory refactor for the shared-CFG dataflow migration. Adds the new Python SSA adapter additively, without changing any production behaviour. Library additions: - semmle.python.dataflow.new.internal.SsaImpl — Python SSA implementation built on the new (shared) CFG. Mirrors the Java SSA adapter (java/ql/lib/semmle/code/java/dataflow/internal/SsaImpl.qll): an InputSig is defined in terms of positional (BasicBlock, int) variable references, and the shared codeql.ssa.Ssa::Make<Location, Cfg, Input> module is then instantiated. SourceVariable is the AST-level Py::Variable. Variable references are looked up via the new CFG facade's NameNode.defines/uses/deletes predicates (added in the preceding PR), which themselves are one-line bridges to AST-level Name.defines/uses/deletes. Implicit-entry definitions are inserted for non-local/global/builtin reads, captured variables, and (when needed) parameters. Test additions: - library-tests/dataflow-new-ssa/ — exercises the new SSA over a representative test corpus and checks expected def/use chains. - library-tests/dataflow-new-ssa-vs-legacy/ — runs both new SSA and legacy ESSA over the same corpus and diffs the results, so any semantic divergence shows up as a test failure. Production impact: None. The new SSA adapter has zero callers in lib/ and src/ — the legacy ESSA SSA (semmle/python/essa/*) remains the default. The dataflow library is not migrated yet; that lands in a follow-up PR. Verified by: - All 367 lib + src + consistency-queries compile clean. - All 641 ControlFlow + PointsTo + dataflow + essa + consistency library-tests pass. - Both new dataflow-new-ssa[/vs-legacy] test packs pass. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
60 lines
2.1 KiB
Plaintext
60 lines
2.1 KiB
Plaintext
/**
|
|
* Inline-expectations test for the new-CFG SSA adapter
|
|
* (`semmle.python.dataflow.new.internal.SsaImpl`).
|
|
*
|
|
* Tags:
|
|
* - `def=<var>`: there is an SSA write definition of `<var>` at this
|
|
* line (parameter init, plain assignment, augmented assignment,
|
|
* exception-handler binding, deletion, etc.).
|
|
* - `use=<var>`: `<var>` is used at this line, and some SSA definition
|
|
* of `<var>` reaches the read.
|
|
* - `phi=<var>`: there is an SSA phi definition of `<var>` whose BB
|
|
* starts on this line.
|
|
*/
|
|
|
|
import python
|
|
import semmle.python.dataflow.new.internal.SsaImpl as SsaImpl
|
|
import semmle.python.controlflow.internal.AstNodeImpl as CfgImpl
|
|
import semmle.python.controlflow.internal.Cfg as Cfg
|
|
import utils.test.InlineExpectationsTest
|
|
|
|
module SsaTest implements TestSig {
|
|
string getARelevantTag() { result = ["def", "use", "phi"] }
|
|
|
|
predicate hasActualResult(Location location, string element, string tag, string value) {
|
|
// A `def=<id>` fires when an SSA WriteDefinition is at a CFG node
|
|
// on the given line.
|
|
exists(SsaImpl::Ssa::WriteDefinition def, CfgImpl::BasicBlock bb, int i, Cfg::NameNode n |
|
|
def.definesAt(_, bb, i) and
|
|
bb.getNode(i) = n and
|
|
tag = "def" and
|
|
location = n.getLocation() and
|
|
element = n.toString() and
|
|
value = n.getId()
|
|
)
|
|
or
|
|
// A `use=<id>` fires when an SSA Definition reaches a read at this
|
|
// CFG node.
|
|
exists(SsaImpl::Ssa::Definition def, CfgImpl::BasicBlock bb, int i, Cfg::NameNode n |
|
|
SsaImpl::Ssa::ssaDefReachesRead(_, def, bb, i) and
|
|
bb.getNode(i) = n and
|
|
tag = "use" and
|
|
location = n.getLocation() and
|
|
element = n.toString() and
|
|
value = n.getId()
|
|
)
|
|
or
|
|
// A `phi=<id>` fires when there is a phi node whose BB's first
|
|
// CFG node is on the given line.
|
|
exists(SsaImpl::Ssa::PhiNode phi, CfgImpl::BasicBlock bb |
|
|
phi.definesAt(_, bb, _) and
|
|
tag = "phi" and
|
|
location = bb.getNode(0).getLocation() and
|
|
element = bb.toString() and
|
|
value = phi.getSourceVariable().(SsaImpl::SsaSourceVariable).getVariable().getId()
|
|
)
|
|
}
|
|
}
|
|
|
|
import MakeTest<SsaTest>
|