Skip to content
Draft
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 @@ -2173,6 +2173,8 @@ module IteratorFlow {
predicate variableRead(IRCfg::BasicBlock bb, int i, SourceVariable v, boolean certain) {
Ssa::variableRead(bb, i, v, certain)
}

predicate ssaCachedStageRevRef() { DataFlowIntegrationImpl::ssaCachedStageRevRef2() }
}

private module IteratorSsa = SsaImpl::Make<Location, IRCfg, SsaInput>;
Expand Down
50 changes: 16 additions & 34 deletions cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/SsaImpl.qll
Original file line number Diff line number Diff line change
Expand Up @@ -1104,37 +1104,29 @@ private module SsaInput implements Ssa::InputSig<Location, IRCfg::BasicBlock> {
if use.isCertain() then certain = true else certain = false
)
}

predicate ssaCachedStageRevRef() { DataFlowIntegrationImpl::ssaCachedStageRevRef2() }
}

/**
* The final SSA predicates used for dataflow purposes.
*/
cached
module SsaCached {
cached
predicate ssaDefReachesRead(SourceVariable v, Definition def, IRBlock bb, int i) {
SsaImpl::ssaDefReachesRead(v, def, bb, i)
}
predicate ssaDefReachesRead(SourceVariable v, Definition def, IRBlock bb, int i) {
SsaImpl::ssaDefReachesRead(v, def, bb, i)
}

cached
predicate phiHasInputFromBlock(PhiNode phi, Definition inp, IRBlock bb) {
SsaImpl::phiHasInputFromBlock(phi, inp, bb)
}
predicate phiHasInputFromBlock(PhiNode phi, Definition inp, IRBlock bb) {
SsaImpl::phiHasInputFromBlock(phi, inp, bb)
}

cached
predicate uncertainWriteDefinitionInput(Definition uncertain, Definition inp) {
SsaImpl::uncertainWriteDefinitionInput(uncertain, inp)
}
predicate uncertainWriteDefinitionInput(Definition uncertain, Definition inp) {
SsaImpl::uncertainWriteDefinitionInput(uncertain, inp)
}

cached
predicate ssaDefReachesEndOfBlock(IRBlock bb, Definition def) {
SsaImpl::ssaDefReachesEndOfBlock(bb, def, _)
}
predicate ssaDefReachesEndOfBlock(IRBlock bb, Definition def) {
SsaImpl::ssaDefReachesEndOfBlock(bb, def, _)
}

predicate variableRead = SsaInput::variableRead/4;
predicate variableRead = SsaInput::variableRead/4;

predicate variableWrite = SsaInput::variableWrite/4;
}
predicate variableWrite = SsaInput::variableWrite/4;

/** Gets the `DefImpl` corresponding to `def`. */
pragma[nomagic]
Expand Down Expand Up @@ -1173,14 +1165,6 @@ private module DataFlowIntegrationInput implements SsaImpl::DataFlowIntegrationI
predicate hasCfgNode(IRCfg::BasicBlock bb, int i) { bb.getInstruction(i) = this }
}

Expr getARead(SsaImpl::Definition def) {
exists(SourceVariable v, IRBlock bb, int i |
ssaDefReachesRead(v, def, bb, i) and
variableRead(bb, i, v, true) and
result.hasCfgNode(bb, i)
)
}

predicate ssaDefHasSource(SsaImpl::WriteDefinition def) { none() }

predicate allowFlowIntoUncertainDef(SsaImpl::UncertainWriteDefinition def) { any() }
Expand Down Expand Up @@ -1654,5 +1638,3 @@ class IndirectExplicitDefinition extends ExplicitDefinition {
class DirectExplicitDefinition extends ExplicitDefinition {
DirectExplicitDefinition() { this.getIndirectionIndex() = 0 }
}

import SsaCached
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,8 @@ private module BaseSsaImpl {
certain = true
)
}

predicate ssaCachedStageRevRef() { BaseSsa::ssaCachedStageRevRef1() }
}

module SsaImpl = SsaImplCommon::Make<Location, Cfg, SsaImplInput>;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,10 @@ private module SsaImplInput implements SsaImplCommon::InputSig<Location, BasicBl
variableReadPseudo(bb, i, v) and
certain = false
}

predicate ssaCachedStageRevRef() {
Ssa_::ssaCachedStageRevRef1() and DataFlowIntegrationImpl::ssaCachedStageRevRef2()
}
}

import SsaImplCommon::Make<Location, Cfg, SsaImplInput> as Impl
Expand Down Expand Up @@ -1012,8 +1016,6 @@ private module DataFlowIntegrationInput implements Impl::DataFlowIntegrationInpu
predicate hasCfgNode(BasicBlock bb, int i) { this = bb.getNode(i) }
}

Expr getARead(Definition def) { def.(SsaDefinition).getARead().getControlFlowNode() = result }

