Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -1880,9 +1880,7 @@ module IteratorFlow {
}
}

private module SsaInput implements SsaImpl::InputSig<Location> {
import Ssa::InputSigCommon

private module SsaInput implements SsaImpl::InputSig<Location, IRCfg::BasicBlock> {
class SourceVariable = IteratorFlow::SourceVariable;

/** A call to function that dereferences an iterator. */
Expand Down Expand Up @@ -1960,7 +1958,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(BasicBlock bb, int i, SourceVariable v, boolean certain) {
predicate variableWrite(IRCfg::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 @@ -1971,12 +1969,12 @@ module IteratorFlow {
}

/** Holds if `(bb, i)` reads the container variable `v`. */
predicate variableRead(BasicBlock bb, int i, SourceVariable v, boolean certain) {
predicate variableRead(IRCfg::BasicBlock bb, int i, SourceVariable v, boolean certain) {
Ssa::variableRead(bb, i, v, certain)
}
}

private module IteratorSsa = SsaImpl::Make<Location, SsaInput>;
private module IteratorSsa = SsaImpl::Make<Location, IRCfg, SsaInput>;

private module DataFlowIntegrationInput implements IteratorSsa::DataFlowIntegrationInputSig {
private import codeql.util.Void
Expand All @@ -1989,7 +1987,7 @@ module IteratorFlow {
)
}

predicate hasCfgNode(SsaInput::BasicBlock bb, int i) { bb.getInstruction(i) = this }
predicate hasCfgNode(IRCfg::BasicBlock bb, int i) { bb.getInstruction(i) = this }
}

predicate ssaDefHasSource(IteratorSsa::WriteDefinition def) { none() }
Expand All @@ -1999,20 +1997,16 @@ module IteratorFlow {
class GuardValue = Void;

class Guard extends Void {
predicate hasValueBranchEdge(
SsaInput::BasicBlock bb1, SsaInput::BasicBlock bb2, GuardValue val
) {
predicate hasValueBranchEdge(IRCfg::BasicBlock bb1, IRCfg::BasicBlock bb2, GuardValue val) {
none()
}

predicate valueControlsBranchEdge(
SsaInput::BasicBlock bb1, SsaInput::BasicBlock bb2, GuardValue val
) {
predicate valueControlsBranchEdge(IRCfg::BasicBlock bb1, IRCfg::BasicBlock bb2, GuardValue val) {
none()
}
}

predicate guardDirectlyControlsBlock(Guard guard, SsaInput::BasicBlock bb, GuardValue val) {
predicate guardDirectlyControlsBlock(Guard guard, IRCfg::BasicBlock bb, GuardValue val) {
none()
}

Expand Down
19 changes: 8 additions & 11 deletions cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/SsaImpl.qll
Original file line number Diff line number Diff line change
Expand Up @@ -891,15 +891,14 @@ private predicate baseSourceVariableIsGlobal(
)
}

private module SsaInput implements Ssa::InputSig<Location> {
import InputSigCommon
private module SsaInput implements Ssa::InputSig<Location, IRCfg::BasicBlock> {
import SourceVariables

/**
* 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(BasicBlock bb, int i, SourceVariable v, boolean certain) {
predicate variableWrite(IRCfg::BasicBlock bb, int i, SourceVariable v, boolean certain) {
DataFlowImplCommon::forceCachingInSameStage() and
(
exists(DefImpl def | def.hasIndexInBlock(v, bb, i) |
Expand All @@ -917,7 +916,7 @@ private module SsaInput implements Ssa::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(BasicBlock bb, int i, SourceVariable v, boolean certain) {
predicate variableRead(IRCfg::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 Expand Up @@ -965,7 +964,7 @@ class GlobalDef extends Definition {
GlobalLikeVariable getVariable() { result = impl.getVariable() }
}

private module SsaImpl = Ssa::Make<Location, SsaInput>;
private module SsaImpl = Ssa::Make<Location, IRCfg, SsaInput>;

private module DataFlowIntegrationInput implements SsaImpl::DataFlowIntegrationInputSig {
private import codeql.util.Boolean
Expand All @@ -978,7 +977,7 @@ private module DataFlowIntegrationInput implements SsaImpl::DataFlowIntegrationI
)
}

predicate hasCfgNode(SsaInput::BasicBlock bb, int i) { bb.getInstruction(i) = this }
predicate hasCfgNode(IRCfg::BasicBlock bb, int i) { bb.getInstruction(i) = this }
}

Expr getARead(SsaImpl::Definition def) {
Expand Down Expand Up @@ -1006,9 +1005,7 @@ private module DataFlowIntegrationInput implements SsaImpl::DataFlowIntegrationI
class Guard instanceof IRGuards::IRGuardCondition {
string toString() { result = super.toString() }

predicate hasValueBranchEdge(
SsaInput::BasicBlock bb1, SsaInput::BasicBlock bb2, GuardValue branch
) {
predicate hasValueBranchEdge(IRCfg::BasicBlock bb1, IRCfg::BasicBlock bb2, GuardValue branch) {
exists(EdgeKind kind |
super.getBlock() = bb1 and
kind = getConditionalEdge(branch) and
Expand All @@ -1017,13 +1014,13 @@ private module DataFlowIntegrationInput implements SsaImpl::DataFlowIntegrationI
}

predicate valueControlsBranchEdge(
SsaInput::BasicBlock bb1, SsaInput::BasicBlock bb2, GuardValue branch
IRCfg::BasicBlock bb1, IRCfg::BasicBlock bb2, GuardValue branch
) {
this.hasValueBranchEdge(bb1, bb2, branch)
}
}

predicate guardDirectlyControlsBlock(Guard guard, SsaInput::BasicBlock bb, GuardValue branch) {
predicate guardDirectlyControlsBlock(Guard guard, IRCfg::BasicBlock bb, GuardValue branch) {
guard.(IRGuards::IRGuardCondition).controls(bb, branch)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -768,21 +768,3 @@ private module Cached {
}

import Cached

/**
* Inputs to the shared SSA library's parameterized module that is shared
* between the SSA pruning stage, and the final SSA stage.
*/
module InputSigCommon {
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() }
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import Instruction
private import internal.IRBlockImports as Imports
import Imports::EdgeKind
private import Cached
private import codeql.controlflow.BasicBlock as BB

/**
* Holds if `block` is a block in `func` and `sortOverride`, `sortKey1`, and `sortKey2` are the
Expand Down Expand Up @@ -263,6 +264,47 @@ private predicate isEntryBlock(TIRBlock block) {
block = MkIRBlock(any(EnterFunctionInstruction enter))
}

module IRCfg implements BB::CfgSig<Language::Location> {
class ControlFlowNode = Instruction;

class SuccessorType = EdgeKind;

final private class FinalIRBlock = IRBlock;

class BasicBlock extends FinalIRBlock {
ControlFlowNode getNode(int i) { result = this.getInstruction(i) }

ControlFlowNode getLastNode() { result = super.getLastInstruction() }

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

BasicBlock getASuccessor() { result = super.getASuccessor() }

BasicBlock getASuccessor(SuccessorType t) { result = super.getSuccessor(t) }

predicate strictlyDominates(BasicBlock bb) { super.strictlyDominates(bb) }

predicate dominates(BasicBlock bb) { super.dominates(bb) }

BasicBlock getImmediateDominator() { result.immediatelyDominates(this) }

predicate inDominanceFrontier(BasicBlock df) { super.dominanceFrontier() = df }

predicate strictlyPostDominates(BasicBlock bb) { super.strictlyPostDominates(bb) }

predicate postDominates(BasicBlock bb) { super.postDominates(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) { isEntryBlock(bb) }
}

cached
private module Cached {
cached
Expand Down
42 changes: 42 additions & 0 deletions cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/IRBlock.qll
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import Instruction
private import internal.IRBlockImports as Imports
import Imports::EdgeKind
private import Cached
private import codeql.controlflow.BasicBlock as BB

/**
* Holds if `block` is a block in `func` and `sortOverride`, `sortKey1`, and `sortKey2` are the
Expand Down Expand Up @@ -263,6 +264,47 @@ private predicate isEntryBlock(TIRBlock block) {
block = MkIRBlock(any(EnterFunctionInstruction enter))
}

module IRCfg implements BB::CfgSig<Language::Location> {
class ControlFlowNode = Instruction;

class SuccessorType = EdgeKind;

final private class FinalIRBlock = IRBlock;

class BasicBlock extends FinalIRBlock {
ControlFlowNode getNode(int i) { result = this.getInstruction(i) }

ControlFlowNode getLastNode() { result = super.getLastInstruction() }

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

BasicBlock getASuccessor() { result = super.getASuccessor() }

BasicBlock getASuccessor(SuccessorType t) { result = super.getSuccessor(t) }

predicate strictlyDominates(BasicBlock bb) { super.strictlyDominates(bb) }

predicate dominates(BasicBlock bb) { super.dominates(bb) }

BasicBlock getImmediateDominator() { result.immediatelyDominates(this) }

predicate inDominanceFrontier(BasicBlock df) { super.dominanceFrontier() = df }

predicate strictlyPostDominates(BasicBlock bb) { super.strictlyPostDominates(bb) }

predicate postDominates(BasicBlock bb) { super.postDominates(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) { isEntryBlock(bb) }
}

cached
private module Cached {
cached
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import Instruction
private import internal.IRBlockImports as Imports
import Imports::EdgeKind
private import Cached
private import codeql.controlflow.BasicBlock as BB

/**
* Holds if `block` is a block in `func` and `sortOverride`, `sortKey1`, and `sortKey2` are the
Expand Down Expand Up @@ -263,6 +264,47 @@ private predicate isEntryBlock(TIRBlock block) {
block = MkIRBlock(any(EnterFunctionInstruction enter))
}

module IRCfg implements BB::CfgSig<Language::Location> {
class ControlFlowNode = Instruction;

class SuccessorType = EdgeKind;

final private class FinalIRBlock = IRBlock;

class BasicBlock extends FinalIRBlock {
ControlFlowNode getNode(int i) { result = this.getInstruction(i) }

ControlFlowNode getLastNode() { result = super.getLastInstruction() }

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

BasicBlock getASuccessor() { result = super.getASuccessor() }

BasicBlock getASuccessor(SuccessorType t) { result = super.getSuccessor(t) }

predicate strictlyDominates(BasicBlock bb) { super.strictlyDominates(bb) }

predicate dominates(BasicBlock bb) { super.dominates(bb) }

BasicBlock getImmediateDominator() { result.immediatelyDominates(this) }

predicate inDominanceFrontier(BasicBlock df) { super.dominanceFrontier() = df }

predicate strictlyPostDominates(BasicBlock bb) { super.strictlyPostDominates(bb) }

predicate postDominates(BasicBlock bb) { super.postDominates(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) { isEntryBlock(bb) }
}

cached
private module Cached {
cached
Expand Down
8 changes: 4 additions & 4 deletions csharp/ql/consistency-queries/CfgConsistency.ql
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ predicate bbSuccInconsistency(ControlFlowElement pred, ControlFlowElement succ)
succBB.getFirstNode() = succ.getAControlFlowNode()
) and
not exists(PreBasicBlock predBB, PreBasicBlock succBB |
predBB.getLastElement() = pred and
predBB.getLastNode() = pred and
succBB = predBB.getASuccessor() and
succBB.getFirstElement() = succ
)
Expand All @@ -41,12 +41,12 @@ predicate bbIntraSuccInconsistency(ControlFlowElement pred, ControlFlowElement s
succ.getAControlFlowNode() = bb.getNode(i + 1)
) and
not exists(PreBasicBlock bb |
bb.getLastElement() = pred and
bb.getLastNode() = pred and
bb.getASuccessor().getFirstElement() = succ
) and
not exists(PreBasicBlock bb, int i |
bb.getElement(i) = pred and
bb.getElement(i + 1) = succ
bb.getNode(i) = pred and
bb.getNode(i + 1) = succ
)
}

Expand Down
Loading