Files
codeql/csharp/ql/lib/semmle/code/cil/Ssa.qll
Andrew Eisenberg c9f1c98390 Packaging: C# refactoring
Split c# pack into `codeql/csharp-all` and `codeql/csharp-queries`.
2021-08-19 14:09:35 -07:00

67 lines
2.1 KiB
Plaintext

/**
* Provides the module `Ssa` for working with static single assignment (SSA) form.
*/
private import CIL
/**
* Provides classes for working with static single assignment (SSA) form.
*/
module Ssa {
private import internal.SsaImplCommon as SsaImpl
private import internal.SsaImpl
/** An SSA definition. */
class Definition extends SsaImpl::Definition {
/** Gets a read of this SSA definition. */
final ReadAccess getARead() { result = getARead(this) }
/** Gets the underlying variable update, if any. */
final VariableUpdate getVariableUpdate() {
exists(BasicBlock bb, int i |
result.updatesAt(bb, i) and
this.definesAt(result.getVariable(), bb, i)
)
}
/** Gets a first read of this SSA definition. */
final ReadAccess getAFirstRead() { result = getAFirstRead(this) }
/** Holds if `first` and `second` are adjacent reads of this SSA definition. */
final predicate hasAdjacentReads(ReadAccess first, ReadAccess second) {
hasAdjacentReads(this, first, second)
}
private Definition getAPhiInput() { result = this.(PhiNode).getAnInput() }
/**
* Gets a definition that ultimately defines this SSA definition and is
* not itself a phi node.
*/
final Definition getAnUltimateDefinition() {
result = this.getAPhiInput*() and
not result instanceof PhiNode
}
/** Gets the location of this SSA definition. */
Location getLocation() { result = this.getVariableUpdate().getLocation() }
}
/** A phi node. */
class PhiNode extends SsaImpl::PhiNode, Definition {
final override Location getLocation() { result = this.getBasicBlock().getLocation() }
/** Gets an input to this phi node. */
final Definition getAnInput() { result = getAPhiInput(this) }
/**
* Holds if if `def` is an input to this phi node, and a reference to `def` at
* index `i` in basic block `bb` can reach this phi node without going through
* other references.
*/
final predicate hasLastInputRef(Definition def, BasicBlock bb, int i) {
hasLastInputRef(this, def, bb, i)
}
}
}