mirror of
https://github.com/github/codeql.git
synced 2026-08-04 17:33:18 +02:00
Phase 0.5 - Adapter API on top of the shared SSA:
Adds the legacy-ESSA-shaped class hierarchy that the dataflow library
consumes, layered on the shared 'Ssa::Make' instantiation:
* EssaDefinition / EssaNodeDefinition: the latter exposes
'getDefiningNode()' (the CFG node at the def's index in its BB)
and 'getVariable()' / 'getScope()'.
* AssignmentDefinition: matches Assign, AnnAssign with value,
AssignExpr and AugAssign target Names. Exposes 'getValue()'
pointing at the RHS' CFG node.
* ParameterDefinition: matches when the defining Name is in
parameter context.
* WithDefinition: matches 'with ... as x:' bindings.
* ScopeEntryDefinition: implicit entry defs at synthetic position
'-1' of the scope's entry basic block (non-local / global /
builtin / captured reads).
* PhiFunction (alias for PhiNode).
* EssaVariable adapter wrapping a 'Ssa::Definition' with 'getAUse()',
'getDefinition()', 'getAnUltimateDefinition()', and 'getName()'.
* AdjacentUses module with 'firstUse' and 'adjacentUseUse' predicates
bridging to 'Ssa::firstUse' / 'Ssa::adjacentUseUse'.
This is the minimum API the new dataflow's internals call into. The
richer legacy ESSA (refinement nodes, attribute refinements, edge
refinements) stays in 'semmle.python.essa.Essa' for legacy code.
Phase 0.6 - Comparison test:
Adds 'dataflow-new-ssa-vs-legacy/CmpTest.ql' that snapshots the
difference between definitions produced by new SSA vs legacy ESSA on
the same Python source. Baseline output records the current
'def-only-old' mismatches, grouped by category:
* function/class/global definitions with no in-scope read (intentional;
SSA is liveness-pruned)
* captured / closure variables (real gap in new SSA - no
closure-capture handling yet)
* module variables __name__ / __package__ / $ (legacy ESSA implicit
bindings)
* exception 'as' bindings (depend on raise modelling)
Zero 'def-only-new' mismatches: the new SSA never produces a spurious
definition compared to legacy ESSA on this corpus.
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
|