diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/SsaInternals.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/SsaInternals.qll index 1ad6701cbf6..6d419e02543 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/SsaInternals.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/SsaInternals.qll @@ -1071,157 +1071,12 @@ module SsaCached { predicate variableWrite = SsaInput::variableWrite/4; } -cached -private newtype TSsaDef = - TDef(DefinitionExt def) or - TPhi(PhiNode phi) +class GlobalDef extends DefinitionExt { + GlobalDefImpl impl; -abstract private class SsaDef extends TSsaDef { - /** Gets a textual representation of this element. */ - string toString() { none() } + GlobalDef() { impl = this.getImpl() } - /** Gets the underlying non-phi definition or use. */ - DefinitionExt asDef() { none() } - - /** Gets the underlying phi node. */ - PhiNode asPhi() { none() } - - /** Gets the location of this element. */ - abstract Location getLocation(); -} - -abstract class Def extends SsaDef, TDef { - DefinitionExt def; - - Def() { this = TDef(def) } - - final override DefinitionExt asDef() { result = def } - - /** Gets the source variable underlying this SSA definition. */ - final SourceVariable getSourceVariable() { result = def.getSourceVariable() } - - override string toString() { result = def.toString() } - - /** - * Holds if this definition (or use) has index `index` in block `block`, - * and is a definition (or use) of the variable `sv`. - */ - predicate hasIndexInBlock(IRBlock block, int index, SourceVariable sv) { - def.definesAt(sv, block, index, _) - } - - /** Gets the value written by this definition, if any. */ - Node0Impl getValue() { none() } - - /** - * Holds if this definition is guaranteed to overwrite the entire - * destination's allocation. - */ - abstract predicate isCertain(); - - /** Gets the address operand written to by this definition. */ - Operand getAddressOperand() { none() } - - /** Gets the address written to by this definition. */ - final Instruction getAddress() { result = this.getAddressOperand().getDef() } - - /** Gets the indirection index of this definition. */ - abstract int getIndirectionIndex(); - - /** - * Gets the indirection level that this definition is writing to. - * For instance, `x = y` is a definition of `x` at indirection level 1 and - * `*x = y` is a definition of `x` at indirection level 2. - */ - abstract int getIndirection(); - - /** - * Gets a definition that ultimately defines this SSA definition and is not - * itself a phi node. - */ - Def getAnUltimateDefinition() { result.asDef() = def.getAnUltimateDefinition() } -} - -private predicate isGlobal(DefinitionExt def, GlobalDefImpl global) { - exists(SourceVariable sv, IRBlock bb, int i | - def.definesAt(sv, bb, i, _) and - global.hasIndexInBlock(bb, i, sv) - ) -} - -private class NonGlobalDef extends Def { - NonGlobalDef() { not isGlobal(def, _) } - - final override Location getLocation() { result = this.getImpl().getLocation() } - - private DefImpl getImpl() { - exists(SourceVariable sv, IRBlock bb, int i | - this.hasIndexInBlock(bb, i, sv) and - result.hasIndexInBlock(bb, i, sv) - ) - } - - override Node0Impl getValue() { result = this.getImpl().getValue() } - - override predicate isCertain() { this.getImpl().isCertain() } - - override Operand getAddressOperand() { result = this.getImpl().getAddressOperand() } - - override int getIndirectionIndex() { result = this.getImpl().getIndirectionIndex() } - - override int getIndirection() { result = this.getImpl().getIndirection() } -} - -class GlobalDef extends Def { - GlobalDefImpl global; - - GlobalDef() { isGlobal(def, global) } - - /** Gets a textual representation of this definition. */ - override string toString() { result = global.toString() } - - final override Location getLocation() { result = global.getLocation() } - - /** - * Gets the type of this definition after specifiers have been deeply stripped - * and typedefs have been resolved. - */ - DataFlowType getUnspecifiedType() { result = global.getUnspecifiedType() } - - /** - * Gets the type of this definition, after typedefs have been resolved. - */ - DataFlowType getUnderlyingType() { result = global.getUnderlyingType() } - - /** Gets the `IRFunction` whose body is evaluated after this definition. */ - IRFunction getIRFunction() { result = global.getIRFunction() } - - /** Gets the global variable associated with this definition. */ - GlobalLikeVariable getVariable() { result = global.getVariable() } - - override predicate isCertain() { any() } - - final override int getIndirectionIndex() { result = global.getIndirectionIndex() } - - final override int getIndirection() { result = global.getIndirection() } -} - -class Phi extends TPhi, SsaDef { - PhiNode phi; - - Phi() { this = TPhi(phi) } - - final override PhiNode asPhi() { result = phi } - - final override Location getLocation() { result = phi.getBasicBlock().getLocation() } - - override string toString() { result = phi.toString() } - - SsaPhiInputNode getNode(IRBlock block) { result.getPhiNode() = phi and result.getBlock() = block } - - predicate hasInputFromBlock(Definition inp, IRBlock bb) { inp = phiHasInputFromBlockExt(phi, bb) } - - final Definition getAnInput() { this.hasInputFromBlock(result, _) } + GlobalLikeVariable getVariable() { result = impl.getVariable() } } private module SsaImpl = SsaImplCommon::Make;