Skip to content

Commit

Permalink
Merge pull request #16896 from hvitved/ssa/dataflow-integration-prep
Browse files Browse the repository at this point in the history
SSA: Add `BasicBlock.{getNode/1,length/0}` to the input signature
  • Loading branch information
hvitved authored Jul 3, 2024
2 parents b779341 + 4ae8720 commit da0909c
Show file tree
Hide file tree
Showing 19 changed files with 117 additions and 33 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -1809,7 +1809,7 @@ module IteratorFlow {
* Holds if `(bb, i)` contains a write to an iterator that may have been obtained
* by calling `begin` (or related functions) on the variable `v`.
*/
predicate variableWrite(IRBlock bb, int i, SourceVariable v, boolean certain) {
predicate variableWrite(BasicBlock bb, int i, SourceVariable v, boolean certain) {
certain = false and
exists(GetsIteratorCall beginCall, Instruction writeToDeref, IRBlock bbQual, int iQual |
isIteratorStoreInstruction(beginCall, writeToDeref) and
Expand All @@ -1820,7 +1820,7 @@ module IteratorFlow {
}

/** Holds if `(bb, i)` reads the container variable `v`. */
predicate variableRead(IRBlock bb, int i, SourceVariable v, boolean certain) {
predicate variableRead(BasicBlock bb, int i, SourceVariable v, boolean certain) {
Ssa::variableRead(bb, i, v, certain)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -981,7 +981,7 @@ private module SsaInput implements SsaImplCommon::InputSig<Location> {
* Holds if the `i`'th write in block `bb` writes to the variable `v`.
* `certain` is `true` if the write is guaranteed to overwrite the entire variable.
*/
predicate variableWrite(IRBlock bb, int i, SourceVariable v, boolean certain) {
predicate variableWrite(BasicBlock bb, int i, SourceVariable v, boolean certain) {
DataFlowImplCommon::forceCachingInSameStage() and
(
exists(DefImpl def | def.hasIndexInBlock(bb, i, v) |
Expand All @@ -999,7 +999,7 @@ private module SsaInput implements SsaImplCommon::InputSig<Location> {
* Holds if the `i`'th read in block `bb` reads to the variable `v`.
* `certain` is `true` if the read is guaranteed. For C++, this is always the case.
*/
predicate variableRead(IRBlock bb, int i, SourceVariable v, boolean certain) {
predicate variableRead(BasicBlock bb, int i, SourceVariable v, boolean certain) {
exists(UseImpl use | use.hasIndexInBlock(bb, i, v) |
if use.isCertain() then certain = true else certain = false
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -757,13 +757,19 @@ import Cached
* between the SSA pruning stage, and the final SSA stage.
*/
module InputSigCommon {
class BasicBlock = IRBlock;
class BasicBlock extends IRBlock {
ControlFlowNode getNode(int i) { result = this.getInstruction(i) }

int length() { result = this.getInstructionCount() }
}

class ControlFlowNode = Instruction;

BasicBlock getImmediateBasicBlockDominator(BasicBlock bb) { result.immediatelyDominates(bb) }

BasicBlock getABasicBlockSuccessor(BasicBlock bb) { result = bb.getASuccessor() }

class ExitBasicBlock extends IRBlock {
class ExitBasicBlock extends BasicBlock {
ExitBasicBlock() { this.getLastInstruction() instanceof ExitFunctionInstruction }
}
}
2 changes: 1 addition & 1 deletion csharp/ql/lib/semmle/code/cil/Ssa.qll
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ deprecated module Ssa {
}

/** Gets the location of this SSA definition. */
Location getLocation() { result = this.getVariableUpdate().getLocation() }
override Location getLocation() { result = this.getVariableUpdate().getLocation() }
}

/** A phi node. */
Expand Down
5 changes: 4 additions & 1 deletion csharp/ql/lib/semmle/code/cil/internal/SsaImpl.qll
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
private import cil
private import CIL
private import codeql.ssa.Ssa as SsaImplCommon

deprecated private module SsaInput implements SsaImplCommon::InputSig<CIL::Location> {
class BasicBlock = CIL::BasicBlock;

class ControlFlowNode = CIL::ControlFlowNode;

BasicBlock getImmediateBasicBlockDominator(BasicBlock bb) { result = bb.getImmediateDominator() }

BasicBlock getABasicBlockSuccessor(BasicBlock bb) { result = bb.getASuccessor() }

class ExitBasicBlock = CIL::ExitBasicBlock;
class ExitBasicBlock extends BasicBlock, CIL::ExitBasicBlock { }

class SourceVariable = CIL::StackVariable;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,11 @@ module PreSsa {
}

module SsaInput implements SsaImplCommon::InputSig<Location> {
class BasicBlock = PreBasicBlocks::PreBasicBlock;
class BasicBlock extends PreBasicBlocks::PreBasicBlock {
ControlFlowNode getNode(int i) { result = this.getElement(i) }
}

class ControlFlowNode = ControlFlowElement;

BasicBlock getImmediateBasicBlockDominator(BasicBlock bb) { result.immediatelyDominates(bb) }

Expand Down Expand Up @@ -192,7 +196,7 @@ module PreSsa {
SsaImpl::ssaDefReachesEndOfBlock(bb, this, _)
}

Location getLocation() {
override Location getLocation() {
result = this.getDefinition().getLocation()
or
exists(Callable c, SsaInput::BasicBlock bb, SsaInput::SourceVariable v |
Expand Down
2 changes: 1 addition & 1 deletion csharp/ql/lib/semmle/code/csharp/dataflow/SSA.qll
Original file line number Diff line number Diff line change
Expand Up @@ -427,7 +427,7 @@ module Ssa {
}

/** Gets the location of this SSA definition. */
Location getLocation() { none() }
override Location getLocation() { none() }
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,13 +36,15 @@ module BaseSsa {

class BasicBlock = ControlFlow::BasicBlock;

class ControlFlowNode = ControlFlow::Node;

BasicBlock getImmediateBasicBlockDominator(BasicBlock bb) {
result = bb.getImmediateDominator()
}

BasicBlock getABasicBlockSuccessor(BasicBlock bb) { result = bb.getASuccessor() }

class ExitBasicBlock = ControlFlow::BasicBlocks::ExitBlock;
class ExitBasicBlock extends BasicBlock, ControlFlow::BasicBlocks::ExitBlock { }

class SourceVariable = PreSsa::SimpleLocalScopeVariable;

Expand Down Expand Up @@ -93,7 +95,7 @@ module BaseSsa {
not result instanceof PhiNode
}

Location getLocation() {
override Location getLocation() {
result = this.getDefinition().getLocation()
or
exists(Callable c, SsaInput::BasicBlock bb, SsaInput::SourceVariable v |
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -263,14 +263,16 @@ module VariableCapture {

private module CaptureInput implements Shared::InputSig<Location> {
private import csharp as Cs
private import semmle.code.csharp.controlflow.ControlFlowGraph
private import semmle.code.csharp.controlflow.ControlFlowGraph as Cfg
private import semmle.code.csharp.controlflow.BasicBlocks as BasicBlocks
private import TaintTrackingPrivate as TaintTrackingPrivate

class BasicBlock extends BasicBlocks::BasicBlock {
Callable getEnclosingCallable() { result = super.getCallable() }
}

class ControlFlowNode = Cfg::ControlFlow::Node;

BasicBlock getImmediateBasicBlockDominator(BasicBlock bb) {
result = bb.getImmediateDominator()
}
Expand Down
10 changes: 6 additions & 4 deletions csharp/ql/lib/semmle/code/csharp/dataflow/internal/SsaImpl.qll
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,13 @@ private import semmle.code.csharp.controlflow.internal.PreSsa
private module SsaInput implements SsaImplCommon::InputSig<Location> {
class BasicBlock = ControlFlow::BasicBlock;

class ControlFlowNode = ControlFlow::Node;

BasicBlock getImmediateBasicBlockDominator(BasicBlock bb) { result = bb.getImmediateDominator() }

BasicBlock getABasicBlockSuccessor(BasicBlock bb) { result = bb.getASuccessor() }

class ExitBasicBlock = ControlFlow::BasicBlocks::ExitBlock;
class ExitBasicBlock extends BasicBlock, ControlFlow::BasicBlocks::ExitBlock { }

class SourceVariable = Ssa::SourceVariable;

Expand All @@ -24,7 +26,7 @@ private module SsaInput implements SsaImplCommon::InputSig<Location> {
*
* This includes implicit writes via calls.
*/
predicate variableWrite(ControlFlow::BasicBlock bb, int i, Ssa::SourceVariable v, boolean certain) {
predicate variableWrite(BasicBlock bb, int i, Ssa::SourceVariable v, boolean certain) {
variableWriteDirect(bb, i, v, certain)
or
variableWriteQualifier(bb, i, v, certain)
Expand All @@ -38,7 +40,7 @@ private module SsaInput implements SsaImplCommon::InputSig<Location> {
*
* This includes implicit reads via calls.
*/
predicate variableRead(ControlFlow::BasicBlock bb, int i, Ssa::SourceVariable v, boolean certain) {
predicate variableRead(BasicBlock bb, int i, Ssa::SourceVariable v, boolean certain) {
variableReadActual(bb, i, v) and
certain = true
or
Expand Down Expand Up @@ -1089,7 +1091,7 @@ class DefinitionExt extends Impl::DefinitionExt {
override string toString() { result = this.(Ssa::Definition).toString() }

/** Gets the location of this definition. */
Location getLocation() { result = this.(Ssa::Definition).getLocation() }
override Location getLocation() { result = this.(Ssa::Definition).getLocation() }

/** Gets the enclosing callable of this definition. */
Callable getEnclosingCallable() { result = this.(Ssa::Definition).getEnclosingCallable() }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,11 +72,17 @@ private module CaptureInput implements VariableCapture::InputSig<Location> {
class BasicBlock instanceof J::BasicBlock {
string toString() { result = super.toString() }

ControlFlowNode getNode(int i) { result = super.getNode(i) }

int length() { result = super.length() }

Callable getEnclosingCallable() { result = super.getEnclosingCallable() }

Location getLocation() { result = super.getLocation() }
}

class ControlFlowNode = J::ControlFlowNode;

BasicBlock getImmediateBasicBlockDominator(BasicBlock bb) { bbIDominates(result, bb) }

BasicBlock getABasicBlockSuccessor(BasicBlock bb) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ private module CaptureInput implements Shared::InputSig<Location> {
}

class BasicBlock extends PY::BasicBlock {
int length() { result = count(int i | exists(this.getNode(i))) }

Callable getEnclosingCallable() { result = this.getScope() }

// Note `PY:BasicBlock` does not have a `getLocation`.
Expand All @@ -34,6 +36,8 @@ private module CaptureInput implements Shared::InputSig<Location> {
Location getLocation() { result = super.getNode(0).getLocation() }
}

class ControlFlowNode = PY::ControlFlowNode;

BasicBlock getImmediateBasicBlockDominator(BasicBlock bb) { result = bb.getImmediateDominator() }

BasicBlock getABasicBlockSuccessor(BasicBlock bb) { result = bb.getASuccessor() }
Expand Down
3 changes: 0 additions & 3 deletions ruby/ql/lib/codeql/ruby/dataflow/SSA.qll
Original file line number Diff line number Diff line change
Expand Up @@ -176,9 +176,6 @@ module Ssa {

override string toString() { result = this.getControlFlowNode().toString() }

/** Gets the location of this SSA definition. */
Location getLocation() { result = this.getControlFlowNode().getLocation() }

/** Gets the scope of this SSA definition. */
CfgScope getScope() { result = this.getBasicBlock().getScope() }
}
Expand Down
5 changes: 3 additions & 2 deletions ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowPrivate.qll
Original file line number Diff line number Diff line change
Expand Up @@ -352,15 +352,16 @@ module VariableCapture {
}

private module CaptureInput implements Shared::InputSig<Location> {
private import ruby as R
private import codeql.ruby.controlflow.ControlFlowGraph
private import codeql.ruby.controlflow.ControlFlowGraph as Cfg
private import codeql.ruby.controlflow.BasicBlocks as BasicBlocks
private import TaintTrackingPrivate as TaintTrackingPrivate

class BasicBlock extends BasicBlocks::BasicBlock {
Callable getEnclosingCallable() { result = this.getScope() }
}

class ControlFlowNode = Cfg::CfgNode;

BasicBlock getImmediateBasicBlockDominator(BasicBlock bb) {
result = bb.getImmediateDominator()
}
Expand Down
10 changes: 6 additions & 4 deletions ruby/ql/lib/codeql/ruby/dataflow/internal/SsaImpl.qll
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,18 @@ private import codeql.ruby.ast.Variable
private import Cfg::CfgNodes::ExprNodes

private module SsaInput implements SsaImplCommon::InputSig<Location> {
private import codeql.ruby.controlflow.ControlFlowGraph as Cfg
private import codeql.ruby.controlflow.BasicBlocks as BasicBlocks

class BasicBlock = BasicBlocks::BasicBlock;

class ControlFlowNode = Cfg::CfgNode;

BasicBlock getImmediateBasicBlockDominator(BasicBlock bb) { result = bb.getImmediateDominator() }

BasicBlock getABasicBlockSuccessor(BasicBlock bb) { result = bb.getASuccessor() }

class ExitBasicBlock = BasicBlocks::ExitBasicBlock;
class ExitBasicBlock extends BasicBlock, BasicBlocks::ExitBasicBlock { }

class SourceVariable = LocalVariable;

Expand Down Expand Up @@ -494,8 +497,7 @@ class DefinitionExt extends Impl::DefinitionExt {

override string toString() { result = this.(Ssa::Definition).toString() }

/** Gets the location of this definition. */
Location getLocation() { result = this.(Ssa::Definition).getLocation() }
override Location getLocation() { result = this.(Ssa::Definition).getLocation() }
}

/**
Expand All @@ -506,5 +508,5 @@ class DefinitionExt extends Impl::DefinitionExt {
class PhiReadNode extends DefinitionExt, Impl::PhiReadNode {
override string toString() { result = "SSA phi read(" + this.getSourceVariable() + ")" }

override Location getLocation() { result = this.getBasicBlock().getLocation() }
override Location getLocation() { result = Impl::PhiReadNode.super.getLocation() }
}
23 changes: 20 additions & 3 deletions shared/dataflow/codeql/dataflow/VariableCapture.qll
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,28 @@ signature module InputSig<LocationSig Location> {
/** Gets a textual representation of this basic block. */
string toString();

/** Gets the `i`th node in this basic block. */
ControlFlowNode getNode(int i);

/** Gets the length of this basic block. */
int length();

/** Gets the enclosing callable. */
Callable getEnclosingCallable();

/** Gets the location of this basic block. */
Location getLocation();
}

/** A control flow node. */
class ControlFlowNode {
/** Gets a textual representation of this control flow node. */
string toString();

/** Gets the location of this control flow node. */
Location getLocation();
}

/**
* Gets the basic block that immediately dominates basic block `bb`, if any.
*
Expand Down Expand Up @@ -672,6 +687,8 @@ module Flow<LocationSig Location, InputSig<Location> Input> implements OutputSig
private module CaptureSsaInput implements Ssa::InputSig<Location> {
final class BasicBlock = Input::BasicBlock;

final class ControlFlowNode = Input::ControlFlowNode;

BasicBlock getImmediateBasicBlockDominator(BasicBlock bb) {
result = Input::getImmediateBasicBlockDominator(bb)
}
Expand Down Expand Up @@ -717,10 +734,10 @@ module Flow<LocationSig Location, InputSig<Location> Input> implements OutputSig
TSynthPhi(CaptureSsa::DefinitionExt phi) {
phi instanceof CaptureSsa::PhiNode or phi instanceof CaptureSsa::PhiReadNode
} or
TExprNode(Expr expr, boolean isPost) {
expr instanceof VariableRead and isPost = [false, true]
TExprNode(Expr expr, Boolean isPost) {
expr instanceof VariableRead
or
synthRead(_, _, _, _, expr) and isPost = [false, true]
synthRead(_, _, _, _, expr)
} or
TParamNode(CapturedParameter p) or
TThisParamNode(Callable c) { captureAccess(_, c) } or
Expand Down
Loading

0 comments on commit da0909c

Please sign in to comment.