Skip to content

Commit f2a6889

Browse files
committed
Python: specialize direct truthiness guards
Keep the modification-of-default-value query on shared SSA while expressing its two direct truthiness checks in a query-shaped predicate. The generic BarrierGuard abstraction causes the evaluator to materialize and rescan a 1,579,772,664-row def-use pair relation before applying branch control. Binding both concrete NameNode uses in one predicate lets the optimizer fuse the same joins with controlsBlock and persist only the 4,992 guarded uses. On FreeCAD@0def330, three prewarmed evaluator runs improve from 309.159-329.621s to 77.781-81.349s with byte-identical query results. A direct symmetric-difference evaluation returns zero rows, and the CommandInjection path-query control retains identical results, work, and plan hashes. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 07c775e7-cd7c-4e1c-8d97-5194ffd43e1a
1 parent feee854 commit f2a6889

1 file changed

Lines changed: 16 additions & 13 deletions

File tree

python/ql/src/semmle/python/functions/ModificationOfParameterWithDefaultCustomizations.qll

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
private import python
77
private import semmle.python.dataflow.new.DataFlow
88
private import semmle.python.dataflow.new.BarrierGuards
9+
private import semmle.python.dataflow.new.internal.SsaImpl as SsaImpl
910
private import semmle.python.controlflow.internal.Cfg as Cfg
1011

1112
/**
@@ -142,26 +143,28 @@ module ModificationOfParameterWithDefault {
142143
}
143144
}
144145

145-
/**
146-
* Holds if `g` is a direct truthiness check that proves its (single
147-
* operand-and-result) value truthy on the `true` branch — i.e. `if g:`.
148-
*/
149-
private predicate truthyGuard(DataFlow::GuardNode g, Cfg::ControlFlowNode node, boolean branch) {
150-
node = g and branch = true
151-
}
152-
153-
/** Holds if `g` is a direct falsiness check — i.e. `if g:` taken to the false branch. */
154-
private predicate falseyGuard(DataFlow::GuardNode g, Cfg::ControlFlowNode node, boolean branch) {
155-
node = g and branch = false
146+
/** Holds if `barrier` is a use guarded by a direct truthiness check on `branch`. */
147+
private predicate directGuardedUse(DataFlow::ExprNode barrier, boolean branch) {
148+
exists(
149+
DataFlow::GuardNode guard, SsaImpl::EssaDefinition def, Cfg::NameNode checked,
150+
Cfg::NameNode use
151+
|
152+
checked = guard and
153+
SsaImpl::AdjacentUses::useOfDef(def, checked) and
154+
SsaImpl::AdjacentUses::useOfDef(def, use) and
155+
checked != use and
156+
guard.controlsBlock(use.getBasicBlock(), branch) and
157+
barrier.asCfgNode() = use
158+
)
156159
}
157160

158161
/** Simple guard detecting truthy values. */
159162
private class MustBeTruthy extends MustBeNonEmpty {
160-
MustBeTruthy() { this = DataFlow::BarrierGuard<truthyGuard/3>::getABarrierNode() }
163+
MustBeTruthy() { directGuardedUse(this, true) }
161164
}
162165

163166
/** Simple guard detecting falsey values. */
164167
private class MustBeFalsey extends MustBeEmpty {
165-
MustBeFalsey() { this = DataFlow::BarrierGuard<falseyGuard/3>::getABarrierNode() }
168+
MustBeFalsey() { directGuardedUse(this, false) }
166169
}
167170
}

0 commit comments

Comments
 (0)