predicate ssaDefHasSource(Impl::WriteDefinition def) {
// exclude flow directly from RHS to SSA definition, as we instead want to
// go from RHS to matching assignable definition, and from there to SSA definition
Expand Down
9 changes: 0 additions & 9 deletions go/ql/lib/semmle/go/dataflow/SsaImpl.qll
Original file line number Diff line number Diff line change
Expand Up @@ -140,32 +140,23 @@ final class PhiNode = Impl::PhiNode;
module Consistency = Impl::Consistency;

/**
* NB: This predicate should be cached.
*
* Holds if the SSA definition of `v` at `def` reaches a read at index `i` in
* basic block `bb`.
*/
cached
predicate ssaDefReachesRead(SsaSourceVariable v, Definition def, BasicBlock bb, int i) {
Impl::ssaDefReachesRead(v, def, bb, i)
}

/**
* NB: This predicate should be cached.
*
* Holds if the SSA definition of `v` at `def` reaches the end of basic block `bb`.
*/
cached
predicate ssaDefReachesEndOfBlock(BasicBlock bb, Definition def, SsaSourceVariable v) {
Impl::ssaDefReachesEndOfBlock(bb, def, v)
}

/**
* NB: This predicate should be cached.
*
* Holds if `inp` is an input to the phi node `phi` along the edge originating in `bb`.
*/
cached
predicate phiHasInputFromBlock(PhiNode phi, Definition inp, BasicBlock bb) {
Impl::phiHasInputFromBlock(phi, inp, bb)
}
Expand Down
2 changes: 2 additions & 0 deletions java/ql/lib/semmle/code/java/dataflow/internal/BaseSSA.qll
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,8 @@ private module SsaImplInput implements SsaImplCommon::InputSig<Location, BasicBl
variableCapture(v, _, bb, i) and
certain = false
}

predicate ssaCachedStageRevRef() { Ssa::ssaCachedStageRevRef1() }
}

private module Impl = SsaImplCommon::Make<Location, Cfg, SsaImplInput>;
Expand Down
6 changes: 4 additions & 2 deletions java/ql/lib/semmle/code/java/dataflow/internal/SsaImpl.qll
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,10 @@ private module SsaImplInput implements SsaImplCommon::InputSig<Location, BasicBl
variableCapture(v, _, bb, i) and
certain = false
}

predicate ssaCachedStageRevRef() {
Ssa::ssaCachedStageRevRef1() and DataFlowIntegrationImpl::ssaCachedStageRevRef2()
}
}

import SsaImplCommon::Make<Location, Cfg, SsaImplInput> as Impl
Expand Down Expand Up @@ -642,8 +646,6 @@ private module DataFlowIntegrationInput implements Impl::DataFlowIntegrationInpu
}
}

Expr getARead(Definition def) { result = def.(SsaDefinition).getARead() }

predicate ssaDefHasSource(WriteDefinition def) { def instanceof SsaExplicitWrite }

predicate allowFlowIntoUncertainDef(UncertainWriteDefinition def) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ module SsaConfig implements InputSig<js::Location, js::Cfg::BasicBlock> {
certain = true and
bb.getNode(i).(ThisUse).getBindingContainer() = v.asThisContainer()
}

predicate ssaCachedStageRevRef() { DataFlowIntegrationImpl::ssaCachedStageRevRef2() }
}

import Make<js::Location, js::Cfg, SsaConfig>
Expand All @@ -56,16 +58,6 @@ module SsaDataflowInput implements DataFlowIntegrationInputSig {
none()
}

cached
Expr getARead(Definition def) {
// Copied from implementation so we can cache it here
exists(SsaConfig::SourceVariable v, js::BasicBlock bb, int i |
ssaDefReachesRead(v, def, bb, i) and
SsaConfig::variableRead(bb, i, v, true) and
result.hasCfgNode(bb, i)
)
}

class GuardValue = Boolean;

class Guard extends js::ControlFlowNode {
Expand Down Expand Up @@ -107,4 +99,6 @@ module SsaDataflowInput implements DataFlowIntegrationInputSig {
}
}

import DataFlowIntegration<SsaDataflowInput>
module DataFlowIntegrationImpl = DataFlowIntegration<SsaDataflowInput>;

import DataFlowIntegrationImpl
6 changes: 4 additions & 2 deletions ruby/ql/lib/codeql/ruby/dataflow/SSA.qll
Original file line number Diff line number Diff line change
Expand Up @@ -333,7 +333,9 @@ module Ssa {
* Gets the immediately preceding definition. Since this update is uncertain,
* the value from the preceding definition might still be valid.
*/
final Definition getPriorDefinition() { result = SsaImpl::uncertainWriteDefinitionInput(this) }
final Definition getPriorDefinition() {
SsaImpl::Impl::uncertainWriteDefinitionInput(this, result)
}

override string toString() { result = "<captured exit> " + this.getSourceVariable() }
}
Expand Down Expand Up @@ -381,7 +383,7 @@ module Ssa {

/** Holds if `inp` is an input to this phi node along the edge originating in `bb`. */
predicate hasInputFromBlock(Definition inp, BasicBlock bb) {
inp = SsaImpl::phiHasInputFromBlock(this, bb)
SsaImpl::Impl::phiHasInputFromBlock(this, inp, bb)
}

override string toString() { result = "phi" }
Expand Down
14 changes: 2 additions & 12 deletions ruby/ql/lib/codeql/ruby/dataflow/internal/SsaImpl.qll
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,8 @@ module SsaInput implements SsaImplCommon::InputSig<Location, BasicBlock> {
namespaceSelfExitRead(bb, i, v) and
certain = false
}

predicate ssaCachedStageRevRef() { DataFlowIntegrationImpl::ssaCachedStageRevRef2() }
}

