Languages: Adapt to api changes.

This commit is contained in:
Anders Schack-Mulligen
2025-08-19 10:34:06 +02:00
parent e53b22dfa7
commit f459ddc40a
34 changed files with 454 additions and 368 deletions

View File

@@ -1,6 +1,7 @@
import python
private import semmle.python.pointsto.PointsTo
private import semmle.python.internal.CachedStages
private import codeql.controlflow.BasicBlock as BB
/*
* Note about matching parent and child nodes and CFG splitting:
@@ -1252,3 +1253,54 @@ private predicate end_bb_likely_reachable(BasicBlock b) {
not p = b.getLastNode()
)
}
private class ControlFlowNodeAlias = ControlFlowNode;
final private class FinalBasicBlock = BasicBlock;
module Cfg implements BB::CfgSig<Location> {
class ControlFlowNode = ControlFlowNodeAlias;
class SuccessorType = Unit;
class BasicBlock extends FinalBasicBlock {
// Note `PY:BasicBlock` does not have a `getLocation`.
// (Instead it has a complicated location info logic.)
// Using the location of the first node is simple
// and we just need a way to identify the basic block
// during debugging, so this will be serviceable.
Location getLocation() { result = super.getNode(0).getLocation() }
int length() { result = count(int i | exists(this.getNode(i))) }
BasicBlock getASuccessor() { result = super.getASuccessor() }
BasicBlock getASuccessor(SuccessorType t) { result = super.getASuccessor() and exists(t) }
predicate strictlyDominates(BasicBlock bb) { super.strictlyDominates(bb) }
predicate dominates(BasicBlock bb) { super.dominates(bb) }
predicate inDominanceFrontier(BasicBlock df) { super.inDominanceFrontier(df) }
BasicBlock getImmediateDominator() { result = super.getImmediateDominator() }
/** Unsupported. Do not use. */
predicate strictlyPostDominates(BasicBlock bb) { none() }
/** Unsupported. Do not use. */
predicate postDominates(BasicBlock bb) {
this.strictlyPostDominates(bb) or
this = bb
}
}
pragma[nomagic]
predicate dominatingEdge(BasicBlock bb1, BasicBlock bb2) {
bb1.getASuccessor() = bb2 and
bb1 = bb2.getImmediateDominator() and
forall(BasicBlock pred | pred = bb2.getAPredecessor() and pred != bb1 | bb2.dominates(pred))
}
predicate entryBlock(BasicBlock bb) { bb.getNode(0).isEntryNode() }
}

View File

@@ -12,7 +12,7 @@ private import codeql.dataflow.VariableCapture as Shared
// The first is the main implementation, the second is a performance motivated restriction.
// The restriction is to clear any `CapturedVariableContent` before writing a new one
// to avoid long access paths (see the link for a nice explanation).
private module CaptureInput implements Shared::InputSig<Location> {
private module CaptureInput implements Shared::InputSig<Location, Cfg::BasicBlock> {
private import python as PY
additional class ExprCfgNode extends ControlFlowNode {
@@ -23,28 +23,7 @@ private module CaptureInput implements Shared::InputSig<Location> {
predicate isConstructor() { none() }
}
final private class PyBasicBlock = PY::BasicBlock;
class BasicBlock extends PyBasicBlock {
int length() { result = count(int i | exists(this.getNode(i))) }
Callable getEnclosingCallable() { result = this.getScope() }
// Note `PY:BasicBlock` does not have a `getLocation`.
// (Instead it has a complicated location info logic.)
// Using the location of the first node is simple
// and we just need a way to identify the basic block
// during debugging, so this will be serviceable.
Location getLocation() { result = super.getNode(0).getLocation() }
BasicBlock getASuccessor() { result = super.getASuccessor() }
BasicBlock getImmediateDominator() { result = super.getImmediateDominator() }
predicate inDominanceFrontier(BasicBlock df) { super.inDominanceFrontier(df) }
}
class ControlFlowNode = PY::ControlFlowNode;
Callable basicBlockGetEnclosingCallable(Cfg::BasicBlock bb) { result = bb.getScope() }
class CapturedVariable extends LocalVariable {
Function f;
@@ -74,7 +53,7 @@ private module CaptureInput implements Shared::InputSig<Location> {
}
class Expr extends ExprCfgNode {
predicate hasCfgNode(BasicBlock bb, int i) { this = bb.getNode(i) }
predicate hasCfgNode(Cfg::BasicBlock bb, int i) { this = bb.getNode(i) }
}
class VariableWrite extends ControlFlowNode {
@@ -84,7 +63,7 @@ private module CaptureInput implements Shared::InputSig<Location> {
CapturedVariable getVariable() { result = v }
predicate hasCfgNode(BasicBlock bb, int i) { this = bb.getNode(i) }
predicate hasCfgNode(Cfg::BasicBlock bb, int i) { this = bb.getNode(i) }
}
class VariableRead extends Expr {
@@ -126,7 +105,7 @@ class CapturedVariable = CaptureInput::CapturedVariable;
class ClosureExpr = CaptureInput::ClosureExpr;
module Flow = Shared::Flow<Location, CaptureInput>;
module Flow = Shared::Flow<Location, Cfg, CaptureInput>;
private Flow::ClosureNode asClosureNode(Node n) {
result = n.(SynthCaptureNode).getSynthesizedCaptureNode()