Compare commits

..

111 Commits

Author SHA1 Message Date
yoff
8cab5a20f2 Python: drop legacy essa import from ImportResolution
`ImportResolution.qll` was the last new-dataflow file with a direct
`import semmle.python.essa.SsaDefinitions`, used only for the
`SsaSource::init_module_submodule_defn` helper. Inline the 5-line body
as a local private predicate. No functional change — the inlined
predicate is clause-for-clause equivalent (the `f = init.getEntryNode()`
join only constrained `package = init`, since `Scope.getEntryNode()` is
unique per scope; we now express that constraint directly).

All 70 dataflow + ApiGraphs library-tests pass.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-05-26 13:10:00 +00:00
yoff
635134ffd2 Python: treat augmented-assignment targets as both load and store
The legacy CFG emitted two ControlFlowNodes for `x[i] += 42` (one load,
one store, with `load.strictlyDominates(store)`). The new CFG collapses
them to a single canonical node, mirroring Java's single-`VarAccess`
model where `isVarRead`/`isVarWrite` are non-disjoint on the same
expression. Reconcile two legacy two-node behaviours with the merged
single-node world:

1. `Cfg::ControlFlowNode.isLoad()` no longer excludes augmented
   targets — both `isLoad` and `isStore` hold on the merged canonical
   node, matching Java. `NameNode.defines` drops the now-redundant
   `not isLoad` guard; `Py::Name.defines` already filters by
   `isDefinition` (Store/Param/AugAssign-target ctx).

2. `LocalFlow::definitionFlowStep` is restricted to NameNode targets,
   matching legacy ESSA's `assignment_definition` which required
   `defn.(NameNode).defines(v)`. Subscript and attribute writes
   (`x[i] = 42`, `obj.attr = 42`) no longer emit a local-flow step
   *into* the LHS expression — that flow is handled by the AttrWrite
   and content-flow machinery. This is essential for keeping augmented
   Subscript/Attribute targets classifiable as `LocalSourceNode` on
   the read side, which the API graph requires for emitting Use edges.

`StoreLoadTest.ql` is updated to filter `isAugLoad` out of the regular
`load` tag, mirroring the pre-existing `not isAugStore` filter on the
`store` tag so augmented-assignment expectations remain
`augload=n augstore=n` (not also `load=n store=n`).

Closes the three remaining ApiGraphs library-test failures
(`getSubscript.ql` semantically, plus cosmetic toString updates in
`ModuleImportWithDots.ql` and `test_crosstalk.ql`).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-05-26 10:56:21 +00:00
yoff
dd2deacd00 Python: model from X import * as uncertain SSA writes
Add a 4th disjunct to `SsaImplInput::variableWrite` in the shared-SSA
adapter that mirrors legacy ESSA's `ImportStarRefinement`: every
variable whose scope is the import-star's scope, OR which is used in
the import-star's scope, gets an uncertain write at the `import *`
position.

Uncertain writes do not kill prior definitions; shared SSA's
`SsaUncertainWrite` joins the new value with the immediately-preceding
definition via `uncertainWriteDefinitionInput`. This is the equivalent
of legacy ESSA's two-input refinement.

Cannot depend on `ImportStar` / `ImportResolution` (those modules
import `SsaImpl`), so the predicate uses the structural heuristic on
`Cfg::ImportStarNode` directly.

This closes the two remaining failing dataflow library-tests:

- `import-star/global` — `module_export` chains via `from X import *`
  re-exports now resolve: the importing module has an SSA def of every
  re-exported name, so `lastUseVar` finds the read at the use site.
- `typetracking_imports/highlight_problem` — a direct `from .foo import
  foo` immediately followed by `from .other import *` is now correctly
  marked as dead at the direct import.

Two scope-entry-def noise rows in `highlight_problem.expected` are also
dropped — legacy ESSA needed them as refinement inputs, but shared SSA
handles uncertain writes without an explicit prior def. They were
always tagged `no use to normal exit` (dead).

Dataflow library-tests: 62/64 → 64/64 passing.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-05-26 10:09:04 +00:00
yoff
6d930099d4 Python: update dataflow tests for new CFG + shared SSA
Test-side changes accompanying the dataflow migration:

  * Test queries (.ql) and shared test harness (TestSummaries,
    TestTaintLib) qualify CFG / SSA types with Cfg:: / SsaImpl::,
    bridge via AST (Name, Call, ...) instead of legacy NameNode /
    CallNode, and switch GlobalSsaVariable / EssaVariable usages
    to the new adapter API.

  * .expected files updated for legitimate precision and toString
    changes:
      - phi-node def-use edges newly exposed in def_use_counts.
      - scope-exit synthetic use surfaces one extra implicit use
        in use-use-counts.
      - For [empty]/[non-empty] outcome rows added in
        EnclosingCallable.
      - SsaSourceVariable / Global Variable label cosmetics
        normalised throughout.

  * Inline annotations:
      - typetracking/test.py: removed MISSING:tracked on lines
        93/95 (now found), added SPURIOUS:tracked on line 108
        (decorator over-reach).
      - global-flow/test.py: added SPURIOUS writes=g_mod on line
        20 (correctly reports immediately-overwritten write).
      - tainttracking/customSanitizer/test.py: marked
        try/except: ensure_tainted(s) cases as MISSING: tainted
        (no-raise CFG abstraction does not connect try body to
        except body).
      - coverage/test.py: marked
        SINK(return_from_inner_scope([])) as
        MISSING: flow=... pending closer investigation.

  * regression/{dataflow,custom_dataflow}.expected: accept two
    if/else cond-correlation over-reaches (documented limitation;
    same imprecision applies under legacy semantics by design).

After this change the dataflow library-tests stand at 62 of 64
passing; the two remaining failures are tracked under the
ImportStarRefinement workstream.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-05-26 07:21:06 +00:00
yoff
ccfaa6ea7f Python: migrate dataflow library to new CFG + shared SSA
Switches the trunk dataflow library and all in-tree consumers
(frameworks, ApiGraphs, Concepts, regexp, security customisations,
test harness) from the legacy Flow.qll/ESSA stack to the new
shared-CFG facade (Cfg.qll) and the ESSA-shaped adapter on the
shared-SSA library (SsaImpl.qll).

Highlights:

  * DataFlowPublic/Private/Dispatch, Attributes, VariableCapture,
    IterableUnpacking, ImportResolution, ImportStar, LocalSources,
    TaintTrackingPrivate, MatchUnpacking, TypeTrackingImpl,
    SsaImpl, Builtins all now qualify CFG/SSA references with
    Cfg:: / SsaImpl:: and stop pulling in semmle.python.essa.*.

  * AstNodeImpl.qll/Cfg.qll: ImportMember exposes its inner
    ImportExpr, DefinitionNode.getValue covers Alias / AnnAssign /
    AugAssign / AssignExpr / For-target / Parameter-default,
    ForNode is treated as an expression node, AnnotatedExitNode is
    canonical, and BoolExprNode.getAnOperand drops the dominance
    constraint that did not hold for short-circuit BBs.

  * SsaImpl.qll: parameters always get a ParameterDefinition (so
    unused parameters still have SSA defs), scope-entry defs for
    module globals require an actual store somewhere, scope-exit
    has a synthetic use so reaching-defs survives to module
    boundary, and the legacy SsaSourceVariable / EssaVariable
    surface (getName, getScope, getAUse, getASourceUse,
    getAnImplicitUse) is reinstated for downstream queries.

  * DataFlowPublic.qll: GuardNode redesigned around the new
    structural outcome nodes (isAfterTrue / isAfterFalse).  The
    legacy ConditionBlock + flipped indirection is gone;
    controlsBlock walks UP through 'not' / '==True' / 'is False'
    etc. via outcomeOfGuard, accumulating polarity cleanly.  Only
    BarrierGuard<...> is preserved as public API.

  * ModuleVariableNode.getAWrite and LocalFlow::definitionFlowStep
    bypass SSA and consult Cfg::NameNode.defines /
    Cfg::DefinitionNode.getValue directly, so that write defs
    pruned by shared SSA (because the variable has no in-scope
    read) still produce dataflow steps.

  * Frameworks + downstream consumers: replace
    EssaVariable.hasDefiningNode, getAReturnValueFlowNode,
    Parameter.getDefault, Scope.getEntryNode / getANormalExit etc.
    with CFG-side bridges through Cfg::ControlFlowNode.

The legacy Flow.qll / Essa.qll stack is untouched and remains
available for queries that import it directly.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-05-26 07:20:44 +00:00
yoff
cccd207ae7 Python: remove getAFlowNode() — bridge AST→CFG only via CFG-side getNode()
Option 2: eliminates the AST→CFG bridge from the AST layer. Previously
'AstNode.getAFlowNode()' returned a 'ControlFlowNode' from the legacy
'Flow.qll' CFG via 'py_flow_bb_node' — this hardcoded the AST to know
about the legacy CFG, preventing files from cleanly switching to the
new shared CFG.

Removes:
  * 'AstNode.getAFlowNode()' from 'AstExtended.qll'
  * Type-narrowing overrides on 'Attribute' / 'Subscript' / 'Call' /
    'IfExp' / 'Name' / 'NameConstant' / 'ImportMember' (in Exprs.qll
    and Import.qll)

Rewrites ~130 call sites across 'python/ql/lib/' and 'python/ql/src/'
to bridge from the CFG side instead:

  Before:  node = expr.getAFlowNode()
  After:   node.getNode() = expr

  Before:  expr.getAFlowNode().(DefinitionNode).getValue()
  After:   exists(DefinitionNode d | d.getNode() = expr | d.getValue())

  Before:  cn.operands(const.getAFlowNode(), op, x)
  After:   exists(ControlFlowNode c | c.getNode() = const | cn.operands(c, op, x))

This is semantically a no-op — both forms are duals of the same predicate.
Verified by passing all library tests:
  * 64 dataflow tests
  * 28 ControlFlow + dataflow-new-ssa tests
  * 1 essa SSA-compute test
  * 93 tests total in the focused suite

Once committed, files that want to switch from the legacy 'Flow' CFG
to the new 'Cfg' facade only need to change their imports — the
bridge sites are CFG-side and respect whichever ControlFlowNode is in
scope.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-05-21 13:08:37 +00:00
yoff
6814bcfb1b Python: SSA adapter: add MultiAssignmentDefinition, definedBy, useOfDef
Extends the ESSA-shaped adapter on top of the new shared SSA with the
remaining APIs consumed by the dataflow library:

  * MultiAssignmentDefinition: matches the AST pattern 'a, b = ...' where
    the LHS is a Tuple/List and the Name being defined is a sub-element.
    Used by IterableUnpacking.qll to recognise unpacking assignments.

  * EssaNodeDefinition.definedBy(var, defNode): a flatter equivalent of
    'getSourceVariable() = var and getDefiningNode() = defNode', matching
    legacy ESSA's signature. Used by DataFlowPublic.qll's
    ModuleVariableNode to enumerate writes of a global.

  * AdjacentUses::useOfDef(def, use): all reachable uses of a definition
    (firstUse plus transitive use-use adjacency). Used by guards in
    DataFlowPublic.qll.

These complete the API surface enumerated by grep across the dataflow
library. The remaining items (EssaNodeRefinement, EssaImportStep) are
ImportResolution-specific and will need separate treatment, possibly via
a different abstraction since the SSA library does not model heap-state
refinements like 'foo.bar = X'.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-05-19 12:19:28 +00:00
yoff
7521d838c0 Python: SSA: handle closure variables via per-scope entry defs
The new SSA's implicit entry-def predicate previously placed entries in
the variable's defining scope. For closure variables that's the outer
function, so inner functions had no entry def for the captured
variable — reads in the inner scope failed to resolve to any
definition.

Mirrors legacy ESSA's 'NonLocalVariable.getScopeEntryDefinition()':
place an implicit entry def at every reading scope's entry block,
independently of where the variable is *defined*. A closure variable
accessed in two nested functions and the outer one gets three entry
defs (one per reading scope).

Also makes 'ScopeEntryDefinition' extend 'EssaNodeDefinition' (matching
legacy ESSA), with 'getDefiningNode()' returning the scope's entry CFG
node. This requires extending the private 'writeDefNode' helper to
project i=-1 entries to bb.getNode(0).

Updates the new-vs-legacy comparison snapshot: closure-variable reads
('x:32:5'), nested global reads ('GLOBAL:52:1') now resolve. New
'def-only-new' entries appear for unbound names ('sum', 'open',
'compute') — the new SSA uniformly creates scope-entry defs for all
non-local reads, including those that legacy ESSA classifies as
builtin and excludes. This is a more uniform semantic and arguably
cleaner.

Updates the SsaTest 'some_undefined' annotation: previously documented
as a known limitation, now correctly resolves to a scope-entry def.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-05-19 12:06:15 +00:00
yoff
c4674bca14 Python: extend new SSA with ESSA-shaped adapter + baseline comparison test
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>
2026-05-18 21:13:57 +00:00
yoff
30f0a3f2b9 Python: qualify Flow.qll's AST references with Py:: prefix
Prepares Flow.qll for co-existence with the new CFG facade by switching
'import python' to 'import python as Py' and qualifying every AST-class
reference inside Flow.qll's body. Flow.qll's own CFG types
(ControlFlowNode, BasicBlock, CallNode, NameNode, etc.) keep their
unqualified names.

This change is a no-op semantically:
  * all 24 evaluation-order tests still pass,
  * the bindings + store-load + new-CFG-SSA library tests still pass,
  * compilation produces zero errors.

The change enables a follow-up commit to swap python.qll's
'import semmle.python.Flow' for 'import semmle.python.controlflow.internal.Cfg'
without triggering name-clash errors inside Flow.qll itself. Legacy
modules that still want the legacy CFG (essa/, GuardedControlFlow,
LegacyPointsTo, objects/, pointsto/, types/, dataflow/old/) will need a
similar treatment in subsequent commits.

The qualification was applied mechanically via a script that prefixed
every reference to a known AST class. The list includes the standard
AST node types from semmle.python.{Files, Variables, Stmts, Exprs,
Class, Function, Patterns, Comprehensions} plus 'Location' / 'File' /
'Folder' / 'Container' / 'ConditionBlock' / 'Delete' / 'Load'.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-05-18 19:19:20 +00:00
yoff
bd9f65478e Python: bring Cfg.qll's facade to API parity with Flow.qll
Adds the methods and type-narrowing overrides needed for Cfg.qll to be
a drop-in replacement for Flow.qll's CFG API surface:

  * 'override getNode()' type narrowing on all AST-shape subclasses
    (CallNode -> Py::Call, AttrNode -> Py::Attribute, ImportExprNode
    -> Py::ImportExpr, etc.). This lets callers chain methods like
    'iexpr.getNode().isRelative()' that previously failed because
    'getNode()' returned the generic AstNode.

  * 'ControlFlowNode.isBranch()' -- true and/or false successor exists.
  * 'ControlFlowNode.getAChild()' -- CFG-level child traversal via the
    AST's getAChildNode, with dominance constraint.
  * 'ControlFlowNode.strictlyReaches(other)' -- node-level reachability.
  * 'NameNode.isSelf()' -- AST-level approximation: uses the 'Variable'
    that is the first parameter of an enclosing method.
  * 'BinaryExprNode.operands(left, op, right)' + 'getAnOperand()'.
  * 'BoolExprNode.getAnOperand()'.
  * 'ForNode.getSequence()' (alias for 'getIter') and
    'ForNode.iterates(target, sequence)'.
  * 'ForNode' / 'RaiseStmtNode' type-narrowing overrides.
  * 'ExceptFlowNode.getName()' / 'ExceptGroupFlowNode.getName()'
    -- the bound 'as'-name CFG node.
  * 'DictNode.getAKey()' (only 'getAValue' was present).

These additions are independent of the dataflow-migration approach
(option 4 vs option 5). They close the API-parity gap identified
during the Option-5 investigation; with them in place, hundreds of
type-resolution errors that previously appeared when swapping Cfg for
Flow at the python.qll level go away.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-05-18 18:24:38 +00:00
yoff
87b2e2fb0f Python: fix augstore for the new CFG and add store/load test
In the legacy CFG the same Python 'Name' that is the target of an
augmented assignment has two distinct CFG nodes — a load node (context
3) earlier in the basic block and a store node (context 5) later.
'augstore(load, store)' relates the pair via dominance.

The new (shared) CFG canonicalises each AST expression to a single
CFG node, so 'load' and 'store' collapse to one. The dominance-based
'augstore' from the legacy implementation no longer holds (it would
require 'load.strictlyDominates(load)'), so 'isAugLoad' / 'isAugStore'
never fired and 'isStore' missed the AugAssign target entirely.

Redefines 'augstore' as reflexive on the AugAssign target's canonical
CFG node. With this change:

  * isAugLoad / isAugStore both fire on the single canonical node.
  * isStore fires (via 'or augstore(_, this)') — matching the legacy
    classification that an augmented-assignment target is a store.
  * isLoad does not fire (excluded by 'not augstore(_, this)').

Adds 'python/ql/test/library-tests/ControlFlow/store-load/' covering
plain load/store/delete, parameters, augmented assignment, tuple
unpacking, attribute and subscript stores. The test asserts the
classification directly on the new-CFG facade.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-05-18 12:29:37 +00:00
yoff
2bb8e90476 Python: introduce shared-SSA adapter on the new CFG
Adds 'python/ql/lib/semmle/python/dataflow/new/internal/SsaImpl.qll', a
minimal Python SSA implementation built on the shared SSA library
('codeql.ssa.Ssa::Make<Location, Cfg, Input>'). The structure mirrors
Java's adapter at 'java/ql/lib/semmle/code/java/dataflow/internal/SsaImpl.qll'.

Key design choices:

  * 'SourceVariable' wraps 'Py::Variable'. Only variables that are read
    or deleted somewhere are tracked - write-only variables don't
    benefit from SSA construction.

  * Variable references are positional ('BasicBlock', 'int') pairs
    looked up via 'Cfg::NameNode.defines'/'.uses'/'.deletes' (which
    themselves are one-line bridges to AST-level 'Name.defines' etc.).

  * Parameter writes are not synthesised: parameter Name nodes are
    already wired into the CFG (per the earlier C#-style parameter
    extension in 'AstNodeImpl.qll'), so the regular 'variableWrite'
    path handles them at their natural CFG index.

  * Non-local / captured / global / builtin variables read in a scope
    but not written in it receive a synthetic entry definition at
    index '-1' of the scope's entry basic block. This matches Java's
    'hasEntryDef'.

  * 'del x' is modelled as a certain write at the deletion site.

Includes an inline-expectations test under
'python/ql/test/library-tests/dataflow-new-ssa/' covering:
plain parameter pass-through, simple assignment + read, reassignment
with dead-write pruning, if/else with phi insertion at the join, and
an undefined-name read (currently a known limitation - no SSA flow
without an enclosing definition).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-05-18 11:03:45 +00:00
yoff
0da0633159 Python: introduce new-CFG facade
Adds 'Cfg.qll' alongside 'AstNodeImpl.qll' in the controlflow internal
package. The facade re-exposes the same API surface as the legacy
'semmle/python/Flow.qll' (ControlFlowNode, BasicBlock, NameNode, CallNode,
AttrNode, ImportExprNode, ImportMemberNode, ImportStarNode, SubscriptNode,
CompareNode, IfExprNode, AssignmentExprNode, BinaryExprNode, BoolExprNode,
UnaryExprNode, DefinitionNode, DeletionNode, ForNode, RaiseStmtNode,
StarredNode, ExceptFlowNode, ExceptGroupFlowNode, TupleNode, ListNode,
SetNode, DictNode, IterableNode, NameConstantNode), but is implemented
on top of the new shared CFG via 'AstNodeImpl.qll'.

The variable-identity predicates ('NameNode.defines', '.uses',
'.deletes', '.isLocal', '.isNonLocal', ...) are one-line bridges to the
underlying AST predicates ('Name.defines', '.uses', '.deletes'),
mirroring the Java pattern.

Re-exports 'EntryBasicBlock' and 'dominatingEdge/2' from the shared
'BB::CfgSig' produced by 'AstNodeImpl.qll', so downstream consumers
(e.g. the SSA adapter) can wire the new CFG into other shared modules
that expect a 'CfgSig' implementation.

This facade is not yet consumed by the dataflow library — that is the
next phase.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-05-18 11:03:32 +00:00
yoff
558cd5b00c Python: test dead bindings under no-raise CFG abstraction
Adds 'dead_under_no_raise.py' to the bindings test suite, capturing the
three CPython patterns where bindings legitimately have no CFG node
because the surrounding code is unreachable under the 'no expressions
raise' abstraction:

  1. Statements after a 'try: return X; except: pass' block.
  2. The 'else:' clause of a try whose body always raises.
  3. Cache-lookup pattern 'try: return cache[k]; except: pass' followed
     by computation and store.

These bindings intentionally carry no 'cfgdefines=' annotations. If
raise modelling is later added to the CFG, the BindingsTest will surface
the new CFG nodes as unexpected results and this file will need to be
revisited.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-05-18 10:48:43 +00:00
yoff
77149be759 Python: wire PEP 695 type parameters into the shared CFG (green)
Adds CFG coverage for the binding 'Name's introduced by PEP 695
type-parameter syntax on functions, classes, and 'type' aliases:

  def func[T](...): ...
  class Box[T]: ...
  def multi[T: int, *Ts, **P](...): ...
  type Alias[T] = ...

For each parametrised AST node, the type-parameter names (and, for
'type' aliases, the alias name itself) are added as children of the
enclosing CFG node so that 'Name.defines(v)' has a corresponding
position. Bounds and defaults are intentionally not wired (they have
no SSA-relevant semantics for our purposes).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-05-18 09:58:27 +00:00
Copilot
aa8402d1b7 Python: wire match-pattern bindings into the shared CFG (green)
Adds concrete `Pattern` subclasses in `AstNodeImpl.qll` for every
`MatchPattern` AST kind, with `getChild` overrides that expose
sub-patterns and bound Names. Specifically:

- MatchCapturePattern (`case x:`) -> getVariable()
- MatchAsPattern (`case … as v:`) -> getPattern(), getAlias()
- MatchStarPattern (`case [*rest]:`) -> getTarget()
- MatchSequencePattern (`case [a, b]:`) -> getPattern(i)
- MatchClassPattern (`case Cls(p, q, k=v)`) -> getClass(), positional, keyword
- MatchMappingPattern (`case {k: v}:`) -> getMapping(i)
- MatchKeyValuePattern, MatchKeywordPattern, MatchDoubleStarPattern
- MatchOrPattern, MatchLiteralPattern, MatchValuePattern

Without these, every Name bound by a match pattern lacked a CFG node.
Removes the corresponding MISSING: annotations from match_pattern.py
(all 11 cases).

Verified: all 24 ControlFlow/evaluation-order tests still pass.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-05-12 13:11:18 +00:00
Copilot
b8c093eefb Python: wire import-statement bindings into the shared CFG (green)
Adds `ImportStmt` and `ImportStarStmt` wrappers in `AstNodeImpl.qll`.
For each `Alias` in an import statement, both the value (module/member
expression) and the bound `asname` Name become children of the CFG node
for the import statement, in evaluation order.

Without this, every `Name` introduced by `import` / `from .. import ..`
lacked a CFG node, even though `Name.defines(v)` returns true for it on
the AST side. This was the highest-volume gap: 20,332 missing import
aliases across CPython.

Removes the corresponding MISSING: annotations from imports.py.

Verified: all 24 ControlFlow/evaluation-order tests still pass.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-05-12 12:35:47 +00:00
Copilot
0742e1e901 Python: wire parameters into the shared CFG (C# pattern)
Implements `AstSig::Parameter` and `callableGetParameter(c, i)` in
`AstNodeImpl.qll`, following the C# template
(`csharp/.../ControlFlowGraph.qll:147-156`) rather than Java's
`Parameter() { none() }`.

Each Python parameter (positional, *args, keyword-only, **kwargs) now
becomes a CFG node at a stable position in the enclosing callable's
entry sequence. Defaults still evaluate at function-definition time
via `FunctionDefExpr.getDefault` / `LambdaExpr.getDefault`, so
`Parameter::getDefaultValue()` returns `none()` (the shared CFG
library calls this to model the missing-argument fallback, which
Python does not surface at the CFG level).

The bindings test now exercises parameters (the `py_expr_contexts(_, 4, ...)`
exclusion has been removed). A new `parameters.py` test case covers
positional, defaulted, vararg, kwarg, keyword-only, kitchen-sink,
method (self/cls), lambda, and PEP 570 positional-only parameters.
Several other test files were updated to annotate parameters that the
test had previously hidden (synthetic `.0` comprehension parameter,
method `self`, decorator `f`, etc.).

Verified:
- All 24 ControlFlow/evaluation-order tests still pass.
- CFG consistency query (`python/ql/consistency-queries/CfgConsistency.ql`)
  shows zero violations on CPython.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-05-12 12:29:28 +00:00
Copilot
a20af3cf41 Python: wire AnnAssign into the shared CFG (green)
Adds an `AnnAssignStmt` wrapper in `AstNodeImpl.qll` so that PEP 526
annotated assignments (`x: int = 1`, `x: int`) participate in the
control flow graph. Evaluation order follows CPython: annotation,
optional value, target binding.

Without this, `x: int = 1` had no CFG node for `x` even though
`Name.defines(v)` returns true for it on the AST side. SSA built on
the new CFG would therefore miss every annotated-assignment write.

Removes the corresponding MISSING: annotations from the CFG-binding
gap test:
- annassign.py — all four cases now green.
- match_pattern.py — class-body annotated fields (`x: int`, `y: int`).
- type_params.py — `item: T` inside class.

Verified: all 24 ControlFlow/evaluation-order tests still pass.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-05-12 12:22:57 +00:00
Copilot
f077e7c27c Python: add CFG-binding gap tests (red)
Adds inline-expectation tests for the new shared CFG implementation in
python/ql/lib/semmle/python/controlflow/internal/AstNodeImpl.qll,
covering every Python binding construct that introduces a variable.

The test files use MISSING: annotations to record bindings whose
defining Name AST node is *not* currently reachable from the new CFG.
These are the 'red' half of red-green commit pairs: subsequent commits
will extend AstNodeImpl to cover each construct and remove the
corresponding MISSING: marker.

Confirmed-broken categories:
- Import aliases (from x import a)
- Annotated assignment (x: int = 1)
- Exception handler (except E as e)
- Match patterns (case x, case [a,b], case ... as v)
- PEP 695 type params (def f[T], class C[T])

Confirmed-working (no MISSING:):
- Compound targets, with-as, comprehensions, decorated def/class,
  walrus, starred.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-05-12 12:19:34 +00:00
Copilot
e816ba61ec Python: project via as* helpers outside characteristic predicates
Style cleanup: avoid naming newtype branch constructors (TPyStmt,
TPyExpr, TBlockStmt, TPattern, TBoolExprPair, TScope) outside the
char-preds that classify their wrappers. Method bodies and helper
predicates now use the as* projections instead:

  // Before: result = TBlockStmt(ifStmt.getBody())
  // After:  result.asStmtList() = ifStmt.getBody()

  // Before: result = TPyStmt(matchStmt.getCase(index))
  // After:  result.asStmt() = matchStmt.getCase(index)

Adds:

- AstNode.asStmtList() - the inverse of TBlockStmt(_).
- BinaryExpr.getIndex() - exposes the synthetic-pair index, used
  internally by getRightOperand to find the next pair without
  naming TBoolExprPair.

No behaviour change: all 24 NewCfg evaluation-order tests pass; all
11 shared-CFG consistency queries report 0 violations on CPython.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-05-07 20:00:55 +00:00
Copilot
3e0ae6ea3c Python: use newtype-branch constructors in characteristic predicates
Style cleanup: when a class's characteristic predicate binds via a
'cast' helper like

  IfStmt() { ifStmt = this.asStmt() }

prefer naming the newtype branch directly:

  IfStmt() { this = TPyStmt(ifStmt) }

This makes the wrapped representation explicit. Apply throughout:
~30 charpreds (every Stmt/Expr leaf wrapper, plus LoopStmt, BreakStmt,
ContinueStmt, BooleanLiteral, UnaryExpr, ArithUnaryExpr, Comprehension).

Method bodies that use asStmt/asExpr to project an underlying
Python AST node (Stmt.toString, BlockStmt.getEnclosingCallable,
UnaryExpr.getOperand, etc.) keep that form - they're projections,
not classifications.

No behaviour change: all 24 NewCfg evaluation-order tests pass; all
11 shared-CFG consistency queries report 0 violations on CPython.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-05-07 19:51:38 +00:00
Copilot
7fefacd56f Python: introduce TExpr union via newtype-branch alias
Mirror the TStmt refactor for the Expr hierarchy: rename the TExpr
newtype branch to TPyExpr and add

  private class TExpr = TPyExpr or TBoolExprPair;

This lets the public Expr class use TExpr directly:

  class Expr extends AstNodeImpl, TExpr { ... }

instead of

  class Expr extends AstNodeImpl {
    Expr() { this instanceof TExpr or this instanceof TBoolExprPair }
    ...
  }

No behaviour change: all 24 NewCfg evaluation-order tests pass; all
11 shared-CFG consistency queries report 0 violations on CPython.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-05-07 19:33:33 +00:00
Copilot
b682877968 Python: simplify TBlockStmt char pred via exclusion list
Replace the 14-disjunct allow-list with a 2-conjunct exclusion list.
Of the 17 Py::StmtList getters in AstGenerated.qll, only Try.getHandlers()
and MatchStmt.getCases() should not be wrapped as BlockStmts (they are
iterated individually by the shared library's Try/Switch logic via
getCatch(int) and getCase(int)). All other StmtLists are imperative
block bodies.

No behaviour change: all 24 NewCfg evaluation-order tests pass; all
11 shared-CFG consistency queries report 0 violations on CPython.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-05-07 17:13:50 +00:00
Copilot
c9445f74c2 Python: introduce TStmt union via newtype-branch alias
Rename the TStmt newtype branch to TPyStmt, and add a private union
type alias

  private class TStmt = TPyStmt or TBlockStmt;

This lets the public Stmt class use TStmt directly in its extends
clause:

  class Stmt extends AstNodeImpl, TStmt { ... }

instead of the previous

  class Stmt extends AstNodeImpl {
    Stmt() { this instanceof TStmt or this instanceof TBlockStmt }
    ...
  }

The same pattern is used in cpp/.../TInstruction.qll and
rust/.../Synth.qll.

No behaviour change: all 24 NewCfg evaluation-order tests pass; all
11 shared-CFG consistency queries report 0 violations on CPython.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-05-07 17:08:10 +00:00
Copilot
ed1709eb4a Python: use private-abstract + final-alias pattern for AstNode
Convert AstNode from a concrete class with empty default predicates into
a private abstract class plus a final alias, matching the pattern used
in cpp/.../EdgeKind.qll and cpp/.../IRVariable.qll:

  abstract private class AstNodeImpl extends TAstNode {
    abstract string toString();
    abstract Py::Location getLocation();
    abstract Callable getEnclosingCallable();
    ...
  }

  final class AstNode = AstNodeImpl;

This makes the compiler enforce that every concrete subclass implements
toString/getLocation/getEnclosingCallable, replacing the brittle
'empty default + per-branch override' arrangement. Sister classes
inside the module now extend AstNodeImpl instead of AstNode (which is
final and cannot be extended).

The empty Parameter stub gains explicit none() overrides for the
three abstract members, since QL requires them statically even when
the class has no instances.

No behaviour change: all 24 NewCfg evaluation-order tests pass; all
11 shared-CFG consistency queries report 0 violations on CPython.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-05-07 16:58:43 +00:00
Copilot
00c742f5ff Python: document why Assignment subclasses are empty
Explain that the shared library's Assignment / CompoundAssignment
hierarchy extends BinaryExpr, so it cannot host Python's statement-
level assignment forms (Assign, AugAssign), and that Python has no
short-circuiting compound operators (&&=, ||=, ??=) so all
subclasses remain empty.

No behaviour change; doc comments only.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-05-07 14:14:16 +00:00
Copilot
06e9bbc3a6 Python: index TBlockStmt by Py::StmtList instead of (parent, slot)
Replace the two-key TBlockStmt(Py::AstNode parent, string slot) newtype
branch with the simpler TBlockStmt(Py::StmtList sl). Each Py::StmtList
that represents an imperative block (function/class/module body, if/
while/for branch, try/except/finally body, case body, except/except*
body) becomes one BlockStmt directly. The slot string disappears;
toString just defers to Py::StmtList.toString() ('StmtList').

The newtype branch keeps an explicit characteristic predicate listing
the slots that count as block bodies. This excludes Try.getHandlers(),
which is a Py::StmtList of ExceptStmt items already iterated by the
shared library's Try logic via getCatch(int) - including it would
produce parallel CFG edges (verified: a permissive
TBlockStmt(Py::StmtList sl) version regressed CPython to 1720
multipleSuccessors and 584 deadEnds before this restriction).

Drops the getBodyStmtList helper. Caller sites now use the StmtList
accessor directly: TBlockStmt(ifStmt.getBody()),
TBlockStmt(tryStmt.getFinalbody()), etc.

No behaviour change: all 24 NewCfg evaluation-order tests pass; all
11 shared-CFG consistency queries report 0 violations on CPython.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-05-07 12:54:02 +00:00
Copilot
250b63c216 Python: unify Py::BoolExpr handling via TBoolExprPair
Previously a Py::BoolExpr appeared in two newtype branches: as TExpr(be)
(the outermost pair) and TBoolExprPair(be, i) for inner pairs of 3+
operand expressions. This forced BinaryExpr/LogicalAndExpr/LogicalOrExpr
to disjoin two cases, and the synthetic-pair handling spanned multiple
layers.

Restrict TExpr to non-BoolExpr Py::Expr, and extend TBoolExprPair to
cover every operand pair (index 0..n-2). Now every Py::BoolExpr is
represented uniformly as TBoolExprPair(_, 0) for the whole expression
and TBoolExprPair(_, i) for inner pairs.

Extend AstNode.asExpr() to also recover the underlying Py::BoolExpr
from TBoolExprPair(_, 0). This makes asExpr() the inverse of
construction: every 'result = TExpr(e)' turns into 'result.asExpr() = e',
which works uniformly for BoolExprs and non-BoolExprs alike.

Consequences:

- BinaryExpr now extends TBoolExprPair directly with a single uniform
  rule for left/right operands.
- LogicalAndExpr/LogicalOrExpr are one-line char preds via
  getBoolExpr().
- The private BoolExprPair wrapper class folds into BinaryExpr.
- 60+ leaf wrappers now read 'result.asExpr() = py_expr' instead of
  'result = TExpr(py_expr)'.

No behaviour change: all 24 NewCfg evaluation-order tests pass; all
11 shared-CFG consistency queries report 0 violations on CPython.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-05-07 12:04:54 +00:00
Copilot
77e36d3cfa Python: merge T*AstNode wrappers into matching public classes
Five of the six per-newtype-branch wrapper classes had a natural
public class corresponding to that branch:

  TStmtAstNode      -> Stmt        (TStmt subset; BlockStmt overrides for TBlockStmt)
  TExprAstNode      -> Expr        (TExpr subset; BoolExprPair overrides for TBoolExprPair)
  TScopeAstNode     -> Callable    (= TScope exactly)
  TPatternAstNode   -> Pattern     (= TPattern exactly)
  TBlockStmtAstNode -> BlockStmt   (= TBlockStmt exactly)

Move toString/getLocation/getEnclosingCallable onto these classes and
delete the wrappers.

The sixth wrapper (TBoolExprPair) has no exact public counterpart -
BinaryExpr is broader, including TExpr-branch BoolExprs - so it
remains as a small private class, renamed BoolExprPair.

No behaviour change: all 24 NewCfg evaluation-order tests pass; all
11 shared-CFG consistency queries report 0 violations on CPython.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-05-07 11:31:07 +00:00
Copilot
f2151fe232 Python: dispatch toString/getLocation/getEnclosingCallable per branch
Replace the three big disjunctive predicates on AstNode with empty
defaults plus per-newtype-branch override classes:

  AstNode.toString()              { none() }
  AstNode.getLocation()           { none() }
  AstNode.getEnclosingCallable()  { none() }

Six private subclasses (one per newtype branch — TStmt, TExpr,
TScope, TPattern, TBoolExprPair, TBlockStmt) override these with
the branch-specific implementation. This mirrors the per-class
dispatch already used for getChild.

No behaviour change: all 24 NewCfg evaluation-order tests pass and
all 11 shared-CFG consistency queries still report 0 violations on
CPython.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-05-07 11:06:40 +00:00
Copilot
9781ee8d66 Python: adapt to new shared CFG signature
Main added two new requirements to AstSig:
- A 'Parameter' class with a 'getDefaultValue()' method, plus a
  'callableGetParameter(Callable, int)' predicate.
- A 'CallableContext' class in InputSig1, replacing the previous
  'CallableBodyPartContext'.

Add stub implementations: 'Parameter' is empty (none()) and
'callableGetParameter' returns nothing, mirroring Java's TODO. Rename
'CallableBodyPartContext = Void' to 'CallableContext = Void' in the
Python Input module.

NewCfg evaluation-order tests still pass at the 22/24 baseline; all
11 shared-CFG consistency queries still report 0 violations on
CPython.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-05-05 15:26:20 +00:00
Copilot
03b8e8fdde Python: refactor getChild into per-class OO dispatch
Replace the single ~240-line top-level getChild predicate with one
override per AST class. AstNode declares a default

  AstNode getChild(int index) { none() }

and each subclass with children overrides it (41 classes total).
The top-level predicate becomes a one-line dispatch:

  AstNode getChild(AstNode n, int index) { result = n.getChild(index) }

No behavioral change: NewCfg evaluation-order tests still pass at the
same 22/24 baseline, and all 11 shared-CFG consistency queries still
report 0 violations on CPython.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-05-05 15:21:43 +00:00
Copilot
93112b2b75 Python: include try-else in getChild for completion propagation
The shared CFG library propagates abrupt completions from child to
parent via getChild(parent, _) = child. Python's try.getElse() was
wired into normal step rules but not listed in getChild(TryStmt, ...),
so return/break/continue/raise statements occurring inside a try-else
block had no parent path and ended up as dead-end CFG nodes.

Add the else block at index -2 (alongside finally at -1). This affects
only completion propagation; the normal-flow CFG is unchanged because
TryStmt has explicit step rules.

Verified on a CPython database: all 11 shared-CFG consistency queries
now pass with 0 violations (deadEnd: 244 -> 0).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-05-05 15:21:43 +00:00
Copilot
76724c5391 Shared CFG: support for-else and while-else loops
Add two default predicates to AstSig:

  default AstNode getWhileElse(WhileStmt loop) { none() }
  default AstNode getForeachElse(ForeachStmt loop) { none() }

When defined, the explicit-step rules for While/Do and Foreach
route the loop's normal-completion exits through the else block
before reaching the after-loop node:

  - WhileStmt: after-false condition -> before-else -> after-while
    (instead of directly after-while).
  - ForeachStmt: after-collection [empty] and the LoopHeader exit
    are both routed through before-else -> after-foreach.

Python's Ast module overrides the predicates to return the
synthetic BlockStmt for the orelse slot, replacing the previous
customisations in Input::step. This eliminates parallel direct
successors emitted by the previous Python-side step additions
(verified: multipleSuccessors on a CPython database goes from
1340 to 0).

Java and C# CFG tests are unaffected.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-05-05 15:21:43 +00:00
Copilot
edfe91832b Python: compact-renumber FunctionExpr/Lambda defaults
`Args.getDefault(int)` and `Args.getKwDefault(int)` are indexed by
argument position (with gaps for args without defaults), not by
default position. The CFG `getChild` predicate for FunctionDefExpr
and LambdaExpr therefore had gaps at low indices and collisions
where defaults and kwdefaults overlapped, producing parallel
edges before the FunctionExpr.

Use `rank` to compact-renumber `getDefault(n)` and `getKwDefault(n)`
in source order. Verified on a CPython database: removes ~536
`multipleSuccessors` consistency results (1340 -> 804); the rest are
`for/else` and `while/else`.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-05-05 15:21:43 +00:00
Copilot
58cda914db Python: collapse two-layer AstNodeImpl into a single Ast module
Merge the previous `Ast` and `AstSigImpl` modules into a single
`module Ast implements AstSig<Py::Location>`. Classes now use the
signature names (IfStmt, WhileStmt, ForeachStmt, etc.) and signature
predicates (getCondition, getThen, getElse, etc.) directly, with no
intermediate renaming layer.

Drop the TStmtListNode newtype branch entirely. Replace it with a
synthetic TBlockStmt(parent, slot) keyed by a parent AST node and a
slot label string ('body', 'orelse', 'finally'). Py::StmtList no
longer appears in the newtype; the BlockStmt class provides indexed
access to the underlying body items via getStmt(n).

All 22 of 24 evaluation-order tests still pass; the same 2
comprehension-related failures predate this refactor.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-05-05 15:21:43 +00:00
yoff
0b4a24884f python: add consistency checks
Co-authored-by: aschackmull <aschackmull@github.com>
2026-05-05 15:21:42 +00:00
yoff
3b0abad701 Python: add pattern nodes
Co-authored-by: Copilot <copilot@github.com>
2026-05-05 15:21:42 +00:00
Taus
68b3d57563 Cleanup, printCFG
Co-authored-by: yoff <yoff@github.com>
2026-05-05 15:21:42 +00:00
Taus
a33b49a3f3 WIP2 2026-05-05 15:21:42 +00:00
Taus
1af415bec3 WIP 2026-05-05 15:21:42 +00:00
Taus
e3155ea544 Python: Handle dict unpacking in calls
Co-authored-by: yoff <yoff@github.com>
2026-05-05 15:21:42 +00:00
Taus
04b8c4bc7e Python: Fix exception issue
Co-authored-by: yoff <yoff@github.com>
2026-05-05 15:21:42 +00:00
Taus
f85b532bb3 Python: Fix match
Co-authored-by: yoff <yoff@github.com>
2026-05-05 15:21:42 +00:00
Taus
0e1f1d9f09 Python: Support match
Co-authored-by: yoff <yoff@github.com>
2026-05-05 15:21:42 +00:00
Taus
53da31bd15 Python: More nodes
Not entirely sure about the `else:` blocks.

Co-authored-by: yoff <yoff@github.com>
2026-05-05 15:21:42 +00:00
Taus
1f82dbc583 Python: Comprehensions
Co-authored-by: yoff <yoff@github.com>
2026-05-05 15:21:41 +00:00
Taus
b229066891 Python: Add with
Co-authored-by: yoff <yoff@github.com>
2026-05-05 15:21:41 +00:00
Taus
0acbb12fb9 Python: More simple statements
Co-authored-by: yoff <yoff@github.com>
2026-05-05 15:21:41 +00:00
Taus
542efce4a6 Python: assignments
Co-authored-by: yoff <yoff@github.com>
2026-05-05 15:21:41 +00:00
Taus
2db400aebd Python: Attributes
Co-authored-by: yoff <yoff@github.com>
2026-05-05 15:21:41 +00:00
Taus
66bbb60614 Python: Function calls
Co-authored-by: yoff <yoff@github.com>
2026-05-05 15:21:41 +00:00
Taus
971beb2d89 Python: Assert statements
Co-authored-by: yoff <yoff@github.com>
2026-05-05 15:21:41 +00:00
Taus
ea204ac75f Python: Support various literals
Co-authored-by: yoff <yoff@github.com>
2026-05-05 15:21:41 +00:00
Taus
3be562929a Python: Ignore synthetic CFG nodes
We can only annotate the ones that correspond directly to AST nodes
anyway.

Co-authored-by: yoff <yoff@github.com>
2026-05-05 15:21:41 +00:00
Taus
dc0344e2fc Python: More AstNodeImpl improvements
Co-authored-by: yoff <yoff@github.com>
2026-05-05 15:21:41 +00:00
Taus
2ed75e7ca7 Python: Instantiate CFG tests with new CFG library
Co-authored-by: yoff <yoff@github.com>
2026-05-05 15:21:40 +00:00
Taus
9974584102 Python: Instantiate CFG module fully
Co-authored-by: yoff <yoff@github.com>
2026-05-05 15:21:40 +00:00
Taus
6086b999f6 Python: Use fields everywhere in new AST classes
Co-authored-by: yoff <yoff@github.com>
2026-05-05 15:21:40 +00:00
Taus
d62e116fc2 Python: First stab at shared control-flow 2026-05-05 15:21:40 +00:00
Taus
4582855de1 Python: Make CFG tests parameterised
Currently we only instantiate them with the old CFG library, but in the
future we'll want to do this with the new library as well.

Co-authored-by: yoff <yoff@github.com>
2026-05-05 15:21:40 +00:00
Taus
ba29e7e34d Python: Add ConsecutiveTimestamps test
This one is potentially a bit iffy -- it checks for a very powerful
propetry (that implies many of the other queries), but as the test
results show, it can produce false positives when there is in fact no
problem. We may want to get rid of it entirely, if it becomes too noisy.
2026-05-05 15:21:40 +00:00
Taus
f97bf38f3b Python: Add NeverReachable test
This looks for nodes annotated with `t.never` in the test that are
reachable in the CFG. This should not happen (it messes with various
queries, e.g. the "mixed returns" query), but the test shows that in a
few particular cases (involving the `match` statement where all cases
contain `return`s), we _do_ have reachable nodes that shouldn't be.
2026-05-05 15:21:40 +00:00
Taus
a8d136d3d6 Python: Add BasicBlockOrdering test
This one demonstrates a bug in the current CFG. In a dictionary
comprehension `{k: v for k, v in d.items()}`, we evaluate the value
before the key, which is incorrect. (A fix for this bug has been
implemented in a separate PR.)
2026-05-05 15:21:40 +00:00
Taus
710a43ac7f Python: Add some CFG-validation queries
These use the annotated, self-verifying test files to check various
consistency requirements.

Some of these may be expressing the same thing in different ways, but
it's fairly cheap to keep them around, so I have not attempted to
produce a minimal set of queries for this.
2026-05-05 15:21:40 +00:00
Taus
3402d0eaeb Python: Add self-validating CFG tests
These tests consist of various Python constructions (hopefully a
somewhat comprehensive set) with specific timestamp annotations
scattered throughout. When the tests are run using the Python 3
interpreter, these annotations are checked and compared to the "current
timestamp" to see that they are in agreement. This is what makes the
tests "self-validating".

There are a few different kinds of annotations: the basic `t[4]` style
(meaning this is executed at timestamp 4), the `t.dead[4]` variant
(meaning this _would_ happen at timestamp 4, but it is in a dead
branch), and `t.never` (meaning this is never executed at all).

In addition to this, there is a query, MissingAnnotations, which checks
whether we have applied these annotations maximally. Many expression
nodes are not actually annotatable, so there is a sizeable list of
excluded nodes for that query.
2026-05-05 15:21:39 +00:00
Tom Hvitved
4c1461ad5b Merge pull request #21786 from hvitved/inline-test-ignore-tags
Inline test expectations: Rename `tagIsOptional` to `tagIsIgnored`
2026-05-05 09:01:58 +02:00
Anders Schack-Mulligen
b67ebd11e0 Merge pull request #21762 from aschackmull/csharp/ssa2
C#: Replace SSA classes with shared code.
2026-05-04 14:21:01 +02:00
Anders Schack-Mulligen
02f5fe9a42 C#: Address some review comments. 2026-05-04 11:49:24 +02:00
Tom Hvitved
04a8ef0f81 Merge pull request #21777 from hvitved/swift/type-inference-tests
Swift: Add type inference tests
2026-05-04 11:45:32 +02:00
Anders Schack-Mulligen
f663eccf66 Merge pull request #21781 from aschackmull/java/rm-deprecated
Java: Delete old deprecated code.
2026-05-04 11:35:09 +02:00
Tom Hvitved
80ccdcc696 Inline test expectations: Rename tagIsOptional to tagIsIgnored 2026-05-04 11:21:33 +02:00
Tom Hvitved
224934645e Swift: Add type inference tests for key path expressions 2026-05-04 11:00:38 +02:00
Tom Hvitved
038f9a2c2f Swift: Split type inference tests into multiple files 2026-05-04 10:55:06 +02:00
Anders Schack-Mulligen
c7904b12c8 Java: Fix reference in deprecated code. 2026-05-04 10:52:27 +02:00
Anders Schack-Mulligen
17fded4aa5 Java: Delete old deprecated code. 2026-05-04 10:52:27 +02:00
Paolo Tranquilli
77cdafd55e Merge pull request #21785 from github/codeql-spark-run-25308467256
Update changelog documentation site for codeql-cli-2.25.3
2026-05-04 10:42:33 +02:00
Paolo Tranquilli
1c20e78593 Docs: replace build mode: none with build-mode: none 2026-05-04 10:26:50 +02:00
github-actions[bot]
5546025f12 update codeql documentation 2026-05-04 08:19:28 +00:00
Tom Hvitved
1f3a8319ed Update csharp/ql/lib/semmle/code/csharp/dataflow/internal/SsaImpl.qll
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2026-05-04 09:41:00 +02:00
Anders Schack-Mulligen
21a0d1444f C#: Add change note. 2026-05-01 13:13:40 +02:00
Anders Schack-Mulligen
e012981e5b C#: Accept test changes for out/ref SSA location changes. 2026-05-01 10:32:18 +02:00
Anders Schack-Mulligen
351e9cc914 C#: Accept test changes. 2026-05-01 10:28:15 +02:00
Anders Schack-Mulligen
439a67a3fe C#: Fix toString for capture definitions. 2026-05-01 10:26:50 +02:00
Anders Schack-Mulligen
5fbba0e9fe C#: Delete ParameterDefaultDefinition. 2026-05-01 10:24:23 +02:00
Anders Schack-Mulligen
d3df5ce110 C#: Deprecate ParameterDefinition in favour of SsaParameterInit. 2026-05-01 10:22:53 +02:00
Anders Schack-Mulligen
ff8ab191d1 C#: Drop caching for deprecated predicates. 2026-04-30 13:58:55 +02:00
Anders Schack-Mulligen
77807c83f8 C#: Exclude entry definitions from qualifier definitions. 2026-04-30 13:56:21 +02:00
Anders Schack-Mulligen
e0421dbf53 C#: Reinstate toString for SSA data flow nodes. 2026-04-30 13:56:16 +02:00
Anders Schack-Mulligen
bedadc9f04 C#: Deprecate some SSA internals. 2026-04-30 13:54:21 +02:00
Anders Schack-Mulligen
55b83ca22a C#: Deprecate Ssa::Definition in favour of SsaDefinition. 2026-04-30 13:54:20 +02:00
Anders Schack-Mulligen
de96b5acfd C#: Deprecate Ssa::ImplicitDefinition. 2026-04-30 13:54:20 +02:00
Anders Schack-Mulligen
80d5e27b46 C#: Deprecate Ssa::ImplicitEntryDefinition. 2026-04-30 13:54:15 +02:00
Anders Schack-Mulligen
65f647a8c0 C#: Replace Ssa::UncertainDefinition with SsaUncertainWrite. 2026-04-30 13:49:23 +02:00
Anders Schack-Mulligen
9a7eb8dfb9 C#: Replace Ssa::PhiNode with SsaPhiDefinition. 2026-04-30 13:49:23 +02:00
Anders Schack-Mulligen
6ecdf3fe32 C#: Replace Ssa::ImplicitParameterDefinition with SsaParameterInit. 2026-04-30 13:49:19 +02:00
Tom Hvitved
4042bbec5b Swift: Add type inference tests 2026-04-30 13:45:57 +02:00
Anders Schack-Mulligen
31e06bc0a9 C#: Remove SSA location overrides. 2026-04-30 12:56:58 +02:00
Anders Schack-Mulligen
dc34b10cb6 C#: Replace Ssa::ExplicitDefinition with SsaExplicitWrite. 2026-04-30 12:52:51 +02:00
Anders Schack-Mulligen
a6c7f27fc1 C#: Deprecate Definition.getEnclosingCallable. 2026-04-30 12:46:28 +02:00
Anders Schack-Mulligen
ed6cdfc227 C#: Move isLiveOutRefParameterDefinition to top-level. 2026-04-30 12:46:27 +02:00
Anders Schack-Mulligen
9345c44e0f C#: Delete test for Definition.getElement. 2026-04-30 12:46:23 +02:00
Anders Schack-Mulligen
c88a22ccf8 C#: Replace most uses of Ssa::Definition with SsaDefinition. 2026-04-30 12:45:25 +02:00
Anders Schack-Mulligen
2545f06b52 C#: Deprecate member predicate Definition.getAReadAtNode. 2026-04-30 12:42:24 +02:00
Anders Schack-Mulligen
83c7a33e53 C#: Deprecate member predicates Definition.getAFirstRead and getAFirstReadAtNode. 2026-04-30 12:42:21 +02:00
Anders Schack-Mulligen
fb438bf512 C#: Remove references to getAFirstReadAtNode. 2026-04-30 11:55:55 +02:00
Anders Schack-Mulligen
e5d219a039 C#: Simplify library instantiations. 2026-04-30 11:50:59 +02:00
Anders Schack-Mulligen
72d21a9a56 C#: Instantiate shared SSA wrappers. 2026-04-30 11:48:27 +02:00
Anders Schack-Mulligen
7ef9e1b939 C#: Rename SsaImpl input. 2026-04-30 11:46:20 +02:00
369 changed files with 11417 additions and 5559 deletions

View File

@@ -7,7 +7,7 @@
* The "Multiplication result converted to larger type" (`cpp/integer-multiplication-cast-to-long`) query has been upgraded to `high` precision. This query will now run in the default code scanning suite.
* The "Suspicious add with sizeof" (`cpp/suspicious-add-sizeof`) query has been upgraded to `high` precision. This query will now run in the default code scanning suite.
* The "Wrong type of arguments to formatting function" (`cpp/wrong-type-format-argument`) query has been upgraded to `high` precision. This query will now run in the default code scanning suite.
* The "Implicit function declaration" (`cpp/implicit-function-declaration`) query has been upgraded to `high` precision. However, for `build mode: none` databases, it no longer produces any results. The results in this mode were found to be very noisy and fundamentally imprecise.
* The "Implicit function declaration" (`cpp/implicit-function-declaration`) query has been upgraded to `high` precision. However, for `build-mode: none` databases, it no longer produces any results. The results in this mode were found to be very noisy and fundamentally imprecise.
## 1.6.0

View File

@@ -14,7 +14,7 @@ function may behave unpredictably.</p>
<p>This may indicate a misspelled function name, or that the required header containing
the function declaration has not been included.</p>
<p>Note: This query is not compatible with <code>build mode: none</code> databases, and produces
<p>Note: This query is not compatible with <code>build-mode: none</code> databases, and produces
no results on those databases.</p>
</overview>

View File

@@ -18,7 +18,7 @@ import TooManyArguments
import semmle.code.cpp.commons.Exclusions
/*
* This query is not compatible with build mode: none databases, and produces
* This query is not compatible with build-mode: none databases, and produces
* no results on those databases.
*/

View File

@@ -7,4 +7,4 @@
* The "Multiplication result converted to larger type" (`cpp/integer-multiplication-cast-to-long`) query has been upgraded to `high` precision. This query will now run in the default code scanning suite.
* The "Suspicious add with sizeof" (`cpp/suspicious-add-sizeof`) query has been upgraded to `high` precision. This query will now run in the default code scanning suite.
* The "Wrong type of arguments to formatting function" (`cpp/wrong-type-format-argument`) query has been upgraded to `high` precision. This query will now run in the default code scanning suite.
* The "Implicit function declaration" (`cpp/implicit-function-declaration`) query has been upgraded to `high` precision. However, for `build mode: none` databases, it no longer produces any results. The results in this mode were found to be very noisy and fundamentally imprecise.
* The "Implicit function declaration" (`cpp/implicit-function-declaration`) query has been upgraded to `high` precision. However, for `build-mode: none` databases, it no longer produces any results. The results in this mode were found to be very noisy and fundamentally imprecise.

View File

@@ -7,8 +7,8 @@ query predicate localDeclWithSsaDef(LocalVariableDeclExpr d) {
// Local variables in C# must be initialized before every use, so uninitialized
// local variables should not have an SSA definition, as that would imply that
// the declaration is live (can reach a use without passing through a definition)
exists(ExplicitDefinition def |
d = def.getADefinition().(AssignableDefinitions::LocalVariableDefinition).getDeclaration()
exists(SsaExplicitWrite def |
d = def.getDefinition().(AssignableDefinitions::LocalVariableDefinition).getDeclaration()
|
not d = any(ForeachStmt fs).getVariableDeclExpr() and
not d = any(SpecificCatchClause scc).getVariableDeclExpr() and

View File

@@ -64,9 +64,9 @@ No user-facing changes.
* When a code-scanning configuration specifies the `paths:` and/or `paths-ignore:` settings, these are now taken into account by the C# extractor's search for `.config`, `.props`, XML and project files.
* Updated the generated .NET “models as data” runtime models to cover .NET 10.
* C# 14: Support for *implicit* span conversions in the QL library.
* Basic extractor support for .NET 10 is now available. Extraction is supported for .NET 10 projects in both traced mode and `build mode: none`. However, code that uses language features new to C# 14 is not yet fully supported for extraction and analysis.
* Basic extractor support for .NET 10 is now available. Extraction is supported for .NET 10 projects in both traced mode and `build-mode: none`. However, code that uses language features new to C# 14 is not yet fully supported for extraction and analysis.
* Added autobuilder and `build-mode: none` support for `.slnx` solution files.
* In `build mode: none`, .NET 10 is now used by default unless a specific .NET version is specified elsewhere.
* In `build-mode: none`, .NET 10 is now used by default unless a specific .NET version is specified elsewhere.
* Added implicit reads of `System.Collections.Generic.KeyValuePair.Value` at taint-tracking sinks and at inputs to additional taint steps. As a result, taint-tracking queries will now produce more results when a container is tainted.
### Bug Fixes

View File

@@ -0,0 +1,4 @@
---
category: deprecated
---
* The QL classes in the C# SSA library have been renamed to improve consistency between languages. Any custom QL code that makes use of SSA needs to be updated. The old classes have been deprecated and include more detailed migration instructions in their qldoc.

View File

@@ -5,9 +5,9 @@
* When a code-scanning configuration specifies the `paths:` and/or `paths-ignore:` settings, these are now taken into account by the C# extractor's search for `.config`, `.props`, XML and project files.
* Updated the generated .NET “models as data” runtime models to cover .NET 10.
* C# 14: Support for *implicit* span conversions in the QL library.
* Basic extractor support for .NET 10 is now available. Extraction is supported for .NET 10 projects in both traced mode and `build mode: none`. However, code that uses language features new to C# 14 is not yet fully supported for extraction and analysis.
* Basic extractor support for .NET 10 is now available. Extraction is supported for .NET 10 projects in both traced mode and `build-mode: none`. However, code that uses language features new to C# 14 is not yet fully supported for extraction and analysis.
* Added autobuilder and `build-mode: none` support for `.slnx` solution files.
* In `build mode: none`, .NET 10 is now used by default unless a specific .NET version is specified elsewhere.
* In `build-mode: none`, .NET 10 is now used by default unless a specific .NET version is specified elsewhere.
* Added implicit reads of `System.Collections.Generic.KeyValuePair.Value` at taint-tracking sinks and at inputs to additional taint steps. As a result, taint-tracking queries will now produce more results when a container is tainted.
### Bug Fixes

View File

@@ -500,11 +500,7 @@ class AssignableDefinition extends TAssignableDefinition {
*/
pragma[nomagic]
AssignableRead getAFirstRead() {
exists(ControlFlowNode cfn | cfn = result.getControlFlowNode() |
exists(Ssa::ExplicitDefinition def | result = def.getAFirstReadAtNode(cfn) |
this = def.getADefinition()
)
)
exists(SsaExplicitWrite def | result = Ssa::ssaGetAFirstUse(def) | this = def.getDefinition())
}
/** Gets a textual representation of this assignable definition. */

View File

@@ -26,17 +26,7 @@ private module ControlFlowInput implements InputSig<Location, ControlFlowNode, B
class Expr = CS::Expr;
class SourceVariable = Ssa::SourceVariable;
class SsaDefinition = Ssa::Definition;
class SsaExplicitWrite extends SsaDefinition instanceof Ssa::ExplicitDefinition {
Expr getValue() { result = super.getADefinition().getSource() }
}
class SsaPhiDefinition = Ssa::PhiNode;
class SsaUncertainWrite = Ssa::UncertainDefinition;
import Ssa
class GuardValue = Guards::GuardValue;

View File

@@ -191,23 +191,7 @@ private module GuardsImpl = SharedGuards::Make<Location, Cfg, GuardsInput>;
class GuardValue = GuardsImpl::GuardValue;
private module LogicInput implements GuardsImpl::LogicInputSig {
class SsaDefinition extends Ssa::Definition {
Expr getARead() { super.getARead() = result }
}
class SsaExplicitWrite extends SsaDefinition instanceof Ssa::ExplicitDefinition {
Expr getValue() { result = super.getADefinition().getSource() }
}
class SsaPhiDefinition extends SsaDefinition instanceof Ssa::PhiNode {
predicate hasInputFromBlock(SsaDefinition inp, BasicBlock bb) {
super.hasInputFromBlock(inp, bb)
}
}
class SsaParameterInit extends SsaDefinition instanceof Ssa::ParameterDefinition {
Parameter getParameter() { result = super.getParameter() }
}
import Ssa
predicate additionalNullCheck(GuardsImpl::PreGuard guard, GuardValue val, Expr e, boolean isNull) {
// Comparison with a non-`null` value, for example `x?.Length > 0`
@@ -586,7 +570,7 @@ class AccessOrCallExpr extends Expr {
* An expression can have more than one SSA qualifier in the presence
* of control flow splitting.
*/
Ssa::Definition getAnSsaQualifier(ControlFlowNode cfn) { result = getAnSsaQualifier(this, cfn) }
SsaDefinition getAnSsaQualifier(ControlFlowNode cfn) { result = getAnSsaQualifier(this, cfn) }
}
private Declaration getDeclarationTarget(Expr e) {
@@ -594,22 +578,22 @@ private Declaration getDeclarationTarget(Expr e) {
result = e.(Call).getTarget()
}
private Ssa::Definition getAnSsaQualifier(Expr e, ControlFlowNode cfn) {
private SsaDefinition getAnSsaQualifier(Expr e, ControlFlowNode cfn) {
e = getATrackedAccess(result, cfn)
or
not e = getATrackedAccess(_, _) and
result = getAnSsaQualifier(e.(QualifiableExpr).getQualifier(), cfn)
}
private AssignableAccess getATrackedAccess(Ssa::Definition def, ControlFlowNode cfn) {
result = def.getAReadAtNode(cfn)
private AssignableAccess getATrackedAccess(SsaDefinition def, ControlFlowNode cfn) {
result = def.getARead() and cfn = result.getControlFlowNode()
or
result = def.(Ssa::ExplicitDefinition).getADefinition().getTargetAccess() and
result = def.(SsaExplicitWrite).getDefinition().getTargetAccess() and
cfn = def.getControlFlowNode()
}
private predicate ssaMustHaveValue(Expr e, GuardValue v) {
exists(Ssa::Definition def, BasicBlock bb |
exists(SsaDefinition def, BasicBlock bb |
e = def.getARead() and
e.getBasicBlock() = bb and
Guards::ssaControls(def, bb, v)
@@ -841,14 +825,12 @@ module Internal {
)
or
e =
any(Ssa::Definition def |
forex(Ssa::Definition u | u = def.getAnUltimateDefinition() | nullDef(u))
any(SsaDefinition def |
forex(SsaDefinition u | u = def.getAnUltimateDefinition() | nullDef(u))
).getARead()
}
private predicate nullDef(Ssa::ExplicitDefinition def) {
nullValueImplied(def.getADefinition().getSource())
}
private predicate nullDef(SsaExplicitWrite def) { nullValueImplied(def.getValue()) }
predicate nonNullValueImplied(Expr e) {
nonNullValue(e)
@@ -856,14 +838,12 @@ module Internal {
exists(Expr e1 | nonNullValueImplied(e1) and nonNullValueImpliedUnary(e1, e))
or
e =
any(Ssa::Definition def |
forex(Ssa::Definition u | u = def.getAnUltimateDefinition() | nonNullDef(u))
any(SsaDefinition def |
forex(SsaDefinition u | u = def.getAnUltimateDefinition() | nonNullDef(u))
).getARead()
}
private predicate nonNullDef(Ssa::ExplicitDefinition def) {
nonNullValueImplied(def.getADefinition().getSource())
}
private predicate nonNullDef(SsaExplicitWrite def) { nonNullValueImplied(def.getValue()) }
/** A callable that always returns a non-`null` value. */
private class NonNullCallable extends Callable {
@@ -1120,7 +1100,7 @@ module Internal {
private predicate nodeIsGuardedBySameSubExprSsaDef0(
ControlFlowNode cfn, BasicBlock guardedBB, AccessOrCallExpr guarded, Guard g,
ControlFlowNode subCfn, BasicBlock subCfnBB, AccessOrCallExpr sub, GuardValue v,
Ssa::Definition def
SsaDefinition def
) {
nodeIsGuardedBySameSubExpr(cfn, guardedBB, guarded, g, sub, v) and
def = sub.getAnSsaQualifier(subCfn) and
@@ -1130,7 +1110,7 @@ module Internal {
pragma[nomagic]
private predicate nodeIsGuardedBySameSubExprSsaDef(
ControlFlowNode guardedCfn, AccessOrCallExpr guarded, Guard g, ControlFlowNode subCfn,
AccessOrCallExpr sub, GuardValue v, Ssa::Definition def
AccessOrCallExpr sub, GuardValue v, SsaDefinition def
) {
exists(BasicBlock guardedBB, BasicBlock subCfnBB |
nodeIsGuardedBySameSubExprSsaDef0(guardedCfn, guardedBB, guarded, g, subCfn, subCfnBB, sub,
@@ -1149,7 +1129,7 @@ module Internal {
cached
predicate isGuardedByExpr(AccessOrCallExpr guarded, Guard g, AccessOrCallExpr sub, GuardValue v) {
isGuardedByExpr0(guarded, g, sub, v) and
forall(ControlFlowNode subCfn, Ssa::Definition def |
forall(ControlFlowNode subCfn, SsaDefinition def |
nodeIsGuardedBySameSubExprSsaDef(_, guarded, g, subCfn, sub, v, def)
|
def = guarded.getAnSsaQualifier(_)
@@ -1161,7 +1141,7 @@ module Internal {
ControlFlowNodes::ElementNode guarded, Guard g, AccessOrCallExpr sub, GuardValue v
) {
nodeIsGuardedBySameSubExpr(guarded, _, _, g, sub, v) and
forall(ControlFlowNode subCfn, Ssa::Definition def |
forall(ControlFlowNode subCfn, SsaDefinition def |
nodeIsGuardedBySameSubExprSsaDef(guarded, _, g, subCfn, sub, v, def)
|
def =

View File

@@ -67,8 +67,8 @@ class AlwaysNullExpr extends Expr {
exists(AlwaysNullExpr e1, AlwaysNullExpr e2 | G::Internal::nullValueImpliedBinary(e1, e2, this))
or
this =
any(Ssa::Definition def |
forex(Ssa::Definition u | u = def.getAnUltimateDefinition() | nullDef(u))
any(SsaDefinition def |
forex(SsaDefinition u | u = def.getAnUltimateDefinition() | nullDef(u))
).getARead()
or
exists(Callable target |
@@ -80,9 +80,7 @@ class AlwaysNullExpr extends Expr {
}
/** Holds if SSA definition `def` is always `null`. */
private predicate nullDef(Ssa::ExplicitDefinition def) {
def.getADefinition().getSource() instanceof AlwaysNullExpr
}
private predicate nullDef(SsaExplicitWrite def) { def.getValue() instanceof AlwaysNullExpr }
/** An expression that is never `null`. */
class NonNullExpr extends Expr {
@@ -94,8 +92,8 @@ class NonNullExpr extends Expr {
this instanceof G::NullGuardedExpr
or
this =
any(Ssa::Definition def |
forex(Ssa::Definition u | u = def.getAnUltimateDefinition() | nonNullDef(u))
any(SsaDefinition def |
forex(SsaDefinition u | u = def.getAnUltimateDefinition() | nonNullDef(u))
).getARead()
or
exists(Callable target |
@@ -108,10 +106,10 @@ class NonNullExpr extends Expr {
}
/** Holds if SSA definition `def` is never `null`. */
private predicate nonNullDef(Ssa::ExplicitDefinition def) {
def.getADefinition().getSource() instanceof NonNullExpr
private predicate nonNullDef(SsaExplicitWrite def) {
def.getValue() instanceof NonNullExpr
or
exists(AssignableDefinition ad | ad = def.getADefinition() |
exists(AssignableDefinition ad | ad = def.getDefinition() |
ad instanceof AssignableDefinitions::PatternDefinition
or
ad =
@@ -124,13 +122,11 @@ private predicate nonNullDef(Ssa::ExplicitDefinition def) {
}
/**
* Holds if `node` is a dereference `d` of SSA definition `def`.
* Holds if `d` is a dereference of SSA definition `def`.
*/
private predicate dereferenceAt(ControlFlowNode node, Ssa::Definition def, Dereference d) {
d = def.getAReadAtNode(node)
}
private predicate dereferenceAt(SsaDefinition def, Dereference d) { d = def.getARead() }
private predicate isMaybeNullArgument(Ssa::ParameterDefinition def, MaybeNullExpr arg) {
private predicate isMaybeNullArgument(SsaParameterInit def, MaybeNullExpr arg) {
exists(AssignableDefinitions::ImplicitParameterDefinition pdef, Parameter p |
p = def.getParameter()
|
@@ -182,7 +178,7 @@ private predicate hasMultipleParamsArguments(Call c) {
}
/** Holds if `def` is an SSA definition that may be `null`. */
private predicate defMaybeNull(Ssa::Definition def, ControlFlowNode node, string msg, Element reason) {
private predicate defMaybeNull(SsaDefinition def, ControlFlowNode node, string msg, Element reason) {
not nonNullDef(def) and
(
// A variable compared to `null` might be `null`
@@ -190,10 +186,10 @@ private predicate defMaybeNull(Ssa::Definition def, ControlFlowNode node, string
de.guardSuggestsMaybeNull(reason) and
msg = "as suggested by $@ null check" and
node = def.getControlFlowNode() and
not de = any(Ssa::PhiNode phi).getARead() and
not de = any(SsaPhiDefinition phi).getARead() and
// Don't use a check as reason if there is a `null` assignment
// or argument
not def.(Ssa::ExplicitDefinition).getADefinition().getSource() instanceof MaybeNullExpr and
not def.(SsaExplicitWrite).getValue() instanceof MaybeNullExpr and
not isMaybeNullArgument(def, _)
)
or
@@ -207,32 +203,32 @@ private predicate defMaybeNull(Ssa::Definition def, ControlFlowNode node, string
)
or
// If the source of a variable is `null` then the variable may be `null`
exists(AssignableDefinition adef | adef = def.(Ssa::ExplicitDefinition).getADefinition() |
exists(AssignableDefinition adef | adef = def.(SsaExplicitWrite).getDefinition() |
adef.getSource() = maybeNullExpr(node.asExpr()) and
reason = adef.getExpr() and
msg = "because of $@ assignment"
)
or
// A variable of nullable type may be null
exists(Dereference d | dereferenceAt(_, def, d) |
exists(Dereference d | dereferenceAt(def, d) |
node = def.getControlFlowNode() and
d.hasNullableType() and
not def instanceof Ssa::PhiNode and
not def instanceof SsaPhiDefinition and
reason = def.getSourceVariable().getAssignable() and
msg = "because it has a nullable type"
)
)
}
private Ssa::Definition getAPseudoInput(Ssa::Definition def) {
result = def.(Ssa::PhiNode).getAnInput()
private SsaDefinition getAPseudoInput(SsaDefinition def) {
result = def.(SsaPhiDefinition).getAnInput()
}
// `def.getAnUltimateDefinition()` includes inputs into uncertain
// definitions, but we only want inputs into pseudo nodes
private Ssa::Definition getAnUltimateDefinition(Ssa::Definition def) {
private SsaDefinition getAnUltimateDefinition(SsaDefinition def) {
result = getAPseudoInput*(def) and
not result instanceof Ssa::PhiNode
not result instanceof SsaPhiDefinition
}
/**
@@ -240,8 +236,8 @@ private Ssa::Definition getAnUltimateDefinition(Ssa::Definition def) {
* through an intermediate dereference that always throws a null reference
* exception.
*/
private predicate defReaches(Ssa::Definition def, ControlFlowNode cfn) {
exists(def.getAFirstReadAtNode(cfn))
private predicate defReaches(SsaDefinition def, ControlFlowNode cfn) {
Ssa::ssaGetAFirstUse(def).getControlFlowNode() = cfn
or
exists(ControlFlowNode mid | defReaches(def, mid) |
SsaImpl::adjacentReadPairSameVar(_, mid, cfn) and
@@ -250,11 +246,12 @@ private predicate defReaches(Ssa::Definition def, ControlFlowNode cfn) {
}
private module NullnessConfig implements ControlFlowReachability::ConfigSig {
predicate source(ControlFlowNode node, Ssa::Definition def) { defMaybeNull(def, node, _, _) }
predicate source(ControlFlowNode node, SsaDefinition def) { defMaybeNull(def, node, _, _) }
predicate sink(ControlFlowNode node, Ssa::Definition def) {
predicate sink(ControlFlowNode node, SsaDefinition def) {
exists(Dereference d |
dereferenceAt(node, def, d) and
dereferenceAt(def, d) and
node = d.getControlFlowNode() and
not d instanceof NonNullExpr
)
}
@@ -267,11 +264,12 @@ private module NullnessConfig implements ControlFlowReachability::ConfigSig {
private module NullnessFlow = ControlFlowReachability::Flow<NullnessConfig>;
predicate maybeNullDeref(Dereference d, Ssa::SourceVariable v, string msg, Element reason) {
exists(Ssa::Definition origin, Ssa::Definition ssa, ControlFlowNode src, ControlFlowNode sink |
exists(SsaDefinition origin, SsaDefinition ssa, ControlFlowNode src, ControlFlowNode sink |
defMaybeNull(origin, src, msg, reason) and
NullnessFlow::flow(src, origin, sink, ssa) and
ssa.getSourceVariable() = v and
dereferenceAt(sink, ssa, d) and
dereferenceAt(ssa, d) and
sink = d.getControlFlowNode() and
not d.isAlwaysNull(v)
)
}
@@ -322,9 +320,7 @@ class Dereference extends G::DereferenceableExpr {
not p.getAnnotatedType().isNullableRefType()
or
p.fromSource() and
exists(
Ssa::ParameterDefinition def, AssignableDefinitions::ImplicitParameterDefinition pdef
|
exists(SsaParameterInit def, AssignableDefinitions::ImplicitParameterDefinition pdef |
p = def.getParameter()
|
p.getUnboundDeclaration() = pdef.getParameter() and
@@ -334,9 +330,9 @@ class Dereference extends G::DereferenceableExpr {
)
}
private predicate isAlwaysNull0(Ssa::Definition def) {
forall(Ssa::Definition input | input = getAnUltimateDefinition(def) |
input.(Ssa::ExplicitDefinition).getADefinition().getSource() instanceof AlwaysNullExpr
private predicate isAlwaysNull0(SsaDefinition def) {
forall(SsaDefinition input | input = getAnUltimateDefinition(def) |
input.(SsaExplicitWrite).getValue() instanceof AlwaysNullExpr
) and
not nonNullDef(def) and
this = def.getARead() and
@@ -352,7 +348,7 @@ class Dereference extends G::DereferenceableExpr {
// Exclude fields and properties, as they may not have an accurate SSA representation
v.getAssignable() instanceof LocalScopeVariable and
(
forex(Ssa::Definition def0 | this = def0.getARead() | this.isAlwaysNull0(def0))
forex(SsaDefinition def0 | this = def0.getARead() | this.isAlwaysNull0(def0))
or
exists(G::GuardValue nv |
this.(G::GuardedExpr).mustHaveValue(nv) and

View File

@@ -3,12 +3,14 @@
*/
import csharp
private import internal.SsaImpl as SsaImpl
import SsaImpl::Ssa_
/**
* Provides classes for working with static single assignment (SSA) form.
*/
module Ssa {
private import internal.SsaImpl as SsaImpl
import SsaImpl::Ssa_
pragma[nomagic]
private predicate assignableDefinitionLocalScopeVariable(
@@ -72,7 +74,7 @@ module Ssa {
* Gets an SSA definition that has this variable as its underlying
* source variable.
*/
Definition getAnSsaDefinition() { result.getSourceVariable() = this }
SsaDefinition getAnSsaDefinition() { result.getSourceVariable() = this }
}
/** Provides different types of `SourceVariable`s. */
@@ -148,11 +150,49 @@ module Ssa {
}
/**
* Gets a read of the source variable underlying the SSA definition `def`
* that can be reached from `def` without passing through any
* other SSA definition or read. Example:
*
* ```csharp
* int Field;
*
* void SetField(int i) {
* this.Field = i;
* Use(this.Field);
* if (i > 0)
* this.Field = i - 1;
* else if (i < 0)
* SetField(1);
* Use(this.Field);
* Use(this.Field);
* }
* ```
*
* - The read of `i` on line 4 can be reached from the explicit SSA
* definition (wrapping an implicit entry definition) on line 3.
* - The reads of `i` on lines 6 and 7 are not the first reads of any SSA
* definition.
* - The read of `this.Field` on line 5 can be reached from the explicit SSA
* definition on line 4.
* - The read of `this.Field` on line 10 can be reached from the phi node
* between lines 9 and 10.
* - The read of `this.Field` on line 11 is not the first read of any SSA
* definition.
*
* Subsequent reads can be found by following the steps defined by
* `AssignableRead.getANextRead()`.
*/
AssignableRead ssaGetAFirstUse(SsaDefinition def) { SsaImpl::firstReadSameVar(def, result) }
/**
* DEPRECATED: Use `SsaDefinition` instead.
*
* A static single assignment (SSA) definition. Either an explicit variable
* definition (`ExplicitDefinition`), an implicit variable definition
* (`ImplicitDefinition`), or a phi node (`PhiNode`).
*/
class Definition extends SsaImpl::Definition {
deprecated class Definition extends SsaImpl::Definition {
/** Gets the control flow node of this SSA definition. */
final ControlFlowNode getControlFlowNode() {
exists(BasicBlock bb, int i | this.definesAt(_, bb, i) | result = bb.getNode(0.maximum(i)))
@@ -193,9 +233,11 @@ module Ssa {
* - The reads of `this.Field` on lines 10 and 11 can be reached from the phi
* node between lines 9 and 10.
*/
final AssignableRead getARead() { result = this.getAReadAtNode(_) }
final AssignableRead getARead() { result = SsaImpl::getAReadAtNode(this, _) }
/**
* DEPRECATED: Use `getARead()` instead.
*
* Gets a read of the source variable underlying this SSA definition at
* control flow node `cfn` that can be reached from this SSA definition
* without passing through any other SSA definitions. Example:
@@ -222,11 +264,13 @@ module Ssa {
* - The reads of `this.Field` on lines 10 and 11 can be reached from the phi
* node between lines 9 and 10.
*/
final AssignableRead getAReadAtNode(ControlFlowNode cfn) {
deprecated final AssignableRead getAReadAtNode(ControlFlowNode cfn) {
result = SsaImpl::getAReadAtNode(this, cfn)
}
/**
* DEPRECATED: Use `ssaGetAFirstUse` instead.
*
* Gets a read of the source variable underlying this SSA definition that
* can be reached from this SSA definition without passing through any
* other SSA definition or read. Example:
@@ -260,9 +304,11 @@ module Ssa {
* Subsequent reads can be found by following the steps defined by
* `AssignableRead.getANextRead()`.
*/
final AssignableRead getAFirstRead() { result = this.getAFirstReadAtNode(_) }
deprecated final AssignableRead getAFirstRead() { result = this.getAFirstReadAtNode(_) }
/**
* DEPRECATED: Use `ssaGetAFirstUse` instead.
*
* Gets a read of the source variable underlying this SSA definition at
* control flow node `cfn` that can be reached from this SSA definition
* without passing through any other SSA definition or read. Example:
@@ -296,8 +342,8 @@ module Ssa {
* Subsequent reads can be found by following the steps defined by
* `AssignableRead.getANextRead()`.
*/
final AssignableRead getAFirstReadAtNode(ControlFlowNode cfn) {
SsaImpl::firstReadSameVar(this, cfn) and
deprecated final AssignableRead getAFirstReadAtNode(ControlFlowNode cfn) {
SsaImpl::firstReadSameVar(this, result) and
result.getControlFlowNode() = cfn
}
@@ -306,8 +352,8 @@ module Ssa {
* includes inputs to phi nodes and the prior definitions of uncertain writes.
*/
private Definition getAPhiInputOrPriorDefinition() {
result = this.(PhiNode).getAnInput() or
result = this.(UncertainDefinition).getPriorDefinition()
result = this.(SsaPhiDefinition).getAnInput() or
result = this.(SsaUncertainWrite).getPriorDefinition()
}
/**
@@ -341,7 +387,7 @@ module Ssa {
*/
final Definition getAnUltimateDefinition() {
result = this.getAPhiInputOrPriorDefinition*() and
not result instanceof PhiNode
not result instanceof SsaPhiDefinition
}
/**
@@ -353,37 +399,46 @@ module Ssa {
result.(ControlFlowElement).getControlFlowNode() = this.getControlFlowNode()
}
/** Gets the callable to which this SSA definition belongs. */
final Callable getEnclosingCallable() {
/**
* DEPRECATED: Use `getSourceVariable().getEnclosingCallable()` instead.
*
* Gets the callable to which this SSA definition belongs.
*/
deprecated final Callable getEnclosingCallable() {
result = this.getSourceVariable().getEnclosingCallable()
}
/**
* DEPRECATED.
*
* Holds if this SSA definition assigns to `out`/`ref` parameter `p`, and the
* parameter may remain unchanged throughout the rest of the enclosing callable.
*/
final predicate isLiveOutRefParameterDefinition(Parameter p) {
deprecated final predicate isLiveOutRefParameterDefinition(Parameter p) {
SsaImpl::isLiveOutRefParameterDefinition(this, p)
}
/** Gets the location of this SSA definition. */
override Location getLocation() { none() }
}
/**
* DEPRECATED: Use `SsaExplicitWrite` instead.
*
* An SSA definition that corresponds to an explicit assignable definition.
*/
class ExplicitDefinition extends Definition, SsaImpl::WriteDefinition {
deprecated class ExplicitDefinition extends Definition, SsaImpl::WriteDefinition {
AssignableDefinition ad;
ExplicitDefinition() { SsaImpl::explicitDefinition(this, _, ad) }
/**
* DEPRECATED: Use `SsaExplicitWrite.getDefinition()` instead.
*
* Gets an underlying assignable definition. The result is always unique,
* except for pathological `out`/`ref` assignments like `M(out x, out x)`,
* where there may be more than one underlying definition.
*/
final AssignableDefinition getADefinition() { result = SsaImpl::getADefinition(this) }
deprecated final AssignableDefinition getADefinition() {
result = SsaImpl::getADefinition(this)
}
/**
* DEPRECATED.
@@ -444,20 +499,18 @@ module Ssa {
}
override Element getElement() { result = ad.getElement() }
override string toString() { result = "SSA def(" + this.getSourceVariable() + ")" }
override Location getLocation() { result = ad.getLocation() }
}
/**
* DEPRECATED: Use `SsaParameterInit` or `SsaImplicitWrite` instead.
*
* An SSA definition that does not correspond to an explicit variable definition.
* Either an implicit initialization of a variable at the beginning of a callable
* (`ImplicitEntryDefinition`), an implicit definition via a call
* (`ImplicitCallDefinition`), or an implicit definition where the qualifier is
* updated (`ImplicitQualifierDefinition`).
*/
class ImplicitDefinition extends Definition, SsaImpl::WriteDefinition {
deprecated class ImplicitDefinition extends Definition, SsaImpl::WriteDefinition {
ImplicitDefinition() {
exists(BasicBlock bb, SourceVariable v, int i | this.definesAt(v, bb, i) |
SsaImpl::implicitEntryDefinition(bb, v) and
@@ -471,11 +524,13 @@ module Ssa {
}
/**
* DEPRECATED: Use `SsaParameterInit` or `SsaImplicitEntryDefinition` instead.
*
* An SSA definition representing the implicit initialization of a variable
* at the beginning of a callable. Either a local scope variable captured by
* the callable or a field or property accessed inside the callable.
*/
class ImplicitEntryDefinition extends ImplicitDefinition {
deprecated class ImplicitEntryDefinition extends ImplicitDefinition {
ImplicitEntryDefinition() {
exists(BasicBlock bb, SourceVariable v |
this.definesAt(v, bb, -1) and
@@ -487,21 +542,14 @@ module Ssa {
final Callable getCallable() { result = this.getBasicBlock().getEnclosingCallable() }
override Element getElement() { result = this.getCallable() }
override string toString() {
if this.getSourceVariable().getAssignable() instanceof LocalScopeVariable
then result = "SSA capture def(" + this.getSourceVariable() + ")"
else result = "SSA entry def(" + this.getSourceVariable() + ")"
}
override Location getLocation() { result = this.getCallable().getLocation() }
}
deprecated class ImplicitParameterDefinition = ParameterDefinition;
/**
* DEPRECATED: Use `SsaParameterInit` instead.
*/
deprecated final class ImplicitParameterDefinition = SsaImpl::ParameterDefinitionImpl;
final class ParameterDefinition = SsaImpl::ParameterDefinitionImpl;
private class ExplicitParameterDefinition extends ExplicitDefinition,
deprecated private class ExplicitParameterDefinition extends ExplicitDefinition,
SsaImpl::ParameterDefinitionImpl
{
private Parameter p;
@@ -514,28 +562,20 @@ module Ssa {
override string toString() { result = SsaImpl::ParameterDefinitionImpl.super.toString() }
}
/**
* An SSA definition representing the default value of a parameter.
*/
class ParameterDefaultDefinition extends ExplicitDefinition {
private Parameter p;
override AssignableDefinitions::ParameterDefaultDefinition ad;
ParameterDefaultDefinition() { p = ad.getParameter() }
/** Gets the parameter that this entry definition represents. */
Parameter getParameter() { result = p }
override string toString() {
result = "SSA param_default(" + pragma[only_bind_out](this.getParameter()) + ")"
/** An SSA definition in a closure that captures a variable. */
class SsaCapturedDefinition extends SsaImplicitEntryDefinition {
SsaCapturedDefinition() {
this.getSourceVariable().getAssignable() instanceof LocalScopeVariable
}
override string toString() { result = "SSA capture def(" + this.getSourceVariable() + ")" }
}
/**
* An SSA definition representing the potential definition of a variable
* via a call.
*/
class ImplicitCallDefinition extends ImplicitDefinition {
class ImplicitCallDefinition extends SsaImplicitWrite {
private Call c;
ImplicitCallDefinition() {
@@ -562,18 +602,17 @@ module Ssa {
}
override string toString() { result = "SSA call def(" + this.getSourceVariable() + ")" }
override Location getLocation() { result = this.getCall().getLocation() }
}
/**
* An SSA definition representing the potential definition of a variable
* via an SSA definition for the qualifier.
*/
class ImplicitQualifierDefinition extends ImplicitDefinition, SsaImpl::WriteDefinition {
private Definition q;
class ImplicitQualifierDefinition extends SsaImplicitWrite {
private SsaDefinition q;
ImplicitQualifierDefinition() {
not this instanceof SsaImplicitEntryDefinition and
exists(BasicBlock bb, int i, SourceVariables::QualifiedFieldOrPropSourceVariable v |
this.definesAt(v, bb, i)
|
@@ -583,19 +622,19 @@ module Ssa {
}
/** Gets the SSA definition for the qualifier. */
final Definition getQualifierDefinition() { result = q }
final SsaDefinition getQualifierDefinition() { result = q }
override string toString() { result = "SSA qualifier def(" + this.getSourceVariable() + ")" }
override Location getLocation() { result = this.getQualifierDefinition().getLocation() }
}
/**
* DEPRECATED: Use `SsaPhiDefinition` instead.
*
* An SSA phi node, that is, a pseudo definition for a variable at a point
* in the flow graph where otherwise two or more definitions for the variable
* would be visible.
*/
class PhiNode extends Definition, SsaImpl::PhiNode {
deprecated class PhiNode extends Definition, SsaImpl::PhiNode {
/**
* Gets an input of this phi node. Example:
*
@@ -624,27 +663,17 @@ module Ssa {
predicate hasInputFromBlock(Definition inp, BasicBlock bb) {
inp = SsaImpl::phiHasInputFromBlock(this, bb)
}
override string toString() { result = "SSA phi(" + this.getSourceVariable() + ")" }
/*
* The location of a phi node is the same as the location of the first node
* in the basic block in which it is defined.
*
* Strictly speaking, the node is *before* the first node, but such a location
* does not exist in the source program.
*/
override Location getLocation() { result = this.getBasicBlock().getFirstNode().getLocation() }
}
/**
* DEPRECATED: Use `SsaUncertainWrite` instead.
*
* An SSA definition that represents an uncertain update of the underlying
* assignable. Either an explicit update that is uncertain (`ref` assignments
* need not be certain), an implicit non-local update via a call, or an
* uncertain update of the qualifier.
*/
class UncertainDefinition extends Definition, SsaImpl::UncertainWriteDefinition {
deprecated class UncertainDefinition extends Definition, SsaImpl::UncertainWriteDefinition {
/**
* Gets the immediately preceding definition. Since this update is uncertain,
* the value from the preceding definition might still be valid.

View File

@@ -1,9 +1,20 @@
import csharp
private import csharp as CS
/**
* Provides a simple SSA implementation for local scope variables.
*/
module BaseSsa {
private import BaseSsaImpl
class SimpleLocalScopeVariable = BaseSsaImpl::SimpleLocalScopeVariable;
module Ssa = SsaImpl::MakeSsa<SsaInput>;
import Ssa
}
private module BaseSsaImpl {
private import CS
private import AssignableDefinitions
private import codeql.ssa.Ssa as SsaImplCommon
@@ -13,7 +24,7 @@ module BaseSsa {
predicate ref() { any() }
cached
predicate backref() { (exists(any(SsaDefinition def).getARead()) implies any()) }
predicate backref() { (exists(any(BaseSsa::SsaDefinition def).getARead()) implies any()) }
}
/**
@@ -112,11 +123,9 @@ module BaseSsa {
}
}
private module SsaImpl = SsaImplCommon::Make<Location, Cfg, SsaImplInput>;
private module SsaInput implements SsaImpl::SsaInputSig {
private import csharp as CS
module SsaImpl = SsaImplCommon::Make<Location, Cfg, SsaImplInput>;
module SsaInput implements SsaImpl::SsaInputSig {
class Expr = CS::Expr;
class Parameter = CS::Parameter;
@@ -139,8 +148,4 @@ module BaseSsa {
w.isParameterInit(v)
}
}
module Ssa = SsaImpl::MakeSsa<SsaInput>;
import Ssa
}

View File

@@ -270,10 +270,10 @@ module VariableCapture {
private predicate closureFlowStep(ControlFlowNodes::ExprNode e1, ControlFlowNodes::ExprNode e2) {
e1.getExpr() = LocalFlow::getALastEvalNode(e2.getExpr())
or
exists(Ssa::Definition def, AssignableDefinition adef |
exists(SsaDefinition def, AssignableDefinition adef |
LocalFlow::defAssigns(adef, _, _, e1) and
def.getAnUltimateDefinition().(Ssa::ExplicitDefinition).getADefinition() = adef and
exists(def.getAReadAtNode(e2))
def.getAnUltimateDefinition().(SsaExplicitWrite).getDefinition() = adef and
def.getARead().getControlFlowNode() = e2
)
}
@@ -600,8 +600,8 @@ module LocalFlow {
or
ThisFlow::adjacentThisRefs(nodeFrom.(PostUpdateNode).getPreUpdateNode(), nodeTo)
or
exists(AssignableDefinition def, ControlFlowNode cfn, Ssa::ExplicitDefinition ssaDef |
ssaDef.getADefinition() = def and
exists(AssignableDefinition def, ControlFlowNode cfn, SsaExplicitWrite ssaDef |
ssaDef.getDefinition() = def and
ssaDef.getControlFlowNode() = cfn and
nodeFrom = TAssignableDefinitionNode(def, cfn) and
nodeTo.(SsaDefinitionNode).getDefinition() = ssaDef
@@ -1244,7 +1244,7 @@ class SsaNode extends NodeImpl, TSsaNode {
class SsaDefinitionNode extends SsaNode {
override SsaImpl::DataFlowIntegration::SsaDefinitionNode node;
Ssa::Definition getDefinition() { result = node.getDefinition() }
SsaDefinition getDefinition() { result = node.getDefinition() }
override ControlFlowNode getControlFlowNodeImpl() {
result = this.getDefinition().getControlFlowNode()
@@ -1302,12 +1302,6 @@ private module NearestLocationInputParamAfterCallable implements NearestLocation
}
private module ParameterNodes {
pragma[nomagic]
private predicate ssaParamDef(Ssa::ParameterDefinition ssaDef, Parameter p, Location l) {
p = ssaDef.getParameter() and
l = ssaDef.getLocation()
}
private module NearestLocationInputParamBeforeCallable implements NearestLocationInputSig {
class C = Parameter;
@@ -1358,11 +1352,9 @@ private module ParameterNodes {
}
/** Gets the SSA definition corresponding to this parameter, if any. */
Ssa::ParameterDefinition getSsaDefinition() {
exists(Parameter p, Location l |
l = this.getParameterLocation(p) and
ssaParamDef(result, p, l)
)
SsaParameterInit getSsaDefinition() {
result.getParameter() = parameter and
result.getBasicBlock() = callable.getABasicBlock()
}
override predicate isParameterOf(DataFlowCallable c, ParameterPosition pos) {
@@ -1438,7 +1430,7 @@ private module ParameterNodes {
}
/** An implicit entry definition for a captured variable. */
class SsaCapturedEntryDefinition extends Ssa::ImplicitEntryDefinition {
deprecated class SsaCapturedEntryDefinition extends Ssa::ImplicitEntryDefinition {
private LocalScopeVariable v;
SsaCapturedEntryDefinition() { this.getSourceVariable().getAssignable() = v }
@@ -1613,7 +1605,7 @@ private module ReturnNodes {
OutRefReturnNode() {
exists(Parameter p |
this.getDefinition().isLiveOutRefParameterDefinition(p) and
SsaImpl::isLiveOutRefParameterDefinition(this.getDefinition(), p) and
kind.getPosition() = p.getPosition()
|
p.isOut() and kind instanceof OutReturnKind
@@ -2016,12 +2008,9 @@ private class FieldOrPropertyRead extends FieldOrPropertyAccess, AssignableRead
* SSA updates.
*/
predicate hasNonlocalValue() {
exists(Ssa::Definition def, Ssa::ImplicitDefinition idef |
exists(SsaDefinition def |
def.getARead() = this and
idef = def.getAnUltimateDefinition()
|
idef instanceof Ssa::ImplicitEntryDefinition or
idef instanceof Ssa::ImplicitCallDefinition
def.getAnUltimateDefinition() instanceof SsaImplicitWrite
)
}
}
@@ -2220,12 +2209,11 @@ private predicate readContentStep(Node node1, Content c, Node node2) {
c instanceof ElementContent
or
exists(
ForeachStmt fs, Ssa::ExplicitDefinition def,
AssignableDefinitions::LocalVariableDefinition defTo
ForeachStmt fs, SsaExplicitWrite def, AssignableDefinitions::LocalVariableDefinition defTo
|
node1.asExpr() = fs.getIterableExpr() and
defTo.getDeclaration() = fs.getVariableDeclExpr() and
def.getADefinition() = defTo and
def.getDefinition() = defTo and
node2.(SsaDefinitionNode).getDefinition() = def and
c instanceof ElementContent
)

View File

@@ -9,7 +9,7 @@ private import semmle.code.csharp.controlflow.Guards as Guards
private import semmle.code.csharp.dataflow.internal.BaseSSA
private import semmle.code.csharp.internal.Location
private module SsaInput implements SsaImplCommon::InputSig<Location, BasicBlock> {
private module SsaImplInput implements SsaImplCommon::InputSig<Location, BasicBlock> {
class SourceVariable = Ssa::SourceVariable;
/**
@@ -41,15 +41,52 @@ private module SsaInput implements SsaImplCommon::InputSig<Location, BasicBlock>
}
}
import SsaImplCommon::Make<Location, Cfg, SsaInput> as Impl
import SsaImplCommon::Make<Location, Cfg, SsaImplInput> as Impl
private module SsaInput implements Impl::SsaInputSig {
private import csharp as CS
class Expr = CS::Expr;
class Parameter = CS::Parameter;
class VariableWrite extends AssignableDefinition {
Expr asExpr() { result = this.getExpr() }
Expr getValue() { result = this.getSource() }
predicate isParameterInit(Parameter p) { this.(ImplicitParameterDefinition).getParameter() = p }
}
predicate explicitWrite(VariableWrite w, BasicBlock bb, int i, SsaImplInput::SourceVariable v) {
exists(AssignableDefinition ad | variableDefinition(bb, i, v, ad) |
w = ad or
w = getASameOutRefDefAfter(v, ad)
)
or
exists(Parameter p |
implicitEntryDefinition(bb, v) and
i = -1 and
p = v.getAssignable() and
pragma[only_bind_out](p.getCallable()) = pragma[only_bind_out](v.getEnclosingCallable()) and
w.isParameterInit(p)
)
}
}
module Ssa_ = Impl::MakeSsa<SsaInput>;
class Definition = Impl::Definition;
class WriteDefinition = Impl::WriteDefinition;
private class SsaDefinitionToStringProxy extends Definition {
override string toString() { result = this.(SsaDefinition).toString() }
}
class UncertainWriteDefinition = Impl::UncertainWriteDefinition;
deprecated class WriteDefinition = Impl::WriteDefinition;
class PhiNode = Impl::PhiNode;
deprecated class UncertainWriteDefinition = Impl::UncertainWriteDefinition;
deprecated class PhiNode = Impl::PhiNode;
module Consistency = Impl::Consistency;
@@ -791,14 +828,6 @@ private module Cached {
)
}
cached
AssignableDefinition getADefinition(Ssa::ExplicitDefinition def) {
exists(Ssa::SourceVariable v, AssignableDefinition ad | explicitDefinition(def, v, ad) |
result = ad or
result = getASameOutRefDefAfter(v, ad)
)
}
/**
* Holds if `call` may change the value of field or property `fp`. The actual
* update occurs in `setter`.
@@ -815,7 +844,7 @@ private module Cached {
predicate variableWriteQualifier(
BasicBlock bb, int i, QualifiedFieldOrPropSourceVariable v, boolean certain
) {
SsaInput::variableWrite(bb, i, v.getQualifier(), certain) and
SsaImplInput::variableWrite(bb, i, v.getQualifier(), certain) and
// Eliminate corner case where a call definition can overlap with a
// qualifier definition: if method `M` updates field `F`, then a call
// to `M` is both an update of `x.M` and `x.M.M`, so the former call
@@ -824,41 +853,15 @@ private module Cached {
not updatesNamedFieldOrProp(bb, i, _, v, _)
}
cached
predicate explicitDefinition(WriteDefinition def, Ssa::SourceVariable v, AssignableDefinition ad) {
exists(BasicBlock bb, int i |
def.definesAt(v, bb, i) and
variableDefinition(bb, i, v, ad)
)
}
cached
predicate isLiveAtEndOfBlock(Definition def, BasicBlock bb) {
Impl::ssaDefReachesEndOfBlock(bb, def, _)
}
cached
Definition phiHasInputFromBlock(Ssa::PhiNode phi, BasicBlock bb) {
Impl::phiHasInputFromBlock(phi, result, bb)
}
cached
AssignableRead getAReadAtNode(Definition def, ControlFlowNode cfn) {
exists(Ssa::SourceVariable v, BasicBlock bb, int i |
Impl::ssaDefReachesRead(v, def, bb, i) and
variableReadActual(bb, i, v) and
cfn = bb.getNode(i) and
result.getControlFlowNode() = cfn
)
}
/**
* Holds if the value defined at SSA definition `def` can reach a read at `cfn`,
* Holds if the value defined at SSA definition `def` can reach a read `read`,
* without passing through any other read.
*/
cached
predicate firstReadSameVar(Definition def, ControlFlowNode cfn) {
exists(BasicBlock bb, int i | Impl::firstUse(def, bb, i, true) and cfn = bb.getNode(i))
predicate firstReadSameVar(Definition def, AssignableRead read) {
exists(BasicBlock bb, int i |
Impl::firstUse(def, bb, i, true) and read.getControlFlowNode() = bb.getNode(i)
)
}
/**
@@ -876,15 +879,14 @@ private module Cached {
)
}
/**
* Holds if the SSA definition `def` assigns to `out`/`ref` parameter `p`, and the
* parameter may remain unchanged throughout the rest of the enclosing callable.
*/
cached
Definition uncertainWriteDefinitionInput(UncertainWriteDefinition def) {
Impl::uncertainWriteDefinitionInput(def, result)
}
cached
predicate isLiveOutRefParameterDefinition(Ssa::Definition def, Parameter p) {
predicate isLiveOutRefParameterDefinition(SsaDefinition def, Parameter p) {
p.isOutOrRef() and
exists(Ssa::SourceVariable v, Ssa::Definition def0, BasicBlock bb, int i |
exists(Ssa::SourceVariable v, SsaDefinition def0, BasicBlock bb, int i |
v = def.getSourceVariable() and
p = v.getAssignable() and
def = def0.getAnUltimateDefinition() and
@@ -966,6 +968,43 @@ private module Cached {
import Cached
deprecated AssignableDefinition getADefinition(Ssa::ExplicitDefinition def) {
exists(Ssa::SourceVariable v, AssignableDefinition ad | explicitDefinition(def, v, ad) |
result = ad or
result = getASameOutRefDefAfter(v, ad)
)
}
deprecated predicate explicitDefinition(
WriteDefinition def, Ssa::SourceVariable v, AssignableDefinition ad
) {
exists(BasicBlock bb, int i |
def.definesAt(v, bb, i) and
variableDefinition(bb, i, v, ad)
)
}
deprecated predicate isLiveAtEndOfBlock(Definition def, BasicBlock bb) {
Impl::ssaDefReachesEndOfBlock(bb, def, _)
}
deprecated Definition phiHasInputFromBlock(Ssa::PhiNode phi, BasicBlock bb) {
Impl::phiHasInputFromBlock(phi, result, bb)
}
deprecated AssignableRead getAReadAtNode(Definition def, ControlFlowNode cfn) {
exists(Ssa::SourceVariable v, BasicBlock bb, int i |
Impl::ssaDefReachesRead(v, def, bb, i) and
variableReadActual(bb, i, v) and
cfn = bb.getNode(i) and
result.getControlFlowNode() = cfn
)
}
deprecated Definition uncertainWriteDefinitionInput(UncertainWriteDefinition def) {
Impl::uncertainWriteDefinitionInput(def, result)
}
private module DataFlowIntegrationInput implements Impl::DataFlowIntegrationInputSig {
private import codeql.util.Boolean
@@ -973,20 +1012,20 @@ private module DataFlowIntegrationInput implements Impl::DataFlowIntegrationInpu
predicate hasCfgNode(BasicBlock bb, int i) { this = bb.getNode(i) }
}
Expr getARead(Definition def) { exists(getAReadAtNode(def, result)) }
Expr getARead(Definition def) { def.(SsaDefinition).getARead().getControlFlowNode() = result }
predicate ssaDefHasSource(WriteDefinition def) {
predicate ssaDefHasSource(Impl::WriteDefinition def) {
// exclude flow directly from RHS to SSA definition, as we instead want to
// go from RHS to matching assignable definition, and from there to SSA definition
def instanceof Ssa::ParameterDefinition
def instanceof SsaParameterInit
}
/**
* Allows for flow into uncertain defintions that are not call definitions,
* Allows for flow into uncertain definitions that are not call definitions,
* as we, conservatively, consider such definitions to be certain.
*/
predicate allowFlowIntoUncertainDef(UncertainWriteDefinition def) {
def instanceof Ssa::ExplicitDefinition
predicate allowFlowIntoUncertainDef(Impl::UncertainWriteDefinition def) {
def instanceof SsaExplicitWrite
or
def =
any(Ssa::ImplicitQualifierDefinition qdef |
@@ -1011,7 +1050,7 @@ private module DataFlowIntegrationInput implements Impl::DataFlowIntegrationInpu
private module DataFlowIntegrationImpl = Impl::DataFlowIntegration<DataFlowIntegrationInput>;
private module MultiBodyNearestLocationInput implements NearestLocationInputSig {
deprecated private module MultiBodyNearestLocationInput implements NearestLocationInputSig {
class C = MultiBodyParameterDefinition;
predicate relevantLocations(MultiBodyParameterDefinition def, Location l1, Location l2) {
@@ -1025,7 +1064,7 @@ private module MultiBodyNearestLocationInput implements NearestLocationInputSig
}
pragma[nomagic]
private predicate implicitEntryDef(
deprecated private predicate implicitEntryDef(
Ssa::ImplicitEntryDefinition def, Ssa::SourceVariable v, Callable c
) {
v = def.getSourceVariable() and
@@ -1036,7 +1075,7 @@ private predicate implicitEntryDef(
* An SSA definition representing the implicit initialization of a parameter
* at the beginning of a callable.
*/
abstract class ParameterDefinitionImpl extends Ssa::Definition {
abstract deprecated class ParameterDefinitionImpl extends Ssa::Definition {
/** Gets the parameter that this definition represents. */
abstract Parameter getParameter();
@@ -1045,7 +1084,9 @@ abstract class ParameterDefinitionImpl extends Ssa::Definition {
}
}
class MultiBodyParameterDefinition extends ParameterDefinitionImpl, Ssa::ImplicitEntryDefinition {
deprecated class MultiBodyParameterDefinition extends ParameterDefinitionImpl,
Ssa::ImplicitEntryDefinition
{
private Parameter p;
MultiBodyParameterDefinition() {

View File

@@ -9,7 +9,7 @@ module Private {
class SsaVariable = SU::SsaVariable;
class SsaPhiNode = CS::Ssa::PhiNode;
class SsaPhiNode = CS::SsaPhiDefinition;
class Expr = CS::ControlFlowNodes::ExprNode;

View File

@@ -19,7 +19,7 @@ private module Impl {
}
/** Holds if SSA definition `def` equals `e + delta`. */
predicate ssaUpdateStep(ExplicitDefinition def, ExprNode e, int delta) {
predicate ssaUpdateStep(SsaExplicitWrite def, ExprNode e, int delta) {
exists(ControlFlowNode cfn | cfn = def.getControlFlowNode() |
e = cfn.(ExprNode::Assignment).getRightOperand() and
delta = 0 and
@@ -106,7 +106,7 @@ private module Impl {
* - `isEq = true` : `def == e + delta`
* - `isEq = false` : `def != e + delta`
*/
Guard eqFlowCond(Definition def, ExprNode e, int delta, boolean isEq, boolean testIsTrue) {
Guard eqFlowCond(SsaDefinition def, ExprNode e, int delta, boolean isEq, boolean testIsTrue) {
exists(boolean eqpolarity |
result.isEquality(ssaRead(def, delta), e, eqpolarity) and
testIsTrue = [false, true] and

View File

@@ -13,9 +13,9 @@ module Private {
class ConstantIntegerExpr = CU::ConstantIntegerExpr;
class SsaVariable = CS::Ssa::Definition;
class SsaVariable = CS::SsaDefinition;
class SsaPhiNode = CS::Ssa::PhiNode;
class SsaPhiNode = CS::SsaPhiDefinition;
class VarAccess = RU::ExprNode::AssignableAccess;
@@ -35,7 +35,7 @@ module Private {
class Expr = CS::ControlFlowNodes::ExprNode;
class VariableUpdate = CS::Ssa::ExplicitDefinition;
class VariableUpdate = CS::SsaExplicitWrite;
class Field = CS::Field;
@@ -122,46 +122,34 @@ private module Impl {
}
/** Returns the underlying variable update of the explicit SSA variable `v`. */
Ssa::ExplicitDefinition getExplicitSsaAssignment(Ssa::ExplicitDefinition v) { result = v }
SsaExplicitWrite getExplicitSsaAssignment(SsaExplicitWrite v) { result = v }
/** Returns the assignment of the variable update `def`. */
ExprNode getExprFromSsaAssignment(Ssa::ExplicitDefinition def) {
exists(AssignableDefinition adef |
adef = def.getADefinition() and
hasChild(adef.getExpr(), adef.getSource(), def.getControlFlowNode(), result)
)
or
exists(AssignableDefinitions::AssignOperationDefinition adef |
adef = def.getADefinition() and
result.getExpr() = adef.getSource()
)
}
ExprNode getExprFromSsaAssignment(SsaExplicitWrite def) { result.getExpr() = def.getValue() }
/** Holds if `def` can have any sign. */
predicate explicitSsaDefWithAnySign(Ssa::ExplicitDefinition def) {
not exists(def.getADefinition().getSource()) and
not def.getElement() instanceof MutatorOperation
predicate explicitSsaDefWithAnySign(SsaExplicitWrite def) {
not exists(def.getValue()) and
not def.getDefiningExpr() instanceof MutatorOperation
}
/** Returns the operand of the operation if `def` is a decrement. */
ExprNode getDecrementOperand(Ssa::ExplicitDefinition def) {
hasChild(def.getElement(), def.getElement().(DecrementOperation).getOperand(),
def.getControlFlowNode(), result)
ExprNode getDecrementOperand(SsaExplicitWrite def) {
result.getExpr() = def.getDefiningExpr().(DecrementOperation).getOperand()
}
/** Returns the operand of the operation if `def` is an increment. */
ExprNode getIncrementOperand(Ssa::ExplicitDefinition def) {
hasChild(def.getElement(), def.getElement().(IncrementOperation).getOperand(),
def.getControlFlowNode(), result)
ExprNode getIncrementOperand(SsaExplicitWrite def) {
result.getExpr() = def.getDefiningExpr().(IncrementOperation).getOperand()
}
/** Gets the variable underlying the implicit SSA variable `def`. */
Declaration getImplicitSsaDeclaration(Ssa::ImplicitDefinition def) {
Declaration getImplicitSsaDeclaration(SsaImplicitWrite def) {
result = def.getSourceVariable().getAssignable()
}
/** Holds if the variable underlying the implicit SSA variable `def` is not a field. */
predicate nonFieldImplicitSsaDefinition(Ssa::ImplicitDefinition def) {
predicate nonFieldImplicitSsaDefinition(SsaImplicitWrite def) {
not getImplicitSsaDeclaration(def) instanceof Field
}
@@ -245,7 +233,7 @@ private module Impl {
)
}
ExprNode getARead(Ssa::Definition v) { exists(v.getAReadAtNode(result)) }
ExprNode getARead(SsaDefinition v) { v.getARead().getControlFlowNode() = result }
Field getField(ExprNode fa) { result = fa.getExpr().(FieldAccess).getTarget() }

View File

@@ -5,9 +5,9 @@
private import csharp as CS
private import SsaReadPositionCommon
class SsaVariable = CS::Ssa::Definition;
class SsaVariable = CS::SsaDefinition;
class SsaPhiNode = CS::Ssa::PhiNode;
class SsaPhiNode = CS::SsaPhiDefinition;
class BasicBlock = CS::BasicBlock;

View File

@@ -10,24 +10,24 @@ private import ConstantUtils
private class ExprNode = ControlFlowNodes::ExprNode;
/** An SSA variable. */
class SsaVariable extends Definition {
class SsaVariable extends SsaDefinition {
/** Gets a read of this SSA variable. */
ExprNode getAUse() { exists(this.getAReadAtNode(result)) }
ExprNode getAUse() { this.getARead().getControlFlowNode() = result }
}
/** Gets a node that reads `src` via an SSA explicit definition. */
ExprNode getAnExplicitDefinitionRead(ExprNode src) {
exists(ExplicitDefinition def |
exists(def.getAReadAtNode(result)) and
hasChild(def.getElement(), def.getADefinition().getSource(), def.getControlFlowNode(), src)
exists(SsaExplicitWrite def |
def.getARead().getControlFlowNode() = result and
hasChild(def.getDefiningExpr(), def.getValue(), def.getControlFlowNode(), src)
)
}
/**
* Gets an expression that equals `v - delta`.
*/
ExprNode ssaRead(Definition v, int delta) {
exists(v.getAReadAtNode(result)) and delta = 0
ExprNode ssaRead(SsaDefinition v, int delta) {
v.getARead().getControlFlowNode() = result and delta = 0
or
exists(ExprNode::AddOperation add, int d1, ConstantIntegerExpr c |
result = add and
@@ -45,15 +45,15 @@ ExprNode ssaRead(Definition v, int delta) {
delta = d1 + c.getIntValue()
)
or
v.(ExplicitDefinition).getControlFlowNode().(ExprNode::PreIncrExpr) = result and delta = 0
v.(SsaExplicitWrite).getControlFlowNode().(ExprNode::PreIncrExpr) = result and delta = 0
or
v.(ExplicitDefinition).getControlFlowNode().(ExprNode::PreDecrExpr) = result and delta = 0
v.(SsaExplicitWrite).getControlFlowNode().(ExprNode::PreDecrExpr) = result and delta = 0
or
v.(ExplicitDefinition).getControlFlowNode().(ExprNode::PostIncrExpr) = result and delta = 1 // x++ === ++x - 1
v.(SsaExplicitWrite).getControlFlowNode().(ExprNode::PostIncrExpr) = result and delta = 1 // x++ === ++x - 1
or
v.(ExplicitDefinition).getControlFlowNode().(ExprNode::PostDecrExpr) = result and delta = -1 // x-- === --x + 1
v.(SsaExplicitWrite).getControlFlowNode().(ExprNode::PostDecrExpr) = result and delta = -1 // x-- === --x + 1
or
v.(ExplicitDefinition).getControlFlowNode().(ExprNode::Assignment) = result and delta = 0
v.(SsaExplicitWrite).getControlFlowNode().(ExprNode::Assignment) = result and delta = 0
or
result.(ExprNode::AssignExpr).getRightOperand() = ssaRead(v, delta)
}

View File

@@ -20,7 +20,7 @@ import semmle.code.csharp.controlflow.Guards as Guards
import codeql.controlflow.queries.ConstantCondition as ConstCond
module ConstCondInput implements ConstCond::InputSig<BasicBlock> {
class SsaDefinition = Ssa::Definition;
class SsaDefinition = Ssa::SsaDefinition;
class GuardValue = Guards::GuardValue;

View File

@@ -92,7 +92,7 @@ class RelevantDefinition extends AssignableDefinition {
private predicate isMaybeLive() {
exists(LocalVariable v | v = this.getTarget() |
// SSA definitions are only created for live variables
this = any(Ssa::ExplicitDefinition ssaDef).getADefinition()
this = any(SsaExplicitWrite ssaDef).getDefinition()
or
mayEscape(v)
or

View File

@@ -36,17 +36,16 @@ abstract class BadDynamicCall extends DynamicExpr {
}
private Type possibleTypeForRelevantSource(Variable v, int i, Expr source) {
exists(AssignableRead read, Ssa::Definition ssaDef, Ssa::ExplicitDefinition ultimateSsaDef |
exists(AssignableRead read, SsaDefinition ssaDef, SsaExplicitWrite ultimateSsaDef |
read = this.getARelevantVariableAccess(i) and
v = read.getTarget() and
result = source.getType() and
read = ssaDef.getARead() and
ultimateSsaDef = ssaDef.getAnUltimateDefinition()
|
ultimateSsaDef.getADefinition() =
any(AssignableDefinition def | source = def.getSource().stripImplicit())
ultimateSsaDef.getValue().stripImplicit() = source
or
ultimateSsaDef.getADefinition() =
ultimateSsaDef.getDefinition() =
any(AssignableDefinitions::ImplicitParameterDefinition p |
source = p.getParameter().getAnAssignedValue().stripImplicit()
)

View File

@@ -1,13 +1,8 @@
import csharp
from AssignableDefinition def, AssignableRead read, Ssa::Definition ult, Ssa::Definition ssaDef
from AssignableDefinition def, AssignableRead read, SsaDefinition ult, SsaDefinition ssaDef
where
ssaDef.getAnUltimateDefinition() = ult and
(
ult.(Ssa::ExplicitDefinition).getADefinition() = def
or
ult.(Ssa::ParameterDefinition).getParameter() =
def.(AssignableDefinitions::ImplicitParameterDefinition).getParameter()
) and
ult.(SsaExplicitWrite).getDefinition() = def and
read = ssaDef.getARead()
select def, read

View File

@@ -35,23 +35,23 @@
| CSharp7.cs:44:9:44:9 | access to parameter y | CSharp7.cs:44:9:44:13 | SSA def(y) |
| CSharp7.cs:44:13:44:13 | access to parameter x | CSharp7.cs:44:9:44:9 | access to parameter y |
| CSharp7.cs:47:10:47:10 | this | CSharp7.cs:49:9:49:24 | this access |
| CSharp7.cs:49:9:49:24 | SSA def(t1) | CSharp7.cs:51:18:51:19 | access to local variable t1 |
| CSharp7.cs:49:9:49:24 | [post] this access | CSharp7.cs:50:9:50:21 | this access |
| CSharp7.cs:49:9:49:24 | this access | CSharp7.cs:50:9:50:21 | this access |
| CSharp7.cs:49:22:49:23 | SSA def(t1) | CSharp7.cs:51:18:51:19 | access to local variable t1 |
| CSharp7.cs:49:22:49:23 | String t1 | CSharp7.cs:49:22:49:23 | SSA def(t1) |
| CSharp7.cs:49:22:49:23 | String t1 | CSharp7.cs:49:9:49:24 | SSA def(t1) |
| CSharp7.cs:50:9:50:21 | SSA def(t2) | CSharp7.cs:54:14:54:15 | access to local variable t2 |
| CSharp7.cs:50:9:50:21 | [post] this access | CSharp7.cs:52:9:52:17 | this access |
| CSharp7.cs:50:9:50:21 | this access | CSharp7.cs:52:9:52:17 | this access |
| CSharp7.cs:50:19:50:20 | SSA def(t2) | CSharp7.cs:54:14:54:15 | access to local variable t2 |
| CSharp7.cs:50:19:50:20 | String t2 | CSharp7.cs:50:19:50:20 | SSA def(t2) |
| CSharp7.cs:50:19:50:20 | String t2 | CSharp7.cs:50:9:50:21 | SSA def(t2) |
| CSharp7.cs:51:18:51:19 | access to local variable t1 | CSharp7.cs:51:13:51:14 | access to local variable t3 |
| CSharp7.cs:52:9:52:17 | SSA def(t1) | CSharp7.cs:53:14:53:15 | access to local variable t1 |
| CSharp7.cs:52:9:52:17 | [post] this access | CSharp7.cs:55:9:55:32 | this access |
| CSharp7.cs:52:9:52:17 | this access | CSharp7.cs:55:9:55:32 | this access |
| CSharp7.cs:52:15:52:16 | SSA def(t1) | CSharp7.cs:53:14:53:15 | access to local variable t1 |
| CSharp7.cs:52:15:52:16 | access to local variable t1 | CSharp7.cs:52:15:52:16 | SSA def(t1) |
| CSharp7.cs:52:15:52:16 | access to local variable t1 | CSharp7.cs:52:9:52:17 | SSA def(t1) |
| CSharp7.cs:53:14:53:15 | access to local variable t1 | CSharp7.cs:53:9:53:10 | access to local variable t3 |
| CSharp7.cs:54:14:54:15 | access to local variable t2 | CSharp7.cs:54:9:54:10 | access to local variable t3 |
| CSharp7.cs:55:30:55:31 | SSA def(t4) | CSharp7.cs:56:18:56:19 | access to local variable t4 |
| CSharp7.cs:55:30:55:31 | String t4 | CSharp7.cs:55:30:55:31 | SSA def(t4) |
| CSharp7.cs:55:9:55:32 | SSA def(t4) | CSharp7.cs:56:18:56:19 | access to local variable t4 |
| CSharp7.cs:55:30:55:31 | String t4 | CSharp7.cs:55:9:55:32 | SSA def(t4) |
| CSharp7.cs:56:18:56:19 | access to local variable t4 | CSharp7.cs:56:13:56:14 | access to local variable t5 |
| CSharp7.cs:60:7:60:12 | this | CSharp7.cs:60:7:60:12 | this access |
| CSharp7.cs:67:10:67:20 | this | CSharp7.cs:69:26:69:28 | this access |

View File

@@ -1,11 +1,12 @@
import csharp
private import semmle.code.csharp.controlflow.Guards
private import semmle.code.csharp.dataflow.internal.SsaImpl as SsaImpl
private predicate outRefDef(DataFlow::ExprNode ne, int outRef) {
exists(Ssa::ExplicitDefinition def, Parameter outRefParameter |
exists(SsaExplicitWrite def, Parameter outRefParameter |
outRefParameter.isOutOrRef() and
ne.getExpr() = def.getADefinition().getSource() and
def.isLiveOutRefParameterDefinition(outRefParameter) and
ne.getExpr() = def.getValue() and
SsaImpl::isLiveOutRefParameterDefinition(def, outRefParameter) and
outRef = outRefParameter.getPosition()
)
}

View File

@@ -12,6 +12,10 @@ predicate defReaches(
def.(AssignableDefinitions::ImplicitParameterDefinition).getParameter().getControlFlowNode()
].getASuccessor()
or
def.getTarget() = v and
cfn =
def.(AssignableDefinitions::ImplicitParameterDefinition).getEnclosingCallable().getEntryPoint()
or
exists(ControlFlowNode mid | defReaches(def, v, mid) |
not mid =
any(AssignableDefinition ad | ad.getTarget() = v and ad.isCertain())
@@ -29,8 +33,8 @@ predicate defUsePair(AssignableDefinition def, AssignableRead read) {
}
private LocalScopeVariableRead getAReachableUncertainRead(AssignableDefinition def) {
exists(Ssa::Definition ssaDef |
def = ssaDef.getAnUltimateDefinition().(Ssa::ExplicitDefinition).getADefinition()
exists(SsaDefinition ssaDef |
def = ssaDef.getAnUltimateDefinition().(SsaExplicitWrite).getDefinition()
|
result = ssaDef.getARead()
)

View File

@@ -23,8 +23,8 @@ predicate parameterUsePair(Parameter p, AssignableRead read) {
private LocalScopeVariableRead getAReachableUncertainRead(
AssignableDefinitions::ImplicitParameterDefinition p
) {
exists(Ssa::Definition ssaDef |
p.getParameter() = ssaDef.getAnUltimateDefinition().(Ssa::ParameterDefinition).getParameter()
exists(SsaDefinition ssaDef |
p.getParameter() = ssaDef.getAnUltimateDefinition().(SsaParameterInit).getParameter()
|
result = ssaDef.getARead()
)

View File

@@ -25,14 +25,14 @@ predicate useUsePair(LocalScopeVariableRead read1, LocalScopeVariableRead read2)
private newtype TLocalScopeVariableReadOrSsaDef =
TLocalScopeVariableRead(LocalScopeVariableRead read) or
TSsaDefinition(Ssa::Definition ssaDef)
TSsaDefinition(SsaDefinition ssaDef)
private TLocalScopeVariableReadOrSsaDef getANextReadOrDef(TLocalScopeVariableReadOrSsaDef prev) {
exists(LocalScopeVariableRead read | prev = TLocalScopeVariableRead(read) |
result = TLocalScopeVariableRead(read.getANextRead())
or
not exists(read.getANextRead()) and
exists(Ssa::Definition ssaDef, Ssa::PhiNode phi, BasicBlock bb |
exists(SsaDefinition ssaDef, SsaPhiDefinition phi, BasicBlock bb |
ssaDef.getARead() = read and
phi.getAnInput() = ssaDef and
phi.definesAt(_, bb, _) and
@@ -41,11 +41,11 @@ private TLocalScopeVariableReadOrSsaDef getANextReadOrDef(TLocalScopeVariableRea
)
)
or
exists(Ssa::Definition ssaDef | prev = TSsaDefinition(ssaDef) |
result = TLocalScopeVariableRead(ssaDef.getAFirstRead())
exists(SsaDefinition ssaDef | prev = TSsaDefinition(ssaDef) |
result = TLocalScopeVariableRead(Ssa::ssaGetAFirstUse(ssaDef))
or
not exists(ssaDef.getAFirstRead()) and
exists(Ssa::PhiNode phi |
not exists(Ssa::ssaGetAFirstUse(ssaDef)) and
exists(SsaPhiDefinition phi |
phi.getAnInput() = ssaDef and
result = TSsaDefinition(phi)
)

View File

@@ -530,8 +530,8 @@
| LocalDataFlow.cs:385:34:385:34 | SSA param(s) | LocalDataFlow.cs:387:15:387:15 | access to parameter s |
| LocalDataFlow.cs:385:34:385:34 | s | LocalDataFlow.cs:385:34:385:34 | SSA param(s) |
| LocalDataFlow.cs:385:38:385:51 | "taint source" | LocalDataFlow.cs:385:38:385:51 | s = ... |
| LocalDataFlow.cs:385:38:385:51 | SSA param_default(s) | LocalDataFlow.cs:387:15:387:15 | access to parameter s |
| LocalDataFlow.cs:385:38:385:51 | s = ... | LocalDataFlow.cs:385:38:385:51 | SSA param_default(s) |
| LocalDataFlow.cs:385:38:385:51 | SSA def(s) | LocalDataFlow.cs:387:15:387:15 | access to parameter s |
| LocalDataFlow.cs:385:38:385:51 | s = ... | LocalDataFlow.cs:385:38:385:51 | SSA def(s) |
| SSA.cs:3:14:3:16 | this | SSA.cs:3:14:3:16 | this access |
| SSA.cs:5:17:5:17 | SSA entry def(this.S) | SSA.cs:67:9:67:14 | access to field S |
| SSA.cs:5:17:5:17 | this | SSA.cs:67:9:67:12 | this access |
@@ -629,29 +629,29 @@
| SSA.cs:58:16:58:33 | SSA def(ssaSink3) | SSA.cs:59:23:59:30 | access to local variable ssaSink3 |
| SSA.cs:58:27:58:33 | access to parameter tainted | SSA.cs:58:16:58:23 | access to local variable ssaSink3 |
| SSA.cs:58:27:58:33 | access to parameter tainted | SSA.cs:67:32:67:38 | access to parameter tainted |
| SSA.cs:59:23:59:30 | SSA def(ssaSink3) | SSA.cs:60:15:60:22 | access to local variable ssaSink3 |
| SSA.cs:59:23:59:30 | [post] access to local variable ssaSink3 | SSA.cs:59:23:59:30 | SSA def(ssaSink3) |
| SSA.cs:59:23:59:30 | access to local variable ssaSink3 | SSA.cs:59:23:59:30 | SSA def(ssaSink3) |
| SSA.cs:59:23:59:30 | access to local variable ssaSink3 | SSA.cs:59:23:59:30 | SSA def(ssaSink3) |
| SSA.cs:63:23:63:30 | SSA def(nonSink0) | SSA.cs:64:15:64:22 | access to local variable nonSink0 |
| SSA.cs:63:23:63:30 | [post] access to local variable nonSink0 | SSA.cs:63:23:63:30 | SSA def(nonSink0) |
| SSA.cs:63:23:63:30 | access to local variable nonSink0 | SSA.cs:63:23:63:30 | SSA def(nonSink0) |
| SSA.cs:63:23:63:30 | access to local variable nonSink0 | SSA.cs:63:23:63:30 | SSA def(nonSink0) |
| SSA.cs:59:9:59:31 | SSA def(ssaSink3) | SSA.cs:60:15:60:22 | access to local variable ssaSink3 |
| SSA.cs:59:23:59:30 | [post] access to local variable ssaSink3 | SSA.cs:59:9:59:31 | SSA def(ssaSink3) |
| SSA.cs:59:23:59:30 | access to local variable ssaSink3 | SSA.cs:59:9:59:31 | SSA def(ssaSink3) |
| SSA.cs:59:23:59:30 | access to local variable ssaSink3 | SSA.cs:59:9:59:31 | SSA def(ssaSink3) |
| SSA.cs:63:9:63:31 | SSA def(nonSink0) | SSA.cs:64:15:64:22 | access to local variable nonSink0 |
| SSA.cs:63:23:63:30 | [post] access to local variable nonSink0 | SSA.cs:63:9:63:31 | SSA def(nonSink0) |
| SSA.cs:63:23:63:30 | access to local variable nonSink0 | SSA.cs:63:9:63:31 | SSA def(nonSink0) |
| SSA.cs:63:23:63:30 | access to local variable nonSink0 | SSA.cs:63:9:63:31 | SSA def(nonSink0) |
| SSA.cs:67:9:67:12 | [post] this access | SSA.cs:68:23:68:26 | this access |
| SSA.cs:67:9:67:12 | this access | SSA.cs:68:23:68:26 | this access |
| SSA.cs:67:9:67:14 | [post] access to field S | SSA.cs:68:23:68:28 | access to field S |
| SSA.cs:67:9:67:14 | access to field S | SSA.cs:68:23:68:28 | access to field S |
| SSA.cs:67:9:67:28 | access to field SsaFieldSink0 | SSA.cs:67:9:67:38 | SSA def(this.S.SsaFieldSink0) |
| SSA.cs:67:9:67:38 | SSA def(this.S.SsaFieldSink0) | SSA.cs:68:23:68:28 | SSA qualifier def(this.S.SsaFieldSink0) |
| SSA.cs:67:9:67:38 | SSA def(this.S.SsaFieldSink0) | SSA.cs:68:9:68:29 | SSA qualifier def(this.S.SsaFieldSink0) |
| SSA.cs:67:32:67:38 | access to parameter tainted | SSA.cs:67:9:67:28 | access to field SsaFieldSink0 |
| SSA.cs:67:32:67:38 | access to parameter tainted | SSA.cs:77:20:77:26 | access to parameter tainted |
| SSA.cs:68:9:68:29 | SSA def(this.S) | SSA.cs:69:15:69:20 | access to field S |
| SSA.cs:68:9:68:29 | SSA qualifier def(this.S.SsaFieldSink0) | SSA.cs:69:15:69:34 | access to field SsaFieldSink0 |
| SSA.cs:68:23:68:26 | [post] this access | SSA.cs:69:15:69:18 | this access |
| SSA.cs:68:23:68:26 | this access | SSA.cs:69:15:69:18 | this access |
| SSA.cs:68:23:68:28 | SSA def(this.S) | SSA.cs:69:15:69:20 | access to field S |
| SSA.cs:68:23:68:28 | SSA qualifier def(this.S.SsaFieldSink0) | SSA.cs:69:15:69:34 | access to field SsaFieldSink0 |
| SSA.cs:68:23:68:28 | [post] access to field S | SSA.cs:68:23:68:28 | SSA def(this.S) |
| SSA.cs:68:23:68:28 | access to field S | SSA.cs:68:23:68:28 | SSA def(this.S) |
| SSA.cs:68:23:68:28 | access to field S | SSA.cs:68:23:68:28 | SSA def(this.S) |
| SSA.cs:68:23:68:28 | [post] access to field S | SSA.cs:68:9:68:29 | SSA def(this.S) |
| SSA.cs:68:23:68:28 | access to field S | SSA.cs:68:9:68:29 | SSA def(this.S) |
| SSA.cs:68:23:68:28 | access to field S | SSA.cs:68:9:68:29 | SSA def(this.S) |
| SSA.cs:69:15:69:18 | [post] this access | SSA.cs:72:9:72:12 | this access |
| SSA.cs:69:15:69:18 | this access | SSA.cs:72:9:72:12 | this access |
| SSA.cs:69:15:69:20 | [post] access to field S | SSA.cs:72:9:72:14 | access to field S |
@@ -661,15 +661,15 @@
| SSA.cs:72:9:72:14 | [post] access to field S | SSA.cs:73:23:73:28 | access to field S |
| SSA.cs:72:9:72:14 | access to field S | SSA.cs:73:23:73:28 | access to field S |
| SSA.cs:72:9:72:31 | access to field SsaFieldNonSink0 | SSA.cs:72:9:72:36 | SSA def(this.S.SsaFieldNonSink0) |
| SSA.cs:72:9:72:36 | SSA def(this.S.SsaFieldNonSink0) | SSA.cs:73:23:73:28 | SSA qualifier def(this.S.SsaFieldNonSink0) |
| SSA.cs:72:9:72:36 | SSA def(this.S.SsaFieldNonSink0) | SSA.cs:73:9:73:29 | SSA qualifier def(this.S.SsaFieldNonSink0) |
| SSA.cs:72:35:72:36 | "" | SSA.cs:72:9:72:31 | access to field SsaFieldNonSink0 |
| SSA.cs:73:9:73:29 | SSA def(this.S) | SSA.cs:74:15:74:20 | access to field S |
| SSA.cs:73:9:73:29 | SSA qualifier def(this.S.SsaFieldNonSink0) | SSA.cs:74:15:74:37 | access to field SsaFieldNonSink0 |
| SSA.cs:73:23:73:26 | [post] this access | SSA.cs:74:15:74:18 | this access |
| SSA.cs:73:23:73:26 | this access | SSA.cs:74:15:74:18 | this access |
| SSA.cs:73:23:73:28 | SSA def(this.S) | SSA.cs:74:15:74:20 | access to field S |
| SSA.cs:73:23:73:28 | SSA qualifier def(this.S.SsaFieldNonSink0) | SSA.cs:74:15:74:37 | access to field SsaFieldNonSink0 |
| SSA.cs:73:23:73:28 | [post] access to field S | SSA.cs:73:23:73:28 | SSA def(this.S) |
| SSA.cs:73:23:73:28 | access to field S | SSA.cs:73:23:73:28 | SSA def(this.S) |
| SSA.cs:73:23:73:28 | access to field S | SSA.cs:73:23:73:28 | SSA def(this.S) |
| SSA.cs:73:23:73:28 | [post] access to field S | SSA.cs:73:9:73:29 | SSA def(this.S) |
| SSA.cs:73:23:73:28 | access to field S | SSA.cs:73:9:73:29 | SSA def(this.S) |
| SSA.cs:73:23:73:28 | access to field S | SSA.cs:73:9:73:29 | SSA def(this.S) |
| SSA.cs:74:15:74:18 | [post] this access | SSA.cs:80:9:80:12 | this access |
| SSA.cs:74:15:74:18 | this access | SSA.cs:80:9:80:12 | this access |
| SSA.cs:74:15:74:20 | [post] access to field S | SSA.cs:80:9:80:14 | access to field S |
@@ -678,8 +678,8 @@
| SSA.cs:77:9:77:26 | SSA def(nonSink0) | SSA.cs:78:21:78:28 | access to local variable nonSink0 |
| SSA.cs:77:20:77:26 | access to parameter tainted | SSA.cs:77:9:77:16 | access to local variable nonSink0 |
| SSA.cs:77:20:77:26 | access to parameter tainted | SSA.cs:80:35:80:41 | access to parameter tainted |
| SSA.cs:78:21:78:28 | SSA def(nonSink0) | SSA.cs:79:15:79:22 | access to local variable nonSink0 |
| SSA.cs:78:21:78:28 | access to local variable nonSink0 | SSA.cs:78:21:78:28 | SSA def(nonSink0) |
| SSA.cs:78:9:78:29 | SSA def(nonSink0) | SSA.cs:79:15:79:22 | access to local variable nonSink0 |
| SSA.cs:78:21:78:28 | access to local variable nonSink0 | SSA.cs:78:9:78:29 | SSA def(nonSink0) |
| SSA.cs:79:15:79:22 | [post] access to local variable nonSink0 | SSA.cs:102:13:102:33 | [input] SSA phi read(nonSink0) |
| SSA.cs:79:15:79:22 | [post] access to local variable nonSink0 | SSA.cs:104:24:104:31 | access to local variable nonSink0 |
| SSA.cs:79:15:79:22 | access to local variable nonSink0 | SSA.cs:102:13:102:33 | [input] SSA phi read(nonSink0) |
@@ -690,11 +690,11 @@
| SSA.cs:80:9:80:14 | access to field S | SSA.cs:81:21:81:26 | access to field S |
| SSA.cs:80:35:80:41 | access to parameter tainted | SSA.cs:80:9:80:31 | access to field SsaFieldNonSink0 |
| SSA.cs:80:35:80:41 | access to parameter tainted | SSA.cs:83:35:83:41 | access to parameter tainted |
| SSA.cs:81:9:81:27 | SSA def(this.S) | SSA.cs:82:15:82:20 | access to field S |
| SSA.cs:81:9:81:27 | SSA qualifier def(this.S.SsaFieldNonSink0) | SSA.cs:82:15:82:37 | access to field SsaFieldNonSink0 |
| SSA.cs:81:21:81:24 | [post] this access | SSA.cs:82:15:82:18 | this access |
| SSA.cs:81:21:81:24 | this access | SSA.cs:82:15:82:18 | this access |
| SSA.cs:81:21:81:26 | SSA def(this.S) | SSA.cs:82:15:82:20 | access to field S |
| SSA.cs:81:21:81:26 | SSA qualifier def(this.S.SsaFieldNonSink0) | SSA.cs:82:15:82:37 | access to field SsaFieldNonSink0 |
| SSA.cs:81:21:81:26 | access to field S | SSA.cs:81:21:81:26 | SSA def(this.S) |
| SSA.cs:81:21:81:26 | access to field S | SSA.cs:81:9:81:27 | SSA def(this.S) |
| SSA.cs:82:15:82:18 | [post] this access | SSA.cs:83:9:83:12 | this access |
| SSA.cs:82:15:82:18 | this access | SSA.cs:83:9:83:12 | this access |
| SSA.cs:82:15:82:20 | [post] access to field S | SSA.cs:83:9:83:14 | access to field S |
@@ -731,10 +731,10 @@
| SSA.cs:93:21:93:28 | access to local variable ssaSink4 | SSA.cs:97:23:97:30 | access to local variable ssaSink4 |
| SSA.cs:95:21:95:28 | [post] access to local variable ssaSink4 | SSA.cs:97:23:97:30 | access to local variable ssaSink4 |
| SSA.cs:95:21:95:28 | access to local variable ssaSink4 | SSA.cs:97:23:97:30 | access to local variable ssaSink4 |
| SSA.cs:97:23:97:30 | SSA def(ssaSink4) | SSA.cs:98:15:98:22 | access to local variable ssaSink4 |
| SSA.cs:97:23:97:30 | [post] access to local variable ssaSink4 | SSA.cs:97:23:97:30 | SSA def(ssaSink4) |
| SSA.cs:97:23:97:30 | access to local variable ssaSink4 | SSA.cs:97:23:97:30 | SSA def(ssaSink4) |
| SSA.cs:97:23:97:30 | access to local variable ssaSink4 | SSA.cs:97:23:97:30 | SSA def(ssaSink4) |
| SSA.cs:97:9:97:31 | SSA def(ssaSink4) | SSA.cs:98:15:98:22 | access to local variable ssaSink4 |
| SSA.cs:97:23:97:30 | [post] access to local variable ssaSink4 | SSA.cs:97:9:97:31 | SSA def(ssaSink4) |
| SSA.cs:97:23:97:30 | access to local variable ssaSink4 | SSA.cs:97:9:97:31 | SSA def(ssaSink4) |
| SSA.cs:97:23:97:30 | access to local variable ssaSink4 | SSA.cs:97:9:97:31 | SSA def(ssaSink4) |
| SSA.cs:101:16:101:23 | access to local variable nonSink3 | SSA.cs:101:16:101:28 | SSA def(nonSink3) |
| SSA.cs:101:16:101:28 | SSA def(nonSink3) | SSA.cs:110:23:110:30 | access to local variable nonSink3 |
| SSA.cs:101:27:101:28 | "" | SSA.cs:101:16:101:23 | access to local variable nonSink3 |
@@ -755,10 +755,10 @@
| SSA.cs:106:21:106:28 | access to local variable nonSink3 | SSA.cs:110:23:110:30 | access to local variable nonSink3 |
| SSA.cs:108:21:108:28 | [post] access to local variable nonSink3 | SSA.cs:110:23:110:30 | access to local variable nonSink3 |
| SSA.cs:108:21:108:28 | access to local variable nonSink3 | SSA.cs:110:23:110:30 | access to local variable nonSink3 |
| SSA.cs:110:23:110:30 | SSA def(nonSink3) | SSA.cs:111:15:111:22 | access to local variable nonSink3 |
| SSA.cs:110:23:110:30 | [post] access to local variable nonSink3 | SSA.cs:110:23:110:30 | SSA def(nonSink3) |
| SSA.cs:110:23:110:30 | access to local variable nonSink3 | SSA.cs:110:23:110:30 | SSA def(nonSink3) |
| SSA.cs:110:23:110:30 | access to local variable nonSink3 | SSA.cs:110:23:110:30 | SSA def(nonSink3) |
| SSA.cs:110:9:110:31 | SSA def(nonSink3) | SSA.cs:111:15:111:22 | access to local variable nonSink3 |
| SSA.cs:110:23:110:30 | [post] access to local variable nonSink3 | SSA.cs:110:9:110:31 | SSA def(nonSink3) |
| SSA.cs:110:23:110:30 | access to local variable nonSink3 | SSA.cs:110:9:110:31 | SSA def(nonSink3) |
| SSA.cs:110:23:110:30 | access to local variable nonSink3 | SSA.cs:110:9:110:31 | SSA def(nonSink3) |
| SSA.cs:114:9:114:12 | [post] this access | SSA.cs:117:13:117:16 | this access |
| SSA.cs:114:9:114:12 | [post] this access | SSA.cs:123:23:123:26 | this access |
| SSA.cs:114:9:114:12 | this access | SSA.cs:117:13:117:16 | this access |
@@ -768,7 +768,7 @@
| SSA.cs:114:9:114:14 | access to field S | SSA.cs:115:13:115:33 | [input] SSA phi read(this.S) |
| SSA.cs:114:9:114:14 | access to field S | SSA.cs:117:13:117:18 | access to field S |
| SSA.cs:114:9:114:28 | access to field SsaFieldSink1 | SSA.cs:114:9:114:33 | SSA def(this.S.SsaFieldSink1) |
| SSA.cs:114:9:114:33 | SSA def(this.S.SsaFieldSink1) | SSA.cs:123:23:123:28 | SSA qualifier def(this.S.SsaFieldSink1) |
| SSA.cs:114:9:114:33 | SSA def(this.S.SsaFieldSink1) | SSA.cs:123:9:123:29 | SSA qualifier def(this.S.SsaFieldSink1) |
| SSA.cs:114:32:114:33 | "" | SSA.cs:114:9:114:28 | access to field SsaFieldSink1 |
| SSA.cs:115:13:115:22 | [post] access to parameter nonTainted | SSA.cs:115:13:115:33 | [input] SSA phi read(nonTainted) |
| SSA.cs:115:13:115:22 | [post] access to parameter nonTainted | SSA.cs:118:17:118:26 | access to parameter nonTainted |
@@ -794,21 +794,21 @@
| SSA.cs:119:21:119:24 | this access | SSA.cs:123:23:123:26 | this access |
| SSA.cs:119:21:119:26 | [post] access to field S | SSA.cs:123:23:123:28 | access to field S |
| SSA.cs:119:21:119:26 | access to field S | SSA.cs:123:23:123:28 | access to field S |
| SSA.cs:119:21:119:40 | [post] access to field SsaFieldSink1 | SSA.cs:123:23:123:28 | SSA qualifier def(this.S.SsaFieldSink1) |
| SSA.cs:119:21:119:40 | access to field SsaFieldSink1 | SSA.cs:123:23:123:28 | SSA qualifier def(this.S.SsaFieldSink1) |
| SSA.cs:119:21:119:40 | [post] access to field SsaFieldSink1 | SSA.cs:123:9:123:29 | SSA qualifier def(this.S.SsaFieldSink1) |
| SSA.cs:119:21:119:40 | access to field SsaFieldSink1 | SSA.cs:123:9:123:29 | SSA qualifier def(this.S.SsaFieldSink1) |
| SSA.cs:121:21:121:24 | [post] this access | SSA.cs:123:23:123:26 | this access |
| SSA.cs:121:21:121:24 | this access | SSA.cs:123:23:123:26 | this access |
| SSA.cs:121:21:121:26 | [post] access to field S | SSA.cs:123:23:123:28 | access to field S |
| SSA.cs:121:21:121:26 | access to field S | SSA.cs:123:23:123:28 | access to field S |
| SSA.cs:121:21:121:40 | [post] access to field SsaFieldSink1 | SSA.cs:123:23:123:28 | SSA qualifier def(this.S.SsaFieldSink1) |
| SSA.cs:121:21:121:40 | access to field SsaFieldSink1 | SSA.cs:123:23:123:28 | SSA qualifier def(this.S.SsaFieldSink1) |
| SSA.cs:121:21:121:40 | [post] access to field SsaFieldSink1 | SSA.cs:123:9:123:29 | SSA qualifier def(this.S.SsaFieldSink1) |
| SSA.cs:121:21:121:40 | access to field SsaFieldSink1 | SSA.cs:123:9:123:29 | SSA qualifier def(this.S.SsaFieldSink1) |
| SSA.cs:123:9:123:29 | SSA def(this.S) | SSA.cs:124:15:124:20 | access to field S |
| SSA.cs:123:9:123:29 | SSA qualifier def(this.S.SsaFieldSink1) | SSA.cs:124:15:124:34 | access to field SsaFieldSink1 |
| SSA.cs:123:23:123:26 | [post] this access | SSA.cs:124:15:124:18 | this access |
| SSA.cs:123:23:123:26 | this access | SSA.cs:124:15:124:18 | this access |
| SSA.cs:123:23:123:28 | SSA def(this.S) | SSA.cs:124:15:124:20 | access to field S |
| SSA.cs:123:23:123:28 | SSA qualifier def(this.S.SsaFieldSink1) | SSA.cs:124:15:124:34 | access to field SsaFieldSink1 |
| SSA.cs:123:23:123:28 | [post] access to field S | SSA.cs:123:23:123:28 | SSA def(this.S) |
| SSA.cs:123:23:123:28 | access to field S | SSA.cs:123:23:123:28 | SSA def(this.S) |
| SSA.cs:123:23:123:28 | access to field S | SSA.cs:123:23:123:28 | SSA def(this.S) |
| SSA.cs:123:23:123:28 | [post] access to field S | SSA.cs:123:9:123:29 | SSA def(this.S) |
| SSA.cs:123:23:123:28 | access to field S | SSA.cs:123:9:123:29 | SSA def(this.S) |
| SSA.cs:123:23:123:28 | access to field S | SSA.cs:123:9:123:29 | SSA def(this.S) |
| SSA.cs:124:15:124:18 | [post] this access | SSA.cs:127:9:127:12 | this access |
| SSA.cs:124:15:124:18 | this access | SSA.cs:127:9:127:12 | this access |
| SSA.cs:124:15:124:20 | [post] access to field S | SSA.cs:127:9:127:14 | access to field S |
@@ -822,7 +822,7 @@
| SSA.cs:127:9:127:14 | access to field S | SSA.cs:128:13:128:33 | [input] SSA phi read(this.S) |
| SSA.cs:127:9:127:14 | access to field S | SSA.cs:130:13:130:18 | access to field S |
| SSA.cs:127:9:127:31 | access to field SsaFieldNonSink0 | SSA.cs:127:9:127:36 | SSA def(this.S.SsaFieldNonSink0) |
| SSA.cs:127:9:127:36 | SSA def(this.S.SsaFieldNonSink0) | SSA.cs:136:23:136:28 | SSA qualifier def(this.S.SsaFieldNonSink0) |
| SSA.cs:127:9:127:36 | SSA def(this.S.SsaFieldNonSink0) | SSA.cs:136:9:136:29 | SSA qualifier def(this.S.SsaFieldNonSink0) |
| SSA.cs:127:35:127:36 | "" | SSA.cs:127:9:127:31 | access to field SsaFieldNonSink0 |
| SSA.cs:128:13:128:22 | [post] access to parameter nonTainted | SSA.cs:131:17:131:26 | access to parameter nonTainted |
| SSA.cs:128:13:128:22 | access to parameter nonTainted | SSA.cs:131:17:131:26 | access to parameter nonTainted |
@@ -843,21 +843,21 @@
| SSA.cs:132:21:132:24 | this access | SSA.cs:136:23:136:26 | this access |
| SSA.cs:132:21:132:26 | [post] access to field S | SSA.cs:136:23:136:28 | access to field S |
| SSA.cs:132:21:132:26 | access to field S | SSA.cs:136:23:136:28 | access to field S |
| SSA.cs:132:21:132:43 | [post] access to field SsaFieldNonSink0 | SSA.cs:136:23:136:28 | SSA qualifier def(this.S.SsaFieldNonSink0) |
| SSA.cs:132:21:132:43 | access to field SsaFieldNonSink0 | SSA.cs:136:23:136:28 | SSA qualifier def(this.S.SsaFieldNonSink0) |
| SSA.cs:132:21:132:43 | [post] access to field SsaFieldNonSink0 | SSA.cs:136:9:136:29 | SSA qualifier def(this.S.SsaFieldNonSink0) |
| SSA.cs:132:21:132:43 | access to field SsaFieldNonSink0 | SSA.cs:136:9:136:29 | SSA qualifier def(this.S.SsaFieldNonSink0) |
| SSA.cs:134:21:134:24 | [post] this access | SSA.cs:136:23:136:26 | this access |
| SSA.cs:134:21:134:24 | this access | SSA.cs:136:23:136:26 | this access |
| SSA.cs:134:21:134:26 | [post] access to field S | SSA.cs:136:23:136:28 | access to field S |
| SSA.cs:134:21:134:26 | access to field S | SSA.cs:136:23:136:28 | access to field S |
| SSA.cs:134:21:134:43 | [post] access to field SsaFieldNonSink0 | SSA.cs:136:23:136:28 | SSA qualifier def(this.S.SsaFieldNonSink0) |
| SSA.cs:134:21:134:43 | access to field SsaFieldNonSink0 | SSA.cs:136:23:136:28 | SSA qualifier def(this.S.SsaFieldNonSink0) |
| SSA.cs:134:21:134:43 | [post] access to field SsaFieldNonSink0 | SSA.cs:136:9:136:29 | SSA qualifier def(this.S.SsaFieldNonSink0) |
| SSA.cs:134:21:134:43 | access to field SsaFieldNonSink0 | SSA.cs:136:9:136:29 | SSA qualifier def(this.S.SsaFieldNonSink0) |
| SSA.cs:136:9:136:29 | SSA def(this.S) | SSA.cs:137:15:137:20 | access to field S |
| SSA.cs:136:9:136:29 | SSA qualifier def(this.S.SsaFieldNonSink0) | SSA.cs:137:15:137:37 | access to field SsaFieldNonSink0 |
| SSA.cs:136:23:136:26 | [post] this access | SSA.cs:137:15:137:18 | this access |
| SSA.cs:136:23:136:26 | this access | SSA.cs:137:15:137:18 | this access |
| SSA.cs:136:23:136:28 | SSA def(this.S) | SSA.cs:137:15:137:20 | access to field S |
| SSA.cs:136:23:136:28 | SSA qualifier def(this.S.SsaFieldNonSink0) | SSA.cs:137:15:137:37 | access to field SsaFieldNonSink0 |
| SSA.cs:136:23:136:28 | [post] access to field S | SSA.cs:136:23:136:28 | SSA def(this.S) |
| SSA.cs:136:23:136:28 | access to field S | SSA.cs:136:23:136:28 | SSA def(this.S) |
| SSA.cs:136:23:136:28 | access to field S | SSA.cs:136:23:136:28 | SSA def(this.S) |
| SSA.cs:136:23:136:28 | [post] access to field S | SSA.cs:136:9:136:29 | SSA def(this.S) |
| SSA.cs:136:23:136:28 | access to field S | SSA.cs:136:9:136:29 | SSA def(this.S) |
| SSA.cs:136:23:136:28 | access to field S | SSA.cs:136:9:136:29 | SSA def(this.S) |
| SSA.cs:144:34:144:34 | SSA param(t) | SSA.cs:146:13:146:13 | access to parameter t |
| SSA.cs:144:34:144:34 | t | SSA.cs:144:34:144:34 | SSA param(t) |
| SSA.cs:146:13:146:13 | access to parameter t | SSA.cs:146:13:146:13 | (...) ... |
@@ -874,8 +874,8 @@
| SSA.cs:154:13:154:13 | access to parameter t | SSA.cs:154:13:154:21 | [input] SSA phi(t) |
| SSA.cs:154:13:154:13 | access to parameter t | SSA.cs:155:25:155:25 | access to parameter t |
| SSA.cs:154:13:154:21 | [input] SSA phi(t) | SSA.cs:154:9:155:27 | SSA phi(t) |
| SSA.cs:155:25:155:25 | SSA def(t) | SSA.cs:154:9:155:27 | SSA phi(t) |
| SSA.cs:155:25:155:25 | access to parameter t | SSA.cs:155:25:155:25 | SSA def(t) |
| SSA.cs:155:13:155:26 | SSA def(t) | SSA.cs:154:9:155:27 | SSA phi(t) |
| SSA.cs:155:25:155:25 | access to parameter t | SSA.cs:155:13:155:26 | SSA def(t) |
| SSA.cs:166:10:166:13 | this | SSA.cs:166:19:166:22 | this access |
| SSA.cs:166:28:166:31 | null | SSA.cs:166:19:166:24 | access to field S |
| SSA.cs:168:22:168:28 | SSA param(tainted) | SSA.cs:173:24:173:30 | access to parameter tainted |

View File

@@ -642,8 +642,8 @@
| LocalDataFlow.cs:385:34:385:34 | SSA param(s) | LocalDataFlow.cs:387:15:387:15 | access to parameter s |
| LocalDataFlow.cs:385:34:385:34 | s | LocalDataFlow.cs:385:34:385:34 | SSA param(s) |
| LocalDataFlow.cs:385:38:385:51 | "taint source" | LocalDataFlow.cs:385:38:385:51 | s = ... |
| LocalDataFlow.cs:385:38:385:51 | SSA param_default(s) | LocalDataFlow.cs:387:15:387:15 | access to parameter s |
| LocalDataFlow.cs:385:38:385:51 | s = ... | LocalDataFlow.cs:385:38:385:51 | SSA param_default(s) |
| LocalDataFlow.cs:385:38:385:51 | SSA def(s) | LocalDataFlow.cs:387:15:387:15 | access to parameter s |
| LocalDataFlow.cs:385:38:385:51 | s = ... | LocalDataFlow.cs:385:38:385:51 | SSA def(s) |
| SSA.cs:3:14:3:16 | this | SSA.cs:3:14:3:16 | this access |
| SSA.cs:5:17:5:17 | SSA entry def(this.S) | SSA.cs:67:9:67:14 | access to field S |
| SSA.cs:5:17:5:17 | this | SSA.cs:67:9:67:12 | this access |
@@ -747,29 +747,29 @@
| SSA.cs:58:16:58:33 | SSA def(ssaSink3) | SSA.cs:59:23:59:30 | access to local variable ssaSink3 |
| SSA.cs:58:27:58:33 | access to parameter tainted | SSA.cs:58:16:58:23 | access to local variable ssaSink3 |
| SSA.cs:58:27:58:33 | access to parameter tainted | SSA.cs:67:32:67:38 | access to parameter tainted |
| SSA.cs:59:23:59:30 | SSA def(ssaSink3) | SSA.cs:60:15:60:22 | access to local variable ssaSink3 |
| SSA.cs:59:23:59:30 | [post] access to local variable ssaSink3 | SSA.cs:59:23:59:30 | SSA def(ssaSink3) |
| SSA.cs:59:23:59:30 | access to local variable ssaSink3 | SSA.cs:59:23:59:30 | SSA def(ssaSink3) |
| SSA.cs:59:23:59:30 | access to local variable ssaSink3 | SSA.cs:59:23:59:30 | SSA def(ssaSink3) |
| SSA.cs:63:23:63:30 | SSA def(nonSink0) | SSA.cs:64:15:64:22 | access to local variable nonSink0 |
| SSA.cs:63:23:63:30 | [post] access to local variable nonSink0 | SSA.cs:63:23:63:30 | SSA def(nonSink0) |
| SSA.cs:63:23:63:30 | access to local variable nonSink0 | SSA.cs:63:23:63:30 | SSA def(nonSink0) |
| SSA.cs:63:23:63:30 | access to local variable nonSink0 | SSA.cs:63:23:63:30 | SSA def(nonSink0) |
| SSA.cs:59:9:59:31 | SSA def(ssaSink3) | SSA.cs:60:15:60:22 | access to local variable ssaSink3 |
| SSA.cs:59:23:59:30 | [post] access to local variable ssaSink3 | SSA.cs:59:9:59:31 | SSA def(ssaSink3) |
| SSA.cs:59:23:59:30 | access to local variable ssaSink3 | SSA.cs:59:9:59:31 | SSA def(ssaSink3) |
| SSA.cs:59:23:59:30 | access to local variable ssaSink3 | SSA.cs:59:9:59:31 | SSA def(ssaSink3) |
| SSA.cs:63:9:63:31 | SSA def(nonSink0) | SSA.cs:64:15:64:22 | access to local variable nonSink0 |
| SSA.cs:63:23:63:30 | [post] access to local variable nonSink0 | SSA.cs:63:9:63:31 | SSA def(nonSink0) |
| SSA.cs:63:23:63:30 | access to local variable nonSink0 | SSA.cs:63:9:63:31 | SSA def(nonSink0) |
| SSA.cs:63:23:63:30 | access to local variable nonSink0 | SSA.cs:63:9:63:31 | SSA def(nonSink0) |
| SSA.cs:67:9:67:12 | [post] this access | SSA.cs:68:23:68:26 | this access |
| SSA.cs:67:9:67:12 | this access | SSA.cs:68:23:68:26 | this access |
| SSA.cs:67:9:67:14 | [post] access to field S | SSA.cs:68:23:68:28 | access to field S |
| SSA.cs:67:9:67:14 | access to field S | SSA.cs:68:23:68:28 | access to field S |
| SSA.cs:67:9:67:28 | access to field SsaFieldSink0 | SSA.cs:67:9:67:38 | SSA def(this.S.SsaFieldSink0) |
| SSA.cs:67:9:67:38 | SSA def(this.S.SsaFieldSink0) | SSA.cs:68:23:68:28 | SSA qualifier def(this.S.SsaFieldSink0) |
| SSA.cs:67:9:67:38 | SSA def(this.S.SsaFieldSink0) | SSA.cs:68:9:68:29 | SSA qualifier def(this.S.SsaFieldSink0) |
| SSA.cs:67:32:67:38 | access to parameter tainted | SSA.cs:67:9:67:28 | access to field SsaFieldSink0 |
| SSA.cs:67:32:67:38 | access to parameter tainted | SSA.cs:77:20:77:26 | access to parameter tainted |
| SSA.cs:68:9:68:29 | SSA def(this.S) | SSA.cs:69:15:69:20 | access to field S |
| SSA.cs:68:9:68:29 | SSA qualifier def(this.S.SsaFieldSink0) | SSA.cs:69:15:69:34 | access to field SsaFieldSink0 |
| SSA.cs:68:23:68:26 | [post] this access | SSA.cs:69:15:69:18 | this access |
| SSA.cs:68:23:68:26 | this access | SSA.cs:69:15:69:18 | this access |
| SSA.cs:68:23:68:28 | SSA def(this.S) | SSA.cs:69:15:69:20 | access to field S |
| SSA.cs:68:23:68:28 | SSA qualifier def(this.S.SsaFieldSink0) | SSA.cs:69:15:69:34 | access to field SsaFieldSink0 |
| SSA.cs:68:23:68:28 | [post] access to field S | SSA.cs:68:23:68:28 | SSA def(this.S) |
| SSA.cs:68:23:68:28 | access to field S | SSA.cs:68:23:68:28 | SSA def(this.S) |
| SSA.cs:68:23:68:28 | access to field S | SSA.cs:68:23:68:28 | SSA def(this.S) |
| SSA.cs:68:23:68:28 | [post] access to field S | SSA.cs:68:9:68:29 | SSA def(this.S) |
| SSA.cs:68:23:68:28 | access to field S | SSA.cs:68:9:68:29 | SSA def(this.S) |
| SSA.cs:68:23:68:28 | access to field S | SSA.cs:68:9:68:29 | SSA def(this.S) |
| SSA.cs:69:15:69:18 | [post] this access | SSA.cs:72:9:72:12 | this access |
| SSA.cs:69:15:69:18 | this access | SSA.cs:72:9:72:12 | this access |
| SSA.cs:69:15:69:20 | [post] access to field S | SSA.cs:72:9:72:14 | access to field S |
@@ -779,15 +779,15 @@
| SSA.cs:72:9:72:14 | [post] access to field S | SSA.cs:73:23:73:28 | access to field S |
| SSA.cs:72:9:72:14 | access to field S | SSA.cs:73:23:73:28 | access to field S |
| SSA.cs:72:9:72:31 | access to field SsaFieldNonSink0 | SSA.cs:72:9:72:36 | SSA def(this.S.SsaFieldNonSink0) |
| SSA.cs:72:9:72:36 | SSA def(this.S.SsaFieldNonSink0) | SSA.cs:73:23:73:28 | SSA qualifier def(this.S.SsaFieldNonSink0) |
| SSA.cs:72:9:72:36 | SSA def(this.S.SsaFieldNonSink0) | SSA.cs:73:9:73:29 | SSA qualifier def(this.S.SsaFieldNonSink0) |
| SSA.cs:72:35:72:36 | "" | SSA.cs:72:9:72:31 | access to field SsaFieldNonSink0 |
| SSA.cs:73:9:73:29 | SSA def(this.S) | SSA.cs:74:15:74:20 | access to field S |
| SSA.cs:73:9:73:29 | SSA qualifier def(this.S.SsaFieldNonSink0) | SSA.cs:74:15:74:37 | access to field SsaFieldNonSink0 |
| SSA.cs:73:23:73:26 | [post] this access | SSA.cs:74:15:74:18 | this access |
| SSA.cs:73:23:73:26 | this access | SSA.cs:74:15:74:18 | this access |
| SSA.cs:73:23:73:28 | SSA def(this.S) | SSA.cs:74:15:74:20 | access to field S |
| SSA.cs:73:23:73:28 | SSA qualifier def(this.S.SsaFieldNonSink0) | SSA.cs:74:15:74:37 | access to field SsaFieldNonSink0 |
| SSA.cs:73:23:73:28 | [post] access to field S | SSA.cs:73:23:73:28 | SSA def(this.S) |
| SSA.cs:73:23:73:28 | access to field S | SSA.cs:73:23:73:28 | SSA def(this.S) |
| SSA.cs:73:23:73:28 | access to field S | SSA.cs:73:23:73:28 | SSA def(this.S) |
| SSA.cs:73:23:73:28 | [post] access to field S | SSA.cs:73:9:73:29 | SSA def(this.S) |
| SSA.cs:73:23:73:28 | access to field S | SSA.cs:73:9:73:29 | SSA def(this.S) |
| SSA.cs:73:23:73:28 | access to field S | SSA.cs:73:9:73:29 | SSA def(this.S) |
| SSA.cs:74:15:74:18 | [post] this access | SSA.cs:80:9:80:12 | this access |
| SSA.cs:74:15:74:18 | this access | SSA.cs:80:9:80:12 | this access |
| SSA.cs:74:15:74:20 | [post] access to field S | SSA.cs:80:9:80:14 | access to field S |
@@ -796,8 +796,8 @@
| SSA.cs:77:9:77:26 | SSA def(nonSink0) | SSA.cs:78:21:78:28 | access to local variable nonSink0 |
| SSA.cs:77:20:77:26 | access to parameter tainted | SSA.cs:77:9:77:16 | access to local variable nonSink0 |
| SSA.cs:77:20:77:26 | access to parameter tainted | SSA.cs:80:35:80:41 | access to parameter tainted |
| SSA.cs:78:21:78:28 | SSA def(nonSink0) | SSA.cs:79:15:79:22 | access to local variable nonSink0 |
| SSA.cs:78:21:78:28 | access to local variable nonSink0 | SSA.cs:78:21:78:28 | SSA def(nonSink0) |
| SSA.cs:78:9:78:29 | SSA def(nonSink0) | SSA.cs:79:15:79:22 | access to local variable nonSink0 |
| SSA.cs:78:21:78:28 | access to local variable nonSink0 | SSA.cs:78:9:78:29 | SSA def(nonSink0) |
| SSA.cs:79:15:79:22 | [post] access to local variable nonSink0 | SSA.cs:102:13:102:33 | [input] SSA phi read(nonSink0) |
| SSA.cs:79:15:79:22 | [post] access to local variable nonSink0 | SSA.cs:104:24:104:31 | access to local variable nonSink0 |
| SSA.cs:79:15:79:22 | access to local variable nonSink0 | SSA.cs:102:13:102:33 | [input] SSA phi read(nonSink0) |
@@ -808,11 +808,11 @@
| SSA.cs:80:9:80:14 | access to field S | SSA.cs:81:21:81:26 | access to field S |
| SSA.cs:80:35:80:41 | access to parameter tainted | SSA.cs:80:9:80:31 | access to field SsaFieldNonSink0 |
| SSA.cs:80:35:80:41 | access to parameter tainted | SSA.cs:83:35:83:41 | access to parameter tainted |
| SSA.cs:81:9:81:27 | SSA def(this.S) | SSA.cs:82:15:82:20 | access to field S |
| SSA.cs:81:9:81:27 | SSA qualifier def(this.S.SsaFieldNonSink0) | SSA.cs:82:15:82:37 | access to field SsaFieldNonSink0 |
| SSA.cs:81:21:81:24 | [post] this access | SSA.cs:82:15:82:18 | this access |
| SSA.cs:81:21:81:24 | this access | SSA.cs:82:15:82:18 | this access |
| SSA.cs:81:21:81:26 | SSA def(this.S) | SSA.cs:82:15:82:20 | access to field S |
| SSA.cs:81:21:81:26 | SSA qualifier def(this.S.SsaFieldNonSink0) | SSA.cs:82:15:82:37 | access to field SsaFieldNonSink0 |
| SSA.cs:81:21:81:26 | access to field S | SSA.cs:81:21:81:26 | SSA def(this.S) |
| SSA.cs:81:21:81:26 | access to field S | SSA.cs:81:9:81:27 | SSA def(this.S) |
| SSA.cs:82:15:82:18 | [post] this access | SSA.cs:83:9:83:12 | this access |
| SSA.cs:82:15:82:18 | this access | SSA.cs:83:9:83:12 | this access |
| SSA.cs:82:15:82:20 | [post] access to field S | SSA.cs:83:9:83:14 | access to field S |
@@ -851,10 +851,10 @@
| SSA.cs:93:21:93:28 | access to local variable ssaSink4 | SSA.cs:97:23:97:30 | access to local variable ssaSink4 |
| SSA.cs:95:21:95:28 | [post] access to local variable ssaSink4 | SSA.cs:97:23:97:30 | access to local variable ssaSink4 |
| SSA.cs:95:21:95:28 | access to local variable ssaSink4 | SSA.cs:97:23:97:30 | access to local variable ssaSink4 |
| SSA.cs:97:23:97:30 | SSA def(ssaSink4) | SSA.cs:98:15:98:22 | access to local variable ssaSink4 |
| SSA.cs:97:23:97:30 | [post] access to local variable ssaSink4 | SSA.cs:97:23:97:30 | SSA def(ssaSink4) |
| SSA.cs:97:23:97:30 | access to local variable ssaSink4 | SSA.cs:97:23:97:30 | SSA def(ssaSink4) |
| SSA.cs:97:23:97:30 | access to local variable ssaSink4 | SSA.cs:97:23:97:30 | SSA def(ssaSink4) |
| SSA.cs:97:9:97:31 | SSA def(ssaSink4) | SSA.cs:98:15:98:22 | access to local variable ssaSink4 |
| SSA.cs:97:23:97:30 | [post] access to local variable ssaSink4 | SSA.cs:97:9:97:31 | SSA def(ssaSink4) |
| SSA.cs:97:23:97:30 | access to local variable ssaSink4 | SSA.cs:97:9:97:31 | SSA def(ssaSink4) |
| SSA.cs:97:23:97:30 | access to local variable ssaSink4 | SSA.cs:97:9:97:31 | SSA def(ssaSink4) |
| SSA.cs:101:16:101:23 | access to local variable nonSink3 | SSA.cs:101:16:101:28 | SSA def(nonSink3) |
| SSA.cs:101:16:101:28 | SSA def(nonSink3) | SSA.cs:110:23:110:30 | access to local variable nonSink3 |
| SSA.cs:101:27:101:28 | "" | SSA.cs:101:16:101:23 | access to local variable nonSink3 |
@@ -877,10 +877,10 @@
| SSA.cs:106:21:106:28 | access to local variable nonSink3 | SSA.cs:110:23:110:30 | access to local variable nonSink3 |
| SSA.cs:108:21:108:28 | [post] access to local variable nonSink3 | SSA.cs:110:23:110:30 | access to local variable nonSink3 |
| SSA.cs:108:21:108:28 | access to local variable nonSink3 | SSA.cs:110:23:110:30 | access to local variable nonSink3 |
| SSA.cs:110:23:110:30 | SSA def(nonSink3) | SSA.cs:111:15:111:22 | access to local variable nonSink3 |
| SSA.cs:110:23:110:30 | [post] access to local variable nonSink3 | SSA.cs:110:23:110:30 | SSA def(nonSink3) |
| SSA.cs:110:23:110:30 | access to local variable nonSink3 | SSA.cs:110:23:110:30 | SSA def(nonSink3) |
| SSA.cs:110:23:110:30 | access to local variable nonSink3 | SSA.cs:110:23:110:30 | SSA def(nonSink3) |
| SSA.cs:110:9:110:31 | SSA def(nonSink3) | SSA.cs:111:15:111:22 | access to local variable nonSink3 |
| SSA.cs:110:23:110:30 | [post] access to local variable nonSink3 | SSA.cs:110:9:110:31 | SSA def(nonSink3) |
| SSA.cs:110:23:110:30 | access to local variable nonSink3 | SSA.cs:110:9:110:31 | SSA def(nonSink3) |
| SSA.cs:110:23:110:30 | access to local variable nonSink3 | SSA.cs:110:9:110:31 | SSA def(nonSink3) |
| SSA.cs:114:9:114:12 | [post] this access | SSA.cs:117:13:117:16 | this access |
| SSA.cs:114:9:114:12 | [post] this access | SSA.cs:123:23:123:26 | this access |
| SSA.cs:114:9:114:12 | this access | SSA.cs:117:13:117:16 | this access |
@@ -890,7 +890,7 @@
| SSA.cs:114:9:114:14 | access to field S | SSA.cs:115:13:115:33 | [input] SSA phi read(this.S) |
| SSA.cs:114:9:114:14 | access to field S | SSA.cs:117:13:117:18 | access to field S |
| SSA.cs:114:9:114:28 | access to field SsaFieldSink1 | SSA.cs:114:9:114:33 | SSA def(this.S.SsaFieldSink1) |
| SSA.cs:114:9:114:33 | SSA def(this.S.SsaFieldSink1) | SSA.cs:123:23:123:28 | SSA qualifier def(this.S.SsaFieldSink1) |
| SSA.cs:114:9:114:33 | SSA def(this.S.SsaFieldSink1) | SSA.cs:123:9:123:29 | SSA qualifier def(this.S.SsaFieldSink1) |
| SSA.cs:114:32:114:33 | "" | SSA.cs:114:9:114:28 | access to field SsaFieldSink1 |
| SSA.cs:115:13:115:22 | [post] access to parameter nonTainted | SSA.cs:115:13:115:33 | [input] SSA phi read(nonTainted) |
| SSA.cs:115:13:115:22 | [post] access to parameter nonTainted | SSA.cs:118:17:118:26 | access to parameter nonTainted |
@@ -918,21 +918,21 @@
| SSA.cs:119:21:119:24 | this access | SSA.cs:123:23:123:26 | this access |
| SSA.cs:119:21:119:26 | [post] access to field S | SSA.cs:123:23:123:28 | access to field S |
| SSA.cs:119:21:119:26 | access to field S | SSA.cs:123:23:123:28 | access to field S |
| SSA.cs:119:21:119:40 | [post] access to field SsaFieldSink1 | SSA.cs:123:23:123:28 | SSA qualifier def(this.S.SsaFieldSink1) |
| SSA.cs:119:21:119:40 | access to field SsaFieldSink1 | SSA.cs:123:23:123:28 | SSA qualifier def(this.S.SsaFieldSink1) |
| SSA.cs:119:21:119:40 | [post] access to field SsaFieldSink1 | SSA.cs:123:9:123:29 | SSA qualifier def(this.S.SsaFieldSink1) |
| SSA.cs:119:21:119:40 | access to field SsaFieldSink1 | SSA.cs:123:9:123:29 | SSA qualifier def(this.S.SsaFieldSink1) |
| SSA.cs:121:21:121:24 | [post] this access | SSA.cs:123:23:123:26 | this access |
| SSA.cs:121:21:121:24 | this access | SSA.cs:123:23:123:26 | this access |
| SSA.cs:121:21:121:26 | [post] access to field S | SSA.cs:123:23:123:28 | access to field S |
| SSA.cs:121:21:121:26 | access to field S | SSA.cs:123:23:123:28 | access to field S |
| SSA.cs:121:21:121:40 | [post] access to field SsaFieldSink1 | SSA.cs:123:23:123:28 | SSA qualifier def(this.S.SsaFieldSink1) |
| SSA.cs:121:21:121:40 | access to field SsaFieldSink1 | SSA.cs:123:23:123:28 | SSA qualifier def(this.S.SsaFieldSink1) |
| SSA.cs:121:21:121:40 | [post] access to field SsaFieldSink1 | SSA.cs:123:9:123:29 | SSA qualifier def(this.S.SsaFieldSink1) |
| SSA.cs:121:21:121:40 | access to field SsaFieldSink1 | SSA.cs:123:9:123:29 | SSA qualifier def(this.S.SsaFieldSink1) |
| SSA.cs:123:9:123:29 | SSA def(this.S) | SSA.cs:124:15:124:20 | access to field S |
| SSA.cs:123:9:123:29 | SSA qualifier def(this.S.SsaFieldSink1) | SSA.cs:124:15:124:34 | access to field SsaFieldSink1 |
| SSA.cs:123:23:123:26 | [post] this access | SSA.cs:124:15:124:18 | this access |
| SSA.cs:123:23:123:26 | this access | SSA.cs:124:15:124:18 | this access |
| SSA.cs:123:23:123:28 | SSA def(this.S) | SSA.cs:124:15:124:20 | access to field S |
| SSA.cs:123:23:123:28 | SSA qualifier def(this.S.SsaFieldSink1) | SSA.cs:124:15:124:34 | access to field SsaFieldSink1 |
| SSA.cs:123:23:123:28 | [post] access to field S | SSA.cs:123:23:123:28 | SSA def(this.S) |
| SSA.cs:123:23:123:28 | access to field S | SSA.cs:123:23:123:28 | SSA def(this.S) |
| SSA.cs:123:23:123:28 | access to field S | SSA.cs:123:23:123:28 | SSA def(this.S) |
| SSA.cs:123:23:123:28 | [post] access to field S | SSA.cs:123:9:123:29 | SSA def(this.S) |
| SSA.cs:123:23:123:28 | access to field S | SSA.cs:123:9:123:29 | SSA def(this.S) |
| SSA.cs:123:23:123:28 | access to field S | SSA.cs:123:9:123:29 | SSA def(this.S) |
| SSA.cs:124:15:124:18 | [post] this access | SSA.cs:127:9:127:12 | this access |
| SSA.cs:124:15:124:18 | this access | SSA.cs:127:9:127:12 | this access |
| SSA.cs:124:15:124:20 | [post] access to field S | SSA.cs:127:9:127:14 | access to field S |
@@ -946,7 +946,7 @@
| SSA.cs:127:9:127:14 | access to field S | SSA.cs:128:13:128:33 | [input] SSA phi read(this.S) |
| SSA.cs:127:9:127:14 | access to field S | SSA.cs:130:13:130:18 | access to field S |
| SSA.cs:127:9:127:31 | access to field SsaFieldNonSink0 | SSA.cs:127:9:127:36 | SSA def(this.S.SsaFieldNonSink0) |
| SSA.cs:127:9:127:36 | SSA def(this.S.SsaFieldNonSink0) | SSA.cs:136:23:136:28 | SSA qualifier def(this.S.SsaFieldNonSink0) |
| SSA.cs:127:9:127:36 | SSA def(this.S.SsaFieldNonSink0) | SSA.cs:136:9:136:29 | SSA qualifier def(this.S.SsaFieldNonSink0) |
| SSA.cs:127:35:127:36 | "" | SSA.cs:127:9:127:31 | access to field SsaFieldNonSink0 |
| SSA.cs:128:13:128:22 | [post] access to parameter nonTainted | SSA.cs:131:17:131:26 | access to parameter nonTainted |
| SSA.cs:128:13:128:22 | access to parameter nonTainted | SSA.cs:131:17:131:26 | access to parameter nonTainted |
@@ -969,21 +969,21 @@
| SSA.cs:132:21:132:24 | this access | SSA.cs:136:23:136:26 | this access |
| SSA.cs:132:21:132:26 | [post] access to field S | SSA.cs:136:23:136:28 | access to field S |
| SSA.cs:132:21:132:26 | access to field S | SSA.cs:136:23:136:28 | access to field S |
| SSA.cs:132:21:132:43 | [post] access to field SsaFieldNonSink0 | SSA.cs:136:23:136:28 | SSA qualifier def(this.S.SsaFieldNonSink0) |
| SSA.cs:132:21:132:43 | access to field SsaFieldNonSink0 | SSA.cs:136:23:136:28 | SSA qualifier def(this.S.SsaFieldNonSink0) |
| SSA.cs:132:21:132:43 | [post] access to field SsaFieldNonSink0 | SSA.cs:136:9:136:29 | SSA qualifier def(this.S.SsaFieldNonSink0) |
| SSA.cs:132:21:132:43 | access to field SsaFieldNonSink0 | SSA.cs:136:9:136:29 | SSA qualifier def(this.S.SsaFieldNonSink0) |
| SSA.cs:134:21:134:24 | [post] this access | SSA.cs:136:23:136:26 | this access |
| SSA.cs:134:21:134:24 | this access | SSA.cs:136:23:136:26 | this access |
| SSA.cs:134:21:134:26 | [post] access to field S | SSA.cs:136:23:136:28 | access to field S |
| SSA.cs:134:21:134:26 | access to field S | SSA.cs:136:23:136:28 | access to field S |
| SSA.cs:134:21:134:43 | [post] access to field SsaFieldNonSink0 | SSA.cs:136:23:136:28 | SSA qualifier def(this.S.SsaFieldNonSink0) |
| SSA.cs:134:21:134:43 | access to field SsaFieldNonSink0 | SSA.cs:136:23:136:28 | SSA qualifier def(this.S.SsaFieldNonSink0) |
| SSA.cs:134:21:134:43 | [post] access to field SsaFieldNonSink0 | SSA.cs:136:9:136:29 | SSA qualifier def(this.S.SsaFieldNonSink0) |
| SSA.cs:134:21:134:43 | access to field SsaFieldNonSink0 | SSA.cs:136:9:136:29 | SSA qualifier def(this.S.SsaFieldNonSink0) |
| SSA.cs:136:9:136:29 | SSA def(this.S) | SSA.cs:137:15:137:20 | access to field S |
| SSA.cs:136:9:136:29 | SSA qualifier def(this.S.SsaFieldNonSink0) | SSA.cs:137:15:137:37 | access to field SsaFieldNonSink0 |
| SSA.cs:136:23:136:26 | [post] this access | SSA.cs:137:15:137:18 | this access |
| SSA.cs:136:23:136:26 | this access | SSA.cs:137:15:137:18 | this access |
| SSA.cs:136:23:136:28 | SSA def(this.S) | SSA.cs:137:15:137:20 | access to field S |
| SSA.cs:136:23:136:28 | SSA qualifier def(this.S.SsaFieldNonSink0) | SSA.cs:137:15:137:37 | access to field SsaFieldNonSink0 |
| SSA.cs:136:23:136:28 | [post] access to field S | SSA.cs:136:23:136:28 | SSA def(this.S) |
| SSA.cs:136:23:136:28 | access to field S | SSA.cs:136:23:136:28 | SSA def(this.S) |
| SSA.cs:136:23:136:28 | access to field S | SSA.cs:136:23:136:28 | SSA def(this.S) |
| SSA.cs:136:23:136:28 | [post] access to field S | SSA.cs:136:9:136:29 | SSA def(this.S) |
| SSA.cs:136:23:136:28 | access to field S | SSA.cs:136:9:136:29 | SSA def(this.S) |
| SSA.cs:136:23:136:28 | access to field S | SSA.cs:136:9:136:29 | SSA def(this.S) |
| SSA.cs:144:34:144:34 | SSA param(t) | SSA.cs:146:13:146:13 | access to parameter t |
| SSA.cs:144:34:144:34 | t | SSA.cs:144:34:144:34 | SSA param(t) |
| SSA.cs:146:13:146:13 | (...) ... | SSA.cs:146:13:146:21 | ... == ... |
@@ -1002,8 +1002,8 @@
| SSA.cs:154:13:154:13 | access to parameter t | SSA.cs:154:13:154:21 | [input] SSA phi(t) |
| SSA.cs:154:13:154:13 | access to parameter t | SSA.cs:155:25:155:25 | access to parameter t |
| SSA.cs:154:13:154:21 | [input] SSA phi(t) | SSA.cs:154:9:155:27 | SSA phi(t) |
| SSA.cs:155:25:155:25 | SSA def(t) | SSA.cs:154:9:155:27 | SSA phi(t) |
| SSA.cs:155:25:155:25 | access to parameter t | SSA.cs:155:25:155:25 | SSA def(t) |
| SSA.cs:155:13:155:26 | SSA def(t) | SSA.cs:154:9:155:27 | SSA phi(t) |
| SSA.cs:155:25:155:25 | access to parameter t | SSA.cs:155:13:155:26 | SSA def(t) |
| SSA.cs:166:10:166:13 | this | SSA.cs:166:19:166:22 | this access |
| SSA.cs:166:28:166:31 | null | SSA.cs:166:19:166:24 | access to field S |
| SSA.cs:168:22:168:28 | SSA param(tainted) | SSA.cs:173:24:173:30 | access to parameter tainted |

View File

@@ -2,6 +2,6 @@ import csharp
from int uses, int live
where
uses = strictcount(Ssa::ExplicitDefinition ssa, AssignableRead read | read = ssa.getARead()) and
live = strictcount(Ssa::ExplicitDefinition ssa, BasicBlock bb | ssa.isLiveAtEndOfBlock(bb))
uses = strictcount(SsaExplicitWrite ssa, AssignableRead read | read = ssa.getARead()) and
live = strictcount(SsaExplicitWrite ssa, BasicBlock bb | ssa.isLiveAtEndOfBlock(bb))
select uses, live

View File

@@ -8,12 +8,8 @@ where
ar = ssaDef.getARead() and
def = ssaDef.getDefinition() and
v = def.getTarget() and
not exists(Ssa::ExplicitDefinition edef |
edef.getADefinition() = def and
edef.getARead() = ar
) and
not exists(Ssa::ParameterDefinition edef |
edef.getParameter() = def.(AssignableDefinitions::ImplicitParameterDefinition).getParameter() and
not exists(SsaExplicitWrite edef |
edef.getDefinition() = def and
edef.getARead() = ar
)
select ar, def

View File

@@ -83,6 +83,8 @@
| Fields.cs:93:19:93:23 | Field | Fields.cs:102:9:102:28 | ... = ... | Fields.cs:104:16:104:25 | access to field Field |
| Fields.cs:95:19:95:19 | f | Fields.cs:95:19:95:19 | f | Fields.cs:97:9:97:9 | access to parameter f |
| Fields.cs:107:33:107:33 | f | Fields.cs:107:33:107:33 | f | Fields.cs:107:38:107:38 | access to parameter f |
| MultiImplementationA.cs:5:22:5:22 | x | MultiImplementationA.cs:5:22:5:22 | x | MultiImplementationA.cs:5:28:5:28 | access to parameter x |
| MultiImplementationA.cs:5:22:5:22 | x | MultiImplementationA.cs:5:22:5:22 | x | MultiImplementationB.cs:3:28:3:28 | access to parameter x |
| OutRef.cs:5:9:5:13 | Field | OutRef.cs:13:28:13:32 | access to field Field | OutRef.cs:15:13:15:17 | access to field Field |
| OutRef.cs:5:9:5:13 | Field | OutRef.cs:16:21:16:25 | access to field Field | OutRef.cs:17:13:17:17 | access to field Field |
| OutRef.cs:5:9:5:13 | Field | OutRef.cs:16:32:16:36 | access to field Field | OutRef.cs:17:13:17:17 | access to field Field |

View File

@@ -1,7 +1,8 @@
import csharp
private import semmle.code.csharp.dataflow.internal.SsaImpl as SsaImpl
from Ssa::SourceVariable v, Ssa::Definition def
from Ssa::SourceVariable v, SsaDefinition def
where
v = def.getSourceVariable() and
def.isLiveOutRefParameterDefinition(_)
SsaImpl::isLiveOutRefParameterDefinition(def, _)
select v, def

View File

@@ -5,13 +5,13 @@
| DefUse.cs:6:14:6:14 | y | DefUse.cs:37:9:40:9 | SSA phi(y) | DefUse.cs:28:13:28:18 | SSA def(y) |
| DefUse.cs:6:14:6:14 | y | DefUse.cs:37:9:40:9 | SSA phi(y) | DefUse.cs:39:13:39:18 | SSA def(y) |
| DefUse.cs:79:13:79:14 | x1 | DefUse.cs:80:9:80:51 | SSA phi(x1) | DefUse.cs:79:13:79:18 | SSA def(x1) |
| DefUse.cs:79:13:79:14 | x1 | DefUse.cs:80:9:80:51 | SSA phi(x1) | DefUse.cs:80:30:80:31 | SSA def(x1) |
| DefUse.cs:79:13:79:14 | x1 | DefUse.cs:80:9:80:51 | SSA phi(x1) | DefUse.cs:80:16:80:32 | SSA def(x1) |
| DefUse.cs:97:13:97:14 | x5 | DefUse.cs:98:9:102:9 | SSA phi(x5) | DefUse.cs:97:13:97:18 | SSA def(x5) |
| DefUse.cs:97:13:97:14 | x5 | DefUse.cs:98:9:102:9 | SSA phi(x5) | DefUse.cs:101:13:101:23 | SSA def(x5) |
| DefaultParam.cs:3:30:3:30 | s | DefaultParam.cs:3:42:3:42 | SSA phi(s) | DefaultParam.cs:3:30:3:30 | SSA param(s) |
| DefaultParam.cs:3:30:3:30 | s | DefaultParam.cs:3:42:3:42 | SSA phi(s) | DefaultParam.cs:3:34:3:35 | SSA param_default(s) |
| DefaultParam.cs:3:30:3:30 | s | DefaultParam.cs:3:42:3:42 | SSA phi(s) | DefaultParam.cs:3:34:3:35 | SSA def(s) |
| DefaultParam.cs:3:42:3:42 | i | DefaultParam.cs:4:5:6:5 | SSA phi(i) | DefaultParam.cs:3:42:3:42 | SSA param(i) |
| DefaultParam.cs:3:42:3:42 | i | DefaultParam.cs:4:5:6:5 | SSA phi(i) | DefaultParam.cs:3:46:3:46 | SSA param_default(i) |
| DefaultParam.cs:3:42:3:42 | i | DefaultParam.cs:4:5:6:5 | SSA phi(i) | DefaultParam.cs:3:46:3:46 | SSA def(i) |
| Example.cs:8:9:8:18 | this.Field | Example.cs:10:9:13:24 | SSA phi(this.Field) | Example.cs:11:13:11:30 | SSA def(this.Field) |
| Example.cs:8:9:8:18 | this.Field | Example.cs:10:9:13:24 | SSA phi(this.Field) | Example.cs:12:14:13:24 | SSA phi(this.Field) |
| Example.cs:8:9:8:18 | this.Field | Example.cs:12:14:13:24 | SSA phi(this.Field) | Example.cs:8:9:8:22 | SSA def(this.Field) |

View File

@@ -1,6 +1,6 @@
import csharp
from Ssa::SourceVariable v, Ssa::PhiNode phi, Ssa::Definition input
from Ssa::SourceVariable v, SsaPhiDefinition phi, SsaDefinition input
where
phi.getAnInput() = input and
v = phi.getSourceVariable()

View File

@@ -35,8 +35,8 @@
| Capture.cs:248:36:248:36 | j | Capture.cs:251:13:251:17 | SSA def(j) |
| Consistency.cs:7:25:7:25 | b | Consistency.cs:7:25:7:25 | SSA param(b) |
| Consistency.cs:15:17:15:17 | i | Consistency.cs:15:17:15:21 | SSA def(i) |
| Consistency.cs:25:29:25:29 | c | Consistency.cs:25:29:25:29 | SSA def(c) |
| Consistency.cs:26:13:26:19 | c.Field | Consistency.cs:25:29:25:29 | SSA qualifier def(c.Field) |
| Consistency.cs:25:29:25:29 | c | Consistency.cs:25:9:25:30 | SSA def(c) |
| Consistency.cs:26:13:26:19 | c.Field | Consistency.cs:25:9:25:30 | SSA qualifier def(c.Field) |
| Consistency.cs:30:30:30:30 | c | Consistency.cs:32:9:32:29 | SSA def(c) |
| Consistency.cs:44:11:44:11 | s | Consistency.cs:44:11:44:11 | SSA def(s) |
| Consistency.cs:49:30:49:30 | a | Consistency.cs:49:30:49:30 | SSA param(a) |
@@ -58,8 +58,8 @@
| DefUse.cs:6:14:6:14 | y | DefUse.cs:37:9:40:9 | SSA phi(y) |
| DefUse.cs:6:14:6:14 | y | DefUse.cs:39:13:39:18 | SSA def(y) |
| DefUse.cs:44:13:44:13 | z | DefUse.cs:44:13:44:17 | SSA def(z) |
| DefUse.cs:44:13:44:13 | z | DefUse.cs:47:23:47:23 | SSA def(z) |
| DefUse.cs:44:13:44:13 | z | DefUse.cs:50:23:50:23 | SSA def(z) |
| DefUse.cs:44:13:44:13 | z | DefUse.cs:47:9:47:24 | SSA def(z) |
| DefUse.cs:44:13:44:13 | z | DefUse.cs:50:9:50:24 | SSA def(z) |
| DefUse.cs:53:9:53:13 | this.Field | DefUse.cs:53:9:53:17 | SSA def(this.Field) |
| DefUse.cs:56:9:56:12 | this.Prop | DefUse.cs:56:9:56:16 | SSA def(this.Prop) |
| DefUse.cs:63:9:63:14 | this.Field2 | DefUse.cs:63:9:63:18 | SSA def(this.Field2) |
@@ -67,12 +67,12 @@
| DefUse.cs:67:19:67:20 | tc | DefUse.cs:67:19:67:27 | SSA def(tc) |
| DefUse.cs:79:13:79:14 | x1 | DefUse.cs:79:13:79:18 | SSA def(x1) |
| DefUse.cs:79:13:79:14 | x1 | DefUse.cs:80:9:80:51 | SSA phi(x1) |
| DefUse.cs:79:13:79:14 | x1 | DefUse.cs:80:30:80:31 | SSA def(x1) |
| DefUse.cs:79:13:79:14 | x1 | DefUse.cs:80:16:80:32 | SSA def(x1) |
| DefUse.cs:83:13:83:14 | x2 | DefUse.cs:83:13:83:18 | SSA def(x2) |
| DefUse.cs:83:13:83:14 | x2 | DefUse.cs:85:15:85:16 | SSA def(x2) |
| DefUse.cs:83:13:83:14 | x2 | DefUse.cs:84:9:86:17 | SSA def(x2) |
| DefUse.cs:89:13:89:14 | x3 | DefUse.cs:89:13:89:18 | SSA def(x3) |
| DefUse.cs:89:13:89:14 | x3 | DefUse.cs:92:15:92:16 | SSA def(x3) |
| DefUse.cs:90:13:90:14 | x4 | DefUse.cs:93:15:93:16 | SSA def(x4) |
| DefUse.cs:89:13:89:14 | x3 | DefUse.cs:91:9:93:17 | SSA def(x3) |
| DefUse.cs:90:13:90:14 | x4 | DefUse.cs:91:9:93:17 | SSA def(x4) |
| DefUse.cs:97:13:97:14 | x5 | DefUse.cs:97:13:97:18 | SSA def(x5) |
| DefUse.cs:97:13:97:14 | x5 | DefUse.cs:98:9:102:9 | SSA phi(x5) |
| DefUse.cs:97:13:97:14 | x5 | DefUse.cs:101:13:101:23 | SSA def(x5) |
@@ -95,10 +95,10 @@
| DefUse.cs:188:13:188:18 | this.Field5 | DefUse.cs:188:13:188:22 | SSA def(this.Field5) |
| DefaultParam.cs:3:20:3:20 | b | DefaultParam.cs:3:20:3:20 | SSA param(b) |
| DefaultParam.cs:3:30:3:30 | s | DefaultParam.cs:3:30:3:30 | SSA param(s) |
| DefaultParam.cs:3:30:3:30 | s | DefaultParam.cs:3:34:3:35 | SSA param_default(s) |
| DefaultParam.cs:3:30:3:30 | s | DefaultParam.cs:3:34:3:35 | SSA def(s) |
| DefaultParam.cs:3:30:3:30 | s | DefaultParam.cs:3:42:3:42 | SSA phi(s) |
| DefaultParam.cs:3:42:3:42 | i | DefaultParam.cs:3:42:3:42 | SSA param(i) |
| DefaultParam.cs:3:42:3:42 | i | DefaultParam.cs:3:46:3:46 | SSA param_default(i) |
| DefaultParam.cs:3:42:3:42 | i | DefaultParam.cs:3:46:3:46 | SSA def(i) |
| DefaultParam.cs:3:42:3:42 | i | DefaultParam.cs:4:5:6:5 | SSA phi(i) |
| Example.cs:6:23:6:23 | i | Example.cs:6:23:6:23 | SSA param(i) |
| Example.cs:8:9:8:18 | this.Field | Example.cs:8:9:8:22 | SSA def(this.Field) |
@@ -162,25 +162,25 @@
| Fields.cs:107:33:107:33 | f | Fields.cs:107:33:107:33 | SSA param(f) |
| Fields.cs:115:20:115:29 | this.Field | Fields.cs:109:10:109:10 | SSA entry def(this.Field) |
| Fields.cs:115:20:115:29 | this.Field | Fields.cs:114:9:114:22 | SSA call def(this.Field) |
| Fields.cs:115:20:115:35 | this.Field.Field | Fields.cs:109:10:109:10 | SSA qualifier def(this.Field.Field) |
| Fields.cs:115:20:115:35 | this.Field.Field | Fields.cs:109:10:109:10 | SSA entry def(this.Field.Field) |
| Fields.cs:115:20:115:35 | this.Field.Field | Fields.cs:114:9:114:22 | SSA call def(this.Field.Field) |
| Fields.cs:116:21:116:39 | this.Field.Field.xs | Fields.cs:109:10:109:10 | SSA qualifier def(this.Field.Field.xs) |
| Fields.cs:116:21:116:39 | this.Field.Field.xs | Fields.cs:109:10:109:10 | SSA entry def(this.Field.Field.xs) |
| Fields.cs:116:21:116:39 | this.Field.Field.xs | Fields.cs:114:9:114:22 | SSA qualifier def(this.Field.Field.xs) |
| MultiImplementationA.cs:5:22:5:22 | x | MultiImplementationA.cs:5:22:5:22 | SSA param(x) |
| MultiImplementationA.cs:5:22:5:22 | x | MultiImplementationB.cs:3:22:3:22 | SSA param(x) |
| OutRef.cs:9:13:9:13 | j | OutRef.cs:9:13:9:17 | SSA def(j) |
| OutRef.cs:9:13:9:13 | j | OutRef.cs:10:32:10:32 | SSA def(j) |
| OutRef.cs:9:13:9:13 | j | OutRef.cs:22:22:22:22 | SSA def(j) |
| OutRef.cs:9:13:9:13 | j | OutRef.cs:24:29:24:29 | SSA def(j) |
| OutRef.cs:10:25:10:25 | i | OutRef.cs:10:25:10:25 | SSA def(i) |
| OutRef.cs:10:25:10:25 | i | OutRef.cs:13:21:13:21 | SSA def(i) |
| OutRef.cs:9:13:9:13 | j | OutRef.cs:10:9:10:33 | SSA def(j) |
| OutRef.cs:9:13:9:13 | j | OutRef.cs:22:9:22:30 | SSA def(j) |
| OutRef.cs:9:13:9:13 | j | OutRef.cs:24:9:24:30 | SSA def(j) |
| OutRef.cs:10:25:10:25 | i | OutRef.cs:10:9:10:33 | SSA def(i) |
| OutRef.cs:10:25:10:25 | i | OutRef.cs:13:9:13:33 | SSA def(i) |
| OutRef.cs:13:28:13:32 | this.Field | OutRef.cs:7:10:7:10 | SSA entry def(this.Field) |
| OutRef.cs:13:28:13:32 | this.Field | OutRef.cs:13:28:13:32 | SSA def(this.Field) |
| OutRef.cs:13:28:13:32 | this.Field | OutRef.cs:16:21:16:25 | SSA def(this.Field) |
| OutRef.cs:13:28:13:32 | this.Field | OutRef.cs:19:21:19:25 | SSA def(this.Field) |
| OutRef.cs:13:28:13:32 | this.Field | OutRef.cs:13:9:13:33 | SSA def(this.Field) |
| OutRef.cs:13:28:13:32 | this.Field | OutRef.cs:16:9:16:37 | SSA def(this.Field) |
| OutRef.cs:13:28:13:32 | this.Field | OutRef.cs:19:9:19:39 | SSA def(this.Field) |
| OutRef.cs:18:13:18:13 | t | OutRef.cs:18:13:18:28 | SSA def(t) |
| OutRef.cs:19:32:19:38 | t.Field | OutRef.cs:18:13:18:28 | SSA qualifier def(t.Field) |
| OutRef.cs:19:32:19:38 | t.Field | OutRef.cs:19:32:19:38 | SSA def(t.Field) |
| OutRef.cs:19:32:19:38 | t.Field | OutRef.cs:19:9:19:39 | SSA def(t.Field) |
| OutRef.cs:28:26:28:26 | i | OutRef.cs:30:9:30:13 | SSA def(i) |
| OutRef.cs:28:37:28:37 | j | OutRef.cs:28:37:28:37 | SSA param(j) |
| OutRef.cs:28:37:28:37 | j | OutRef.cs:31:9:31:13 | SSA def(j) |
@@ -245,9 +245,9 @@
| Properties.cs:106:37:106:37 | p | Properties.cs:106:37:106:37 | SSA param(p) |
| Properties.cs:114:20:114:29 | this.Props | Properties.cs:108:10:108:10 | SSA entry def(this.Props) |
| Properties.cs:114:20:114:29 | this.Props | Properties.cs:113:9:113:22 | SSA call def(this.Props) |
| Properties.cs:114:20:114:35 | this.Props.Props | Properties.cs:108:10:108:10 | SSA qualifier def(this.Props.Props) |
| Properties.cs:114:20:114:35 | this.Props.Props | Properties.cs:108:10:108:10 | SSA entry def(this.Props.Props) |
| Properties.cs:114:20:114:35 | this.Props.Props | Properties.cs:113:9:113:22 | SSA call def(this.Props.Props) |
| Properties.cs:115:21:115:39 | this.Props.Props.xs | Properties.cs:108:10:108:10 | SSA qualifier def(this.Props.Props.xs) |
| Properties.cs:115:21:115:39 | this.Props.Props.xs | Properties.cs:108:10:108:10 | SSA entry def(this.Props.Props.xs) |
| Properties.cs:115:21:115:39 | this.Props.Props.xs | Properties.cs:113:9:113:22 | SSA qualifier def(this.Props.Props.xs) |
| Test.cs:5:15:5:20 | param1 | Test.cs:5:15:5:20 | SSA param(param1) |
| Test.cs:5:15:5:20 | param1 | Test.cs:25:9:32:9 | SSA phi(param1) |

View File

@@ -1,5 +1,5 @@
import csharp
from Ssa::SourceVariable v, Ssa::Definition def
from Ssa::SourceVariable v, SsaDefinition def
where v = def.getSourceVariable()
select v, def

View File

@@ -1,277 +0,0 @@
| Capture.cs:10:16:27:9 | SSA def(a) | Capture.cs:10:16:27:9 | Action a = ... |
| Capture.cs:17:17:17:21 | SSA def(y) | Capture.cs:17:17:17:21 | Int32 y = ... |
| Capture.cs:19:20:23:13 | SSA def(b) | Capture.cs:19:20:23:13 | Action b = ... |
| Capture.cs:19:24:23:13 | SSA capture def(y) | Capture.cs:19:24:23:13 | (...) => ... |
| Capture.cs:30:16:30:35 | SSA def(c) | Capture.cs:30:16:30:35 | Action c = ... |
| Capture.cs:52:16:52:43 | SSA def(b) | Capture.cs:52:16:52:43 | Action b = ... |
| Capture.cs:57:57:57:63 | SSA param(strings) | Capture.cs:57:57:57:63 | strings |
| Capture.cs:60:27:60:38 | SSA def(e) | Capture.cs:60:27:60:38 | Func<String,Int32> e = ... |
| Capture.cs:65:45:65:51 | SSA param(strings) | Capture.cs:65:45:65:51 | strings |
| Capture.cs:68:32:68:32 | SSA param(s) | Capture.cs:68:32:68:32 | s |
| Capture.cs:68:32:68:49 | SSA capture def(c) | Capture.cs:68:32:68:49 | (...) => ... |
| Capture.cs:69:9:69:62 | SSA capture def(c) | Capture.cs:69:9:69:62 | M |
| Capture.cs:69:25:69:25 | SSA param(s) | Capture.cs:69:25:69:25 | s |
| Capture.cs:73:67:73:73 | SSA param(strings) | Capture.cs:73:67:73:73 | strings |
| Capture.cs:76:63:76:81 | SSA def(e) | Capture.cs:76:63:76:81 | Expression<Func<String,Int32>> e = ... |
| Capture.cs:81:28:81:28 | SSA param(i) | Capture.cs:81:28:81:28 | i |
| Capture.cs:81:34:81:36 | SSA def(i) | Capture.cs:81:34:81:36 | ...++ |
| Capture.cs:83:65:83:71 | SSA param(strings) | Capture.cs:83:65:83:71 | strings |
| Capture.cs:86:64:86:73 | SSA def(e) | Capture.cs:86:64:86:73 | Expression<Func<String,Boolean>> e = ... |
| Capture.cs:86:68:86:73 | SSA capture def(b) | Capture.cs:86:68:86:73 | (...) => ... |
| Capture.cs:92:18:92:18 | SSA param(d) | Capture.cs:92:18:92:18 | d |
| Capture.cs:96:12:100:9 | SSA capture def(y) | Capture.cs:96:12:100:9 | (...) => ... |
| Capture.cs:98:17:98:21 | SSA def(x) | Capture.cs:98:17:98:21 | Int32 x = ... |
| Capture.cs:115:9:119:9 | SSA capture def(a) | Capture.cs:115:9:119:9 | M1 |
| Capture.cs:117:17:117:21 | SSA def(x) | Capture.cs:117:17:117:21 | Int32 x = ... |
| Capture.cs:163:9:166:9 | SSA capture def(g) | Capture.cs:163:9:166:9 | M7 |
| Capture.cs:183:13:186:13 | SSA capture def(i) | Capture.cs:183:13:186:13 | M11 |
| Capture.cs:198:28:198:44 | SSA def(eh) | Capture.cs:198:28:198:44 | MyEventHandler eh = ... |
| Capture.cs:198:33:198:44 | SSA capture def(i) | Capture.cs:198:33:198:44 | (...) => ... |
| Capture.cs:203:28:203:45 | SSA def(eh2) | Capture.cs:203:28:203:45 | MyEventHandler eh2 = ... |
| Capture.cs:203:34:203:45 | SSA capture def(i) | Capture.cs:203:34:203:45 | (...) => ... |
| Capture.cs:210:24:210:59 | SSA def(p) | Capture.cs:210:24:210:59 | Process p = ... |
| Capture.cs:212:30:212:71 | SSA def(exited) | Capture.cs:212:30:212:71 | EventHandler exited = ... |
| Capture.cs:212:39:212:71 | SSA capture def(i) | Capture.cs:212:39:212:71 | (...) => ... |
| Capture.cs:251:13:251:17 | SSA def(j) | Capture.cs:251:13:251:17 | ... = ... |
| Consistency.cs:7:25:7:25 | SSA param(b) | Consistency.cs:7:25:7:25 | b |
| Consistency.cs:15:17:15:21 | SSA def(i) | Consistency.cs:15:17:15:21 | Int32 i = ... |
| Consistency.cs:25:29:25:29 | SSA def(c) | Consistency.cs:25:9:25:30 | call to method Out |
| Consistency.cs:25:29:25:29 | SSA qualifier def(c.Field) | Consistency.cs:25:9:25:30 | call to method Out |
| Consistency.cs:32:9:32:29 | SSA def(c) | Consistency.cs:32:9:32:29 | ... = ... |
| Consistency.cs:44:11:44:11 | SSA def(s) | Consistency.cs:44:11:44:11 | S s |
| Consistency.cs:49:30:49:30 | SSA param(a) | Consistency.cs:49:30:49:30 | a |
| Consistency.cs:49:37:49:37 | SSA param(i) | Consistency.cs:49:37:49:37 | i |
| Consistency.cs:51:20:51:20 | SSA param(a) | Consistency.cs:51:20:51:20 | a |
| Consistency.cs:56:17:56:40 | SSA def(k) | Consistency.cs:56:17:56:40 | Int32 k = ... |
| Consistency.cs:57:9:57:13 | SSA def(k) | Consistency.cs:57:9:57:13 | ... = ... |
| Consistency.cs:58:9:58:13 | SSA def(k) | Consistency.cs:58:9:58:13 | ... = ... |
| DefUse.cs:3:26:3:26 | SSA param(w) | DefUse.cs:3:26:3:26 | w |
| DefUse.cs:5:13:5:17 | SSA def(x) | DefUse.cs:5:13:5:17 | Int32 x = ... |
| DefUse.cs:6:14:6:19 | SSA def(y) | DefUse.cs:6:14:6:19 | Int64 y = ... |
| DefUse.cs:13:13:13:18 | SSA def(y) | DefUse.cs:13:13:13:18 | ... = ... |
| DefUse.cs:18:13:18:18 | SSA def(y) | DefUse.cs:18:13:18:18 | ... = ... |
| DefUse.cs:19:13:19:18 | SSA def(w) | DefUse.cs:19:13:19:18 | ... = ... |
| DefUse.cs:28:13:28:18 | SSA def(y) | DefUse.cs:28:13:28:18 | ... = ... |
| DefUse.cs:29:13:29:18 | SSA def(w) | DefUse.cs:29:13:29:18 | ... = ... |
| DefUse.cs:39:13:39:18 | SSA def(y) | DefUse.cs:39:13:39:18 | ... = ... |
| DefUse.cs:44:13:44:17 | SSA def(z) | DefUse.cs:44:13:44:17 | Int32 z = ... |
| DefUse.cs:47:23:47:23 | SSA def(z) | DefUse.cs:47:9:47:24 | call to method outMethod |
| DefUse.cs:50:23:50:23 | SSA def(z) | DefUse.cs:50:9:50:24 | call to method refMethod |
| DefUse.cs:53:9:53:17 | SSA def(this.Field) | DefUse.cs:53:9:53:17 | ... = ... |
| DefUse.cs:56:9:56:16 | SSA def(this.Prop) | DefUse.cs:56:9:56:16 | ... = ... |
| DefUse.cs:63:9:63:18 | SSA def(this.Field2) | DefUse.cs:63:9:63:18 | ... = ... |
| DefUse.cs:66:9:66:18 | SSA def(this.Field3) | DefUse.cs:66:9:66:18 | ... = ... |
| DefUse.cs:67:19:67:27 | SSA def(tc) | DefUse.cs:67:19:67:27 | TestClass tc = ... |
| DefUse.cs:79:13:79:18 | SSA def(x1) | DefUse.cs:79:13:79:18 | Int32 x1 = ... |
| DefUse.cs:80:30:80:31 | SSA def(x1) | DefUse.cs:80:16:80:32 | call to method refMethod |
| DefUse.cs:83:13:83:18 | SSA def(x2) | DefUse.cs:83:13:83:18 | Int32 x2 = ... |
| DefUse.cs:85:15:85:16 | SSA def(x2) | DefUse.cs:84:9:86:17 | call to method refOutMethod |
| DefUse.cs:89:13:89:18 | SSA def(x3) | DefUse.cs:89:13:89:18 | Int32 x3 = ... |
| DefUse.cs:92:15:92:16 | SSA def(x3) | DefUse.cs:91:9:93:17 | call to method refOutMethod |
| DefUse.cs:93:15:93:16 | SSA def(x4) | DefUse.cs:91:9:93:17 | call to method refOutMethod |
| DefUse.cs:97:13:97:18 | SSA def(x5) | DefUse.cs:97:13:97:18 | Int32 x5 = ... |
| DefUse.cs:101:13:101:23 | SSA def(x5) | DefUse.cs:101:13:101:23 | ... = ... |
| DefUse.cs:104:9:104:15 | SSA def(x5) | DefUse.cs:104:9:104:15 | ... += ... |
| DefUse.cs:114:47:114:52 | SSA def(i) | DefUse.cs:114:47:114:52 | ... = ... |
| DefUse.cs:116:47:116:51 | SSA def(i) | DefUse.cs:116:47:116:51 | ... = ... |
| DefUse.cs:118:45:118:45 | SSA param(i) | DefUse.cs:118:45:118:45 | i |
| DefUse.cs:118:61:118:65 | SSA def(j) | DefUse.cs:118:61:118:65 | ... = ... |
| DefUse.cs:118:68:118:72 | SSA def(i) | DefUse.cs:118:68:118:72 | ... = ... |
| DefUse.cs:128:19:128:19 | SSA param(i) | DefUse.cs:128:19:128:19 | i |
| DefUse.cs:134:22:134:22 | SSA param(d) | DefUse.cs:134:22:134:22 | d |
| DefUse.cs:142:68:142:69 | SSA param(ie) | DefUse.cs:142:68:142:69 | ie |
| DefUse.cs:144:22:144:22 | SSA def(x) | DefUse.cs:144:22:144:22 | String x |
| DefUse.cs:155:9:155:18 | SSA def(this.Field4) | DefUse.cs:155:9:155:18 | ... = ... |
| DefUse.cs:160:10:160:16 | SSA entry def(this.Field4) | DefUse.cs:160:10:160:16 | FieldM2 |
| DefUse.cs:171:23:180:9 | SSA def(a) | DefUse.cs:171:23:180:9 | Action a = ... |
| DefUse.cs:184:9:184:18 | SSA def(this.Field5) | DefUse.cs:184:9:184:18 | ... = ... |
| DefUse.cs:186:9:190:9 | SSA def(a) | DefUse.cs:186:9:190:9 | ... = ... |
| DefUse.cs:188:13:188:22 | SSA def(this.Field5) | DefUse.cs:188:13:188:22 | ... = ... |
| DefUse.cs:191:9:191:11 | SSA call def(this.Field5) | DefUse.cs:191:9:191:11 | delegate call |
| DefaultParam.cs:3:20:3:20 | SSA param(b) | DefaultParam.cs:3:20:3:20 | b |
| DefaultParam.cs:3:30:3:30 | SSA param(s) | DefaultParam.cs:3:30:3:30 | s |
| DefaultParam.cs:3:34:3:35 | SSA param_default(s) | DefaultParam.cs:3:34:3:35 | "" |
| DefaultParam.cs:3:42:3:42 | SSA param(i) | DefaultParam.cs:3:42:3:42 | i |
| DefaultParam.cs:3:42:3:42 | SSA phi(s) | DefaultParam.cs:3:42:3:42 | i |
| DefaultParam.cs:3:46:3:46 | SSA param_default(i) | DefaultParam.cs:3:46:3:46 | 0 |
| DefaultParam.cs:4:5:6:5 | SSA phi(i) | DefaultParam.cs:4:5:6:5 | {...} |
| Example.cs:6:23:6:23 | SSA param(i) | Example.cs:6:23:6:23 | i |
| Example.cs:8:9:8:22 | SSA def(this.Field) | Example.cs:8:9:8:22 | ... = ... |
| Example.cs:11:13:11:30 | SSA def(this.Field) | Example.cs:11:13:11:30 | ... = ... |
| Example.cs:13:13:13:23 | SSA call def(this.Field) | Example.cs:13:13:13:23 | call to method SetField |
| Example.cs:18:16:18:16 | SSA param(p) | Example.cs:18:16:18:16 | p |
| Example.cs:18:24:18:24 | SSA param(b) | Example.cs:18:24:18:24 | b |
| Example.cs:23:13:23:17 | SSA def(p) | Example.cs:23:13:23:17 | ... = ... |
| Fields.cs:16:17:16:17 | SSA entry def(this.xs) | Fields.cs:16:17:16:17 | F |
| Fields.cs:19:9:19:13 | SSA call def(this.xs) | Fields.cs:19:9:19:13 | call to method Upd |
| Fields.cs:20:9:20:14 | SSA def(x) | Fields.cs:20:9:20:14 | ... = ... |
| Fields.cs:22:13:22:17 | SSA call def(this.xs) | Fields.cs:22:13:22:17 | call to method Upd |
| Fields.cs:24:9:24:23 | SSA def(this.xs) | Fields.cs:24:9:24:23 | ... = ... |
| Fields.cs:28:17:28:17 | SSA entry def(Fields.stat) | Fields.cs:28:17:28:17 | G |
| Fields.cs:28:17:28:17 | SSA entry def(this.xs) | Fields.cs:28:17:28:17 | G |
| Fields.cs:30:13:30:28 | SSA def(f) | Fields.cs:30:13:30:28 | Fields f = ... |
| Fields.cs:30:13:30:28 | SSA qualifier def(f.xs) | Fields.cs:30:13:30:28 | Fields f = ... |
| Fields.cs:30:17:30:28 | SSA call def(Fields.stat) | Fields.cs:30:17:30:28 | object creation of type Fields |
| Fields.cs:34:9:34:16 | SSA call def(Fields.stat) | Fields.cs:34:9:34:16 | call to method F |
| Fields.cs:34:9:34:16 | SSA call def(f.xs) | Fields.cs:34:9:34:16 | call to method F |
| Fields.cs:34:9:34:16 | SSA call def(this.xs) | Fields.cs:34:9:34:16 | call to method F |
| Fields.cs:38:9:38:13 | SSA call def(Fields.stat) | Fields.cs:38:9:38:13 | call to method F |
| Fields.cs:38:9:38:13 | SSA call def(f.xs) | Fields.cs:38:9:38:13 | call to method F |
| Fields.cs:38:9:38:13 | SSA call def(this.xs) | Fields.cs:38:9:38:13 | call to method F |
| Fields.cs:42:9:42:23 | SSA def(this.xs) | Fields.cs:42:9:42:23 | ... = ... |
| Fields.cs:45:9:45:25 | SSA def(f.xs) | Fields.cs:45:9:45:25 | ... = ... |
| Fields.cs:47:9:47:14 | SSA def(z) | Fields.cs:47:9:47:14 | ... = ... |
| Fields.cs:49:13:49:28 | SSA def(f) | Fields.cs:49:13:49:28 | ... = ... |
| Fields.cs:49:13:49:28 | SSA qualifier def(f.xs) | Fields.cs:49:13:49:28 | ... = ... |
| Fields.cs:49:17:49:28 | SSA call def(Fields.stat) | Fields.cs:49:17:49:28 | object creation of type Fields |
| Fields.cs:51:9:51:20 | SSA call def(Fields.stat) | Fields.cs:51:9:51:20 | object creation of type Fields |
| Fields.cs:61:17:61:17 | SSA entry def(this.LoopField) | Fields.cs:61:17:61:17 | H |
| Fields.cs:61:17:61:17 | SSA entry def(this.SingleAccessedField) | Fields.cs:61:17:61:17 | H |
| Fields.cs:74:17:74:17 | SSA entry def(this.SingleAccessedField) | Fields.cs:74:17:74:17 | I |
| Fields.cs:77:13:77:45 | SSA def(f) | Fields.cs:77:13:77:45 | Fields f = ... |
| Fields.cs:78:23:78:54 | SSA def(a) | Fields.cs:78:23:78:54 | Action a = ... |
| Fields.cs:78:27:78:54 | SSA capture def(f) | Fields.cs:78:27:78:54 | (...) => ... |
| Fields.cs:79:23:79:35 | SSA def(b) | Fields.cs:79:23:79:35 | Action b = ... |
| Fields.cs:80:9:80:25 | SSA def(f.xs) | Fields.cs:80:9:80:25 | ... = ... |
| Fields.cs:81:9:81:11 | SSA call def(f.xs) | Fields.cs:81:9:81:11 | delegate call |
| Fields.cs:83:9:83:25 | SSA def(f.xs) | Fields.cs:83:9:83:25 | ... = ... |
| Fields.cs:85:9:85:22 | SSA def(this.xs) | Fields.cs:85:9:85:22 | ... = ... |
| Fields.cs:86:9:86:47 | SSA call def(f.xs) | Fields.cs:86:9:86:47 | call to method Select<Int32,Int32> |
| Fields.cs:86:24:86:46 | SSA capture def(a) | Fields.cs:86:24:86:46 | (...) => ... |
| Fields.cs:87:9:87:22 | SSA def(this.xs) | Fields.cs:87:9:87:22 | ... = ... |
| Fields.cs:88:9:88:25 | SSA def(f.xs) | Fields.cs:88:9:88:25 | ... = ... |
| Fields.cs:89:24:89:46 | SSA capture def(b) | Fields.cs:89:24:89:46 | (...) => ... |
| Fields.cs:95:19:95:19 | SSA param(f) | Fields.cs:95:19:95:19 | f |
| Fields.cs:97:9:97:30 | SSA def(f.Field) | Fields.cs:97:9:97:30 | ... = ... |
| Fields.cs:97:9:97:30 | SSA qualifier def(f.Field.Field) | Fields.cs:97:9:97:30 | ... = ... |
| Fields.cs:97:9:97:30 | SSA qualifier def(f.Field.Field.Field) | Fields.cs:97:9:97:30 | ... = ... |
| Fields.cs:97:9:97:30 | SSA qualifier def(f.Field.Field.Field.Field) | Fields.cs:97:9:97:30 | ... = ... |
| Fields.cs:102:9:102:28 | SSA def(this.Field) | Fields.cs:102:9:102:28 | ... = ... |
| Fields.cs:107:33:107:33 | SSA param(f) | Fields.cs:107:33:107:33 | f |
| Fields.cs:109:10:109:10 | SSA entry def(this.Field) | Fields.cs:109:10:109:10 | K |
| Fields.cs:114:9:114:22 | SSA call def(this.Field) | Fields.cs:114:9:114:22 | call to method SetField |
| Fields.cs:114:9:114:22 | SSA call def(this.Field.Field) | Fields.cs:114:9:114:22 | call to method SetField |
| Fields.cs:114:9:114:22 | SSA qualifier def(this.Field.Field.xs) | Fields.cs:114:9:114:22 | call to method SetField |
| MultiImplementationA.cs:5:22:5:22 | SSA param(x) | MultiImplementationA.cs:5:16:5:16 | M |
| MultiImplementationB.cs:3:22:3:22 | SSA param(x) | MultiImplementationA.cs:5:16:5:16 | M |
| OutRef.cs:7:10:7:10 | SSA entry def(this.Field) | OutRef.cs:7:10:7:10 | M |
| OutRef.cs:9:13:9:17 | SSA def(j) | OutRef.cs:9:13:9:17 | Int32 j = ... |
| OutRef.cs:10:25:10:25 | SSA def(i) | OutRef.cs:10:9:10:33 | call to method OutRefM |
| OutRef.cs:10:32:10:32 | SSA def(j) | OutRef.cs:10:9:10:33 | call to method OutRefM |
| OutRef.cs:13:21:13:21 | SSA def(i) | OutRef.cs:13:9:13:33 | call to method OutRefM |
| OutRef.cs:13:28:13:32 | SSA def(this.Field) | OutRef.cs:13:9:13:33 | call to method OutRefM |
| OutRef.cs:16:21:16:25 | SSA def(this.Field) | OutRef.cs:16:9:16:37 | call to method OutRefM |
| OutRef.cs:18:13:18:28 | SSA def(t) | OutRef.cs:18:13:18:28 | OutRef t = ... |
| OutRef.cs:18:13:18:28 | SSA qualifier def(t.Field) | OutRef.cs:18:13:18:28 | OutRef t = ... |
| OutRef.cs:19:21:19:25 | SSA def(this.Field) | OutRef.cs:19:9:19:39 | call to method OutRefM |
| OutRef.cs:19:32:19:38 | SSA def(t.Field) | OutRef.cs:19:9:19:39 | call to method OutRefM |
| OutRef.cs:22:22:22:22 | SSA def(j) | OutRef.cs:22:9:22:30 | call to method OutRefM2 |
| OutRef.cs:24:29:24:29 | SSA def(j) | OutRef.cs:24:9:24:30 | call to method OutRefM3 |
| OutRef.cs:28:37:28:37 | SSA param(j) | OutRef.cs:28:37:28:37 | j |
| OutRef.cs:30:9:30:13 | SSA def(i) | OutRef.cs:30:9:30:13 | ... = ... |
| OutRef.cs:31:9:31:13 | SSA def(j) | OutRef.cs:31:9:31:13 | ... = ... |
| OutRef.cs:34:38:34:38 | SSA param(j) | OutRef.cs:34:38:34:38 | j |
| OutRef.cs:36:9:36:13 | SSA def(i) | OutRef.cs:36:9:36:13 | ... = ... |
| OutRef.cs:39:24:39:24 | SSA param(b) | OutRef.cs:39:24:39:24 | b |
| OutRef.cs:39:35:39:35 | SSA param(j) | OutRef.cs:39:35:39:35 | j |
| OutRef.cs:42:13:42:17 | SSA def(j) | OutRef.cs:42:13:42:17 | ... = ... |
| Patterns.cs:7:16:7:23 | SSA def(o) | Patterns.cs:7:16:7:23 | Object o = ... |
| Patterns.cs:8:18:8:23 | SSA def(i1) | Patterns.cs:8:18:8:23 | Int32 i1 |
| Patterns.cs:12:23:12:31 | SSA def(s1) | Patterns.cs:12:23:12:31 | String s1 |
| Patterns.cs:24:18:24:23 | SSA def(i2) | Patterns.cs:24:18:24:23 | Int32 i2 |
| Patterns.cs:27:18:27:23 | SSA def(i3) | Patterns.cs:27:18:27:23 | Int32 i3 |
| Patterns.cs:30:18:30:26 | SSA def(s2) | Patterns.cs:30:18:30:26 | String s2 |
| Properties.cs:16:17:16:17 | SSA entry def(this.xs) | Properties.cs:16:17:16:17 | F |
| Properties.cs:19:9:19:13 | SSA call def(this.xs) | Properties.cs:19:9:19:13 | call to method Upd |
| Properties.cs:20:9:20:14 | SSA def(x) | Properties.cs:20:9:20:14 | ... = ... |
| Properties.cs:22:13:22:17 | SSA call def(this.xs) | Properties.cs:22:13:22:17 | call to method Upd |
| Properties.cs:24:9:24:23 | SSA def(this.xs) | Properties.cs:24:9:24:23 | ... = ... |
| Properties.cs:28:17:28:17 | SSA entry def(Properties.stat) | Properties.cs:28:17:28:17 | G |
| Properties.cs:28:17:28:17 | SSA entry def(this.xs) | Properties.cs:28:17:28:17 | G |
| Properties.cs:30:13:30:32 | SSA def(f) | Properties.cs:30:13:30:32 | Properties f = ... |
| Properties.cs:30:13:30:32 | SSA qualifier def(f.xs) | Properties.cs:30:13:30:32 | Properties f = ... |
| Properties.cs:30:17:30:32 | SSA call def(Properties.stat) | Properties.cs:30:17:30:32 | object creation of type Properties |
| Properties.cs:34:9:34:16 | SSA call def(Properties.stat) | Properties.cs:34:9:34:16 | call to method F |
| Properties.cs:34:9:34:16 | SSA call def(f.xs) | Properties.cs:34:9:34:16 | call to method F |
| Properties.cs:34:9:34:16 | SSA call def(this.xs) | Properties.cs:34:9:34:16 | call to method F |
| Properties.cs:38:9:38:13 | SSA call def(Properties.stat) | Properties.cs:38:9:38:13 | call to method F |
| Properties.cs:38:9:38:13 | SSA call def(f.xs) | Properties.cs:38:9:38:13 | call to method F |
| Properties.cs:38:9:38:13 | SSA call def(this.xs) | Properties.cs:38:9:38:13 | call to method F |
| Properties.cs:42:9:42:23 | SSA def(this.xs) | Properties.cs:42:9:42:23 | ... = ... |
| Properties.cs:45:9:45:25 | SSA def(f.xs) | Properties.cs:45:9:45:25 | ... = ... |
| Properties.cs:47:9:47:14 | SSA def(z) | Properties.cs:47:9:47:14 | ... = ... |
| Properties.cs:49:13:49:32 | SSA def(f) | Properties.cs:49:13:49:32 | ... = ... |
| Properties.cs:49:13:49:32 | SSA qualifier def(f.xs) | Properties.cs:49:13:49:32 | ... = ... |
| Properties.cs:49:17:49:32 | SSA call def(Properties.stat) | Properties.cs:49:17:49:32 | object creation of type Properties |
| Properties.cs:51:9:51:24 | SSA call def(Properties.stat) | Properties.cs:51:9:51:24 | object creation of type Properties |
| Properties.cs:61:17:61:17 | SSA entry def(this.LoopProp) | Properties.cs:61:17:61:17 | H |
| Properties.cs:61:17:61:17 | SSA entry def(this.SingleAccessedProp) | Properties.cs:61:17:61:17 | H |
| Properties.cs:61:23:61:23 | SSA param(i) | Properties.cs:61:23:61:23 | i |
| Properties.cs:63:16:63:18 | SSA def(i) | Properties.cs:63:16:63:18 | ...-- |
| Properties.cs:70:17:70:17 | SSA entry def(this.SingleAccessedProp) | Properties.cs:70:17:70:17 | I |
| Properties.cs:73:13:73:32 | SSA def(f) | Properties.cs:73:13:73:32 | Properties f = ... |
| Properties.cs:74:23:74:54 | SSA def(a) | Properties.cs:74:23:74:54 | Action a = ... |
| Properties.cs:74:27:74:54 | SSA capture def(f) | Properties.cs:74:27:74:54 | (...) => ... |
| Properties.cs:75:23:75:35 | SSA def(b) | Properties.cs:75:23:75:35 | Action b = ... |
| Properties.cs:76:9:76:25 | SSA def(f.xs) | Properties.cs:76:9:76:25 | ... = ... |
| Properties.cs:77:9:77:11 | SSA call def(f.xs) | Properties.cs:77:9:77:11 | delegate call |
| Properties.cs:79:9:79:25 | SSA def(f.xs) | Properties.cs:79:9:79:25 | ... = ... |
| Properties.cs:81:9:81:22 | SSA def(this.xs) | Properties.cs:81:9:81:22 | ... = ... |
| Properties.cs:82:9:82:47 | SSA call def(f.xs) | Properties.cs:82:9:82:47 | call to method Select<Int32,Int32> |
| Properties.cs:82:24:82:46 | SSA capture def(a) | Properties.cs:82:24:82:46 | (...) => ... |
| Properties.cs:83:9:83:22 | SSA def(this.xs) | Properties.cs:83:9:83:22 | ... = ... |
| Properties.cs:84:9:84:25 | SSA def(f.xs) | Properties.cs:84:9:84:25 | ... = ... |
| Properties.cs:85:24:85:46 | SSA capture def(b) | Properties.cs:85:24:85:46 | (...) => ... |
| Properties.cs:106:37:106:37 | SSA param(p) | Properties.cs:106:37:106:37 | p |
| Properties.cs:108:10:108:10 | SSA entry def(this.Props) | Properties.cs:108:10:108:10 | K |
| Properties.cs:113:9:113:22 | SSA call def(this.Props) | Properties.cs:113:9:113:22 | call to method SetProps |
| Properties.cs:113:9:113:22 | SSA call def(this.Props.Props) | Properties.cs:113:9:113:22 | call to method SetProps |
| Properties.cs:113:9:113:22 | SSA qualifier def(this.Props.Props.xs) | Properties.cs:113:9:113:22 | call to method SetProps |
| Test.cs:5:15:5:20 | SSA param(param1) | Test.cs:5:15:5:20 | param1 |
| Test.cs:5:67:5:72 | SSA param(param2) | Test.cs:5:67:5:72 | param2 |
| Test.cs:7:9:7:17 | SSA def(this.field) | Test.cs:7:9:7:17 | ... = ... |
| Test.cs:8:13:8:17 | SSA def(x) | Test.cs:8:13:8:17 | Int32 x = ... |
| Test.cs:13:13:13:15 | SSA def(x) | Test.cs:13:13:13:15 | ...++ |
| Test.cs:14:13:14:19 | SSA def(y) | Test.cs:14:13:14:19 | ... = ... |
| Test.cs:14:17:14:19 | SSA def(x) | Test.cs:14:17:14:19 | ++... |
| Test.cs:15:13:15:17 | SSA def(z) | Test.cs:15:13:15:17 | ... = ... |
| Test.cs:19:13:19:17 | SSA def(y) | Test.cs:19:13:19:17 | ... = ... |
| Test.cs:20:13:20:18 | SSA def(y) | Test.cs:20:13:20:18 | ... += ... |
| Test.cs:21:13:21:22 | SSA def(this.field) | Test.cs:21:13:21:22 | ... = ... |
| Test.cs:22:13:22:17 | SSA def(z) | Test.cs:22:13:22:17 | ... = ... |
| Test.cs:27:17:27:24 | SSA def(param1) | Test.cs:27:17:27:24 | ...++ |
| Test.cs:31:13:31:18 | SSA def(y) | Test.cs:31:13:31:18 | ... -= ... |
| Test.cs:34:18:34:22 | SSA def(i) | Test.cs:34:18:34:22 | Int32 i = ... |
| Test.cs:34:33:34:35 | SSA def(i) | Test.cs:34:33:34:35 | ...++ |
| Test.cs:36:13:36:18 | SSA def(x) | Test.cs:36:13:36:18 | ... += ... |
| Test.cs:39:22:39:22 | SSA def(w) | Test.cs:39:22:39:22 | Int32 w |
| Test.cs:39:22:39:22 | SSA phi(param1) | Test.cs:39:22:39:22 | Int32 w |
| Test.cs:41:13:41:23 | SSA def(param1) | Test.cs:41:13:41:23 | ... += ... |
| Test.cs:46:10:46:10 | SSA entry def(this.field) | Test.cs:46:10:46:10 | g |
| Test.cs:46:16:46:18 | SSA param(in) | Test.cs:46:16:46:18 | in |
| Test.cs:50:13:50:20 | SSA def(out) | Test.cs:50:13:50:20 | ... = ... |
| Test.cs:54:13:54:20 | SSA def(out) | Test.cs:54:13:54:20 | ... = ... |
| Test.cs:57:9:57:17 | SSA def(this.field) | Test.cs:57:9:57:17 | ... = ... |
| Test.cs:62:16:62:16 | SSA param(x) | Test.cs:62:16:62:16 | x |
| Test.cs:68:45:68:45 | SSA def(e) | Test.cs:68:45:68:45 | DivideByZeroException e |
| Test.cs:76:24:76:25 | SSA param(b1) | Test.cs:76:24:76:25 | b1 |
| Test.cs:76:33:76:34 | SSA param(b2) | Test.cs:76:33:76:34 | b2 |
| Test.cs:76:42:76:43 | SSA param(b3) | Test.cs:76:42:76:43 | b3 |
| Test.cs:76:51:76:52 | SSA param(b4) | Test.cs:76:51:76:52 | b4 |
| Test.cs:76:60:76:61 | SSA param(b5) | Test.cs:76:60:76:61 | b5 |
| Test.cs:76:69:76:70 | SSA param(b6) | Test.cs:76:69:76:70 | b6 |
| Test.cs:78:13:78:17 | SSA def(x) | Test.cs:78:13:78:17 | Int32 x = ... |
| Test.cs:108:13:108:17 | SSA def(x) | Test.cs:108:13:108:17 | ... = ... |
| Tuples.cs:10:9:10:54 | SSA def(b) | Tuples.cs:10:9:10:54 | ... = ... |
| Tuples.cs:10:9:10:54 | SSA def(s) | Tuples.cs:10:9:10:54 | ... = ... |
| Tuples.cs:10:9:10:54 | SSA def(x) | Tuples.cs:10:9:10:54 | ... = ... |
| Tuples.cs:14:9:14:32 | SSA def(b) | Tuples.cs:14:9:14:32 | ... = ... |
| Tuples.cs:14:9:14:32 | SSA def(s) | Tuples.cs:14:9:14:32 | ... = ... |
| Tuples.cs:14:9:14:32 | SSA def(x) | Tuples.cs:14:9:14:32 | ... = ... |
| Tuples.cs:18:40:18:57 | SSA def(tuple) | Tuples.cs:18:40:18:57 | (Int32,(Boolean,String)) tuple = ... |
| Tuples.cs:20:9:20:34 | SSA def(this.Field) | Tuples.cs:20:9:20:34 | ... = ... |
| Tuples.cs:20:9:20:34 | SSA def(this.Property) | Tuples.cs:20:9:20:34 | ... = ... |
| Tuples.cs:23:9:23:37 | SSA def(x) | Tuples.cs:23:9:23:37 | ... = ... |
| Tuples.cs:25:13:25:28 | SSA def(t) | Tuples.cs:25:13:25:28 | Tuples t = ... |
| Tuples.cs:26:9:26:33 | SSA def(t.Field) | Tuples.cs:26:9:26:33 | ... = ... |
| Tuples.cs:26:9:26:33 | SSA def(this.Field) | Tuples.cs:26:9:26:33 | ... = ... |

View File

@@ -1,4 +0,0 @@
import csharp
from Ssa::Definition def
select def, def.getElement()

View File

@@ -24,7 +24,7 @@
| Capture.cs:248:36:248:36 | j | Capture.cs:251:13:251:17 | SSA def(j) | Capture.cs:251:13:251:17 | ... = ... |
| Consistency.cs:7:25:7:25 | b | Consistency.cs:7:25:7:25 | SSA param(b) | Consistency.cs:7:25:7:25 | b |
| Consistency.cs:15:17:15:17 | i | Consistency.cs:15:17:15:21 | SSA def(i) | Consistency.cs:15:17:15:21 | Int32 i = ... |
| Consistency.cs:25:29:25:29 | c | Consistency.cs:25:29:25:29 | SSA def(c) | Consistency.cs:25:29:25:29 | Consistency c |
| Consistency.cs:25:29:25:29 | c | Consistency.cs:25:9:25:30 | SSA def(c) | Consistency.cs:25:29:25:29 | Consistency c |
| Consistency.cs:30:30:30:30 | c | Consistency.cs:32:9:32:29 | SSA def(c) | Consistency.cs:32:9:32:29 | ... = ... |
| Consistency.cs:44:11:44:11 | s | Consistency.cs:44:11:44:11 | SSA def(s) | Consistency.cs:44:11:44:11 | S s |
| Consistency.cs:49:30:49:30 | a | Consistency.cs:49:30:49:30 | SSA param(a) | Consistency.cs:49:30:49:30 | a |
@@ -43,21 +43,21 @@
| DefUse.cs:6:14:6:14 | y | DefUse.cs:28:13:28:18 | SSA def(y) | DefUse.cs:28:13:28:18 | ... = ... |
| DefUse.cs:6:14:6:14 | y | DefUse.cs:39:13:39:18 | SSA def(y) | DefUse.cs:39:13:39:18 | ... = ... |
| DefUse.cs:44:13:44:13 | z | DefUse.cs:44:13:44:17 | SSA def(z) | DefUse.cs:44:13:44:17 | Int32 z = ... |
| DefUse.cs:44:13:44:13 | z | DefUse.cs:47:23:47:23 | SSA def(z) | DefUse.cs:47:23:47:23 | access to local variable z |
| DefUse.cs:44:13:44:13 | z | DefUse.cs:50:23:50:23 | SSA def(z) | DefUse.cs:50:23:50:23 | access to local variable z |
| DefUse.cs:44:13:44:13 | z | DefUse.cs:47:9:47:24 | SSA def(z) | DefUse.cs:47:23:47:23 | access to local variable z |
| DefUse.cs:44:13:44:13 | z | DefUse.cs:50:9:50:24 | SSA def(z) | DefUse.cs:50:23:50:23 | access to local variable z |
| DefUse.cs:53:9:53:13 | this.Field | DefUse.cs:53:9:53:17 | SSA def(this.Field) | DefUse.cs:53:9:53:17 | ... = ... |
| DefUse.cs:56:9:56:12 | this.Prop | DefUse.cs:56:9:56:16 | SSA def(this.Prop) | DefUse.cs:56:9:56:16 | ... = ... |
| DefUse.cs:63:9:63:14 | this.Field2 | DefUse.cs:63:9:63:18 | SSA def(this.Field2) | DefUse.cs:63:9:63:18 | ... = ... |
| DefUse.cs:66:9:66:14 | this.Field3 | DefUse.cs:66:9:66:18 | SSA def(this.Field3) | DefUse.cs:66:9:66:18 | ... = ... |
| DefUse.cs:67:19:67:20 | tc | DefUse.cs:67:19:67:27 | SSA def(tc) | DefUse.cs:67:19:67:27 | TestClass tc = ... |
| DefUse.cs:79:13:79:14 | x1 | DefUse.cs:79:13:79:18 | SSA def(x1) | DefUse.cs:79:13:79:18 | Int32 x1 = ... |
| DefUse.cs:79:13:79:14 | x1 | DefUse.cs:80:30:80:31 | SSA def(x1) | DefUse.cs:80:30:80:31 | access to local variable x1 |
| DefUse.cs:79:13:79:14 | x1 | DefUse.cs:80:16:80:32 | SSA def(x1) | DefUse.cs:80:30:80:31 | access to local variable x1 |
| DefUse.cs:83:13:83:14 | x2 | DefUse.cs:83:13:83:18 | SSA def(x2) | DefUse.cs:83:13:83:18 | Int32 x2 = ... |
| DefUse.cs:83:13:83:14 | x2 | DefUse.cs:85:15:85:16 | SSA def(x2) | DefUse.cs:85:15:85:16 | access to local variable x2 |
| DefUse.cs:83:13:83:14 | x2 | DefUse.cs:85:15:85:16 | SSA def(x2) | DefUse.cs:86:15:86:16 | access to local variable x2 |
| DefUse.cs:83:13:83:14 | x2 | DefUse.cs:84:9:86:17 | SSA def(x2) | DefUse.cs:85:15:85:16 | access to local variable x2 |
| DefUse.cs:83:13:83:14 | x2 | DefUse.cs:84:9:86:17 | SSA def(x2) | DefUse.cs:86:15:86:16 | access to local variable x2 |
| DefUse.cs:89:13:89:14 | x3 | DefUse.cs:89:13:89:18 | SSA def(x3) | DefUse.cs:89:13:89:18 | Int32 x3 = ... |
| DefUse.cs:89:13:89:14 | x3 | DefUse.cs:92:15:92:16 | SSA def(x3) | DefUse.cs:92:15:92:16 | access to local variable x3 |
| DefUse.cs:90:13:90:14 | x4 | DefUse.cs:93:15:93:16 | SSA def(x4) | DefUse.cs:93:15:93:16 | access to local variable x4 |
| DefUse.cs:89:13:89:14 | x3 | DefUse.cs:91:9:93:17 | SSA def(x3) | DefUse.cs:92:15:92:16 | access to local variable x3 |
| DefUse.cs:90:13:90:14 | x4 | DefUse.cs:91:9:93:17 | SSA def(x4) | DefUse.cs:93:15:93:16 | access to local variable x4 |
| DefUse.cs:97:13:97:14 | x5 | DefUse.cs:97:13:97:18 | SSA def(x5) | DefUse.cs:97:13:97:18 | Int32 x5 = ... |
| DefUse.cs:97:13:97:14 | x5 | DefUse.cs:101:13:101:23 | SSA def(x5) | DefUse.cs:101:13:101:23 | ... = ... |
| DefUse.cs:97:13:97:14 | x5 | DefUse.cs:104:9:104:15 | SSA def(x5) | DefUse.cs:104:9:104:15 | ... += ... |
@@ -77,9 +77,9 @@
| DefUse.cs:188:13:188:18 | this.Field5 | DefUse.cs:188:13:188:22 | SSA def(this.Field5) | DefUse.cs:188:13:188:22 | ... = ... |
| DefaultParam.cs:3:20:3:20 | b | DefaultParam.cs:3:20:3:20 | SSA param(b) | DefaultParam.cs:3:20:3:20 | b |
| DefaultParam.cs:3:30:3:30 | s | DefaultParam.cs:3:30:3:30 | SSA param(s) | DefaultParam.cs:3:30:3:30 | s |
| DefaultParam.cs:3:30:3:30 | s | DefaultParam.cs:3:34:3:35 | SSA param_default(s) | DefaultParam.cs:3:34:3:35 | s = ... |
| DefaultParam.cs:3:30:3:30 | s | DefaultParam.cs:3:34:3:35 | SSA def(s) | DefaultParam.cs:3:34:3:35 | s = ... |
| DefaultParam.cs:3:42:3:42 | i | DefaultParam.cs:3:42:3:42 | SSA param(i) | DefaultParam.cs:3:42:3:42 | i |
| DefaultParam.cs:3:42:3:42 | i | DefaultParam.cs:3:46:3:46 | SSA param_default(i) | DefaultParam.cs:3:46:3:46 | i = ... |
| DefaultParam.cs:3:42:3:42 | i | DefaultParam.cs:3:46:3:46 | SSA def(i) | DefaultParam.cs:3:46:3:46 | i = ... |
| Example.cs:6:23:6:23 | i | Example.cs:6:23:6:23 | SSA param(i) | Example.cs:6:23:6:23 | i |
| Example.cs:8:9:8:18 | this.Field | Example.cs:8:9:8:22 | SSA def(this.Field) | Example.cs:8:9:8:22 | ... = ... |
| Example.cs:8:9:8:18 | this.Field | Example.cs:11:13:11:30 | SSA def(this.Field) | Example.cs:11:13:11:30 | ... = ... |
@@ -105,18 +105,20 @@
| Fields.cs:97:9:97:15 | f.Field | Fields.cs:97:9:97:30 | SSA def(f.Field) | Fields.cs:97:9:97:30 | ... = ... |
| Fields.cs:102:9:102:18 | this.Field | Fields.cs:102:9:102:28 | SSA def(this.Field) | Fields.cs:102:9:102:28 | ... = ... |
| Fields.cs:107:33:107:33 | f | Fields.cs:107:33:107:33 | SSA param(f) | Fields.cs:107:33:107:33 | f |
| MultiImplementationA.cs:5:22:5:22 | x | MultiImplementationA.cs:5:22:5:22 | SSA param(x) | MultiImplementationA.cs:5:22:5:22 | x |
| MultiImplementationA.cs:5:22:5:22 | x | MultiImplementationB.cs:3:22:3:22 | SSA param(x) | MultiImplementationA.cs:5:22:5:22 | x |
| OutRef.cs:9:13:9:13 | j | OutRef.cs:9:13:9:17 | SSA def(j) | OutRef.cs:9:13:9:17 | Int32 j = ... |
| OutRef.cs:9:13:9:13 | j | OutRef.cs:10:32:10:32 | SSA def(j) | OutRef.cs:10:32:10:32 | access to local variable j |
| OutRef.cs:9:13:9:13 | j | OutRef.cs:22:22:22:22 | SSA def(j) | OutRef.cs:22:22:22:22 | access to local variable j |
| OutRef.cs:9:13:9:13 | j | OutRef.cs:24:29:24:29 | SSA def(j) | OutRef.cs:24:29:24:29 | access to local variable j |
| OutRef.cs:10:25:10:25 | i | OutRef.cs:10:25:10:25 | SSA def(i) | OutRef.cs:10:25:10:25 | Int32 i |
| OutRef.cs:10:25:10:25 | i | OutRef.cs:13:21:13:21 | SSA def(i) | OutRef.cs:13:21:13:21 | access to local variable i |
| OutRef.cs:13:28:13:32 | this.Field | OutRef.cs:13:28:13:32 | SSA def(this.Field) | OutRef.cs:13:28:13:32 | access to field Field |
| OutRef.cs:13:28:13:32 | this.Field | OutRef.cs:16:21:16:25 | SSA def(this.Field) | OutRef.cs:16:21:16:25 | access to field Field |
| OutRef.cs:13:28:13:32 | this.Field | OutRef.cs:16:21:16:25 | SSA def(this.Field) | OutRef.cs:16:32:16:36 | access to field Field |
| OutRef.cs:13:28:13:32 | this.Field | OutRef.cs:19:21:19:25 | SSA def(this.Field) | OutRef.cs:19:21:19:25 | access to field Field |
| OutRef.cs:9:13:9:13 | j | OutRef.cs:10:9:10:33 | SSA def(j) | OutRef.cs:10:32:10:32 | access to local variable j |
| OutRef.cs:9:13:9:13 | j | OutRef.cs:22:9:22:30 | SSA def(j) | OutRef.cs:22:22:22:22 | access to local variable j |
| OutRef.cs:9:13:9:13 | j | OutRef.cs:24:9:24:30 | SSA def(j) | OutRef.cs:24:29:24:29 | access to local variable j |
| OutRef.cs:10:25:10:25 | i | OutRef.cs:10:9:10:33 | SSA def(i) | OutRef.cs:10:25:10:25 | Int32 i |
| OutRef.cs:10:25:10:25 | i | OutRef.cs:13:9:13:33 | SSA def(i) | OutRef.cs:13:21:13:21 | access to local variable i |
| OutRef.cs:13:28:13:32 | this.Field | OutRef.cs:13:9:13:33 | SSA def(this.Field) | OutRef.cs:13:28:13:32 | access to field Field |
| OutRef.cs:13:28:13:32 | this.Field | OutRef.cs:16:9:16:37 | SSA def(this.Field) | OutRef.cs:16:21:16:25 | access to field Field |
| OutRef.cs:13:28:13:32 | this.Field | OutRef.cs:16:9:16:37 | SSA def(this.Field) | OutRef.cs:16:32:16:36 | access to field Field |
| OutRef.cs:13:28:13:32 | this.Field | OutRef.cs:19:9:19:39 | SSA def(this.Field) | OutRef.cs:19:21:19:25 | access to field Field |
| OutRef.cs:18:13:18:13 | t | OutRef.cs:18:13:18:28 | SSA def(t) | OutRef.cs:18:13:18:28 | OutRef t = ... |
| OutRef.cs:19:32:19:38 | t.Field | OutRef.cs:19:32:19:38 | SSA def(t.Field) | OutRef.cs:19:32:19:38 | access to field Field |
| OutRef.cs:19:32:19:38 | t.Field | OutRef.cs:19:9:19:39 | SSA def(t.Field) | OutRef.cs:19:32:19:38 | access to field Field |
| OutRef.cs:28:26:28:26 | i | OutRef.cs:30:9:30:13 | SSA def(i) | OutRef.cs:30:9:30:13 | ... = ... |
| OutRef.cs:28:37:28:37 | j | OutRef.cs:28:37:28:37 | SSA param(j) | OutRef.cs:28:37:28:37 | j |
| OutRef.cs:28:37:28:37 | j | OutRef.cs:31:9:31:13 | SSA def(j) | OutRef.cs:31:9:31:13 | ... = ... |

View File

@@ -1,5 +1,5 @@
import csharp
from Ssa::SourceVariable v, Ssa::ExplicitDefinition def
from Ssa::SourceVariable v, SsaExplicitWrite def
where v = def.getSourceVariable()
select v, def, def.getADefinition()
select v, def, def.getDefinition()

View File

@@ -1,5 +1,5 @@
import csharp
from Ssa::SourceVariable v, Ssa::ParameterDefinition def
from Ssa::SourceVariable v, SsaParameterInit def
where v = def.getSourceVariable()
select v, def, def.getParameter()

View File

@@ -1,15 +1,11 @@
| Consistency.cs:26:13:26:19 | c.Field | Consistency.cs:25:29:25:29 | SSA qualifier def(c.Field) | Consistency.cs:25:29:25:29 | SSA def(c) |
| Consistency.cs:26:13:26:19 | c.Field | Consistency.cs:25:9:25:30 | SSA qualifier def(c.Field) | Consistency.cs:25:9:25:30 | SSA def(c) |
| Fields.cs:31:19:31:22 | f.xs | Fields.cs:30:13:30:28 | SSA qualifier def(f.xs) | Fields.cs:30:13:30:28 | SSA def(f) |
| Fields.cs:31:19:31:22 | f.xs | Fields.cs:49:13:49:28 | SSA qualifier def(f.xs) | Fields.cs:49:13:49:28 | SSA def(f) |
| Fields.cs:98:20:98:32 | f.Field.Field | Fields.cs:97:9:97:30 | SSA qualifier def(f.Field.Field) | Fields.cs:97:9:97:30 | SSA def(f.Field) |
| Fields.cs:99:16:99:34 | f.Field.Field.Field | Fields.cs:97:9:97:30 | SSA qualifier def(f.Field.Field.Field) | Fields.cs:97:9:97:30 | SSA qualifier def(f.Field.Field) |
| Fields.cs:100:16:100:40 | f.Field.Field.Field.Field | Fields.cs:97:9:97:30 | SSA qualifier def(f.Field.Field.Field.Field) | Fields.cs:97:9:97:30 | SSA qualifier def(f.Field.Field.Field) |
| Fields.cs:115:20:115:35 | this.Field.Field | Fields.cs:109:10:109:10 | SSA qualifier def(this.Field.Field) | Fields.cs:109:10:109:10 | SSA entry def(this.Field) |
| Fields.cs:116:21:116:39 | this.Field.Field.xs | Fields.cs:109:10:109:10 | SSA qualifier def(this.Field.Field.xs) | Fields.cs:109:10:109:10 | SSA qualifier def(this.Field.Field) |
| Fields.cs:116:21:116:39 | this.Field.Field.xs | Fields.cs:114:9:114:22 | SSA qualifier def(this.Field.Field.xs) | Fields.cs:114:9:114:22 | SSA call def(this.Field.Field) |
| OutRef.cs:19:32:19:38 | t.Field | OutRef.cs:18:13:18:28 | SSA qualifier def(t.Field) | OutRef.cs:18:13:18:28 | SSA def(t) |
| Properties.cs:31:19:31:22 | f.xs | Properties.cs:30:13:30:32 | SSA qualifier def(f.xs) | Properties.cs:30:13:30:32 | SSA def(f) |
| Properties.cs:31:19:31:22 | f.xs | Properties.cs:49:13:49:32 | SSA qualifier def(f.xs) | Properties.cs:49:13:49:32 | SSA def(f) |
| Properties.cs:114:20:114:35 | this.Props.Props | Properties.cs:108:10:108:10 | SSA qualifier def(this.Props.Props) | Properties.cs:108:10:108:10 | SSA entry def(this.Props) |
| Properties.cs:115:21:115:39 | this.Props.Props.xs | Properties.cs:108:10:108:10 | SSA qualifier def(this.Props.Props.xs) | Properties.cs:108:10:108:10 | SSA qualifier def(this.Props.Props) |
| Properties.cs:115:21:115:39 | this.Props.Props.xs | Properties.cs:113:9:113:22 | SSA qualifier def(this.Props.Props.xs) | Properties.cs:113:9:113:22 | SSA call def(this.Props.Props) |

View File

@@ -35,10 +35,10 @@
| Capture.cs:212:30:212:35 | exited | Capture.cs:212:30:212:71 | SSA def(exited) | Capture.cs:213:29:213:34 | access to local variable exited |
| Consistency.cs:7:25:7:25 | b | Consistency.cs:7:25:7:25 | SSA param(b) | Consistency.cs:11:17:11:17 | access to parameter b |
| Consistency.cs:15:17:15:17 | i | Consistency.cs:15:17:15:21 | SSA def(i) | Consistency.cs:16:17:16:17 | access to local variable i |
| Consistency.cs:25:29:25:29 | c | Consistency.cs:25:29:25:29 | SSA def(c) | Consistency.cs:26:13:26:13 | access to local variable c |
| Consistency.cs:25:29:25:29 | c | Consistency.cs:25:29:25:29 | SSA def(c) | Consistency.cs:27:13:27:13 | access to local variable c |
| Consistency.cs:26:13:26:19 | c.Field | Consistency.cs:25:29:25:29 | SSA qualifier def(c.Field) | Consistency.cs:26:13:26:19 | access to field Field |
| Consistency.cs:26:13:26:19 | c.Field | Consistency.cs:25:29:25:29 | SSA qualifier def(c.Field) | Consistency.cs:27:13:27:19 | access to field Field |
| Consistency.cs:25:29:25:29 | c | Consistency.cs:25:9:25:30 | SSA def(c) | Consistency.cs:26:13:26:13 | access to local variable c |
| Consistency.cs:25:29:25:29 | c | Consistency.cs:25:9:25:30 | SSA def(c) | Consistency.cs:27:13:27:13 | access to local variable c |
| Consistency.cs:26:13:26:19 | c.Field | Consistency.cs:25:9:25:30 | SSA qualifier def(c.Field) | Consistency.cs:26:13:26:19 | access to field Field |
| Consistency.cs:26:13:26:19 | c.Field | Consistency.cs:25:9:25:30 | SSA qualifier def(c.Field) | Consistency.cs:27:13:27:19 | access to field Field |
| Consistency.cs:30:30:30:30 | c | Consistency.cs:32:9:32:29 | SSA def(c) | Consistency.cs:33:9:33:9 | access to parameter c |
| Consistency.cs:44:11:44:11 | s | Consistency.cs:44:11:44:11 | SSA def(s) | Consistency.cs:45:9:45:9 | access to local variable s |
| Consistency.cs:44:11:44:11 | s | Consistency.cs:44:11:44:11 | SSA def(s) | Consistency.cs:46:13:46:13 | access to local variable s |
@@ -63,9 +63,9 @@
| DefUse.cs:6:14:6:14 | y | DefUse.cs:28:13:28:18 | SSA def(y) | DefUse.cs:34:13:34:13 | access to local variable y |
| DefUse.cs:6:14:6:14 | y | DefUse.cs:37:9:40:9 | SSA phi(y) | DefUse.cs:42:13:42:13 | access to local variable y |
| DefUse.cs:44:13:44:13 | z | DefUse.cs:44:13:44:17 | SSA def(z) | DefUse.cs:45:13:45:13 | access to local variable z |
| DefUse.cs:44:13:44:13 | z | DefUse.cs:47:23:47:23 | SSA def(z) | DefUse.cs:48:13:48:13 | access to local variable z |
| DefUse.cs:44:13:44:13 | z | DefUse.cs:47:23:47:23 | SSA def(z) | DefUse.cs:50:23:50:23 | access to local variable z |
| DefUse.cs:44:13:44:13 | z | DefUse.cs:50:23:50:23 | SSA def(z) | DefUse.cs:51:13:51:13 | access to local variable z |
| DefUse.cs:44:13:44:13 | z | DefUse.cs:47:9:47:24 | SSA def(z) | DefUse.cs:48:13:48:13 | access to local variable z |
| DefUse.cs:44:13:44:13 | z | DefUse.cs:47:9:47:24 | SSA def(z) | DefUse.cs:50:23:50:23 | access to local variable z |
| DefUse.cs:44:13:44:13 | z | DefUse.cs:50:9:50:24 | SSA def(z) | DefUse.cs:51:13:51:13 | access to local variable z |
| DefUse.cs:53:9:53:13 | this.Field | DefUse.cs:53:9:53:17 | SSA def(this.Field) | DefUse.cs:54:13:54:17 | access to field Field |
| DefUse.cs:56:9:56:12 | this.Prop | DefUse.cs:56:9:56:16 | SSA def(this.Prop) | DefUse.cs:57:13:57:16 | access to property Prop |
| DefUse.cs:63:9:63:14 | this.Field2 | DefUse.cs:63:9:63:18 | SSA def(this.Field2) | DefUse.cs:64:13:64:18 | access to field Field2 |
@@ -73,12 +73,12 @@
| DefUse.cs:66:9:66:14 | this.Field3 | DefUse.cs:66:9:66:18 | SSA def(this.Field3) | DefUse.cs:69:13:69:18 | access to field Field3 |
| DefUse.cs:67:19:67:20 | tc | DefUse.cs:67:19:67:27 | SSA def(tc) | DefUse.cs:68:9:68:10 | access to local variable tc |
| DefUse.cs:79:13:79:14 | x1 | DefUse.cs:80:9:80:51 | SSA phi(x1) | DefUse.cs:80:30:80:31 | access to local variable x1 |
| DefUse.cs:79:13:79:14 | x1 | DefUse.cs:80:30:80:31 | SSA def(x1) | DefUse.cs:81:13:81:14 | access to local variable x1 |
| DefUse.cs:79:13:79:14 | x1 | DefUse.cs:80:16:80:32 | SSA def(x1) | DefUse.cs:81:13:81:14 | access to local variable x1 |
| DefUse.cs:83:13:83:14 | x2 | DefUse.cs:83:13:83:18 | SSA def(x2) | DefUse.cs:85:15:85:16 | access to local variable x2 |
| DefUse.cs:83:13:83:14 | x2 | DefUse.cs:85:15:85:16 | SSA def(x2) | DefUse.cs:87:13:87:14 | access to local variable x2 |
| DefUse.cs:83:13:83:14 | x2 | DefUse.cs:84:9:86:17 | SSA def(x2) | DefUse.cs:87:13:87:14 | access to local variable x2 |
| DefUse.cs:89:13:89:14 | x3 | DefUse.cs:89:13:89:18 | SSA def(x3) | DefUse.cs:92:15:92:16 | access to local variable x3 |
| DefUse.cs:89:13:89:14 | x3 | DefUse.cs:92:15:92:16 | SSA def(x3) | DefUse.cs:94:13:94:14 | access to local variable x3 |
| DefUse.cs:90:13:90:14 | x4 | DefUse.cs:93:15:93:16 | SSA def(x4) | DefUse.cs:95:13:95:14 | access to local variable x4 |
| DefUse.cs:89:13:89:14 | x3 | DefUse.cs:91:9:93:17 | SSA def(x3) | DefUse.cs:94:13:94:14 | access to local variable x3 |
| DefUse.cs:90:13:90:14 | x4 | DefUse.cs:91:9:93:17 | SSA def(x4) | DefUse.cs:95:13:95:14 | access to local variable x4 |
| DefUse.cs:97:13:97:14 | x5 | DefUse.cs:98:9:102:9 | SSA phi(x5) | DefUse.cs:98:16:98:17 | access to local variable x5 |
| DefUse.cs:97:13:97:14 | x5 | DefUse.cs:98:9:102:9 | SSA phi(x5) | DefUse.cs:100:17:100:18 | access to local variable x5 |
| DefUse.cs:97:13:97:14 | x5 | DefUse.cs:98:9:102:9 | SSA phi(x5) | DefUse.cs:101:18:101:19 | access to local variable x5 |
@@ -198,22 +198,22 @@
| MultiImplementationA.cs:5:22:5:22 | x | MultiImplementationA.cs:5:22:5:22 | SSA param(x) | MultiImplementationA.cs:5:28:5:28 | access to parameter x |
| MultiImplementationA.cs:5:22:5:22 | x | MultiImplementationB.cs:3:22:3:22 | SSA param(x) | MultiImplementationB.cs:3:28:3:28 | access to parameter x |
| OutRef.cs:9:13:9:13 | j | OutRef.cs:9:13:9:17 | SSA def(j) | OutRef.cs:10:32:10:32 | access to local variable j |
| OutRef.cs:9:13:9:13 | j | OutRef.cs:10:32:10:32 | SSA def(j) | OutRef.cs:12:13:12:13 | access to local variable j |
| OutRef.cs:9:13:9:13 | j | OutRef.cs:10:32:10:32 | SSA def(j) | OutRef.cs:22:29:22:29 | access to local variable j |
| OutRef.cs:9:13:9:13 | j | OutRef.cs:22:22:22:22 | SSA def(j) | OutRef.cs:23:13:23:13 | access to local variable j |
| OutRef.cs:9:13:9:13 | j | OutRef.cs:22:22:22:22 | SSA def(j) | OutRef.cs:24:29:24:29 | access to local variable j |
| OutRef.cs:9:13:9:13 | j | OutRef.cs:24:29:24:29 | SSA def(j) | OutRef.cs:25:13:25:13 | access to local variable j |
| OutRef.cs:10:25:10:25 | i | OutRef.cs:10:25:10:25 | SSA def(i) | OutRef.cs:11:13:11:13 | access to local variable i |
| OutRef.cs:10:25:10:25 | i | OutRef.cs:13:21:13:21 | SSA def(i) | OutRef.cs:14:13:14:13 | access to local variable i |
| OutRef.cs:9:13:9:13 | j | OutRef.cs:10:9:10:33 | SSA def(j) | OutRef.cs:12:13:12:13 | access to local variable j |
| OutRef.cs:9:13:9:13 | j | OutRef.cs:10:9:10:33 | SSA def(j) | OutRef.cs:22:29:22:29 | access to local variable j |
| OutRef.cs:9:13:9:13 | j | OutRef.cs:22:9:22:30 | SSA def(j) | OutRef.cs:23:13:23:13 | access to local variable j |
| OutRef.cs:9:13:9:13 | j | OutRef.cs:22:9:22:30 | SSA def(j) | OutRef.cs:24:29:24:29 | access to local variable j |
| OutRef.cs:9:13:9:13 | j | OutRef.cs:24:9:24:30 | SSA def(j) | OutRef.cs:25:13:25:13 | access to local variable j |
| OutRef.cs:10:25:10:25 | i | OutRef.cs:10:9:10:33 | SSA def(i) | OutRef.cs:11:13:11:13 | access to local variable i |
| OutRef.cs:10:25:10:25 | i | OutRef.cs:13:9:13:33 | SSA def(i) | OutRef.cs:14:13:14:13 | access to local variable i |
| OutRef.cs:13:28:13:32 | this.Field | OutRef.cs:7:10:7:10 | SSA entry def(this.Field) | OutRef.cs:13:28:13:32 | access to field Field |
| OutRef.cs:13:28:13:32 | this.Field | OutRef.cs:13:28:13:32 | SSA def(this.Field) | OutRef.cs:15:13:15:17 | access to field Field |
| OutRef.cs:13:28:13:32 | this.Field | OutRef.cs:13:28:13:32 | SSA def(this.Field) | OutRef.cs:16:32:16:36 | access to field Field |
| OutRef.cs:13:28:13:32 | this.Field | OutRef.cs:16:21:16:25 | SSA def(this.Field) | OutRef.cs:17:13:17:17 | access to field Field |
| OutRef.cs:13:28:13:32 | this.Field | OutRef.cs:19:21:19:25 | SSA def(this.Field) | OutRef.cs:20:13:20:17 | access to field Field |
| OutRef.cs:13:28:13:32 | this.Field | OutRef.cs:13:9:13:33 | SSA def(this.Field) | OutRef.cs:15:13:15:17 | access to field Field |
| OutRef.cs:13:28:13:32 | this.Field | OutRef.cs:13:9:13:33 | SSA def(this.Field) | OutRef.cs:16:32:16:36 | access to field Field |
| OutRef.cs:13:28:13:32 | this.Field | OutRef.cs:16:9:16:37 | SSA def(this.Field) | OutRef.cs:17:13:17:17 | access to field Field |
| OutRef.cs:13:28:13:32 | this.Field | OutRef.cs:19:9:19:39 | SSA def(this.Field) | OutRef.cs:20:13:20:17 | access to field Field |
| OutRef.cs:18:13:18:13 | t | OutRef.cs:18:13:18:28 | SSA def(t) | OutRef.cs:19:32:19:32 | access to local variable t |
| OutRef.cs:18:13:18:13 | t | OutRef.cs:18:13:18:28 | SSA def(t) | OutRef.cs:21:13:21:13 | access to local variable t |
| OutRef.cs:19:32:19:38 | t.Field | OutRef.cs:18:13:18:28 | SSA qualifier def(t.Field) | OutRef.cs:19:32:19:38 | access to field Field |
| OutRef.cs:19:32:19:38 | t.Field | OutRef.cs:19:32:19:38 | SSA def(t.Field) | OutRef.cs:21:13:21:19 | access to field Field |
| OutRef.cs:19:32:19:38 | t.Field | OutRef.cs:19:9:19:39 | SSA def(t.Field) | OutRef.cs:21:13:21:19 | access to field Field |
| OutRef.cs:28:37:28:37 | j | OutRef.cs:28:37:28:37 | SSA param(j) | OutRef.cs:30:13:30:13 | access to parameter j |
| OutRef.cs:34:38:34:38 | j | OutRef.cs:34:38:34:38 | SSA param(j) | OutRef.cs:36:13:36:13 | access to parameter j |
| OutRef.cs:39:24:39:24 | b | OutRef.cs:39:24:39:24 | SSA param(b) | OutRef.cs:41:13:41:13 | access to parameter b |

View File

@@ -1,6 +1,6 @@
import csharp
from Ssa::SourceVariable v, Ssa::Definition def, AssignableRead read
from Ssa::SourceVariable v, SsaDefinition def, AssignableRead read
where
read = def.getARead() and
v = def.getSourceVariable()

View File

@@ -35,8 +35,8 @@
| Capture.cs:248:36:248:36 | j | Capture.cs:251:13:251:17 | SSA def(j) | Capture.cs:251:13:251:17 | SSA def(j) |
| Consistency.cs:7:25:7:25 | b | Consistency.cs:7:25:7:25 | SSA param(b) | Consistency.cs:7:25:7:25 | SSA param(b) |
| Consistency.cs:15:17:15:17 | i | Consistency.cs:15:17:15:21 | SSA def(i) | Consistency.cs:15:17:15:21 | SSA def(i) |
| Consistency.cs:25:29:25:29 | c | Consistency.cs:25:29:25:29 | SSA def(c) | Consistency.cs:25:29:25:29 | SSA def(c) |
| Consistency.cs:26:13:26:19 | c.Field | Consistency.cs:25:29:25:29 | SSA qualifier def(c.Field) | Consistency.cs:25:29:25:29 | SSA qualifier def(c.Field) |
| Consistency.cs:25:29:25:29 | c | Consistency.cs:25:9:25:30 | SSA def(c) | Consistency.cs:25:9:25:30 | SSA def(c) |
| Consistency.cs:26:13:26:19 | c.Field | Consistency.cs:25:9:25:30 | SSA qualifier def(c.Field) | Consistency.cs:25:9:25:30 | SSA qualifier def(c.Field) |
| Consistency.cs:30:30:30:30 | c | Consistency.cs:32:9:32:29 | SSA def(c) | Consistency.cs:32:9:32:29 | SSA def(c) |
| Consistency.cs:44:11:44:11 | s | Consistency.cs:44:11:44:11 | SSA def(s) | Consistency.cs:44:11:44:11 | SSA def(s) |
| Consistency.cs:49:30:49:30 | a | Consistency.cs:49:30:49:30 | SSA param(a) | Consistency.cs:49:30:49:30 | SSA param(a) |
@@ -61,8 +61,8 @@
| DefUse.cs:6:14:6:14 | y | DefUse.cs:37:9:40:9 | SSA phi(y) | DefUse.cs:39:13:39:18 | SSA def(y) |
| DefUse.cs:6:14:6:14 | y | DefUse.cs:39:13:39:18 | SSA def(y) | DefUse.cs:39:13:39:18 | SSA def(y) |
| DefUse.cs:44:13:44:13 | z | DefUse.cs:44:13:44:17 | SSA def(z) | DefUse.cs:44:13:44:17 | SSA def(z) |
| DefUse.cs:44:13:44:13 | z | DefUse.cs:47:23:47:23 | SSA def(z) | DefUse.cs:47:23:47:23 | SSA def(z) |
| DefUse.cs:44:13:44:13 | z | DefUse.cs:50:23:50:23 | SSA def(z) | DefUse.cs:50:23:50:23 | SSA def(z) |
| DefUse.cs:44:13:44:13 | z | DefUse.cs:47:9:47:24 | SSA def(z) | DefUse.cs:47:9:47:24 | SSA def(z) |
| DefUse.cs:44:13:44:13 | z | DefUse.cs:50:9:50:24 | SSA def(z) | DefUse.cs:50:9:50:24 | SSA def(z) |
| DefUse.cs:53:9:53:13 | this.Field | DefUse.cs:53:9:53:17 | SSA def(this.Field) | DefUse.cs:53:9:53:17 | SSA def(this.Field) |
| DefUse.cs:56:9:56:12 | this.Prop | DefUse.cs:56:9:56:16 | SSA def(this.Prop) | DefUse.cs:56:9:56:16 | SSA def(this.Prop) |
| DefUse.cs:63:9:63:14 | this.Field2 | DefUse.cs:63:9:63:18 | SSA def(this.Field2) | DefUse.cs:63:9:63:18 | SSA def(this.Field2) |
@@ -70,13 +70,13 @@
| DefUse.cs:67:19:67:20 | tc | DefUse.cs:67:19:67:27 | SSA def(tc) | DefUse.cs:67:19:67:27 | SSA def(tc) |
| DefUse.cs:79:13:79:14 | x1 | DefUse.cs:79:13:79:18 | SSA def(x1) | DefUse.cs:79:13:79:18 | SSA def(x1) |
| DefUse.cs:79:13:79:14 | x1 | DefUse.cs:80:9:80:51 | SSA phi(x1) | DefUse.cs:79:13:79:18 | SSA def(x1) |
| DefUse.cs:79:13:79:14 | x1 | DefUse.cs:80:9:80:51 | SSA phi(x1) | DefUse.cs:80:30:80:31 | SSA def(x1) |
| DefUse.cs:79:13:79:14 | x1 | DefUse.cs:80:30:80:31 | SSA def(x1) | DefUse.cs:80:30:80:31 | SSA def(x1) |
| DefUse.cs:79:13:79:14 | x1 | DefUse.cs:80:9:80:51 | SSA phi(x1) | DefUse.cs:80:16:80:32 | SSA def(x1) |
| DefUse.cs:79:13:79:14 | x1 | DefUse.cs:80:16:80:32 | SSA def(x1) | DefUse.cs:80:16:80:32 | SSA def(x1) |
| DefUse.cs:83:13:83:14 | x2 | DefUse.cs:83:13:83:18 | SSA def(x2) | DefUse.cs:83:13:83:18 | SSA def(x2) |
| DefUse.cs:83:13:83:14 | x2 | DefUse.cs:85:15:85:16 | SSA def(x2) | DefUse.cs:85:15:85:16 | SSA def(x2) |
| DefUse.cs:83:13:83:14 | x2 | DefUse.cs:84:9:86:17 | SSA def(x2) | DefUse.cs:84:9:86:17 | SSA def(x2) |
| DefUse.cs:89:13:89:14 | x3 | DefUse.cs:89:13:89:18 | SSA def(x3) | DefUse.cs:89:13:89:18 | SSA def(x3) |
| DefUse.cs:89:13:89:14 | x3 | DefUse.cs:92:15:92:16 | SSA def(x3) | DefUse.cs:92:15:92:16 | SSA def(x3) |
| DefUse.cs:90:13:90:14 | x4 | DefUse.cs:93:15:93:16 | SSA def(x4) | DefUse.cs:93:15:93:16 | SSA def(x4) |
| DefUse.cs:89:13:89:14 | x3 | DefUse.cs:91:9:93:17 | SSA def(x3) | DefUse.cs:91:9:93:17 | SSA def(x3) |
| DefUse.cs:90:13:90:14 | x4 | DefUse.cs:91:9:93:17 | SSA def(x4) | DefUse.cs:91:9:93:17 | SSA def(x4) |
| DefUse.cs:97:13:97:14 | x5 | DefUse.cs:97:13:97:18 | SSA def(x5) | DefUse.cs:97:13:97:18 | SSA def(x5) |
| DefUse.cs:97:13:97:14 | x5 | DefUse.cs:98:9:102:9 | SSA phi(x5) | DefUse.cs:97:13:97:18 | SSA def(x5) |
| DefUse.cs:97:13:97:14 | x5 | DefUse.cs:98:9:102:9 | SSA phi(x5) | DefUse.cs:101:13:101:23 | SSA def(x5) |
@@ -101,13 +101,13 @@
| DefUse.cs:188:13:188:18 | this.Field5 | DefUse.cs:188:13:188:22 | SSA def(this.Field5) | DefUse.cs:188:13:188:22 | SSA def(this.Field5) |
| DefaultParam.cs:3:20:3:20 | b | DefaultParam.cs:3:20:3:20 | SSA param(b) | DefaultParam.cs:3:20:3:20 | SSA param(b) |
| DefaultParam.cs:3:30:3:30 | s | DefaultParam.cs:3:30:3:30 | SSA param(s) | DefaultParam.cs:3:30:3:30 | SSA param(s) |
| DefaultParam.cs:3:30:3:30 | s | DefaultParam.cs:3:34:3:35 | SSA param_default(s) | DefaultParam.cs:3:34:3:35 | SSA param_default(s) |
| DefaultParam.cs:3:30:3:30 | s | DefaultParam.cs:3:34:3:35 | SSA def(s) | DefaultParam.cs:3:34:3:35 | SSA def(s) |
| DefaultParam.cs:3:30:3:30 | s | DefaultParam.cs:3:42:3:42 | SSA phi(s) | DefaultParam.cs:3:30:3:30 | SSA param(s) |
| DefaultParam.cs:3:30:3:30 | s | DefaultParam.cs:3:42:3:42 | SSA phi(s) | DefaultParam.cs:3:34:3:35 | SSA param_default(s) |
| DefaultParam.cs:3:30:3:30 | s | DefaultParam.cs:3:42:3:42 | SSA phi(s) | DefaultParam.cs:3:34:3:35 | SSA def(s) |
| DefaultParam.cs:3:42:3:42 | i | DefaultParam.cs:3:42:3:42 | SSA param(i) | DefaultParam.cs:3:42:3:42 | SSA param(i) |
| DefaultParam.cs:3:42:3:42 | i | DefaultParam.cs:3:46:3:46 | SSA param_default(i) | DefaultParam.cs:3:46:3:46 | SSA param_default(i) |
| DefaultParam.cs:3:42:3:42 | i | DefaultParam.cs:3:46:3:46 | SSA def(i) | DefaultParam.cs:3:46:3:46 | SSA def(i) |
| DefaultParam.cs:3:42:3:42 | i | DefaultParam.cs:4:5:6:5 | SSA phi(i) | DefaultParam.cs:3:42:3:42 | SSA param(i) |
| DefaultParam.cs:3:42:3:42 | i | DefaultParam.cs:4:5:6:5 | SSA phi(i) | DefaultParam.cs:3:46:3:46 | SSA param_default(i) |
| DefaultParam.cs:3:42:3:42 | i | DefaultParam.cs:4:5:6:5 | SSA phi(i) | DefaultParam.cs:3:46:3:46 | SSA def(i) |
| Example.cs:6:23:6:23 | i | Example.cs:6:23:6:23 | SSA param(i) | Example.cs:6:23:6:23 | SSA param(i) |
| Example.cs:8:9:8:18 | this.Field | Example.cs:8:9:8:22 | SSA def(this.Field) | Example.cs:8:9:8:22 | SSA def(this.Field) |
| Example.cs:8:9:8:18 | this.Field | Example.cs:10:9:13:24 | SSA phi(this.Field) | Example.cs:8:9:8:22 | SSA def(this.Field) |
@@ -210,28 +210,28 @@
| Fields.cs:115:20:115:29 | this.Field | Fields.cs:109:10:109:10 | SSA entry def(this.Field) | Fields.cs:109:10:109:10 | SSA entry def(this.Field) |
| Fields.cs:115:20:115:29 | this.Field | Fields.cs:114:9:114:22 | SSA call def(this.Field) | Fields.cs:109:10:109:10 | SSA entry def(this.Field) |
| Fields.cs:115:20:115:29 | this.Field | Fields.cs:114:9:114:22 | SSA call def(this.Field) | Fields.cs:114:9:114:22 | SSA call def(this.Field) |
| Fields.cs:115:20:115:35 | this.Field.Field | Fields.cs:109:10:109:10 | SSA qualifier def(this.Field.Field) | Fields.cs:109:10:109:10 | SSA qualifier def(this.Field.Field) |
| Fields.cs:115:20:115:35 | this.Field.Field | Fields.cs:114:9:114:22 | SSA call def(this.Field.Field) | Fields.cs:109:10:109:10 | SSA qualifier def(this.Field.Field) |
| Fields.cs:115:20:115:35 | this.Field.Field | Fields.cs:109:10:109:10 | SSA entry def(this.Field.Field) | Fields.cs:109:10:109:10 | SSA entry def(this.Field.Field) |
| Fields.cs:115:20:115:35 | this.Field.Field | Fields.cs:114:9:114:22 | SSA call def(this.Field.Field) | Fields.cs:109:10:109:10 | SSA entry def(this.Field.Field) |
| Fields.cs:115:20:115:35 | this.Field.Field | Fields.cs:114:9:114:22 | SSA call def(this.Field.Field) | Fields.cs:114:9:114:22 | SSA call def(this.Field.Field) |
| Fields.cs:116:21:116:39 | this.Field.Field.xs | Fields.cs:109:10:109:10 | SSA qualifier def(this.Field.Field.xs) | Fields.cs:109:10:109:10 | SSA qualifier def(this.Field.Field.xs) |
| Fields.cs:116:21:116:39 | this.Field.Field.xs | Fields.cs:114:9:114:22 | SSA qualifier def(this.Field.Field.xs) | Fields.cs:109:10:109:10 | SSA qualifier def(this.Field.Field.xs) |
| Fields.cs:116:21:116:39 | this.Field.Field.xs | Fields.cs:109:10:109:10 | SSA entry def(this.Field.Field.xs) | Fields.cs:109:10:109:10 | SSA entry def(this.Field.Field.xs) |
| Fields.cs:116:21:116:39 | this.Field.Field.xs | Fields.cs:114:9:114:22 | SSA qualifier def(this.Field.Field.xs) | Fields.cs:109:10:109:10 | SSA entry def(this.Field.Field.xs) |
| Fields.cs:116:21:116:39 | this.Field.Field.xs | Fields.cs:114:9:114:22 | SSA qualifier def(this.Field.Field.xs) | Fields.cs:114:9:114:22 | SSA qualifier def(this.Field.Field.xs) |
| MultiImplementationA.cs:5:22:5:22 | x | MultiImplementationA.cs:5:22:5:22 | SSA param(x) | MultiImplementationA.cs:5:22:5:22 | SSA param(x) |
| MultiImplementationA.cs:5:22:5:22 | x | MultiImplementationB.cs:3:22:3:22 | SSA param(x) | MultiImplementationB.cs:3:22:3:22 | SSA param(x) |
| OutRef.cs:9:13:9:13 | j | OutRef.cs:9:13:9:17 | SSA def(j) | OutRef.cs:9:13:9:17 | SSA def(j) |
| OutRef.cs:9:13:9:13 | j | OutRef.cs:10:32:10:32 | SSA def(j) | OutRef.cs:10:32:10:32 | SSA def(j) |
| OutRef.cs:9:13:9:13 | j | OutRef.cs:22:22:22:22 | SSA def(j) | OutRef.cs:22:22:22:22 | SSA def(j) |
| OutRef.cs:9:13:9:13 | j | OutRef.cs:24:29:24:29 | SSA def(j) | OutRef.cs:22:22:22:22 | SSA def(j) |
| OutRef.cs:9:13:9:13 | j | OutRef.cs:24:29:24:29 | SSA def(j) | OutRef.cs:24:29:24:29 | SSA def(j) |
| OutRef.cs:10:25:10:25 | i | OutRef.cs:10:25:10:25 | SSA def(i) | OutRef.cs:10:25:10:25 | SSA def(i) |
| OutRef.cs:10:25:10:25 | i | OutRef.cs:13:21:13:21 | SSA def(i) | OutRef.cs:13:21:13:21 | SSA def(i) |
| OutRef.cs:9:13:9:13 | j | OutRef.cs:10:9:10:33 | SSA def(j) | OutRef.cs:10:9:10:33 | SSA def(j) |
| OutRef.cs:9:13:9:13 | j | OutRef.cs:22:9:22:30 | SSA def(j) | OutRef.cs:22:9:22:30 | SSA def(j) |
| OutRef.cs:9:13:9:13 | j | OutRef.cs:24:9:24:30 | SSA def(j) | OutRef.cs:22:9:22:30 | SSA def(j) |
| OutRef.cs:9:13:9:13 | j | OutRef.cs:24:9:24:30 | SSA def(j) | OutRef.cs:24:9:24:30 | SSA def(j) |
| OutRef.cs:10:25:10:25 | i | OutRef.cs:10:9:10:33 | SSA def(i) | OutRef.cs:10:9:10:33 | SSA def(i) |
| OutRef.cs:10:25:10:25 | i | OutRef.cs:13:9:13:33 | SSA def(i) | OutRef.cs:13:9:13:33 | SSA def(i) |
| OutRef.cs:13:28:13:32 | this.Field | OutRef.cs:7:10:7:10 | SSA entry def(this.Field) | OutRef.cs:7:10:7:10 | SSA entry def(this.Field) |
| OutRef.cs:13:28:13:32 | this.Field | OutRef.cs:13:28:13:32 | SSA def(this.Field) | OutRef.cs:13:28:13:32 | SSA def(this.Field) |
| OutRef.cs:13:28:13:32 | this.Field | OutRef.cs:16:21:16:25 | SSA def(this.Field) | OutRef.cs:16:21:16:25 | SSA def(this.Field) |
| OutRef.cs:13:28:13:32 | this.Field | OutRef.cs:19:21:19:25 | SSA def(this.Field) | OutRef.cs:19:21:19:25 | SSA def(this.Field) |
| OutRef.cs:13:28:13:32 | this.Field | OutRef.cs:13:9:13:33 | SSA def(this.Field) | OutRef.cs:13:9:13:33 | SSA def(this.Field) |
| OutRef.cs:13:28:13:32 | this.Field | OutRef.cs:16:9:16:37 | SSA def(this.Field) | OutRef.cs:16:9:16:37 | SSA def(this.Field) |
| OutRef.cs:13:28:13:32 | this.Field | OutRef.cs:19:9:19:39 | SSA def(this.Field) | OutRef.cs:19:9:19:39 | SSA def(this.Field) |
| OutRef.cs:18:13:18:13 | t | OutRef.cs:18:13:18:28 | SSA def(t) | OutRef.cs:18:13:18:28 | SSA def(t) |
| OutRef.cs:19:32:19:38 | t.Field | OutRef.cs:18:13:18:28 | SSA qualifier def(t.Field) | OutRef.cs:18:13:18:28 | SSA qualifier def(t.Field) |
| OutRef.cs:19:32:19:38 | t.Field | OutRef.cs:19:32:19:38 | SSA def(t.Field) | OutRef.cs:19:32:19:38 | SSA def(t.Field) |
| OutRef.cs:19:32:19:38 | t.Field | OutRef.cs:19:9:19:39 | SSA def(t.Field) | OutRef.cs:19:9:19:39 | SSA def(t.Field) |
| OutRef.cs:28:26:28:26 | i | OutRef.cs:30:9:30:13 | SSA def(i) | OutRef.cs:30:9:30:13 | SSA def(i) |
| OutRef.cs:28:37:28:37 | j | OutRef.cs:28:37:28:37 | SSA param(j) | OutRef.cs:28:37:28:37 | SSA param(j) |
| OutRef.cs:28:37:28:37 | j | OutRef.cs:31:9:31:13 | SSA def(j) | OutRef.cs:31:9:31:13 | SSA def(j) |
@@ -333,11 +333,11 @@
| Properties.cs:114:20:114:29 | this.Props | Properties.cs:108:10:108:10 | SSA entry def(this.Props) | Properties.cs:108:10:108:10 | SSA entry def(this.Props) |
| Properties.cs:114:20:114:29 | this.Props | Properties.cs:113:9:113:22 | SSA call def(this.Props) | Properties.cs:108:10:108:10 | SSA entry def(this.Props) |
| Properties.cs:114:20:114:29 | this.Props | Properties.cs:113:9:113:22 | SSA call def(this.Props) | Properties.cs:113:9:113:22 | SSA call def(this.Props) |
| Properties.cs:114:20:114:35 | this.Props.Props | Properties.cs:108:10:108:10 | SSA qualifier def(this.Props.Props) | Properties.cs:108:10:108:10 | SSA qualifier def(this.Props.Props) |
| Properties.cs:114:20:114:35 | this.Props.Props | Properties.cs:113:9:113:22 | SSA call def(this.Props.Props) | Properties.cs:108:10:108:10 | SSA qualifier def(this.Props.Props) |
| Properties.cs:114:20:114:35 | this.Props.Props | Properties.cs:108:10:108:10 | SSA entry def(this.Props.Props) | Properties.cs:108:10:108:10 | SSA entry def(this.Props.Props) |
| Properties.cs:114:20:114:35 | this.Props.Props | Properties.cs:113:9:113:22 | SSA call def(this.Props.Props) | Properties.cs:108:10:108:10 | SSA entry def(this.Props.Props) |
| Properties.cs:114:20:114:35 | this.Props.Props | Properties.cs:113:9:113:22 | SSA call def(this.Props.Props) | Properties.cs:113:9:113:22 | SSA call def(this.Props.Props) |
| Properties.cs:115:21:115:39 | this.Props.Props.xs | Properties.cs:108:10:108:10 | SSA qualifier def(this.Props.Props.xs) | Properties.cs:108:10:108:10 | SSA qualifier def(this.Props.Props.xs) |
| Properties.cs:115:21:115:39 | this.Props.Props.xs | Properties.cs:113:9:113:22 | SSA qualifier def(this.Props.Props.xs) | Properties.cs:108:10:108:10 | SSA qualifier def(this.Props.Props.xs) |
| Properties.cs:115:21:115:39 | this.Props.Props.xs | Properties.cs:108:10:108:10 | SSA entry def(this.Props.Props.xs) | Properties.cs:108:10:108:10 | SSA entry def(this.Props.Props.xs) |
| Properties.cs:115:21:115:39 | this.Props.Props.xs | Properties.cs:113:9:113:22 | SSA qualifier def(this.Props.Props.xs) | Properties.cs:108:10:108:10 | SSA entry def(this.Props.Props.xs) |
| Properties.cs:115:21:115:39 | this.Props.Props.xs | Properties.cs:113:9:113:22 | SSA qualifier def(this.Props.Props.xs) | Properties.cs:113:9:113:22 | SSA qualifier def(this.Props.Props.xs) |
| Test.cs:5:15:5:20 | param1 | Test.cs:5:15:5:20 | SSA param(param1) | Test.cs:5:15:5:20 | SSA param(param1) |
| Test.cs:5:15:5:20 | param1 | Test.cs:25:9:32:9 | SSA phi(param1) | Test.cs:5:15:5:20 | SSA param(param1) |

View File

@@ -1,6 +1,6 @@
import csharp
from Ssa::SourceVariable v, Ssa::Definition def, Ssa::Definition u
from Ssa::SourceVariable v, SsaDefinition def, SsaDefinition u
where
u = def.getAnUltimateDefinition() and
v = def.getSourceVariable()

View File

@@ -152,9 +152,9 @@ C#
* When a code-scanning configuration specifies the :code:`paths:` and/or :code:`paths-ignore:` settings, these are now taken into account by the C# extractor's search for :code:`.config`, :code:`.props`, XML and project files.
* Updated the generated .NET “models as data” runtime models to cover .NET 10.
* C# 14: Support for *implicit* span conversions in the QL library.
* Basic extractor support for .NET 10 is now available. Extraction is supported for .NET 10 projects in both traced mode and :code:`build mode: none`. However, code that uses language features new to C# 14 is not yet fully supported for extraction and analysis.
* Basic extractor support for .NET 10 is now available. Extraction is supported for .NET 10 projects in both traced mode and :code:`build-mode: none`. However, code that uses language features new to C# 14 is not yet fully supported for extraction and analysis.
* Added autobuilder and :code:`build-mode: none` support for :code:`.slnx` solution files.
* In :code:`build mode: none`, .NET 10 is now used by default unless a specific .NET version is specified elsewhere.
* In :code:`build-mode: none`, .NET 10 is now used by default unless a specific .NET version is specified elsewhere.
* Added implicit reads of :code:`System.Collections.Generic.KeyValuePair.Value` at taint-tracking sinks and at inputs to additional taint steps. As a result, taint-tracking queries will now produce more results when a container is tainted.
Golang

View File

@@ -0,0 +1,124 @@
.. _codeql-cli-2.25.3:
==========================
CodeQL 2.25.3 (2026-05-01)
==========================
.. contents:: Contents
:depth: 2
:local:
:backlinks: none
This is an overview of changes in the CodeQL CLI and relevant CodeQL query and library packs. For additional updates on changes to the CodeQL code scanning experience, check out the `code scanning section on the GitHub blog <https://github.blog/tag/code-scanning/>`__, `relevant GitHub Changelog updates <https://github.blog/changelog/label/application-security/>`__, `changes in the CodeQL extension for Visual Studio Code <https://marketplace.visualstudio.com/items/GitHub.vscode-codeql/changelog>`__, and the `CodeQL Action changelog <https://github.com/github/codeql-action/blob/main/CHANGELOG.md>`__.
Security Coverage
-----------------
CodeQL 2.25.3 runs a total of 496 security queries when configured with the Default suite (covering 169 CWE). The Extended suite enables an additional 131 queries (covering 32 more CWE).
CodeQL CLI
----------
Improvements
~~~~~~~~~~~~
* The :code:`codeql database finalize` command now accepts the :code:`--working-dir` flag. When specified, any extractor pre-finalize scripts will be run in that directory. If the flag is not used, the scripts will run in the source root directory (maintaining existing behavior). The flag will also be automatically passed through when running the higher-level
:code:`codeql database create` command.
Query Packs
-----------
Major Analysis Improvements
~~~~~~~~~~~~~~~~~~~~~~~~~~~
GitHub Actions
""""""""""""""
* Fixed alert messages in :code:`actions/artifact-poisoning/critical` and :code:`actions/artifact-poisoning/medium` as they previously included a redundant placeholder in the alert message that would on occasion contain a long block of yml that makes the alert difficult to understand. Also improved the wording to make it clearer that it is not the artifact that is being poisoned, but instead a potentially untrusted artifact that is consumed. Finally, changed the alert location to be the source, to align more with other queries reporting an artifact (e.g. zipslip) which is more useful.
Minor Analysis Improvements
~~~~~~~~~~~~~~~~~~~~~~~~~~~
C/C++
"""""
* Added :code:`AllocationFunction` models for :code:`aligned_alloc`, :code:`std::aligned_alloc`, and :code:`bsl::aligned_alloc`.
* The "Comparison of narrow type with wide type in loop condition" (:code:`cpp/comparison-with-wider-type`) query has been upgraded to :code:`high` precision. This query will now run in the default code scanning suite.
* The "Multiplication result converted to larger type" (:code:`cpp/integer-multiplication-cast-to-long`) query has been upgraded to :code:`high` precision. This query will now run in the default code scanning suite.
* The "Suspicious add with sizeof" (:code:`cpp/suspicious-add-sizeof`) query has been upgraded to :code:`high` precision. This query will now run in the default code scanning suite.
* The "Wrong type of arguments to formatting function" (:code:`cpp/wrong-type-format-argument`) query has been upgraded to :code:`high` precision. This query will now run in the default code scanning suite.
* The "Implicit function declaration" (:code:`cpp/implicit-function-declaration`) query has been upgraded to :code:`high` precision. However, for :code:`build-mode: none` databases, it no longer produces any results. The results in this mode were found to be very noisy and fundamentally imprecise.
C#
""
* The query :code:`cs/useless-tostring-call` has been updated to avoid false positive results in calls to :code:`StringBuilder.AppendLine` and calls of the form :code:`base.ToString()`. Moreover, the alert message has been made more precise.
JavaScript/TypeScript
"""""""""""""""""""""
* The query :code:`js/missing-rate-limiting` now takes Fastify per-route rate limiting into account.
Python
""""""
* The :code:`py/bind-socket-all-network-interfaces` query now uses the global data-flow library, leading to better precision and more results. Also, wrappers of :code:`socket.socket` in the :code:`eventlet` and :code:`gevent` libraries are now also recognized as socket binding operations.
GitHub Actions
""""""""""""""
* The query :code:`actions/missing-workflow-permissions` no longer produces false positive results on reusable workflows where all callers set permissions.
Language Libraries
------------------
Breaking Changes
~~~~~~~~~~~~~~~~
C/C++
"""""
* The deprecated :code:`NonThrowingFunction` class has been removed, use :code:`NonCppThrowingFunction` instead.
* The deprecated :code:`ThrowingFunction` class has been removed, use :code:`AlwaysSehThrowingFunction` instead.
Major Analysis Improvements
~~~~~~~~~~~~~~~~~~~~~~~~~~~
Swift
"""""
* Upgraded to allow analysis of Swift 6.3.
Minor Analysis Improvements
~~~~~~~~~~~~~~~~~~~~~~~~~~~
Java/Kotlin
"""""""""""
* The queries "Resolving XML external entity in user-controlled data" (:code:`java/xxe`) and "Resolving XML external entity in user-controlled data from local source" (:code:`java/xxe-local`) now recognize sinks in the Woodstox StAX library when :code:`com.ctc.wstx.stax.WstxInputFactory` or :code:`org.codehaus.stax2.XMLInputFactory2` are used directly.
Python
""""""
* The Python extractor now supports the new :code:`lazy import ...` and :code:`lazy from ... import ...` (as defined in `PEP-810 <https://peps.python.org/pep-0810/>`__) that will be part of Python 3.15.
GitHub Actions
""""""""""""""
* Removed false positive injection sink models for the :code:`context` input of :code:`docker/build-push-action` and the :code:`allowed-endpoints` input of :code:`step-security/harden-runner`.
Deprecated APIs
~~~~~~~~~~~~~~~
C#
""
* The predicates :code:`get[L|R]Value` in the class :code:`Assignment` have been deprecated. Use :code:`get[Left|Right]Operand` instead.
New Features
~~~~~~~~~~~~
C/C++
"""""
* Added a subclass :code:`AutoconfConfigureTestFile` of :code:`ConfigurationTestFile` that represents files created by GNU autoconf configure scripts to test the build configuration.

View File

@@ -11,6 +11,7 @@ A list of queries for each suite and language `is available here <https://docs.g
.. toctree::
:maxdepth: 1
codeql-cli-2.25.3
codeql-cli-2.25.2
codeql-cli-2.25.1
codeql-cli-2.25.0

View File

@@ -2732,11 +2732,6 @@ class PatternExpr extends Expr {
*/
LocalVariableDeclExpr asBindingOrUnnamedPattern() { result = this }
/**
* DEPRECATED: alias for `asBindingOrUnnamedPattern`.
*/
deprecated LocalVariableDeclExpr asBindingPattern() { result = this.asBindingOrUnnamedPattern() }
/**
* Gets this pattern cast to a record pattern.
*/

View File

@@ -810,14 +810,6 @@ class Field extends Member, ExprParent, @field, Variable {
)
}
/**
* DEPRECATED: The result is always `this`.
*/
deprecated Field getSourceDeclaration() { result = this }
/** DEPRECATED: This always holds. */
deprecated predicate isSourceDeclaration() { any() }
override predicate isPublic() {
Member.super.isPublic()
or

View File

@@ -558,11 +558,6 @@ class ConstCase extends SwitchCase {
class PatternCase extends SwitchCase {
PatternCase() { exists(PatternExpr pe | pe.isNthChildOf(this, _)) }
/**
* DEPRECATED: alias for getPattern(0)
*/
deprecated PatternExpr getPattern() { result = this.getPattern(0) }
/**
* Gets this case's `n`th pattern.
*/

View File

@@ -637,9 +637,6 @@ class RefType extends Type, Annotatable, Modifiable, @reftype {
this.(NestedType).getEnclosingType().getNestedName() + "$" + this.getName() = result
}
/** DEPRECATED: Alias for `getNestedName`. */
deprecated string nestedName() { result = this.getNestedName() }
/**
* Gets the source declaration of this type.
*

View File

@@ -10,57 +10,6 @@ import java
* Predicates for basic-block-level dominance.
*/
/**
* DEPRECATED: Use `BasicBlock::immediatelyDominates` instead.
*
* The immediate dominance relation for basic blocks.
*/
deprecated predicate bbIDominates(BasicBlock dom, BasicBlock node) {
dom.immediatelyDominates(node)
}
/** Exit points for basic-block control-flow. */
private predicate bbSink(BasicBlock exit) { exit.getLastNode() instanceof ControlFlow::ExitNode }
/** Reversed `bbSucc`. */
private predicate bbPred(BasicBlock post, BasicBlock pre) { post = pre.getASuccessor() }
/** The immediate post-dominance relation on basic blocks. */
deprecated predicate bbIPostDominates(BasicBlock dominator, BasicBlock node) =
idominance(bbSink/1, bbPred/2)(_, dominator, node)
/**
* DEPRECATED: Use `BasicBlock::strictlyDominates` instead.
*
* Holds if `dom` strictly dominates `node`.
*/
deprecated predicate bbStrictlyDominates(BasicBlock dom, BasicBlock node) {
dom.strictlyDominates(node)
}
/**
* DEPRECATED: Use `BasicBlock::dominates` instead.
*
* Holds if `dom` dominates `node`. (This is reflexive.)
*/
deprecated predicate bbDominates(BasicBlock dom, BasicBlock node) { dom.dominates(node) }
/**
* DEPRECATED: Use `BasicBlock::strictlyPostDominates` instead.
*
* Holds if `dom` strictly post-dominates `node`.
*/
deprecated predicate bbStrictlyPostDominates(BasicBlock dom, BasicBlock node) {
dom.strictlyPostDominates(node)
}
/**
* DEPRECATED: Use `BasicBlock::postDominates` instead.
*
* Holds if `dom` post-dominates `node`. (This is reflexive.)
*/
deprecated predicate bbPostDominates(BasicBlock dom, BasicBlock node) { dom.postDominates(node) }
/**
* The dominance frontier relation for basic blocks.
*

View File

@@ -43,14 +43,6 @@ abstract class SourceNode extends DataFlow::Node {
abstract string getThreatModel();
}
/**
* DEPRECATED: Use `ActiveThreatModelSource` instead.
*
* A class of data flow sources that respects the
* current threat model configuration.
*/
deprecated class ThreatModelFlowSource = ActiveThreatModelSource;
/**
* A data flow source that is enabled in the current threat model configuration.
*/

View File

@@ -8,14 +8,6 @@ import java
private import internal.FlowSummaryImpl as Impl
private import internal.DataFlowUtil
deprecated class SummaryComponent = Impl::Private::SummaryComponent;
deprecated module SummaryComponent = Impl::Private::SummaryComponent;
deprecated class SummaryComponentStack = Impl::Private::SummaryComponentStack;
deprecated module SummaryComponentStack = Impl::Private::SummaryComponentStack;
/** A synthetic callable with a set of concrete call sites and a flow summary. */
abstract class SyntheticCallable extends string {
bindingset[this]
@@ -147,5 +139,3 @@ private class SummarizedSyntheticCallableAdapter extends SummarizedCallable::Ran
)
}
}
deprecated class RequiredSummaryComponentStack = Impl::Private::RequiredSummaryComponentStack;

View File

@@ -196,18 +196,6 @@ Expr basicNullGuard(Expr e, boolean branch, boolean isnull) {
Guards_v3::nullGuard(result, any(GuardValue v | v.asBooleanValue() = branch), e, isnull)
}
/**
* DEPRECATED: Use `basicNullGuard` instead.
*
* Gets an expression that directly tests whether a given expression, `e`, is null or not.
*
* If `result` evaluates to `branch`, then `e` is guaranteed to be null if `isnull`
* is true, and non-null if `isnull` is false.
*/
deprecated Expr basicOrCustomNullGuard(Expr e, boolean branch, boolean isnull) {
result = basicNullGuard(e, branch, isnull)
}
/**
* Gets an expression that directly tests whether a given SSA variable is null or not.
*
@@ -218,18 +206,6 @@ Expr directNullGuard(SsaDefinition v, boolean branch, boolean isnull) {
result = basicNullGuard(sameValue(v, _), branch, isnull)
}
/**
* DEPRECATED: Use `nullGuardControls`/`nullGuardControlsBranchEdge` instead.
*
* Gets a `Guard` that tests (possibly indirectly) whether a given SSA variable is null or not.
*
* If `result` evaluates to `branch`, then `v` is guaranteed to be null if `isnull`
* is true, and non-null if `isnull` is false.
*/
deprecated Guard nullGuard(SsaDefinition v, boolean branch, boolean isnull) {
result = directNullGuard(v, branch, isnull)
}
/**
* Holds if there exists a null check on `v`, such that taking the branch edge
* from `bb1` to `bb2` implies that `v` is guaranteed to be null if `isnull` is

View File

@@ -198,19 +198,6 @@ module Public {
or
result = this.getType() and not exists(this.getImprovedTypeBound())
}
/**
* Holds if this element is at the specified location.
* The location spans column `startcolumn` of line `startline` to
* column `endcolumn` of line `endline` in file `filepath`.
* For more information, see
* [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
*/
deprecated predicate hasLocationInfo(
string filepath, int startline, int startcolumn, int endline, int endcolumn
) {
this.getLocation().hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn)
}
}
/**

View File

@@ -48,18 +48,6 @@ class MethodLdapNameAddAll extends Method {
}
}
/**
* DEPRECATED: No longer needed as clone steps are handled uniformly.
*
* A method with the name `clone` declared in `javax.naming.ldap.LdapName`.
*/
deprecated class MethodLdapNameClone extends Method {
MethodLdapNameClone() {
this.getDeclaringType() instanceof TypeLdapName and
this.hasName("clone")
}
}
/** A method with the name `getAll` declared in `javax.naming.ldap.LdapName`. */
class MethodLdapNameGetAll extends Method {
MethodLdapNameGetAll() {

View File

@@ -156,9 +156,6 @@ class SpringRequestMappingMethod extends SpringControllerMethod {
result = this.getProducesExpr().(CompileTimeConstantExpr).getStringValue()
}
/** DEPRECATED: Use `getAValue()` instead. */
deprecated string getValue() { result = requestMappingAnnotation.getStringValue("value") }
/**
* Gets a "value" @RequestMapping annotation string value, if present.
*

View File

@@ -20,13 +20,6 @@ class AndroidNetworkSecurityConfigFile extends XmlFile {
}
}
/**
* DEPRECATED. Use `semmle.code.java.frameworks.android.Android::inAndroidApplication` instead.
*
* Holds if this database contains an Android manifest file.
*/
deprecated predicate isAndroid() { exists(AndroidManifestXmlFile m) }
/** Holds if the given domain name is trusted by the Network Security Configuration XML file. */
private predicate trustedDomainViaXml(string domainName) {
exists(

View File

@@ -1,49 +1,5 @@
/** Provides taint-tracking configurations to reason about arithmetic using local-user-controlled data. */
overlay[local?]
deprecated module;
import java
private import semmle.code.java.dataflow.FlowSources
private import semmle.code.java.security.ArithmeticCommon
/**
* DEPRECATED: Use `ArithmeticOverflowConfig` instead.
*
* A taint-tracking configuration to reason about arithmetic overflow using local-user-controlled data.
*/
deprecated module ArithmeticTaintedLocalOverflowConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node source) { source instanceof LocalUserInput }
predicate isSink(DataFlow::Node sink) { overflowSink(_, sink.asExpr()) }
predicate isBarrier(DataFlow::Node n) { overflowBarrier(n) }
predicate isBarrierIn(DataFlow::Node node) { isSource(node) }
}
/**
* DEPRECATED: Use `ArithmeticOverflow` instead and configure threat model sources to include `local`.
*
* Taint-tracking flow for arithmetic overflow using local-user-controlled data.
*/
deprecated module ArithmeticTaintedLocalOverflowFlow =
TaintTracking::Global<ArithmeticTaintedLocalOverflowConfig>;
/**
* A taint-tracking configuration to reason about arithmetic underflow using local-user-controlled data.
*/
deprecated module ArithmeticTaintedLocalUnderflowConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node source) { source instanceof LocalUserInput }
predicate isSink(DataFlow::Node sink) { underflowSink(_, sink.asExpr()) }
predicate isBarrier(DataFlow::Node n) { underflowBarrier(n) }
predicate isBarrierIn(DataFlow::Node node) { isSource(node) }
}
/**
* DEPRECATED: Use `ArithmeticUnderflow` instead and configure threat model sources to include `local`.
*
* Taint-tracking flow for arithmetic underflow using local-user-controlled data.
*/
deprecated module ArithmeticTaintedLocalUnderflowFlow =
TaintTracking::Global<ArithmeticTaintedLocalUnderflowConfig>;

View File

@@ -25,11 +25,6 @@ module ArithmeticOverflowConfig implements DataFlow::ConfigSig {
}
}
/**
* DEPRECATED: Use `ArithmeticOverflowConfig` instead.
*/
deprecated module RemoteUserInputOverflowConfig = ArithmeticOverflowConfig;
/** A taint-tracking configuration to reason about underflow from unvalidated input. */
module ArithmeticUnderflowConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node source) { source instanceof ActiveThreatModelSource }
@@ -51,23 +46,8 @@ module ArithmeticUnderflowConfig implements DataFlow::ConfigSig {
}
}
/**
* DEPRECATED: Use `ArithmeticUnderflowConfig` instead.
*/
deprecated module RemoteUserInputUnderflowConfig = ArithmeticUnderflowConfig;
/** Taint-tracking flow for overflow from unvalidated input. */
module ArithmeticOverflow = TaintTracking::Global<ArithmeticOverflowConfig>;
/**
* DEPRECATED: Use `ArithmeticOverflow` instead.
*/
deprecated module RemoteUserInputOverflow = ArithmeticOverflow;
/** Taint-tracking flow for underflow from unvalidated input. */
module ArithmeticUnderflow = TaintTracking::Global<ArithmeticUnderflowConfig>;
/**
* DEPRECATED: Use `ArithmeticUnderflow` instead.
*/
deprecated module RemoteUserInputUnderflow = ArithmeticUnderflow;

View File

@@ -78,44 +78,11 @@ module InputToArgumentToExecFlowConfig implements DataFlow::ConfigSig {
}
}
/**
* DEPRECATED: Use `InputToArgumentToExecFlowConfig` instead.
*/
deprecated module RemoteUserInputToArgumentToExecFlowConfig = InputToArgumentToExecFlowConfig;
/**
* Taint-tracking flow for unvalidated input that is used to run an external process.
*/
module InputToArgumentToExecFlow = TaintTracking::Global<InputToArgumentToExecFlowConfig>;
/**
* DEPRECATED: Use `InputToArgumentToExecFlow` instead.
*/
deprecated module RemoteUserInputToArgumentToExecFlow = InputToArgumentToExecFlow;
/**
* A taint-tracking configuration for unvalidated local user input that is used to run an external process.
*/
deprecated module LocalUserInputToArgumentToExecFlowConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node src) { src instanceof LocalUserInput }
predicate isSink(DataFlow::Node sink) { sink instanceof CommandInjectionSink }
predicate isBarrier(DataFlow::Node node) { node instanceof CommandInjectionSanitizer }
predicate isAdditionalFlowStep(DataFlow::Node n1, DataFlow::Node n2) {
any(CommandInjectionAdditionalTaintStep s).step(n1, n2)
}
}
/**
* DEPRECATED: Use `InputToArgumentToExecFlow` instead and configure threat model sources to include `local`.
*
* Taint-tracking flow for unvalidated local user input that is used to run an external process.
*/
deprecated module LocalUserInputToArgumentToExecFlow =
TaintTracking::Global<LocalUserInputToArgumentToExecFlowConfig>;
/**
* Implementation of `ExecTainted.ql`. It is extracted to a QLL
* so that it can be excluded from `ExecUnescaped.ql` to avoid

View File

@@ -1,27 +1,5 @@
/** Provides a taint-tracking configuration to reason about use of externally controlled strings for command injection vulnerabilities. */
overlay[local?]
deprecated module;
import java
private import semmle.code.java.dataflow.FlowSources
private import semmle.code.java.security.ExternalProcess
private import semmle.code.java.security.CommandArguments
private import semmle.code.java.security.Sanitizers
/** A taint-tracking configuration to reason about use of externally controlled strings to make command line commands. */
deprecated module ExecTaintedLocalConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node src) { src instanceof LocalUserInput }
predicate isSink(DataFlow::Node sink) { sink.asExpr() instanceof ArgumentToExec }
predicate isBarrier(DataFlow::Node node) {
node instanceof SimpleTypeSanitizer
or
isSafeCommandArgument(node.asExpr())
}
}
/**
* DEPRCATED: Unused.
*
* Taint-tracking flow for use of externally controlled strings to make command line commands.
*/
deprecated module ExecTaintedLocalFlow = TaintTracking::Global<ExecTaintedLocalConfig>;

View File

@@ -1,26 +1,5 @@
/** Provides a taint-tracking configuration to reason about externally-controlled format strings from local sources. */
overlay[local?]
deprecated module;
import java
private import semmle.code.java.dataflow.FlowSources
private import semmle.code.java.StringFormat
/** A taint-tracking configuration to reason about externally-controlled format strings from local sources. */
deprecated module ExternallyControlledFormatStringLocalConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node source) { source instanceof LocalUserInput }
predicate isSink(DataFlow::Node sink) {
sink.asExpr() = any(StringFormat formatCall).getFormatArgument()
}
predicate isBarrier(DataFlow::Node node) {
node.getType() instanceof NumericType or node.getType() instanceof BooleanType
}
}
/**
* DEPRECATED: Use `ExternallyControlledFormatStringFlow` instead and configure threat model sources to include `local`.
*
* Taint-tracking flow for externally-controlled format strings from local sources.
*/
deprecated module ExternallyControlledFormatStringLocalFlow =
TaintTracking::Global<ExternallyControlledFormatStringLocalConfig>;

View File

@@ -1,24 +1,5 @@
/** Provides a taint-tracking configuration to reason about improper validation of local user-provided size used for array construction. */
overlay[local?]
deprecated module;
import java
private import semmle.code.java.security.internal.ArraySizing
private import semmle.code.java.dataflow.FlowSources
/**
* A taint-tracking configuration to reason about improper validation of local user-provided size used for array construction.
*/
deprecated module ImproperValidationOfArrayConstructionLocalConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node source) { source instanceof LocalUserInput }
predicate isSink(DataFlow::Node sink) {
any(CheckableArrayAccess caa).canThrowOutOfBoundsDueToEmptyArray(sink.asExpr(), _)
}
}
/**
* DEPRECATED: Use `ImproperValidationOfArrayConstructionFlow` instead and configure threat model sources to include `local`.
*
* Taint-tracking flow for improper validation of local user-provided size used for array construction.
*/
deprecated module ImproperValidationOfArrayConstructionLocalFlow =
TaintTracking::Global<ImproperValidationOfArrayConstructionLocalConfig>;

View File

@@ -1,28 +1,5 @@
/** Provides a taint-tracking configuration to reason about improper validation of local user-provided array index. */
overlay[local?]
deprecated module;
import java
private import semmle.code.java.security.internal.ArraySizing
private import semmle.code.java.dataflow.FlowSources
/**
* A taint-tracking configuration to reason about improper validation of local user-provided array index.
*/
deprecated module ImproperValidationOfArrayIndexLocalConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node source) { source instanceof LocalUserInput }
predicate isSink(DataFlow::Node sink) {
any(CheckableArrayAccess caa).canThrowOutOfBounds(sink.asExpr())
}
predicate isBarrier(DataFlow::Node node) { node.getType() instanceof BooleanType }
predicate isBarrierIn(DataFlow::Node node) { isSource(node) }
}
/**
* DEPRECATED: Use `ImproperValidationOfArrayIndexFlow` instead and configure threat model sources to include `local`.
*
* Taint-tracking flow for improper validation of local user-provided array index.
*/
deprecated module ImproperValidationOfArrayIndexLocalFlow =
TaintTracking::Global<ImproperValidationOfArrayIndexLocalConfig>;

View File

@@ -115,34 +115,3 @@ module NumericCastFlowConfig implements DataFlow::ConfigSig {
* Taint-tracking flow for user input that is used in a numeric cast.
*/
module NumericCastFlow = TaintTracking::Global<NumericCastFlowConfig>;
/**
* A taint-tracking configuration for reasoning about local user input that is
* used in a numeric cast.
*/
deprecated module NumericCastLocalFlowConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node src) { src instanceof LocalUserInput }
predicate isSink(DataFlow::Node sink) {
sink.asExpr() = any(NumericNarrowingCastExpr cast).getExpr() and
sink.asExpr() instanceof VarAccess
}
predicate isBarrier(DataFlow::Node node) {
boundedRead(node.asExpr()) or
castCheck(node.asExpr()) or
node.getType() instanceof SmallType or
smallExpr(node.asExpr()) or
node.getEnclosingCallable() instanceof HashCodeMethod or
exists(RightShiftOp e | e.getShiftedVariable().getAnAccess() = node.asExpr())
}
predicate isBarrierIn(DataFlow::Node node) { isSource(node) }
}
/**
* DEPRECATED: Use `NumericCastFlow` instead and configure threat model sources to include `local`.
*
* Taint-tracking flow for local user input that is used in a numeric cast.
*/
deprecated module NumericCastLocalFlow = TaintTracking::Global<NumericCastLocalFlowConfig>;

View File

@@ -1,39 +1,5 @@
/** Provides a taint-tracking configuration to reason about response splitting vulnerabilities from local user input. */
overlay[local?]
deprecated module;
import java
private import semmle.code.java.dataflow.FlowSources
private import semmle.code.java.security.ResponseSplitting
/**
* A taint-tracking configuration to reason about response splitting vulnerabilities from local user input.
*/
deprecated module ResponseSplittingLocalConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node source) { source instanceof LocalUserInput }
predicate isSink(DataFlow::Node sink) { sink instanceof HeaderSplittingSink }
predicate isBarrier(DataFlow::Node node) {
node.getType() instanceof PrimitiveType
or
node.getType() instanceof BoxedType
or
exists(MethodCall ma, string methodName, CompileTimeConstantExpr target |
node.asExpr() = ma and
ma.getMethod().hasQualifiedName("java.lang", "String", methodName) and
target = ma.getArgument(0) and
(
methodName = "replace" and target.getIntValue() = [10, 13] // 10 == "\n", 13 == "\r"
or
methodName = "replaceAll" and
target.getStringValue().regexpMatch(".*([\n\r]|\\[\\^[^\\]\r\n]*\\]).*")
)
)
}
}
/**
* DEPRECATED: Use `ResponseSplittingFlow` instead and configure threat model sources to include `local`.
*
* Taint-tracking flow for response splitting vulnerabilities from local user input.
*/
deprecated module ResponseSplittingLocalFlow = TaintTracking::Global<ResponseSplittingLocalConfig>;

View File

@@ -2,32 +2,7 @@
* Provides a taint-tracking configuration for reasoning about local user input
* that is used in a SQL query.
*/
overlay[local?]
deprecated module;
import java
private import semmle.code.java.dataflow.FlowSources
private import semmle.code.java.security.SqlInjectionQuery
private import semmle.code.java.security.Sanitizers
/**
* A taint-tracking configuration for reasoning about local user input that is
* used in a SQL query.
*/
deprecated module LocalUserInputToQueryInjectionFlowConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node src) { src instanceof LocalUserInput }
predicate isSink(DataFlow::Node sink) { sink instanceof QueryInjectionSink }
predicate isBarrier(DataFlow::Node node) { node instanceof SimpleTypeSanitizer }
predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) {
any(AdditionalQueryInjectionTaintStep s).step(node1, node2)
}
}
/**
* DEPRECATED: Use `QueryInjectionFlow` instead and configure threat model sources to include `local`.
*
* Taint-tracking flow for local user input that is used in a SQL query.
*/
deprecated module LocalUserInputToQueryInjectionFlow =
TaintTracking::Global<LocalUserInputToQueryInjectionFlowConfig>;

View File

@@ -78,28 +78,3 @@ module TaintedPathConfig implements DataFlow::ConfigSig {
/** Tracks flow from remote sources to the creation of a path. */
module TaintedPathFlow = TaintTracking::Global<TaintedPathConfig>;
/**
* A taint-tracking configuration for tracking flow from local user input to the creation of a path.
*/
deprecated module TaintedPathLocalConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node source) { source instanceof LocalUserInput }
predicate isSink(DataFlow::Node sink) { sink instanceof TaintedPathSink }
predicate isBarrier(DataFlow::Node sanitizer) {
sanitizer instanceof SimpleTypeSanitizer or
sanitizer instanceof PathInjectionSanitizer
}
predicate isAdditionalFlowStep(DataFlow::Node n1, DataFlow::Node n2) {
any(TaintedPathAdditionalTaintStep s).step(n1, n2)
}
}
/**
* DEPRECATED: Use `TaintedPathFlow` instead and configure threat model sources to include `local`.
*
* Tracks flow from local user input to the creation of a path.
*/
deprecated module TaintedPathLocalFlow = TaintTracking::Global<TaintedPathLocalConfig>;

View File

@@ -1,21 +1,5 @@
/** Provides a taint-tracking configuration to reason about URL redirection from local sources. */
overlay[local?]
deprecated module;
import java
private import semmle.code.java.dataflow.FlowSources
private import semmle.code.java.security.UrlRedirect
/**
* A taint-tracking configuration to reason about URL redirection from local sources.
*/
deprecated module UrlRedirectLocalConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node source) { source instanceof LocalUserInput }
predicate isSink(DataFlow::Node sink) { sink instanceof UrlRedirectSink }
}
/**
* DEPRECATED: Use `UrlRedirectFlow` instead and configure threat model sources to include `local`.
*
* Taint-tracking flow for URL redirection from local sources.
*/
deprecated module UrlRedirectLocalFlow = TaintTracking::Global<UrlRedirectLocalConfig>;

View File

@@ -1,30 +1,5 @@
/** Provides a taint-tracking configuration to reason about cross-site scripting from a local source. */
overlay[local?]
deprecated module;
import java
private import semmle.code.java.dataflow.FlowSources
private import semmle.code.java.dataflow.TaintTracking
private import semmle.code.java.security.XSS
/**
* A taint-tracking configuration for reasoning about cross-site scripting vulnerabilities from a local source.
*/
deprecated module XssLocalConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node source) { source instanceof LocalUserInput }
predicate isSink(DataFlow::Node sink) { sink instanceof XssSink }
predicate isBarrier(DataFlow::Node node) { node instanceof XssSanitizer }
predicate isBarrierOut(DataFlow::Node node) { node instanceof XssSinkBarrier }
predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) {
any(XssAdditionalTaintStep s).step(node1, node2)
}
}
/**
* DEPRECATED: Use `XssFlow` instead and configure threat model sources to include `local`.
*
* Taint-tracking flow for cross-site scripting vulnerabilities from a local source.
*/
deprecated module XssLocalFlow = TaintTracking::Global<XssLocalConfig>;

View File

@@ -1,28 +1,5 @@
/** Provides taint tracking configurations to be used in local XXE queries. */
overlay[local?]
deprecated module;
import java
private import semmle.code.java.dataflow.FlowSources
private import semmle.code.java.dataflow.TaintTracking
private import semmle.code.java.security.XxeQuery
/**
* A taint-tracking configuration for unvalidated local user input that is used in XML external entity expansion.
*/
deprecated module XxeLocalConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node src) { src instanceof LocalUserInput }
predicate isSink(DataFlow::Node sink) { sink instanceof XxeSink }
predicate isBarrier(DataFlow::Node sanitizer) { sanitizer instanceof XxeSanitizer }
predicate isAdditionalFlowStep(DataFlow::Node n1, DataFlow::Node n2) {
any(XxeAdditionalTaintStep s).step(n1, n2)
}
}
/**
* DEPRECATED: Use `XxeFlow` instead and configure threat model sources to include `local`.
*
* Detect taint flow of unvalidated local user input that is used in XML external entity expansion.
*/
deprecated module XxeLocalFlow = TaintTracking::Global<XxeLocalConfig>;

View File

@@ -43,7 +43,7 @@ deprecated private predicate mayBeExploitable(Method m) {
// hence, here we check for the param type to be a Java `String`.
p.getType() instanceof TypeString and
// Exclude cases where a regex check is applied on a parameter to prevent false positives.
not m.(SpringRequestMappingMethod).getValue().matches("%{%:[%]%}%")
not m.(SpringRequestMappingMethod).getAValue().matches("%{%:[%]%}%")
) and
not maybeATestMethod(m)
}

View File

@@ -1,117 +0,0 @@
/**
* Provides classes for working with MyBatis mapper xml files and their content.
*/
deprecated module;
import java
/**
* MyBatis Mapper XML file.
*/
class MyBatisMapperXmlFile extends XmlFile {
MyBatisMapperXmlFile() {
count(XmlElement e | e = this.getAChild()) = 1 and
this.getAChild().getName() = "mapper"
}
}
/**
* An XML element in a `MyBatisMapperXMLFile`.
*/
class MyBatisMapperXmlElement extends XmlElement {
MyBatisMapperXmlElement() { this.getFile() instanceof MyBatisMapperXmlFile }
/**
* Gets the value for this element, with leading and trailing whitespace trimmed.
*/
string getValue() { result = this.allCharactersString().trim() }
/**
* Gets the reference type bound to MyBatis Mapper XML File.
*/
RefType getNamespaceRefType() {
result.getQualifiedName() = this.getAttribute("namespace").getValue()
}
}
/**
* An MyBatis Mapper sql operation element.
*/
abstract class MyBatisMapperSqlOperation extends MyBatisMapperXmlElement {
/**
* Gets the value of the `id` attribute of MyBatis Mapper sql operation element.
*/
string getId() { result = this.getAttribute("id").getValue() }
/**
* Gets the `<include>` element in a `MyBatisMapperSqlOperation`.
*/
MyBatisMapperInclude getInclude() { result = this.getAChild*() }
/**
* Gets the method bound to MyBatis Mapper XML File.
*/
Method getMapperMethod() {
result.getName() = this.getId() and
result.getDeclaringType() = this.getParent().(MyBatisMapperXmlElement).getNamespaceRefType()
}
}
/**
* A `<insert>` element in a `MyBatisMapperSqlOperation`.
*/
class MyBatisMapperInsert extends MyBatisMapperSqlOperation {
MyBatisMapperInsert() { this.getName() = "insert" }
}
/**
* A `<update>` element in a `MyBatisMapperSqlOperation`.
*/
class MyBatisMapperUpdate extends MyBatisMapperSqlOperation {
MyBatisMapperUpdate() { this.getName() = "update" }
}
/**
* A `<delete>` element in a `MyBatisMapperSqlOperation`.
*/
class MyBatisMapperDelete extends MyBatisMapperSqlOperation {
MyBatisMapperDelete() { this.getName() = "delete" }
}
/**
* A `<select>` element in a `MyBatisMapperSqlOperation`.
*/
class MyBatisMapperSelect extends MyBatisMapperSqlOperation {
MyBatisMapperSelect() { this.getName() = "select" }
}
/**
* A `<sql>` element in a `MyBatisMapperXMLElement`.
*/
class MyBatisMapperSql extends MyBatisMapperXmlElement {
MyBatisMapperSql() { this.getName() = "sql" }
/**
* Gets the value of the `id` attribute of this `<sql>`.
*/
string getId() { result = this.getAttribute("id").getValue() }
}
/**
* A `<include>` element in a `MyBatisMapperXMLElement`.
*/
class MyBatisMapperInclude extends MyBatisMapperXmlElement {
MyBatisMapperInclude() { this.getName() = "include" }
/**
* Gets the value of the `refid` attribute of this `<include>`.
*/
string getRefid() { result = this.getAttribute("refid").getValue() }
}
/**
* A `<foreach>` element in a `MyBatisMapperXMLElement`.
*/
class MyBatisMapperForeach extends MyBatisMapperXmlElement {
MyBatisMapperForeach() { this.getName() = "foreach" }
}

View File

@@ -1,17 +0,0 @@
extensions:
- addsTo:
pack: codeql/javascript-all
extensible: typeModel
data:
- ["anthropic.Client", "@anthropic-ai/sdk", "Instance"]
- addsTo:
pack: codeql/javascript-all
extensible: sinkModel
data:
- ["anthropic.Client", "Member[messages].Member[create].Argument[0].Member[system]", "system-prompt-injection"]
- ["anthropic.Client", "Member[messages].Member[create].Argument[0].Member[system].ArrayElement.Member[text]", "system-prompt-injection"]
- ["anthropic.Client", "Member[beta].Member[messages].Member[create].Argument[0].Member[system]", "system-prompt-injection"]
- ["anthropic.Client", "Member[beta].Member[messages].Member[create].Argument[0].Member[system].ArrayElement.Member[text]", "system-prompt-injection"]
- ["anthropic.Client", "Member[beta].Member[agents].Member[create].Argument[0].Member[system]", "system-prompt-injection"]
- ["anthropic.Client", "Member[beta].Member[agents].Member[update].Argument[1].Member[system]", "system-prompt-injection"]

View File

@@ -1,22 +0,0 @@
extensions:
- addsTo:
pack: codeql/javascript-all
extensible: typeModel
data:
- ["google-genai.Client", "@google/genai", "Member[GoogleGenAI].Instance"]
- addsTo:
pack: codeql/javascript-all
extensible: sinkModel
data:
- ["google-genai.Client", "Member[models].Member[generateContent,generateContentStream].Argument[0].Member[config].Member[systemInstruction]", "system-prompt-injection"]
- ["google-genai.Client", "Member[chats].Member[create].Argument[0].Member[config].Member[systemInstruction]", "system-prompt-injection"]
- ["google-genai.Client", "Member[chats].Member[create].ReturnValue.Member[sendMessage].Argument[0].Member[config].Member[systemInstruction]", "system-prompt-injection"]
- ["google-genai.Client", "Member[live].Member[connect].Argument[0].Member[config].Member[systemInstruction]", "system-prompt-injection"]
- ["google-genai.Client", "Member[models].Member[generateContent,generateContentStream].Argument[0].Member[contents]", "user-prompt-injection"]
- ["google-genai.Client", "Member[models].Member[generateImages].Argument[0].Member[prompt]", "user-prompt-injection"]
- ["google-genai.Client", "Member[models].Member[editImage].Argument[0].Member[prompt]", "user-prompt-injection"]
- ["google-genai.Client", "Member[models].Member[generateVideos].Argument[0].Member[prompt]", "user-prompt-injection"]
- ["google-genai.Client", "Member[chats].Member[create].ReturnValue.Member[sendMessage,sendMessageStream].Argument[0].Member[message]", "user-prompt-injection"]
- ["google-genai.Client", "Member[chats].Member[create].ReturnValue.Member[sendMessage,sendMessageStream].Argument[0].Member[content]", "user-prompt-injection"]
- ["google-genai.Client", "Member[interactions].Member[create].Argument[0].Member[input]", "user-prompt-injection"]

View File

@@ -1,48 +0,0 @@
extensions:
- addsTo:
pack: codeql/javascript-all
extensible: typeModel
data:
- ["langchain.ChatModel", "@langchain/openai", "Member[ChatOpenAI].Instance"]
- ["langchain.ChatModel", "@langchain/anthropic", "Member[ChatAnthropic].Instance"]
- ["langchain.ChatModel", "@langchain/google-genai", "Member[ChatGoogleGenerativeAI].Instance"]
- ["langchain.ChatModel", "@langchain/mistralai", "Member[ChatMistralAI].Instance"]
- ["langchain.ChatModel", "@langchain/groq", "Member[ChatGroq].Instance"]
- ["langchain.ChatModel", "@langchain/cohere", "Member[ChatCohere].Instance"]
- ["langchain.ChatModel", "@langchain/community/chat_models/fireworks", "Member[ChatFireworks].Instance"]
- ["langchain.ChatModel", "@langchain/ollama", "Member[ChatOllama].Instance"]
- ["langchain.ChatModel", "@langchain/aws", "Member[BedrockChat,ChatBedrockConverse].Instance"]
- ["langchain.ChatModel", "@langchain/community/chat_models/togetherai", "Member[ChatTogetherAI].Instance"]
- ["langchain.ChatModel", "@langchain/xai", "Member[ChatXAI].Instance"]
- ["langchain.ChatModel", "@langchain/openrouter", "Member[ChatOpenRouter].Instance"]
- ["langchain.ChatModel", "langchain", "Member[initChatModel].ReturnValue.Awaited"]
- ["langchain.AgentExecutor", "langchain/agents", "Member[AgentExecutor].Instance"]
- ["langchain.AgentExecutor", "langchain/agents", "Member[AgentExecutor].Member[fromAgentAndTools].ReturnValue"]
- ["langchain.Agent", "langchain", "Member[createAgent].ReturnValue"]
- ["langchain.LLMChain", "langchain/chains", "Member[LLMChain].Instance"]
- addsTo:
pack: codeql/javascript-all
extensible: sinkModel
data:
- ["@langchain/core/messages", "Member[HumanMessage].Argument[0]", "user-prompt-injection"]
- ["@langchain/core/messages", "Member[HumanMessage].Argument[0].Member[content]", "user-prompt-injection"]
- ["langchain", "Member[HumanMessage].Argument[0]", "user-prompt-injection"]
- ["langchain", "Member[HumanMessage].Argument[0].Member[content]", "user-prompt-injection"]
- ["@langchain/core/messages", "Member[SystemMessage].Argument[0]", "system-prompt-injection"]
- ["@langchain/core/messages", "Member[SystemMessage].Argument[0].Member[content]", "system-prompt-injection"]
- ["langchain", "Member[SystemMessage].Argument[0]", "system-prompt-injection"]
- ["langchain", "Member[SystemMessage].Argument[0].Member[content]", "system-prompt-injection"]
- ["langchain.ChatModel", "Member[invoke].Argument[0]", "user-prompt-injection"]
- ["langchain.ChatModel", "Member[stream].Argument[0]", "user-prompt-injection"]
- ["langchain.ChatModel", "Member[call].Argument[0]", "user-prompt-injection"]
- ["langchain.ChatModel", "Member[predict].Argument[0]", "user-prompt-injection"]
- ["langchain.ChatModel", "Member[batch].Argument[0].ArrayElement", "user-prompt-injection"]
- ["langchain.ChatModel", "Member[generate].Argument[0].ArrayElement.ArrayElement", "user-prompt-injection"]
- ["langchain.AgentExecutor", "Member[invoke].Argument[0].Member[input]", "user-prompt-injection"]
- ["langchain.Agent", "Member[invoke].Argument[0].Member[messages].ArrayElement.Member[content]", "user-prompt-injection"]
- ["langchain.Agent", "Member[stream].Argument[0].Member[messages].ArrayElement.Member[content]", "user-prompt-injection"]
- ["langchain", "Member[createAgent].Argument[0].Member[systemPrompt]", "system-prompt-injection"]
- ["langchain.LLMChain", "Member[call,invoke].Argument[0].Member[input]", "user-prompt-injection"]
- ["@langchain/core/prompts", "Member[ChatPromptTemplate].Member[fromMessages].Argument[0].ArrayElement.ArrayElement", "user-prompt-injection"]
- ["@langchain/core/prompts", "Member[PromptTemplate].Instance.Member[format].Argument[0]", "user-prompt-injection"]

View File

@@ -1,25 +0,0 @@
extensions:
- addsTo:
pack: codeql/javascript-all
extensible: typeModel
data:
- ["openai.Client", "openai", "Instance"]
- ["openai.Client", "openai", "Member[OpenAI,AzureOpenAI].Instance"]
- ["openai.Client", "@openai/guardrails", "Member[GuardrailsOpenAI,GuardrailsAzureOpenAI].Member[create].ReturnValue.Awaited"]
- addsTo:
pack: codeql/javascript-all
extensible: sinkModel
data:
- ["openai.Client", "Member[responses].Member[create].Argument[0].Member[instructions]", "system-prompt-injection"]
- ["openai.Client", "Member[beta].Member[assistants].Member[create,update].Argument[0].Member[instructions]", "system-prompt-injection"]
- ["openai.Client", "Member[beta].Member[threads].Member[runs].Member[create].Argument[1].Member[instructions,additional_instructions]", "system-prompt-injection"]
- ["@openai/agents", "Member[Agent].Argument[0].Member[instructions,handoffDescription]", "system-prompt-injection"]
- ["@openai/guardrails", "Member[Agent].Argument[0].Member[instructions,handoffDescription]", "system-prompt-injection"]
- ["@openai/agents", "Member[Agent].Instance.Member[asTool].Argument[0].Member[toolDescription]", "system-prompt-injection"]
- ["@openai/guardrails", "Member[Agent].Instance.Member[asTool].Argument[0].Member[toolDescription]", "system-prompt-injection"]
- ["@openai/agents", "Member[tool].Argument[0].Member[description]", "system-prompt-injection"]
- ["@openai/guardrails", "Member[tool].Argument[0].Member[description]", "system-prompt-injection"]
- ["@openai/guardrails", "Member[GuardrailAgent].Member[create].Argument[2]", "system-prompt-injection"]
- ["@openai/agents", "Member[run].Argument[1]", "user-prompt-injection"]
- ["@openai/agents", "Member[Runner].Instance.Member[run].Argument[1]", "user-prompt-injection"]

View File

@@ -226,28 +226,3 @@ module Cryptography {
class CryptographicAlgorithm = SC::CryptographicAlgorithm;
}
/**
* A data-flow node that prompts an AI model.
*
* Extend this class to refine existing API models. If you want to model new APIs,
* extend `AIPrompt::Range` instead.
*/
class AIPrompt extends DataFlow::Node instanceof AIPrompt::Range {
/** Gets an input that is used as AI prompt. */
DataFlow::Node getAPrompt() { result = super.getAPrompt() }
}
/** Provides a class for modeling new AI prompting mechanisms. */
module AIPrompt {
/**
* A data-flow node that prompts an AI model.
*
* Extend this class to model new APIs. If you want to refine existing API models,
* extend `AIPrompt` instead.
*/
abstract class Range extends DataFlow::Node {
/** Gets an input that is used as AI prompt. */
abstract DataFlow::Node getAPrompt();
}
}

View File

@@ -1,55 +0,0 @@
/**
* Provides classes modeling security-relevant aspects of the `@anthropic-ai/sdk` package.
* See https://github.com/anthropics/anthropic-sdk-typescript
*
* Structurally typed sinks (system, beta.agents) have been moved to
* Models as Data: javascript/ql/lib/ext/anthropic.model.yml
*
* This file retains only role-filtered message sinks that require inspecting
* a sibling `role` property, which MaD cannot express.
*/
private import javascript
module Anthropic {
/** Gets a reference to the `Anthropic` client instance. */
private API::Node classRef() {
result = API::moduleImport("@anthropic-ai/sdk").getInstance()
}
/** Gets a reference to the messages.create params (both stable and beta). */
private API::Node messagesCreateParams() {
result = classRef().getMember("messages").getMember("create").getParameter(0)
or
result =
classRef().getMember("beta").getMember("messages").getMember("create").getParameter(0)
}
/**
* Gets role-filtered system/assistant message sinks.
* These require checking a sibling `role` property and cannot be expressed in MaD.
*/
API::Node getSystemOrAssistantPromptNode() {
// messages: [{ role: "assistant", content: "..." }]
exists(API::Node msg |
msg = messagesCreateParams().getMember("messages").getArrayElement() and
msg.getMember("role").asSink().mayHaveStringValue(["system", "assistant"])
|
result = msg.getMember("content")
)
}
/**
* Gets role-filtered user message sinks.
* These require checking a sibling `role` property and cannot be expressed in MaD.
*/
API::Node getUserPromptNode() {
// messages: [{ role: "user", content: "..." }]
exists(API::Node msg |
msg = messagesCreateParams().getMember("messages").getArrayElement() and
not msg.getMember("role").asSink().mayHaveStringValue(["system", "assistant"])
|
result = msg.getMember("content")
)
}
}

View File

@@ -1,61 +0,0 @@
/**
* Provides classes modeling security-relevant aspects of the `@google/genai` package.
* See https://github.com/googleapis/js-genai
*
* Structurally typed sinks (systemInstruction, prompt, message, etc.) have been
* moved to Models as Data: javascript/ql/lib/ext/google-genai.model.yml
*
* This file retains only role-filtered content sinks that require inspecting
* a sibling `role` property, which MaD cannot express.
*/
private import javascript
module GoogleGenAI {
/** Gets a reference to the `GoogleGenAI` client instance. */
private API::Node clientRef() {
result =
API::moduleImport("@google/genai").getMember("GoogleGenAI").getInstance()
}
/**
* Gets role-filtered system/model message sinks.
* These require checking a sibling `role` property and cannot be expressed in MaD.
*/
API::Node getSystemOrAssistantPromptNode() {
// contents: [{ role: "model", parts: [{ text: "..." }] }]
// Gemini uses "model" role instead of "assistant"
exists(API::Node msg |
msg =
clientRef()
.getMember("models")
.getMember(["generateContent", "generateContentStream"])
.getParameter(0)
.getMember("contents")
.getArrayElement() and
msg.getMember("role").asSink().mayHaveStringValue(["system", "model"])
|
result = msg.getMember("parts").getArrayElement().getMember("text")
)
}
/**
* Gets role-filtered user message sinks.
* These require checking a sibling `role` property and cannot be expressed in MaD.
*/
API::Node getUserPromptNode() {
// contents: [{ role: "user", parts: [{ text: "..." }] }]
exists(API::Node msg |
msg =
clientRef()
.getMember("models")
.getMember(["generateContent", "generateContentStream"])
.getParameter(0)
.getMember("contents")
.getArrayElement() and
not msg.getMember("role").asSink().mayHaveStringValue(["system", "model"])
|
result = msg.getMember("parts").getArrayElement().getMember("text")
)
}
}

View File

@@ -1,287 +0,0 @@
/**
* Provides classes modeling security-relevant aspects of the `openAI-Node` package.
* See https://github.com/openai/openai-node
*
* Structurally typed sinks (instructions, prompt, input, etc.) have been moved to
* Models as Data: javascript/ql/lib/ext/openai.model.yml
*
* This file retains only role-filtered sinks that require inspecting a sibling
* `role` property, which MaD cannot express.
*/
private import javascript
/** Holds if `msg` is a message array element with a privileged role. */
private predicate isSystemOrDevMessage(API::Node msg) {
msg.getMember("role").asSink().mayHaveStringValue(["system", "developer", "assistant"])
}
module OpenAI {
/** Gets a reference to all OpenAI client instances. */
private API::Node allClients() {
result = API::moduleImport("openai").getInstance()
or
result = API::moduleImport("openai").getMember(["OpenAI", "AzureOpenAI"]).getInstance()
or
result =
API::moduleImport("@openai/guardrails")
.getMember(["GuardrailsOpenAI", "GuardrailsAzureOpenAI"])
.getMember("create")
.getReturn()
.getPromised()
}
/** Gets a guarded client that is clearly configured without input guardrails. */
private API::Node unprotectedGuardedClient() {
exists(API::Node createCall |
createCall =
API::moduleImport("@openai/guardrails")
.getMember(["GuardrailsOpenAI", "GuardrailsAzureOpenAI"])
.getMember("create") and
result = createCall.getReturn().getPromised() and
exists(createCall.getParameter(0).getMember("version")) and
not exists(
createCall.getParameter(0).getMember("input").getMember("guardrails").getArrayElement()
) and
not exists(
createCall.getParameter(0).getMember("pre_flight").getMember("guardrails").getArrayElement()
)
)
}
/** Gets a reference to all clients without input guardrails. */
private API::Node clientsNoGuardrails() {
result = API::moduleImport("openai").getInstance()
or
result = API::moduleImport("openai").getMember(["OpenAI", "AzureOpenAI"]).getInstance()
or
result = unprotectedGuardedClient()
}
/**
* Gets role-filtered system/developer/assistant message sinks.
* These require checking a sibling `role` property and cannot be expressed in MaD.
*/
API::Node getSystemOrAssistantPromptNode() {
// responses.create({ input: [{ role: "system"/"developer", content: "..." }] })
exists(API::Node msg |
msg =
allClients()
.getMember("responses")
.getMember("create")
.getParameter(0)
.getMember("input")
.getArrayElement() and
isSystemOrDevMessage(msg)
|
result = msg.getMember("content")
)
or
// chat.completions.create({ messages: [{ role: "system"/"developer", content: ... }] })
exists(API::Node msg, API::Node content |
msg =
allClients()
.getMember("chat")
.getMember("completions")
.getMember("create")
.getParameter(0)
.getMember("messages")
.getArrayElement() and
isSystemOrDevMessage(msg) and
content = msg.getMember("content")
|
result = content
or
result = content.getArrayElement().getMember("text")
)
or
// beta.threads.messages.create(threadId, { role: "system"/"developer", content: ... })
exists(API::Node msg |
msg =
allClients()
.getMember("beta")
.getMember("threads")
.getMember("messages")
.getMember("create")
.getParameter(1) and
isSystemOrDevMessage(msg)
|
result = msg.getMember("content")
)
}
/**
* Gets role-filtered user message sinks.
* These require checking a sibling `role` property and cannot be expressed in MaD.
*/
API::Node getUserPromptNode() {
// responses.create({ input: "string" })
result =
clientsNoGuardrails()
.getMember("responses")
.getMember("create")
.getParameter(0)
.getMember("input")
or
// responses.create({ input: [{ role: "user", content: ... }] })
exists(API::Node msg |
msg =
clientsNoGuardrails()
.getMember("responses")
.getMember("create")
.getParameter(0)
.getMember("input")
.getArrayElement() and
not isSystemOrDevMessage(msg)
|
result = msg.getMember("content")
)
or
// chat.completions.create({ messages: [{ role: "user", content: ... }] })
exists(API::Node msg, API::Node content |
msg =
clientsNoGuardrails()
.getMember("chat")
.getMember("completions")
.getMember("create")
.getParameter(0)
.getMember("messages")
.getArrayElement() and
not isSystemOrDevMessage(msg) and
content = msg.getMember("content")
|
result = content
or
result = content.getArrayElement().getMember("text")
)
or
// Legacy completions API: completions.create({ prompt: ... })
result =
clientsNoGuardrails()
.getMember("completions")
.getMember("create")
.getParameter(0)
.getMember("prompt")
or
// images.generate({ prompt: ... }) and images.edit({ prompt: ... })
result =
clientsNoGuardrails()
.getMember("images")
.getMember(["generate", "edit"])
.getParameter(0)
.getMember("prompt")
or
// beta.threads.messages.create(threadId, { role: "user", content: ... })
exists(API::Node msg |
msg =
clientsNoGuardrails()
.getMember("beta")
.getMember("threads")
.getMember("messages")
.getMember("create")
.getParameter(1) and
not isSystemOrDevMessage(msg)
|
result = msg.getMember("content")
)
or
// audio.transcriptions/translations.create({ prompt: ... })
result =
clientsNoGuardrails()
.getMember("audio")
.getMember(["transcriptions", "translations"])
.getMember("create")
.getParameter(0)
.getMember("prompt")
}
}
/**
* Provides models for agents SDK.
*
* See https://github.com/openai/openai-agents-js and
* https://github.com/openai/openai-guardrails-js.
*
* Structurally typed sinks have been moved to openai.model.yml.
* This module retains only role-filtered sinks, callback-based sinks, and
* unsafe agent detection that MaD cannot express.
*/
module AgentSDK {
API::Node moduleRef() {
result = API::moduleImport("@openai/agents")
or
result = API::moduleImport("@openai/guardrails")
}
/** Gets a reference to the top-level run() or Runner.run() functions. */
private API::Node run() {
result = moduleRef().getMember("run")
or
result = moduleRef().getMember("Runner").getInstance().getMember("run")
}
/**
* Gets role-filtered and callback-based system prompt sinks that MaD cannot express.
*/
API::Node getSystemOrAssistantPromptNode() {
// Agent({ instructions: (runContext) => returnValue }) — callback form
result = moduleRef()
.getMember("Agent")
.getParameter(0)
.getMember("instructions")
.getReturn()
or
// run(agent, [{ role: "system"/"developer", content: ... }])
exists(API::Node msg |
msg = run()
.getParameter(1)
.getArrayElement() and
isSystemOrDevMessage(msg)
|
result = msg.getMember("content")
)
}
/**
* Gets role-filtered user prompt sinks for run(agent, input).
* The string-input case is handled via MaD (openai.model.yml).
*/
API::Node getUserPromptNode() {
// run(agent, [{ role: "user", content: ... }])
exists(API::Node msg |
msg = run().getParameter(1).getArrayElement() and
not isSystemOrDevMessage(msg)
|
result = msg.getMember("content")
)
}
/**
* Gets an agent constructor config that visibly lacks input guardrails.
* Covers both native Agent({ inputGuardrails: [...] }) and
* GuardrailAgent.create({ input: { guardrails: [...] } }, ...).
*/
API::Node getUnsafeAgentNode() {
// new Agent({ name: '...', ... }) without inputGuardrails
result = moduleRef().getMember("Agent").getParameter(0) and
// Config is an inspectable object literal
(exists(result.getMember("name")) or exists(result.getMember("instructions"))) and
not exists(result.getMember("inputGuardrails").getArrayElement())
or
// GuardrailAgent.create(config, ...) without input/pre_flight guardrails
exists(API::Node createCall |
createCall =
moduleRef()
.getMember("GuardrailAgent")
.getMember("create") and
result = createCall.getParameter(0) and
exists(result.getMember("version")) and
not exists(
result.getMember("input").getMember("guardrails").getArrayElement()
) and
not exists(
result.getMember("pre_flight").getMember("guardrails").getArrayElement()
)
)
}
}

View File

@@ -1,114 +0,0 @@
/**
* Provides default sources, sinks and sanitizers for detecting
* "prompt injection"
* vulnerabilities, as well as extension points for adding your own.
*/
import javascript
private import semmle.javascript.dataflow.DataFlow
private import semmle.javascript.Concepts
private import semmle.javascript.security.dataflow.RemoteFlowSources
private import semmle.javascript.dataflow.internal.BarrierGuards
private import semmle.javascript.frameworks.data.ModelsAsData
private import semmle.javascript.frameworks.OpenAI
private import semmle.javascript.frameworks.Anthropic
private import semmle.javascript.frameworks.GoogleGenAI
/**
* Provides default sources, sinks and sanitizers for detecting
* "prompt injection"
* vulnerabilities, as well as extension points for adding your own.
*/
module SystemPromptInjection {
/**
* A data flow source for "prompt injection" vulnerabilities.
*/
abstract class Source extends DataFlow::Node { }
/**
* A data flow sink for "prompt injection" vulnerabilities.
*/
abstract class Sink extends DataFlow::Node { }
/**
* A sanitizer for "prompt injection" vulnerabilities.
*/
abstract class Sanitizer extends DataFlow::Node { }
/**
* An active threat-model source, considered as a flow source.
*/
private class ActiveThreatModelSourceAsSource extends Source, ActiveThreatModelSource {
}
/**
* A prompt to an AI model, considered as a flow sink.
*/
class AIPromptAsSink extends Sink {
AIPromptAsSink() { this = any(AIPrompt p).getAPrompt() }
}
private class SinkFromModel extends Sink {
SinkFromModel() {
this = ModelOutput::getASinkNode("system-prompt-injection").asSink()
}
}
private class PromptContentSink extends Sink {
PromptContentSink() {
this = OpenAI::getSystemOrAssistantPromptNode().asSink()
or
this = AgentSDK::getSystemOrAssistantPromptNode().asSink()
or
this = Anthropic::getSystemOrAssistantPromptNode().asSink()
or
this = GoogleGenAI::getSystemOrAssistantPromptNode().asSink()
}
}
private class ConstCompareAsSanitizerGuard extends Sanitizer {
ConstCompareAsSanitizerGuard()
{
this = DataFlow::MakeBarrierGuard<ConstCompareBarrierGuard>::getABarrierNode()
}
}
/**
* Content placed in a message with `role: "user"` is not a system prompt
* injection vector; it is intended user-role content.
*
* This prevents false positives when user input and system prompts are
* combined in the same message array (e.g. `[{role:"system", content: ...},
* {role:"user", content: tainted}]`) and taint would otherwise propagate
* through array operations to the system message.
*/
private class UserRoleMessageContentBarrier extends Sanitizer {
UserRoleMessageContentBarrier() {
exists(DataFlow::SourceNode obj |
obj.getAPropertySource("role").mayHaveStringValue("user") and
this = obj.getAPropertyWrite("content").getRhs()
)
}
}
/**
* A comparison with a constant, considered as a sanitizer-guard.
*/
private class ConstCompareBarrierGuard extends DataFlow::ValueNode
{
override EqualityTest astNode;
ConstCompareBarrierGuard()
{
astNode.hasOperands(_, any(ConstantString cs))
}
predicate blocksExpr(boolean outcome, Expr e) {
outcome = astNode.getPolarity() and
e = astNode.getLeftOperand() and
e = astNode.getAnOperand() and
not e instanceof ConstantString
}
}
}

View File

@@ -1,25 +0,0 @@
/**
* Provides a taint-tracking configuration for detecting "prompt injection" vulnerabilities.
*
* Note, for performance reasons: only import this file if
* `SystemPromptInjectionFlow::Configuration` is needed, otherwise
* `SystemPromptInjectionCustomizations` should be imported instead.
*/
private import javascript
import semmle.javascript.dataflow.DataFlow
import semmle.javascript.dataflow.TaintTracking
import SystemPromptInjectionCustomizations::SystemPromptInjection
private module SystemPromptInjectionConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node node) { node instanceof Source }
predicate isSink(DataFlow::Node node) { node instanceof Sink }
predicate isBarrier(DataFlow::Node node) { node instanceof Sanitizer }
predicate observeDiffInformedIncrementalMode() { any() }
}
/** Global taint-tracking for detecting "prompt injection" vulnerabilities. */
module SystemPromptInjectionFlow = TaintTracking::Global<SystemPromptInjectionConfig>;

View File

@@ -1,31 +0,0 @@
<!DOCTYPE qhelp PUBLIC
"-//Semmle//qhelp//EN"
"qhelp.dtd">
<qhelp>
<overview>
<p>If user-controlled data is included in a system prompt, an attacker can manipulate the instructions
that govern the AI model's behavior, bypassing intended restrictions and potentially causing sensitive
data leaks or unintended operations.</p>
</overview>
<recommendation>
<p>Do not include user input in system-level or developer-level prompts. If user input must influence
the system prompt, validate it against a fixed allowlist of permitted values.</p>
</recommendation>
<example>
<p>In the following example, a user-controlled value is inserted directly into a system-level prompt
without validation, allowing an attacker to manipulate the AI's behavior.</p>
<sample src="examples/prompt-injection.js" />
<p>The fix validates the user input against a fixed allowlist of permitted values before
including it in the prompt.</p>
<sample src="examples/prompt-injection_fixed.js" />
</example>
<references>
<li>OWASP: <a href="https://genai.owasp.org/llmrisk/llm01-prompt-injection/">LLM01: Prompt Injection</a>.</li>
<li>MITRE CWE: <a href="https://cwe.mitre.org/data/definitions/1427.html">CWE-1427: Improper Neutralization of Input Used for LLM Prompting</a>.</li>
</references>
</qhelp>

View File

@@ -1,19 +0,0 @@
/**
* @name Prompt injection
* @kind path-problem
* @problem.severity error
* @security-severity 5.0
* @precision high
* @id js/system-prompt-injection
* @tags security
* external/cwe/cwe-1427
*/
import javascript
import semmle.javascript.security.dataflow.SystemPromptInjectionQuery
import SystemPromptInjectionFlow::PathGraph
from SystemPromptInjectionFlow::PathNode source, SystemPromptInjectionFlow::PathNode sink
where SystemPromptInjectionFlow::flowPath(source, sink)
select sink.getNode(), source, sink, "This prompt construction depends on a $@.", source.getNode(),
"user-provided value"

View File

@@ -1,26 +0,0 @@
const express = require("express");
const OpenAI = require("openai");
const app = express();
const client = new OpenAI();
app.get("/chat", async (req, res) => {
let persona = req.query.persona;
// BAD: user input is used directly in a system-level prompt
const response = await client.chat.completions.create({
model: "gpt-4.1",
messages: [
{
role: "system",
content: "You are a helpful assistant. Act as a " + persona,
},
{
role: "user",
content: req.query.message,
},
],
});
res.json(response);
});

View File

@@ -1,32 +0,0 @@
const express = require("express");
const OpenAI = require("openai");
const app = express();
const client = new OpenAI();
const ALLOWED_PERSONAS = ["pirate", "teacher", "poet"];
app.get("/chat", async (req, res) => {
let persona = req.query.persona;
// GOOD: user input is validated against a fixed allowlist before use in a prompt
if (!ALLOWED_PERSONAS.includes(persona)) {
return res.status(400).json({ error: "Invalid persona" });
}
const response = await client.chat.completions.create({
model: "gpt-4.1",
messages: [
{
role: "system",
content: "You are a helpful assistant. Act as a " + persona,
},
{
role: "user",
content: req.query.message,
},
],
});
res.json(response);
});

View File

@@ -1,41 +0,0 @@
<!DOCTYPE qhelp PUBLIC
"-//Semmle//qhelp//EN"
"qhelp.dtd">
<qhelp>
<overview>
<p>If untrusted input is included in a user-role prompt sent to an AI model, an attacker can inject
instructions that manipulate the model's behavior. This is known as <i>indirect prompt injection</i>
when the malicious content arrives through data the model processes, or <i>direct prompt injection</i>
when the attacker controls the prompt directly.</p>
<p>Unlike system prompt injection, user prompt injection targets the user-role messages. Although
user messages are expected to carry user input, passing unsanitized data directly into structured
prompt templates can still allow an attacker to override intended instructions, extract sensitive
context, or trigger unintended tool calls.</p>
</overview>
<recommendation>
<p>To mitigate user prompt injection:</p>
<ul>
<li>Validate user input against a fixed allowlist of permitted values before including it in a prompt.</li>
<li>Use parameterized prompt templates that clearly separate instructions from user data.</li>
<li>Apply output filtering to detect and block responses that indicate prompt injection attempts.</li>
</ul>
</recommendation>
<example>
<p>In the following example, user-controlled data is inserted directly into a user-role prompt
without any validation, allowing an attacker to inject arbitrary instructions.</p>
<sample src="examples/user-prompt-injection.js" />
<p>The fix validates the user input against a fixed allowlist of permitted values before
including it in the prompt.</p>
<sample src="examples/user-prompt-injection_fixed.js" />
</example>
<references>
<li>OWASP: <a href="https://genai.owasp.org/llmrisk/llm01-prompt-injection/">LLM01: Prompt Injection</a>.</li>
<li>MITRE CWE: <a href="https://cwe.mitre.org/data/definitions/1427.html">CWE-1427: Improper Neutralization of Input Used for LLM Prompting</a>.</li>
</references>
</qhelp>

View File

@@ -1,22 +0,0 @@
/**
* @name User prompt injection
* @description Untrusted input flowing into a user-role prompt of an AI model
* may allow an attacker to manipulate the model's behavior.
* @kind path-problem
* @problem.severity warning
* @security-severity 5.0
* @precision medium
* @id js/user-prompt-injection
* @tags security
* experimental
* external/cwe/cwe-1427
*/
import javascript
import experimental.semmle.javascript.security.PromptInjection.UserPromptinjectionQuery
import UserPromptInjectionFlow::PathGraph
from UserPromptInjectionFlow::PathNode source, UserPromptInjectionFlow::PathNode sink
where UserPromptInjectionFlow::flowPath(source, sink)
select sink.getNode(), source, sink, "This prompt construction depends on a $@.", source.getNode(),
"user-provided value"

View File

@@ -1,26 +0,0 @@
const express = require("express");
const OpenAI = require("openai");
const app = express();
const client = new OpenAI();
app.get("/chat", async (req, res) => {
let topic = req.query.topic;
// BAD: user input is used directly in a user-role prompt
const response = await client.chat.completions.create({
model: "gpt-4.1",
messages: [
{
role: "system",
content: "You are a helpful assistant that summarizes topics.",
},
{
role: "user",
content: "Summarize the following topic: " + topic,
},
],
});
res.json(response);
});

View File

@@ -1,32 +0,0 @@
const express = require("express");
const OpenAI = require("openai");
const app = express();
const client = new OpenAI();
const ALLOWED_TOPICS = ["science", "history", "technology"];
app.get("/chat", async (req, res) => {
let topic = req.query.topic;
// GOOD: user input is validated against a fixed allowlist before use in a prompt
if (!ALLOWED_TOPICS.includes(topic)) {
return res.status(400).json({ error: "Invalid topic" });
}
const response = await client.chat.completions.create({
model: "gpt-4.1",
messages: [
{
role: "system",
content: "You are a helpful assistant that summarizes topics.",
},
{
role: "user",
content: "Summarize the following topic: " + topic,
},
],
});
res.json(response);
});

View File

@@ -1,90 +0,0 @@
/**
* Provides default sources, sinks and sanitizers for detecting
* "user prompt injection"
* vulnerabilities, as well as extension points for adding your own.
*/
import javascript
private import semmle.javascript.dataflow.DataFlow
private import semmle.javascript.Concepts
private import semmle.javascript.security.dataflow.RemoteFlowSources
private import semmle.javascript.dataflow.internal.BarrierGuards
private import semmle.javascript.frameworks.data.ModelsAsData
private import semmle.javascript.frameworks.OpenAI
private import semmle.javascript.frameworks.Anthropic
private import semmle.javascript.frameworks.GoogleGenAI
/**
* Provides default sources, sinks and sanitizers for detecting
* "user prompt injection"
* vulnerabilities, as well as extension points for adding your own.
*/
module UserPromptInjection {
/**
* A data flow source for "user prompt injection" vulnerabilities.
*/
abstract class Source extends DataFlow::Node { }
/**
* A data flow sink for "user prompt injection" vulnerabilities.
*/
abstract class Sink extends DataFlow::Node {
}
/**
* A sanitizer for "user prompt injection" vulnerabilities.
*/
abstract class Sanitizer extends DataFlow::Node { }
/**
* An active threat-model source, considered as a flow source.
*/
private class ActiveThreatModelSourceAsSource extends Source, ActiveThreatModelSource {
}
/**
* A prompt to an AI model, considered as a flow sink.
*/
class AIPromptAsSink extends Sink {
AIPromptAsSink() { this = any(AIPrompt p).getAPrompt() }
}
private class SinkFromModel extends Sink {
SinkFromModel() {
this = ModelOutput::getASinkNode("user-prompt-injection").asSink()
}
}
private class PromptContentSink extends Sink {
PromptContentSink() {
this = OpenAI::getUserPromptNode().asSink()
or
this = Anthropic::getUserPromptNode().asSink()
or
this = GoogleGenAI::getUserPromptNode().asSink()
or
this = AgentSDK::getUserPromptNode().asSink()
}
}
/**
* A comparison with a constant, considered as a sanitizer-guard.
*/
private class ConstCompareBarrierGuard extends DataFlow::ValueNode
{
override EqualityTest astNode;
ConstCompareBarrierGuard()
{
astNode.hasOperands(_, any(ConstantString cs))
}
predicate blocksExpr(boolean outcome, Expr e) {
outcome = astNode.getPolarity() and
e = astNode.getLeftOperand() and
e = astNode.getAnOperand() and
not e instanceof ConstantString
}
}
}

Some files were not shown because too many files have changed in this diff Show More