mirror of
https://github.com/github/codeql.git
synced 2026-08-04 01:13:00 +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>
54 lines
645 B
Python
54 lines
645 B
Python
def simple_assign():
|
|
x = 1
|
|
return x
|
|
|
|
|
|
def reassignment():
|
|
x = 1
|
|
x = 2
|
|
return x
|
|
|
|
|
|
def if_else_branch(cond):
|
|
if cond:
|
|
x = 1
|
|
else:
|
|
x = 2
|
|
return x
|
|
|
|
|
|
def loop(xs):
|
|
total = 0
|
|
for x in xs:
|
|
total = total + x
|
|
return total
|
|
|
|
|
|
def parameter(a, b=2, *args, **kwargs):
|
|
return a + b + sum(args)
|
|
|
|
|
|
def closure(x):
|
|
def inner():
|
|
return x
|
|
return inner
|
|
|
|
|
|
def exception_binding():
|
|
try:
|
|
compute()
|
|
except Exception as e:
|
|
return e
|
|
|
|
|
|
def with_binding():
|
|
with open("file") as f:
|
|
return f.read()
|
|
|
|
|
|
GLOBAL = 1
|
|
|
|
|
|
def read_global():
|
|
return GLOBAL
|