import SsaImplCommon::Make<Location, Cfg::Cfg, SsaInput> as Impl
Expand Down Expand Up @@ -279,11 +281,6 @@ private module Cached {

private import codeql.ruby.dataflow.SSA

cached
Definition phiHasInputFromBlock(PhiNode phi, Cfg::BasicBlock bb) {
Impl::phiHasInputFromBlock(phi, result, bb)
}

/**
* Holds if the value defined at SSA definition `def` can reach a read at `read`,
* without passing through any other non-pseudo read.
Expand All @@ -310,11 +307,6 @@ private module Cached {
)
}

cached
Definition uncertainWriteDefinitionInput(UncertainWriteDefinition def) {
Impl::uncertainWriteDefinitionInput(def, result)
}

cached
module DataFlowIntegration {
import DataFlowIntegrationImpl
Expand Down Expand Up @@ -446,8 +438,6 @@ private module DataFlowIntegrationInput implements Impl::DataFlowIntegrationInpu
predicate hasCfgNode(BasicBlock bb, int i) { this = bb.getNode(i) }
}

Expr getARead(Definition def) { result = Cached::getARead(def) }

predicate ssaDefHasSource(WriteDefinition def) {
any(ParameterExt p).isInitializedBy(def) or def.(Ssa::WriteDefinition).assigns(_)
}
Expand Down
6 changes: 4 additions & 2 deletions rust/ql/lib/codeql/rust/dataflow/Ssa.qll
Original file line number Diff line number Diff line change
Expand Up @@ -266,7 +266,7 @@ module Ssa {

/** Holds if `inp` is an input to this phi definition along the edge originating in `bb`. */
predicate hasInputFromBlock(Definition inp, BasicBlock bb) {
inp = SsaImpl::phiHasInputFromBlock(this, bb)
SsaImpl::Impl::phiHasInputFromBlock(this, inp, bb)
}

private string getSplitString() {
Expand Down Expand Up @@ -354,7 +354,9 @@ module Ssa {
* Gets the immediately preceding definition. Since this update is uncertain,
* the value from the preceding definition might still be valid.
*/
final Definition getPriorDefinition() { result = SsaImpl::uncertainWriteDefinitionInput(this) }
final Definition getPriorDefinition() {
SsaImpl::Impl::uncertainWriteDefinitionInput(this, result)
}

override string toString() { result = "<captured exit> " + this.getSourceVariable() }
}
Expand Down
14 changes: 2 additions & 12 deletions rust/ql/lib/codeql/rust/dataflow/internal/SsaImpl.qll
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,8 @@ module SsaInput implements SsaImplCommon::InputSig<Location, BasicBlock> {
or
capturedExitRead(bb, i, v) and certain = false
}

predicate ssaCachedStageRevRef() { DataFlowIntegrationImpl::ssaCachedStageRevRef2() }
}

import SsaImplCommon::Make<Location, BasicBlocks::Cfg, SsaInput> as Impl
Expand Down Expand Up @@ -236,11 +238,6 @@ private module Cached {
)
}

cached
Definition phiHasInputFromBlock(PhiDefinition phi, BasicBlock bb) {
Impl::phiHasInputFromBlock(phi, result, bb)
}

/**
* Holds if the value defined at SSA definition `def` can reach a read at `read`,
* without passing through any other non-pseudo read.
Expand All @@ -267,11 +264,6 @@ private module Cached {
)
}

cached
Definition uncertainWriteDefinitionInput(UncertainWriteDefinition def) {
Impl::uncertainWriteDefinitionInput(def, result)
}

cached
module DataFlowIntegration {
import DataFlowIntegrationImpl
Expand Down Expand Up @@ -346,8 +338,6 @@ private module DataFlowIntegrationInput implements Impl::DataFlowIntegrationInpu
predicate hasCfgNode(BasicBlock bb, int i) { this.getACfgNode() = bb.getNode(i) }
}

Expr getARead(Definition def) { result = Cached::getARead(def) }

predicate ssaDefHasSource(WriteDefinition def) { none() } // handled in `DataFlowImpl.qll` instead

private predicate isArg(Call call, Expr e) {
Expand Down
2 changes: 2 additions & 0 deletions shared/dataflow/codeql/dataflow/VariableCapture.qll
Original file line number Diff line number Diff line change
Expand Up @@ -739,6 +739,8 @@ module Flow<
) and
certain = true
}

predicate ssaCachedStageRevRef() { SsaFlow::ssaCachedStageRevRef2() }
}

private module CaptureSsa = Ssa::Make<Location, Cfg, CaptureSsaInput>;
Expand Down
Loading
Loading