diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/SSA.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/SSA.qll index ae875e97c6db..92149e026405 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/SSA.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/SSA.qll @@ -311,69 +311,6 @@ module Ssa { result.getControlFlowNode() = cfn } - /** - * Gets a last read of the source variable underlying this SSA definition. - * That is, a read that can reach the end of the enclosing callable, or - * another SSA definition for the source variable, without passing through - * any other read. Example: - * - * ```csharp - * int Field; - * - * void SetField(int i) { - * this.Field = i; - * Use(this.Field); - * if (i > 0) - * this.Field = i - 1; - * else if (i < 0) - * SetField(1); - * Use(this.Field); - * Use(this.Field); - * } - * ``` - * - * - The reads of `i` on lines 7 and 8 are the last reads for the implicit - * parameter definition on line 3. - * - The read of `this.Field` on line 5 is a last read of the definition on - * line 4. - * - The read of `this.Field` on line 11 is a last read of the phi node - * between lines 9 and 10. - */ - deprecated final AssignableRead getALastRead() { result = this.getALastReadAtNode(_) } - - /** - * Gets a last read of the source variable underlying this SSA definition at - * control flow node `cfn`. That is, a read that can reach the end of the - * enclosing callable, or another SSA definition for the source variable, - * without passing through any other read. Example: - * - * ```csharp - * int Field; - * - * void SetField(int i) { - * this.Field = i; - * Use(this.Field); - * if (i > 0) - * this.Field = i - 1; - * else if (i < 0) - * SetField(1); - * Use(this.Field); - * Use(this.Field); - * } - * ``` - * - * - The reads of `i` on lines 7 and 8 are the last reads for the implicit - * parameter definition on line 3. - * - The read of `this.Field` on line 5 is a last read of the definition on - * line 4. - * - The read of `this.Field` on line 11 is a last read of the phi node - * between lines 9 and 10. - */ - deprecated final AssignableRead getALastReadAtNode(ControlFlowNode cfn) { - SsaImpl::lastReadSameVar(this, cfn) and - result.getControlFlowNode() = cfn - } - /** * Gets an SSA definition whose value can flow to this one in one step. This * includes inputs to phi nodes and the prior definitions of uncertain writes. diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/SsaImpl.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/SsaImpl.qll index 0a8a4680191b..6e933c6a8e0c 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/SsaImpl.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/SsaImpl.qll @@ -713,61 +713,6 @@ private predicate variableReadPseudo(BasicBlock bb, int i, Ssa::SourceVariable v refReadBeforeWrite(bb, i, v) } -pragma[noinline] -deprecated private predicate adjacentDefRead( - Definition def, BasicBlock bb1, int i1, BasicBlock bb2, int i2, SsaInput::SourceVariable v -) { - Impl::adjacentDefRead(def, bb1, i1, bb2, i2) and - v = def.getSourceVariable() -} - -deprecated private predicate adjacentDefReachesRead( - Definition def, SsaInput::SourceVariable v, BasicBlock bb1, int i1, BasicBlock bb2, int i2 -) { - adjacentDefRead(def, bb1, i1, bb2, i2, v) and - ( - def.definesAt(v, bb1, i1) - or - SsaInput::variableRead(bb1, i1, v, true) - ) - or - exists(BasicBlock bb3, int i3 | - adjacentDefReachesRead(def, v, bb1, i1, bb3, i3) and - SsaInput::variableRead(bb3, i3, _, false) and - Impl::adjacentDefRead(def, bb3, i3, bb2, i2) - ) -} - -deprecated private predicate adjacentDefReachesUncertainRead( - Definition def, BasicBlock bb1, int i1, BasicBlock bb2, int i2 -) { - exists(SsaInput::SourceVariable v | - adjacentDefReachesRead(def, v, bb1, i1, bb2, i2) and - SsaInput::variableRead(bb2, i2, v, false) - ) -} - -/** Same as `lastRefRedef`, but skips uncertain reads. */ -pragma[nomagic] -deprecated private predicate lastRefSkipUncertainReads(Definition def, BasicBlock bb, int i) { - Impl::lastRef(def, bb, i) and - not SsaInput::variableRead(bb, i, def.getSourceVariable(), false) - or - exists(BasicBlock bb0, int i0 | - Impl::lastRef(def, bb0, i0) and - adjacentDefReachesUncertainRead(def, bb, i, bb0, i0) - ) -} - -pragma[nomagic] -deprecated predicate lastReadSameVar(Definition def, ControlFlowNode cfn) { - exists(BasicBlock bb, int i | - lastRefSkipUncertainReads(def, bb, i) and - variableReadActual(bb, i, _) and - cfn = bb.getNode(i) - ) -} - cached private module Cached { cached diff --git a/ruby/ql/lib/codeql/ruby/dataflow/SSA.qll b/ruby/ql/lib/codeql/ruby/dataflow/SSA.qll index 1478d9ed9d6b..08ca08732b6b 100644 --- a/ruby/ql/lib/codeql/ruby/dataflow/SSA.qll +++ b/ruby/ql/lib/codeql/ruby/dataflow/SSA.qll @@ -78,34 +78,6 @@ module Ssa { */ final VariableReadAccessCfgNode getAFirstRead() { SsaImpl::firstRead(this, result) } - /** - * Gets a last control-flow node that reads the value of this SSA definition. - * That is, a read that can reach the end of the enclosing CFG scope, or another - * SSA definition for the source variable, without passing through any other read. - * - * Example: - * - * ```rb - * def m b # defines b_0 - * i = 0 # defines i_0 - * puts i - * puts i + 1 # last read of i_0 - * if b # last read of b_0 - * i = 1 # defines i_1 - * puts i - * puts i + 1 # last read of i_1 - * else - * i = 2 # defines i_2 - * puts i - * puts i + 1 # last read of i_2 - * end - * # defines i_3 = phi(i_1, i_2) - * puts i # last read of i3 - * end - * ``` - */ - deprecated final VariableReadAccessCfgNode getALastRead() { SsaImpl::lastRead(this, result) } - /** * Holds if `read1` and `read2` are adjacent reads of this SSA definition. * That is, `read2` can be reached from `read1` without passing through diff --git a/ruby/ql/lib/codeql/ruby/dataflow/internal/SsaImpl.qll b/ruby/ql/lib/codeql/ruby/dataflow/internal/SsaImpl.qll index 1856d03c1190..74394150ca32 100644 --- a/ruby/ql/lib/codeql/ruby/dataflow/internal/SsaImpl.qll +++ b/ruby/ql/lib/codeql/ruby/dataflow/internal/SsaImpl.qll @@ -212,63 +212,6 @@ private predicate hasVariableReadWithCapturedWrite( variableReadActualInOuterScope(bb, i, v, scope) } -pragma[noinline] -deprecated private predicate adjacentDefReadExt( - Definition def, BasicBlock bb1, int i1, BasicBlock bb2, int i2, SsaInput::SourceVariable v -) { - Impl::adjacentDefReadExt(def, _, bb1, i1, bb2, i2) and - v = def.getSourceVariable() -} - -deprecated private predicate adjacentDefReachesReadExt( - Definition def, BasicBlock bb1, int i1, BasicBlock bb2, int i2 -) { - exists(SsaInput::SourceVariable v | adjacentDefReadExt(def, bb1, i1, bb2, i2, v) | - def.definesAt(v, bb1, i1) - or - SsaInput::variableRead(bb1, i1, v, true) - ) - or - exists(BasicBlock bb3, int i3 | - adjacentDefReachesReadExt(def, bb1, i1, bb3, i3) and - SsaInput::variableRead(bb3, i3, _, false) and - Impl::adjacentDefReadExt(def, _, bb3, i3, bb2, i2) - ) -} - -deprecated private predicate adjacentDefReachesUncertainReadExt( - Definition def, BasicBlock bb1, int i1, BasicBlock bb2, int i2 -) { - adjacentDefReachesReadExt(def, bb1, i1, bb2, i2) and - SsaInput::variableRead(bb2, i2, _, false) -} - -/** Same as `lastRefRedef`, but skips uncertain reads. */ -pragma[nomagic] -deprecated private predicate lastRefSkipUncertainReadsExt(Definition def, BasicBlock bb, int i) { - Impl::lastRef(def, bb, i) and - not SsaInput::variableRead(bb, i, def.getSourceVariable(), false) - or - exists(BasicBlock bb0, int i0 | - Impl::lastRef(def, bb0, i0) and - adjacentDefReachesUncertainReadExt(def, bb, i, bb0, i0) - ) -} - -/** - * Holds if the read of `def` at `read` may be a last read. That is, `read` - * can either reach another definition of the underlying source variable or - * the end of the CFG scope, without passing through another non-pseudo read. - */ -pragma[nomagic] -deprecated predicate lastRead(Definition def, VariableReadAccessCfgNode read) { - exists(Cfg::BasicBlock bb, int i | - lastRefSkipUncertainReadsExt(def, bb, i) and - variableReadActual(bb, i, _) and - read = bb.getNode(i) - ) -} - cached private module Cached { /** diff --git a/shared/controlflow/codeql/controlflow/Cfg.qll b/shared/controlflow/codeql/controlflow/Cfg.qll index 157bf0ffd4f3..02ada45bef60 100644 --- a/shared/controlflow/codeql/controlflow/Cfg.qll +++ b/shared/controlflow/codeql/controlflow/Cfg.qll @@ -252,20 +252,9 @@ module MakeWithSplitting< rank[i + 1](ControlFlowTree child, int j | child = this.getChildNode(j) | child order by j) } - /** Gets the first child node of this element. */ - deprecated final AstNode getFirstChildNode() { result = this.getChildTreeRanked(0) } - /** Gets the first child node of this element. */ final ControlFlowTree getFirstChildTree() { result = this.getChildTreeRanked(0) } - /** Gets the last child node of this node. */ - deprecated final AstNode getLastChildElement() { - exists(int last | - result = this.getChildTreeRanked(last) and - not exists(this.getChildTreeRanked(last + 1)) - ) - } - /** Gets the last child node of this node. */ final ControlFlowTree getLastChildTree() { exists(int last | diff --git a/shared/dataflow/codeql/dataflow/DataFlow.qll b/shared/dataflow/codeql/dataflow/DataFlow.qll index cacd52cf8396..53da239d83ee 100644 --- a/shared/dataflow/codeql/dataflow/DataFlow.qll +++ b/shared/dataflow/codeql/dataflow/DataFlow.qll @@ -784,19 +784,6 @@ private module DataFlowMakeCore Lang> { /** Gets the location of this node. */ Location getLocation() { result = this.getNode().getLocation() } - - /** - * Holds if this element is at the specified location. - * The location spans column `startcolumn` of line `startline` to - * column `endcolumn` of line `endline` in file `filepath`. - * For more information, see - * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). - */ - deprecated predicate hasLocationInfo( - string filepath, int startline, int startcolumn, int endline, int endcolumn - ) { - this.getLocation().hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn) - } } /** @@ -853,19 +840,6 @@ private module DataFlowMakeCore Lang> { /** Gets a textual representation of this element. */ string toString() { result = super.toString() } - /** - * Holds if this element is at the specified location. - * The location spans column `startcolumn` of line `startline` to - * column `endcolumn` of line `endline` in file `filepath`. - * For more information, see - * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). - */ - deprecated predicate hasLocationInfo( - string filepath, int startline, int startcolumn, int endline, int endcolumn - ) { - super.hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn) - } - /** Gets the underlying `Node`. */ Node getNode() { result = super.getNode() } diff --git a/shared/dataflow/codeql/dataflow/internal/DataFlowImpl.qll b/shared/dataflow/codeql/dataflow/internal/DataFlowImpl.qll index ed0412d1cd4d..3af6b9eab99a 100644 --- a/shared/dataflow/codeql/dataflow/internal/DataFlowImpl.qll +++ b/shared/dataflow/codeql/dataflow/internal/DataFlowImpl.qll @@ -2531,36 +2531,6 @@ module MakeImpl Lang> { /** Holds if this node is a sink. */ final predicate isSink() { this instanceof PathNodeSink } - - /** - * Holds if this element is at the specified location. - * The location spans column `startcolumn` of line `startline` to - * column `endcolumn` of line `endline` in file `filepath`. - * For more information, see - * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). - */ - overlay[caller?] - pragma[inline] - deprecated final predicate hasLocationInfo( - string filepath, int startline, int startcolumn, int endline, int endcolumn - ) { - this.getLocation() - .hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn) - } - - /** - * DEPRECATED: This functionality is no longer available. - * - * Holds if this node is a grouping of source nodes. - */ - deprecated final predicate isSourceGroup(string group) { none() } - - /** - * DEPRECATED: This functionality is no longer available. - * - * Holds if this node is a grouping of sink nodes. - */ - deprecated final predicate isSinkGroup(string group) { none() } } /** Holds if `n1.getASuccessor() = n2` and `n2` can reach a sink. */ diff --git a/shared/dataflow/codeql/dataflow/internal/DataFlowImplCommon.qll b/shared/dataflow/codeql/dataflow/internal/DataFlowImplCommon.qll index 962a58c26f94..c64f0edb8468 100644 --- a/shared/dataflow/codeql/dataflow/internal/DataFlowImplCommon.qll +++ b/shared/dataflow/codeql/dataflow/internal/DataFlowImplCommon.qll @@ -27,26 +27,6 @@ module MakeImplCommon Lang> { private import Aliases module DataFlowImplCommonPublic { - /** - * DEPRECATED: Generally, a custom `FlowState` type should be used instead, - * but `string` can of course still be used without referring to this - * module. - * - * Provides `FlowState = string`. - */ - deprecated module FlowStateString { - /** A state value to track during data flow. */ - deprecated class FlowState = string; - - /** - * The default state, which is used when the state is unspecified for a source - * or a sink. - */ - deprecated class FlowStateEmpty extends FlowState { - FlowStateEmpty() { this = "" } - } - } - private newtype TFlowFeature = TFeatureHasSourceCallContext() or TFeatureHasSinkCallContext() or diff --git a/shared/dataflow/codeql/dataflow/internal/DataFlowImplStage1.qll b/shared/dataflow/codeql/dataflow/internal/DataFlowImplStage1.qll index b7a45a67b567..7c9881c90d73 100644 --- a/shared/dataflow/codeql/dataflow/internal/DataFlowImplStage1.qll +++ b/shared/dataflow/codeql/dataflow/internal/DataFlowImplStage1.qll @@ -1847,21 +1847,6 @@ module MakeImplStage1 Lang> { /** Gets the location of this node. */ Location getLocation() { result = this.getNodeEx().getLocation() } - /** - * Holds if this element is at the specified location. - * The location spans column `startcolumn` of line `startline` to - * column `endcolumn` of line `endline` in file `filepath`. - * For more information, see - * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). - */ - overlay[caller?] - pragma[inline] - deprecated predicate hasLocationInfo( - string filepath, int startline, int startcolumn, int endline, int endcolumn - ) { - this.getLocation().hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn) - } - /** Gets the underlying `Node`. */ final Node getNode() { this.getNodeEx().projectToNode() = result } diff --git a/shared/ssa/codeql/ssa/Ssa.qll b/shared/ssa/codeql/ssa/Ssa.qll index cb2d527c9641..8d6b960b2833 100644 --- a/shared/ssa/codeql/ssa/Ssa.qll +++ b/shared/ssa/codeql/ssa/Ssa.qll @@ -474,7 +474,7 @@ module Make< private class TDefinition = TWriteDef or TPhiNode; - private module SsaDefReachesNew { + private module SsaDefReaches { /** * Holds if the `i`th node of basic block `bb` is a reference to `v`, * either a read (when `k` is `Read()`) or an SSA definition (when @@ -737,352 +737,12 @@ module Make< ) } - private module SsaDefReaches { - deprecated newtype TSsaRefKind = - SsaActualRead() or - SsaPhiRead() or - SsaDef() - - deprecated class SsaRead = SsaActualRead or SsaPhiRead; - - deprecated class SsaDefExt = SsaDef or SsaPhiRead; - - deprecated SsaDefExt ssaDefExt() { any() } - - /** - * A classification of SSA variable references into reads and definitions. - */ - deprecated class SsaRefKind extends TSsaRefKind { - string toString() { - this = SsaActualRead() and - result = "SsaActualRead" - or - this = SsaPhiRead() and - result = "SsaPhiRead" - or - this = SsaDef() and - result = "SsaDef" - } - - int getOrder() { - this instanceof SsaRead and - result = 0 - or - this = SsaDef() and - result = 1 - } - } - - /** - * Holds if the `i`th node of basic block `bb` is a reference to `v`, - * either a read (when `k` is `SsaActualRead()`), an SSA definition (when `k` - * is `SsaDef()`), or a phi-read (when `k` is `SsaPhiRead()`). - * - * Unlike `Liveness::varRef`, this includes `phi` (read) nodes. - */ - pragma[nomagic] - deprecated predicate ssaRef(BasicBlock bb, int i, SourceVariable v, SsaRefKind k) { - variableRead(bb, i, v, _) and - k = SsaActualRead() - or - any(Definition def).definesAt(v, bb, i) and - k = SsaDef() - or - synthPhiRead(bb, v) and i = -1 and k = SsaPhiRead() - } - - /** - * Holds if the `i`th node of basic block `bb` is a reference to `v`, and - * this reference is not a phi-read. - */ - deprecated predicate ssaRefNonPhiRead(BasicBlock bb, int i, SourceVariable v) { - ssaRef(bb, i, v, [SsaActualRead().(TSsaRefKind), SsaDef()]) - } - - deprecated private newtype OrderedSsaRefIndex = - deprecated MkOrderedSsaRefIndex(int i, SsaRefKind k) { ssaRef(_, i, _, k) } - - deprecated private OrderedSsaRefIndex ssaRefOrd( - BasicBlock bb, int i, SourceVariable v, SsaRefKind k, int ord - ) { - ssaRef(bb, i, v, k) and - result = MkOrderedSsaRefIndex(i, k) and - ord = k.getOrder() - } - - /** - * Gets the (1-based) rank of the reference to `v` at the `i`th node of basic - * block `bb`, which has the given reference kind `k`. - * - * For example, if `bb` is a basic block with a phi node for `v` (considered - * to be at index -1), reads `v` at node 2, and defines it at node 5, we have: - * - * ```ql - * ssaRefRank(bb, -1, v, SsaDef()) = 1 // phi node - * ssaRefRank(bb, 2, v, Read()) = 2 // read at node 2 - * ssaRefRank(bb, 5, v, SsaDef()) = 3 // definition at node 5 - * ``` - * - * Reads are considered before writes when they happen at the same index. - */ - deprecated int ssaRefRank(BasicBlock bb, int i, SourceVariable v, SsaRefKind k) { - ssaRefOrd(bb, i, v, k, _) = - rank[result](int j, int ord, OrderedSsaRefIndex res | - res = ssaRefOrd(bb, j, v, _, ord) - | - res order by j, ord - ) - } - - deprecated int maxSsaRefRank(BasicBlock bb, SourceVariable v) { - result = ssaRefRank(bb, _, v, _) and - not result + 1 = ssaRefRank(bb, _, v, _) - } - - /** - * Holds if the SSA definition `def` reaches rank index `rnk` in its own - * basic block `bb`. - */ - deprecated predicate ssaDefReachesRank( - BasicBlock bb, DefinitionExt def, int rnk, SourceVariable v - ) { - exists(int i | - rnk = ssaRefRank(bb, i, v, ssaDefExt()) and - def.definesAt(v, bb, i, _) - ) - or - ssaDefReachesRank(bb, def, rnk - 1, v) and - rnk = ssaRefRank(bb, _, v, SsaActualRead()) - } - - /** - * Holds if the SSA definition of `v` at `def` reaches index `i` in the same - * basic block `bb`, without crossing another SSA definition of `v`. - */ - deprecated predicate ssaDefReachesReadWithinBlock( - SourceVariable v, DefinitionExt def, BasicBlock bb, int i - ) { - exists(int rnk | - ssaDefReachesRank(bb, def, rnk, v) and - rnk = ssaRefRank(bb, i, v, SsaActualRead()) - ) - } - - /** - * Same as `ssaRefRank()`, but restricted to a particular SSA definition `def`. - */ - deprecated int ssaDefRank( - DefinitionExt def, SourceVariable v, BasicBlock bb, int i, SsaRefKind k - ) { - result = ssaRefRank(bb, i, v, k) and - ( - ssaDefReachesReadExt(v, def, bb, i) - or - def.definesAt(v, bb, i, k) - ) - } - - /** - * Holds if the reference to `def` at index `i` in basic block `bb` is the - * last reference to `v` inside `bb`. - */ - pragma[noinline] - deprecated predicate lastSsaRefExt(DefinitionExt def, SourceVariable v, BasicBlock bb, int i) { - ssaDefRank(def, v, bb, i, _) = maxSsaRefRank(bb, v) - } - - /** Gets a phi-read node into which `inp` is an input, if any. */ - pragma[nomagic] - deprecated private DefinitionExt getAPhiReadOutput(DefinitionExt inp) { - phiHasInputFromBlockExt(result.(PhiReadNode), inp, _) - } - - pragma[nomagic] - deprecated DefinitionExt getAnUltimateOutput(Definition def) { - result = getAPhiReadOutput*(def) - } - - /** - * Same as `lastSsaRefExt`, but ignores phi-reads. - */ - pragma[noinline] - deprecated predicate lastSsaRef(Definition def, SourceVariable v, BasicBlock bb, int i) { - lastSsaRefExt(getAnUltimateOutput(def), v, bb, i) and - ssaRefNonPhiRead(bb, i, v) - } - - deprecated predicate defOccursInBlock( - DefinitionExt def, BasicBlock bb, SourceVariable v, SsaRefKind k - ) { - exists(ssaDefRank(def, v, bb, _, k)) - } - - pragma[noinline] - deprecated predicate ssaDefReachesThroughBlock(DefinitionExt def, BasicBlock bb) { - exists(SourceVariable v | - ssaDefReachesEndOfBlockExt0(bb, def, v) and - not defOccursInBlock(_, bb, v, _) - ) - } - - /** - * Holds if `def` is accessed in basic block `bb1` (either a read or a write), - * `bb2` is a transitive successor of `bb1`, `def` is live at the end of _some_ - * predecessor of `bb2`, and the underlying variable for `def` is neither read - * nor written in any block on the path between `bb1` and `bb2`. - */ - pragma[nomagic] - deprecated predicate varBlockReachesExt( - DefinitionExt def, SourceVariable v, BasicBlock bb1, BasicBlock bb2 - ) { - defOccursInBlock(def, bb1, v, _) and - bb2 = bb1.getASuccessor() - or - exists(BasicBlock mid | - varBlockReachesExt(def, v, bb1, mid) and - ssaDefReachesThroughBlock(def, mid) and - bb2 = mid.getASuccessor() - ) - } - - pragma[nomagic] - deprecated private predicate phiReadStep( - DefinitionExt def, PhiReadNode phi, BasicBlock bb1, BasicBlock bb2 - ) { - exists(SourceVariable v | - varBlockReachesExt(pragma[only_bind_into](def), v, bb1, pragma[only_bind_into](bb2)) and - phi.definesAt(v, bb2, _, _) and - not varRef(bb2, _, v, _) - ) - } - - pragma[nomagic] - deprecated private predicate varBlockReachesExclPhiRead( - DefinitionExt def, SourceVariable v, BasicBlock bb1, BasicBlock bb2 - ) { - varBlockReachesExt(def, v, bb1, bb2) and - ssaRefNonPhiRead(bb2, _, v) - or - exists(PhiReadNode phi, BasicBlock mid | - varBlockReachesExclPhiRead(phi, v, mid, bb2) and - phiReadStep(def, phi, bb1, mid) - ) - } - - /** - * Same as `varBlockReachesExt`, but ignores phi-reads, and furthermore - * `bb2` is restricted to blocks in which the underlying variable `v` of - * `def` is referenced (either a read or a write). - */ - pragma[nomagic] - deprecated predicate varBlockReachesRef( - Definition def, SourceVariable v, BasicBlock bb1, BasicBlock bb2 - ) { - varBlockReachesExclPhiRead(getAnUltimateOutput(def), v, bb1, bb2) and - ssaRefNonPhiRead(bb1, _, v) - } - - pragma[nomagic] - deprecated predicate defAdjacentReadExt( - DefinitionExt def, BasicBlock bb1, BasicBlock bb2, int i2 - ) { - exists(SourceVariable v | - varBlockReachesExt(def, v, bb1, bb2) and - ssaRefRank(bb2, i2, v, SsaActualRead()) = 1 - ) - } - - pragma[nomagic] - deprecated predicate defAdjacentRead(Definition def, BasicBlock bb1, BasicBlock bb2, int i2) { - exists(SourceVariable v | varBlockReachesRef(def, v, bb1, bb2) | - ssaRefRank(bb2, i2, v, SsaActualRead()) = 1 - or - ssaRefRank(bb2, _, v, SsaPhiRead()) = 1 and - ssaRefRank(bb2, i2, v, SsaActualRead()) = 2 - ) - } - - /** - * Holds if `def` is accessed in basic block `bb` (either a read or a write), - * `bb` can reach a transitive successor `bb2` where `def` is no longer live, - * and `v` is neither read nor written in any block on the path between `bb` - * and `bb2`. - */ - pragma[nomagic] - deprecated predicate varBlockReachesExitExt(DefinitionExt def, BasicBlock bb) { - exists(BasicBlock bb2 | varBlockReachesExt(def, _, bb, bb2) | - not defOccursInBlock(def, bb2, _, _) and - not ssaDefReachesEndOfBlockExt0(bb2, def, _) - ) - } - - pragma[nomagic] - deprecated private predicate varBlockReachesExitExclPhiRead(DefinitionExt def, BasicBlock bb) { - exists(BasicBlock bb2, SourceVariable v | - varBlockReachesExt(def, v, bb, bb2) and - not defOccursInBlock(def, bb2, _, _) and - not ssaDefReachesEndOfBlockExt0(bb2, def, _) and - not any(PhiReadNode phi).definesAt(v, bb2, _, _) - ) - or - exists(PhiReadNode phi, BasicBlock bb2 | - varBlockReachesExitExclPhiRead(phi, bb2) and - phiReadStep(def, phi, bb, bb2) - ) - } - - /** - * Same as `varBlockReachesExitExt`, but ignores phi-reads. - */ - pragma[nomagic] - deprecated predicate varBlockReachesExit(Definition def, BasicBlock bb) { - varBlockReachesExitExclPhiRead(getAnUltimateOutput(def), bb) - } - } - - private import SsaDefReaches - - pragma[nomagic] - deprecated private predicate liveThroughExt(BasicBlock bb, SourceVariable v) { - liveAtExit(bb, v) and - not ssaRef(bb, _, v, ssaDefExt()) - } - - /** - * NB: If this predicate is exposed, it should be cached. - * - * Holds if the SSA definition of `v` at `def` reaches the end of basic - * block `bb`, at which point it is still live, without crossing another - * SSA definition of `v`. - */ - pragma[nomagic] - deprecated private predicate ssaDefReachesEndOfBlockExt0( - BasicBlock bb, DefinitionExt def, SourceVariable v - ) { - exists(int last | - last = maxSsaRefRank(pragma[only_bind_into](bb), pragma[only_bind_into](v)) and - ssaDefReachesRank(bb, def, last, v) and - liveAtExit(bb, v) - ) - or - // The construction of SSA form ensures that each read of a variable is - // dominated by its definition. An SSA definition therefore reaches a - // control flow node if it is the _closest_ SSA definition that dominates - // the node. If two definitions dominate a node then one must dominate the - // other, so therefore the definition of _closest_ is given by the dominator - // tree. Thus, reaching definitions can be calculated in terms of dominance. - ssaDefReachesEndOfBlockExt0(bb.getImmediateDominator(), def, pragma[only_bind_into](v)) and - liveThroughExt(bb, pragma[only_bind_into](v)) - } - - deprecated predicate ssaDefReachesEndOfBlockExt = ssaDefReachesEndOfBlockExt0/3; - /** * NB: If this predicate is exposed, it should be cached. * * Same as `ssaDefReachesEndOfBlockExt`, but ignores phi-reads. */ - predicate ssaDefReachesEndOfBlock = SsaDefReachesNew::ssaDefReachesEndOfBlock/3; + predicate ssaDefReachesEndOfBlock = SsaDefReaches::ssaDefReachesEndOfBlock/3; /** * NB: If this predicate is exposed, it should be cached. @@ -1098,176 +758,16 @@ module Make< ) } - /** - * NB: If this predicate is exposed, it should be cached. - * - * Holds if `inp` is an input to the phi (read) node `phi` along the edge originating in `bb`. - */ - pragma[nomagic] - deprecated predicate phiHasInputFromBlockExt(DefinitionExt phi, DefinitionExt inp, BasicBlock bb) { - exists(SourceVariable v, BasicBlock bbDef | - phi.definesAt(v, bbDef, _, _) and - getABasicBlockPredecessor(bbDef) = bb and - ssaDefReachesEndOfBlockExt0(bb, inp, v) - | - phi instanceof PhiNode or - phi instanceof PhiReadNode - ) - } - - /** - * NB: If this predicate is exposed, it should be cached. - * - * Holds if the SSA definition of `v` at `def` reaches a read at index `i` in - * basic block `bb`, without crossing another SSA definition of `v`. - */ - pragma[nomagic] - deprecated predicate ssaDefReachesReadExt( - SourceVariable v, DefinitionExt def, BasicBlock bb, int i - ) { - ssaDefReachesReadWithinBlock(v, def, bb, i) - or - ssaRef(bb, i, v, SsaActualRead()) and - ssaDefReachesEndOfBlockExt0(getABasicBlockPredecessor(bb), def, v) and - not ssaDefReachesReadWithinBlock(v, _, bb, i) - } - /** * NB: If this predicate is exposed, it should be cached. * * Same as `ssaDefReachesReadExt`, but ignores phi-reads. */ predicate ssaDefReachesRead(SourceVariable v, Definition def, BasicBlock bb, int i) { - SsaDefReachesNew::ssaDefReachesRead(v, def, bb, i) and + SsaDefReaches::ssaDefReachesRead(v, def, bb, i) and variableRead(bb, i, v, _) } - /** - * NB: If this predicate is exposed, it should be cached. - * - * Holds if `def` is accessed at index `i1` in basic block `bb1` (either a read - * or a write), `def` is read at index `i2` in basic block `bb2`, and there is a - * path between them without any read of `def`. - */ - pragma[nomagic] - deprecated predicate adjacentDefReadExt( - DefinitionExt def, SourceVariable v, BasicBlock bb1, int i1, BasicBlock bb2, int i2 - ) { - exists(int rnk | - rnk = ssaDefRank(def, v, bb1, i1, _) and - rnk + 1 = ssaDefRank(def, v, bb1, i2, SsaActualRead()) and - variableRead(bb1, i2, v, _) and - bb2 = bb1 - ) - or - lastSsaRefExt(def, v, bb1, i1) and - defAdjacentReadExt(def, bb1, bb2, i2) - } - - /** - * NB: If this predicate is exposed, it should be cached. - * - * Same as `adjacentDefReadExt`, but ignores phi-reads. - */ - pragma[nomagic] - deprecated predicate adjacentDefRead( - Definition def, BasicBlock bb1, int i1, BasicBlock bb2, int i2 - ) { - exists(SourceVariable v | - adjacentDefReadExt(getAnUltimateOutput(def), v, bb1, i1, bb2, i2) and - ssaRefNonPhiRead(bb1, i1, v) - ) - or - lastSsaRef(def, _, bb1, i1) and - defAdjacentRead(def, bb1, bb2, i2) - } - - deprecated private predicate lastRefRedefExtSameBlock( - DefinitionExt def, SourceVariable v, BasicBlock bb, int i, DefinitionExt next - ) { - exists(int rnk, int j | - rnk = ssaDefRank(def, v, bb, i, _) and - next.definesAt(v, bb, j, _) and - rnk + 1 = ssaRefRank(bb, j, v, ssaDefExt()) - ) - } - - /** - * NB: If this predicate is exposed, it should be cached. - * - * Holds if the node at index `i` in `bb` is a last reference to SSA definition - * `def`. The reference is last because it can reach another write `next`, - * without passing through another read or write. - */ - pragma[nomagic] - deprecated predicate lastRefRedefExt( - DefinitionExt def, SourceVariable v, BasicBlock bb, int i, DefinitionExt next - ) { - // Next reference to `v` inside `bb` is a write - lastRefRedefExtSameBlock(def, v, bb, i, next) - or - // Can reach a write using one or more steps - lastSsaRefExt(def, v, bb, i) and - exists(BasicBlock bb2 | - varBlockReachesExt(def, v, bb, bb2) and - 1 = ssaDefRank(next, v, bb2, _, ssaDefExt()) - ) - } - - /** - * NB: If this predicate is exposed, it should be cached. - * - * Holds if the node at index `i` in `bb` is a last reference to SSA definition - * `def`. The reference is last because it can reach another write `next`, - * without passing through another read or write. - * - * The path from node `i` in `bb` to `next` goes via basic block `input`, which is - * either a predecessor of the basic block of `next`, or `input = bb` in case `next` - * occurs in basic block `bb`. - */ - pragma[nomagic] - deprecated predicate lastRefRedefExt( - DefinitionExt def, SourceVariable v, BasicBlock bb, int i, BasicBlock input, DefinitionExt next - ) { - // Next reference to `v` inside `bb` is a write - lastRefRedefExtSameBlock(def, v, bb, i, next) and - input = bb - or - // Can reach a write using one or more steps - lastSsaRefExt(def, v, bb, i) and - exists(BasicBlock bb2 | - input = getABasicBlockPredecessor(bb2) and - 1 = ssaDefRank(next, v, bb2, _, ssaDefExt()) - | - input = bb - or - varBlockReachesExt(def, v, bb, input) and - ssaDefReachesThroughBlock(def, pragma[only_bind_into](input)) - ) - } - - /** - * NB: If this predicate is exposed, it should be cached. - * - * Same as `lastRefRedefExt`, but ignores phi-reads. - */ - pragma[nomagic] - deprecated predicate lastRefRedef(Definition def, BasicBlock bb, int i, Definition next) { - exists(SourceVariable v | - lastRefRedefExt(getAnUltimateOutput(def), v, bb, i, next) and - ssaRefNonPhiRead(bb, i, v) - ) - or - // Can reach a write using one or more steps - exists(SourceVariable v | - lastSsaRef(def, v, bb, i) and - exists(BasicBlock bb2 | - varBlockReachesRef(def, v, bb, bb2) and - 1 = ssaDefRank(next, v, bb2, _, SsaDef()) - ) - ) - } - /** * NB: If this predicate is exposed, it should be cached. * @@ -1275,55 +775,7 @@ module Make< * `def`. Since `def` is uncertain, the value from the preceding definition might * still be valid. */ - predicate uncertainWriteDefinitionInput = SsaDefReachesNew::uncertainWriteDefinitionInput/2; - - /** Holds if `bb` is a control-flow exit point. */ - private predicate exitBlock(BasicBlock bb) { not exists(bb.getASuccessor()) } - - /** - * NB: If this predicate is exposed, it should be cached. - * - * Holds if the node at index `i` in `bb` is a last reference to SSA - * definition `def`. - * - * That is, the node can reach the end of the enclosing callable, or another - * SSA definition for the underlying source variable, without passing through - * another read. - */ - pragma[nomagic] - deprecated predicate lastRefExt(DefinitionExt def, BasicBlock bb, int i) { - // Can reach another definition - lastRefRedefExt(def, _, bb, i, _) - or - lastSsaRefExt(def, _, bb, i) and - ( - // Can reach exit directly - exitBlock(bb) - or - // Can reach a block using one or more steps, where `def` is no longer live - varBlockReachesExitExt(def, bb) - ) - } - - /** - * NB: If this predicate is exposed, it should be cached. - * - * Same as `lastRefExt`, but ignores phi-reads. - */ - pragma[nomagic] - deprecated predicate lastRef(Definition def, BasicBlock bb, int i) { - // Can reach another definition - lastRefRedef(def, bb, i, _) - or - lastSsaRef(def, _, bb, i) and - ( - // Can reach exit directly - exitBlock(bb) - or - // Can reach a block using one or more steps, where `def` is no longer live - varBlockReachesExit(def, bb) - ) - } + predicate uncertainWriteDefinitionInput = SsaDefReaches::uncertainWriteDefinitionInput/2; /** A static single assignment (SSA) definition. */ class Definition extends TDefinition { @@ -1382,30 +834,16 @@ module Make< } } - deprecated class DefinitionExt = DefinitionExt_; - /** * An extended static single assignment (SSA) definition. * * This is either a normal SSA definition (`Definition`) or a * phi-read node (`PhiReadNode`). */ - private class DefinitionExt_ extends TDefinitionExt { + private class DefinitionExt extends TDefinitionExt { /** Gets the source variable underlying this SSA definition. */ SourceVariable getSourceVariable() { this.definesAt(result, _, _) } - /** - * Holds if this SSA definition defines `v` at index `i` in basic block `bb`. - * Phi nodes are considered to be at index `-1`, while normal variable writes - * are at the index of the control flow node they wrap. - */ - deprecated final predicate definesAt(SourceVariable v, BasicBlock bb, int i, SsaRefKind kind) { - this.(Definition).definesAt(v, bb, i) and - kind = SsaDef() - or - this = TPhiReadNode(v, bb) and i = -1 and kind = SsaPhiRead() - } - /** * Holds if this SSA definition defines `v` at index `i` in basic block `bb`. * Phi nodes are considered to be at index `-1`, while normal variable writes @@ -1427,8 +865,6 @@ module Make< Location getLocation() { result = this.(Definition).getLocation() } } - deprecated class PhiReadNode = PhiReadNode_; - /** * A phi-read node. * @@ -1510,7 +946,7 @@ module Make< * to `phi-read` goes through a dominance-frontier block, and hence a phi node, * which contradicts reachability. */ - private class PhiReadNode_ extends DefinitionExt_, TPhiReadNode { + private class PhiReadNode extends DefinitionExt, TPhiReadNode { override string toString() { result = "SSA phi read(" + this.getSourceVariable() + ")" } override Location getLocation() { result = this.getBasicBlock().getLocation() } @@ -1823,11 +1259,11 @@ module Make< /** Holds if a read is not dominated by a definition. */ query predicate notDominatedByDef(Definition def, SourceVariable v, BasicBlock bb, int i) { exists(BasicBlock bbDef, int iDef | def.definesAt(v, bbDef, iDef) | - SsaDefReachesNew::ssaDefReachesReadWithinBlock(v, def, bb, i) and + SsaDefReaches::ssaDefReachesReadWithinBlock(v, def, bb, i) and (bb != bbDef or i < iDef) or ssaDefReachesRead(v, def, bb, i) and - not SsaDefReachesNew::ssaDefReachesReadWithinBlock(v, def, bb, i) and + not SsaDefReaches::ssaDefReachesReadWithinBlock(v, def, bb, i) and not def.definesAt(v, bb.getImmediateDominator*(), _) ) } @@ -2048,14 +1484,14 @@ module Make< module DataFlowIntegration { private import codeql.util.Boolean - final private class DefinitionExtFinal = DefinitionExt_; + final private class DefinitionExtFinal = DefinitionExt; /** An SSA definition which is either a phi node or a phi read node. */ private class SsaPhiExt extends DefinitionExtFinal { SsaPhiExt() { this instanceof PhiNode or - this instanceof PhiReadNode_ + this instanceof PhiReadNode } } @@ -2222,13 +1658,13 @@ module Make< private newtype TNode = TWriteDefSource(WriteDefinition def) { DfInput::ssaDefHasSource(def) } or TExprNode(DfInput::Expr e, Boolean isPost) { e = DfInput::getARead(_) } or - TSsaDefinitionNode(DefinitionExt_ def) { + TSsaDefinitionNode(DefinitionExt def) { not phiHasUniqNextNode(def) and if DfInput::includeWriteDefsInFlowStep() then any() else ( def instanceof PhiNode or - def instanceof PhiReadNode_ or + def instanceof PhiReadNode or DfInput::allowFlowIntoUncertainDef(def) ) } or @@ -2330,9 +1766,6 @@ module Make< /** A synthesized SSA data flow node. */ abstract private class SsaNodeImpl extends NodeImpl { - /** Gets the underlying SSA definition. */ - abstract deprecated DefinitionExt getDefinitionExt(); - /** Gets the SSA definition this node corresponds to, if any. */ Definition asDefinition() { this = TSsaDefinitionNode(result) } @@ -2354,14 +1787,12 @@ module Make< /** An SSA definition, viewed as a node in a data flow graph. */ private class SsaDefinitionExtNodeImpl extends SsaNodeImpl, TSsaDefinitionNode { - private DefinitionExt_ def; + private DefinitionExt def; SsaDefinitionExtNodeImpl() { this = TSsaDefinitionNode(def) } /** Gets the corresponding `DefinitionExt`. */ - DefinitionExt_ getDefExt() { result = def } - - deprecated override DefinitionExt getDefinitionExt() { result = def } + DefinitionExt getDefExt() { result = def } override BasicBlock getBasicBlock() { result = def.getBasicBlock() } @@ -2374,8 +1805,6 @@ module Make< override string toString() { result = def.toString() } } - deprecated final class SsaDefinitionExtNode = SsaDefinitionExtNodeImpl; - /** An SSA definition, viewed as a node in a data flow graph. */ private class SsaDefinitionNodeImpl extends SsaDefinitionExtNodeImpl { private Definition def; @@ -2391,7 +1820,7 @@ module Make< /** A node that represents a synthetic read of a source variable. */ final class SsaSynthReadNode extends SsaNode { SsaSynthReadNode() { - this.(SsaDefinitionExtNodeImpl).getDefExt() instanceof PhiReadNode_ or + this.(SsaDefinitionExtNodeImpl).getDefExt() instanceof PhiReadNode or this instanceof SsaInputNodeImpl } } @@ -2438,15 +1867,13 @@ module Make< SsaInputNodeImpl() { this = TSsaInputNode(def_, input_) } /** Holds if this node represents input into SSA definition `def` via basic block `input`. */ - predicate isInputInto(DefinitionExt_ def, BasicBlock input) { + predicate isInputInto(DefinitionExt def, BasicBlock input) { def = def_ and input = input_ } SsaPhiExt getPhi() { result = def_ } - deprecated override SsaPhiExt getDefinitionExt() { result = def_ } - override BasicBlock getBasicBlock() { result = input_ } override int getIndex() { result = input_.length() } @@ -2458,8 +1885,6 @@ module Make< override string toString() { result = "[input] " + def_.toString() } } - deprecated final class SsaInputNode = SsaInputNodeImpl; - /** * Holds if `nodeFrom` corresponds to the reference to `v` at index `i` in * `bb`. The boolean `isUseStep` indicates whether `nodeFrom` is an actual @@ -2469,7 +1894,7 @@ module Make< private predicate flowOutOf( Node nodeFrom, SourceVariable v, BasicBlock bb, int i, boolean isUseStep ) { - exists(DefinitionExt_ def | + exists(DefinitionExt def | nodeFrom.(SsaDefinitionExtNodeImpl).getDefExt() = def and def.definesAt(v, bb, i) and isUseStep = false @@ -2497,7 +1922,7 @@ module Make< ) or // Flow from definition/read to phi input - exists(BasicBlock input, BasicBlock bbPhi, DefinitionExt_ phi | + exists(BasicBlock input, BasicBlock bbPhi, DefinitionExt phi | AdjacentSsaRefs::adjacentRefPhi(bb1, i1, input, bbPhi, v) and phi.definesAt(v, bbPhi, -1) | @@ -2507,9 +1932,7 @@ module Make< ) } - private predicate flowIntoPhi( - DefinitionExt_ phi, SourceVariable v, BasicBlock bbPhi, Node nodeTo - ) { + private predicate flowIntoPhi(DefinitionExt phi, SourceVariable v, BasicBlock bbPhi, Node nodeTo) { phi.definesAt(v, bbPhi, -1) and if phiHasUniqNextNode(phi) then flowFromRefToNode(v, bbPhi, -1, nodeTo) @@ -2545,7 +1968,7 @@ module Make< ) or // Flow from input node to def - exists(DefinitionExt_ phi | + exists(DefinitionExt phi | phi = nodeFrom.(SsaInputNodeImpl).getPhi() and isUseStep = false and nodeFrom != nodeTo and @@ -2565,7 +1988,7 @@ module Make< ) or // Flow from SSA definition to read - exists(DefinitionExt_ def | + exists(DefinitionExt def | nodeFrom.(SsaDefinitionExtNodeImpl).getDefExt() = def and nodeTo.(ExprNode).getExpr() = DfInput::getARead(def) and v = def.getSourceVariable() diff --git a/swift/ql/lib/codeql/swift/dataflow/Ssa.qll b/swift/ql/lib/codeql/swift/dataflow/Ssa.qll index 4f0754ff5900..b66eaedef736 100644 --- a/swift/ql/lib/codeql/swift/dataflow/Ssa.qll +++ b/swift/ql/lib/codeql/swift/dataflow/Ssa.qll @@ -155,11 +155,6 @@ module Ssa { read2 = bb2.getNode(i2) ) } - - cached - deprecated predicate lastRefRedef(BasicBlocks::BasicBlock bb, int i, Definition next) { - SsaImpl::lastRefRedef(this, bb, i, next) - } } cached