Skip to content

Commit c2f439a

Browse files
yoffCopilot
andcommitted
Python: preserve bindingset on new-CFG node dominance wrappers
The `Cfg::ControlFlowNode` facade re-exports the shared CFG library's `dominates`/`strictlyDominates` predicates, which are declared `bindingset[this, that]` + `pragma[inline_late]` and are meant to be used as bound-pair membership checks. The facade wrappers dropped these annotations (using plain `pragma[inline]`), so even though the only callers — the `with` / `async with` taint steps in DataFlowPrivate.qll and TaintTrackingPrivate.qll — bind both endpoints, the optimizer was free to materialise `Cfg::ControlFlowNode.strictlyDominates/1` as a full O(nodes^2) relation over the (larger) shared-CFG node set. On some projects this dominated analysis time entirely (DCA showed e.g. ICTU/quality-time and biosimulations regressing ~75-160x). Restoring `bindingset[this, other]` + `pragma[inline_late]` on the wrappers turns the predicate back into a bound-pair check and is result-preserving (only binding annotations change, the predicate body is unchanged). Reproduced on ICTU/quality-time: full python-security-extended suite went from stalling >20min on `strictlyDominates` to completing in ~6min; all ControlFlow and dataflow/coverage library tests pass. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent b7f01fb commit c2f439a

1 file changed

Lines changed: 4 additions & 2 deletions

File tree

  • python/ql/lib/semmle/python/controlflow/internal

python/ql/lib/semmle/python/controlflow/internal/Cfg.qll

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -110,11 +110,13 @@ class ControlFlowNode extends CfgImpl::ControlFlowNode {
110110
}
111111

112112
/** Holds if this strictly dominates `other`. */
113-
pragma[inline]
113+
bindingset[this, other]
114+
pragma[inline_late]
114115
predicate strictlyDominates(ControlFlowNode other) { super.strictlyDominates(other) }
115116

116117
/** Holds if this dominates `other` (reflexively). */
117-
pragma[inline]
118+
bindingset[this, other]
119+
pragma[inline_late]
118120
predicate dominates(ControlFlowNode other) { super.dominates(other) }
119121

120122
/** Holds if this is the first node in its enclosing scope. */

0 commit comments

Comments
 (0)