From 4ae872093088eef4eb075c9efae91a93b5a3c5d9 Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Wed, 3 Jul 2024 11:09:56 +0200 Subject: [PATCH] SSA: Add `BasicBlock.{getNode/1,length/0}` to the input signature --- .../ir/dataflow/internal/DataFlowPrivate.qll | 4 +-- .../cpp/ir/dataflow/internal/SsaInternals.qll | 4 +-- .../dataflow/internal/SsaInternalsCommon.qll | 10 +++++-- csharp/ql/lib/semmle/code/cil/Ssa.qll | 2 +- .../lib/semmle/code/cil/internal/SsaImpl.qll | 5 +++- .../csharp/controlflow/internal/PreSsa.qll | 8 +++-- .../lib/semmle/code/csharp/dataflow/SSA.qll | 2 +- .../code/csharp/dataflow/internal/BaseSSA.qll | 6 ++-- .../dataflow/internal/DataFlowPrivate.qll | 4 ++- .../code/csharp/dataflow/internal/SsaImpl.qll | 10 ++++--- .../dataflow/internal/DataFlowPrivate.qll | 6 ++++ .../dataflow/new/internal/VariableCapture.qll | 4 +++ ruby/ql/lib/codeql/ruby/dataflow/SSA.qll | 3 -- .../dataflow/internal/DataFlowPrivate.qll | 5 ++-- .../codeql/ruby/dataflow/internal/SsaImpl.qll | 10 ++++--- .../codeql/dataflow/VariableCapture.qll | 23 +++++++++++++-- shared/ssa/codeql/ssa/Ssa.qll | 29 +++++++++++++++++++ swift/ql/lib/codeql/swift/dataflow/Ssa.qll | 8 +++-- .../dataflow/internal/DataFlowPrivate.qll | 7 +++++ 19 files changed, 117 insertions(+), 33 deletions(-) diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowPrivate.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowPrivate.qll index 4bbb675a9d16..3b26093ff5de 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowPrivate.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowPrivate.qll @@ -1809,7 +1809,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(IRBlock bb, int i, SourceVariable v, boolean certain) { + predicate variableWrite(BasicBlock bb, int i, SourceVariable v, boolean certain) { certain = false and exists(GetsIteratorCall beginCall, Instruction writeToDeref, IRBlock bbQual, int iQual | isIteratorStoreInstruction(beginCall, writeToDeref) and @@ -1820,7 +1820,7 @@ module IteratorFlow { } /** Holds if `(bb, i)` reads the container variable `v`. */ - predicate variableRead(IRBlock bb, int i, SourceVariable v, boolean certain) { + predicate variableRead(BasicBlock bb, int i, SourceVariable v, boolean certain) { Ssa::variableRead(bb, i, v, certain) } } 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 203437a91861..34fdb500139a 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 @@ -981,7 +981,7 @@ private module SsaInput implements SsaImplCommon::InputSig { * 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(IRBlock bb, int i, SourceVariable v, boolean certain) { + predicate variableWrite(BasicBlock bb, int i, SourceVariable v, boolean certain) { DataFlowImplCommon::forceCachingInSameStage() and ( exists(DefImpl def | def.hasIndexInBlock(bb, i, v) | @@ -999,7 +999,7 @@ private module SsaInput implements SsaImplCommon::InputSig { * 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(IRBlock bb, int i, SourceVariable v, boolean certain) { + predicate variableRead(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 ) diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/SsaInternalsCommon.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/SsaInternalsCommon.qll index 0920e5a38657..65f1c57b80c3 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/SsaInternalsCommon.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/SsaInternalsCommon.qll @@ -757,13 +757,19 @@ import Cached * between the SSA pruning stage, and the final SSA stage. */ module InputSigCommon { - class BasicBlock = IRBlock; + 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() } - class ExitBasicBlock extends IRBlock { + class ExitBasicBlock extends BasicBlock { ExitBasicBlock() { this.getLastInstruction() instanceof ExitFunctionInstruction } } } diff --git a/csharp/ql/lib/semmle/code/cil/Ssa.qll b/csharp/ql/lib/semmle/code/cil/Ssa.qll index c1dcad4fef5a..4aebad1a602f 100644 --- a/csharp/ql/lib/semmle/code/cil/Ssa.qll +++ b/csharp/ql/lib/semmle/code/cil/Ssa.qll @@ -35,7 +35,7 @@ deprecated module Ssa { } /** Gets the location of this SSA definition. */ - Location getLocation() { result = this.getVariableUpdate().getLocation() } + override Location getLocation() { result = this.getVariableUpdate().getLocation() } } /** A phi node. */ diff --git a/csharp/ql/lib/semmle/code/cil/internal/SsaImpl.qll b/csharp/ql/lib/semmle/code/cil/internal/SsaImpl.qll index 70e77c66ddb7..41acf8ed1f6f 100644 --- a/csharp/ql/lib/semmle/code/cil/internal/SsaImpl.qll +++ b/csharp/ql/lib/semmle/code/cil/internal/SsaImpl.qll @@ -1,14 +1,17 @@ private import cil +private import CIL private import codeql.ssa.Ssa as SsaImplCommon deprecated private module SsaInput implements SsaImplCommon::InputSig { class BasicBlock = CIL::BasicBlock; + class ControlFlowNode = CIL::ControlFlowNode; + BasicBlock getImmediateBasicBlockDominator(BasicBlock bb) { result = bb.getImmediateDominator() } BasicBlock getABasicBlockSuccessor(BasicBlock bb) { result = bb.getASuccessor() } - class ExitBasicBlock = CIL::ExitBasicBlock; + class ExitBasicBlock extends BasicBlock, CIL::ExitBasicBlock { } class SourceVariable = CIL::StackVariable; diff --git a/csharp/ql/lib/semmle/code/csharp/controlflow/internal/PreSsa.qll b/csharp/ql/lib/semmle/code/csharp/controlflow/internal/PreSsa.qll index c7c1de2308b6..0984d0ac41ba 100644 --- a/csharp/ql/lib/semmle/code/csharp/controlflow/internal/PreSsa.qll +++ b/csharp/ql/lib/semmle/code/csharp/controlflow/internal/PreSsa.qll @@ -80,7 +80,11 @@ module PreSsa { } module SsaInput implements SsaImplCommon::InputSig { - class BasicBlock = PreBasicBlocks::PreBasicBlock; + class BasicBlock extends PreBasicBlocks::PreBasicBlock { + ControlFlowNode getNode(int i) { result = this.getElement(i) } + } + + class ControlFlowNode = ControlFlowElement; BasicBlock getImmediateBasicBlockDominator(BasicBlock bb) { result.immediatelyDominates(bb) } @@ -192,7 +196,7 @@ module PreSsa { SsaImpl::ssaDefReachesEndOfBlock(bb, this, _) } - Location getLocation() { + override Location getLocation() { result = this.getDefinition().getLocation() or exists(Callable c, SsaInput::BasicBlock bb, SsaInput::SourceVariable v | diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/SSA.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/SSA.qll index 0d79eafdf5c6..a5960fd349f6 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/SSA.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/SSA.qll @@ -427,7 +427,7 @@ module Ssa { } /** Gets the location of this SSA definition. */ - Location getLocation() { none() } + override Location getLocation() { none() } } /** diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/BaseSSA.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/BaseSSA.qll index f30b1769107e..9e72b0280868 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/BaseSSA.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/BaseSSA.qll @@ -36,13 +36,15 @@ module BaseSsa { class BasicBlock = ControlFlow::BasicBlock; + class ControlFlowNode = ControlFlow::Node; + BasicBlock getImmediateBasicBlockDominator(BasicBlock bb) { result = bb.getImmediateDominator() } BasicBlock getABasicBlockSuccessor(BasicBlock bb) { result = bb.getASuccessor() } - class ExitBasicBlock = ControlFlow::BasicBlocks::ExitBlock; + class ExitBasicBlock extends BasicBlock, ControlFlow::BasicBlocks::ExitBlock { } class SourceVariable = PreSsa::SimpleLocalScopeVariable; @@ -93,7 +95,7 @@ module BaseSsa { not result instanceof PhiNode } - Location getLocation() { + override Location getLocation() { result = this.getDefinition().getLocation() or exists(Callable c, SsaInput::BasicBlock bb, SsaInput::SourceVariable v | diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowPrivate.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowPrivate.qll index 8fe50958f20a..f14e93d7efda 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowPrivate.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowPrivate.qll @@ -263,7 +263,7 @@ module VariableCapture { private module CaptureInput implements Shared::InputSig { private import csharp as Cs - private import semmle.code.csharp.controlflow.ControlFlowGraph + private import semmle.code.csharp.controlflow.ControlFlowGraph as Cfg private import semmle.code.csharp.controlflow.BasicBlocks as BasicBlocks private import TaintTrackingPrivate as TaintTrackingPrivate @@ -271,6 +271,8 @@ module VariableCapture { Callable getEnclosingCallable() { result = super.getCallable() } } + class ControlFlowNode = Cfg::ControlFlow::Node; + BasicBlock getImmediateBasicBlockDominator(BasicBlock bb) { result = bb.getImmediateDominator() } 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 9757121566b2..1215c564a062 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/SsaImpl.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/SsaImpl.qll @@ -10,11 +10,13 @@ private import semmle.code.csharp.controlflow.internal.PreSsa private module SsaInput implements SsaImplCommon::InputSig { class BasicBlock = ControlFlow::BasicBlock; + class ControlFlowNode = ControlFlow::Node; + BasicBlock getImmediateBasicBlockDominator(BasicBlock bb) { result = bb.getImmediateDominator() } BasicBlock getABasicBlockSuccessor(BasicBlock bb) { result = bb.getASuccessor() } - class ExitBasicBlock = ControlFlow::BasicBlocks::ExitBlock; + class ExitBasicBlock extends BasicBlock, ControlFlow::BasicBlocks::ExitBlock { } class SourceVariable = Ssa::SourceVariable; @@ -24,7 +26,7 @@ private module SsaInput implements SsaImplCommon::InputSig { * * This includes implicit writes via calls. */ - predicate variableWrite(ControlFlow::BasicBlock bb, int i, Ssa::SourceVariable v, boolean certain) { + predicate variableWrite(BasicBlock bb, int i, Ssa::SourceVariable v, boolean certain) { variableWriteDirect(bb, i, v, certain) or variableWriteQualifier(bb, i, v, certain) @@ -38,7 +40,7 @@ private module SsaInput implements SsaImplCommon::InputSig { * * This includes implicit reads via calls. */ - predicate variableRead(ControlFlow::BasicBlock bb, int i, Ssa::SourceVariable v, boolean certain) { + predicate variableRead(BasicBlock bb, int i, Ssa::SourceVariable v, boolean certain) { variableReadActual(bb, i, v) and certain = true or @@ -1089,7 +1091,7 @@ class DefinitionExt extends Impl::DefinitionExt { override string toString() { result = this.(Ssa::Definition).toString() } /** Gets the location of this definition. */ - Location getLocation() { result = this.(Ssa::Definition).getLocation() } + override Location getLocation() { result = this.(Ssa::Definition).getLocation() } /** Gets the enclosing callable of this definition. */ Callable getEnclosingCallable() { result = this.(Ssa::Definition).getEnclosingCallable() } diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowPrivate.qll b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowPrivate.qll index dd8d1ee3d767..a8f12a4da51a 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowPrivate.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowPrivate.qll @@ -72,11 +72,17 @@ private module CaptureInput implements VariableCapture::InputSig { class BasicBlock instanceof J::BasicBlock { string toString() { result = super.toString() } + ControlFlowNode getNode(int i) { result = super.getNode(i) } + + int length() { result = super.length() } + Callable getEnclosingCallable() { result = super.getEnclosingCallable() } Location getLocation() { result = super.getLocation() } } + class ControlFlowNode = J::ControlFlowNode; + BasicBlock getImmediateBasicBlockDominator(BasicBlock bb) { bbIDominates(result, bb) } BasicBlock getABasicBlockSuccessor(BasicBlock bb) { diff --git a/python/ql/lib/semmle/python/dataflow/new/internal/VariableCapture.qll b/python/ql/lib/semmle/python/dataflow/new/internal/VariableCapture.qll index f1ba86344a49..86dcee2bfe36 100644 --- a/python/ql/lib/semmle/python/dataflow/new/internal/VariableCapture.qll +++ b/python/ql/lib/semmle/python/dataflow/new/internal/VariableCapture.qll @@ -24,6 +24,8 @@ private module CaptureInput implements Shared::InputSig { } class BasicBlock extends PY::BasicBlock { + int length() { result = count(int i | exists(this.getNode(i))) } + Callable getEnclosingCallable() { result = this.getScope() } // Note `PY:BasicBlock` does not have a `getLocation`. @@ -34,6 +36,8 @@ private module CaptureInput implements Shared::InputSig { Location getLocation() { result = super.getNode(0).getLocation() } } + class ControlFlowNode = PY::ControlFlowNode; + BasicBlock getImmediateBasicBlockDominator(BasicBlock bb) { result = bb.getImmediateDominator() } BasicBlock getABasicBlockSuccessor(BasicBlock bb) { result = bb.getASuccessor() } diff --git a/ruby/ql/lib/codeql/ruby/dataflow/SSA.qll b/ruby/ql/lib/codeql/ruby/dataflow/SSA.qll index 23623e4d6178..f21dadb7c5ab 100644 --- a/ruby/ql/lib/codeql/ruby/dataflow/SSA.qll +++ b/ruby/ql/lib/codeql/ruby/dataflow/SSA.qll @@ -176,9 +176,6 @@ module Ssa { override string toString() { result = this.getControlFlowNode().toString() } - /** Gets the location of this SSA definition. */ - Location getLocation() { result = this.getControlFlowNode().getLocation() } - /** Gets the scope of this SSA definition. */ CfgScope getScope() { result = this.getBasicBlock().getScope() } } diff --git a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowPrivate.qll b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowPrivate.qll index 1a2622454ab1..c0bc6ac243d7 100644 --- a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowPrivate.qll +++ b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowPrivate.qll @@ -352,8 +352,7 @@ module VariableCapture { } private module CaptureInput implements Shared::InputSig { - private import ruby as R - private import codeql.ruby.controlflow.ControlFlowGraph + private import codeql.ruby.controlflow.ControlFlowGraph as Cfg private import codeql.ruby.controlflow.BasicBlocks as BasicBlocks private import TaintTrackingPrivate as TaintTrackingPrivate @@ -361,6 +360,8 @@ module VariableCapture { Callable getEnclosingCallable() { result = this.getScope() } } + class ControlFlowNode = Cfg::CfgNode; + BasicBlock getImmediateBasicBlockDominator(BasicBlock bb) { result = bb.getImmediateDominator() } diff --git a/ruby/ql/lib/codeql/ruby/dataflow/internal/SsaImpl.qll b/ruby/ql/lib/codeql/ruby/dataflow/internal/SsaImpl.qll index 1490a8c7ca33..8824d0813084 100644 --- a/ruby/ql/lib/codeql/ruby/dataflow/internal/SsaImpl.qll +++ b/ruby/ql/lib/codeql/ruby/dataflow/internal/SsaImpl.qll @@ -7,15 +7,18 @@ private import codeql.ruby.ast.Variable private import Cfg::CfgNodes::ExprNodes private module SsaInput implements SsaImplCommon::InputSig { + private import codeql.ruby.controlflow.ControlFlowGraph as Cfg private import codeql.ruby.controlflow.BasicBlocks as BasicBlocks class BasicBlock = BasicBlocks::BasicBlock; + class ControlFlowNode = Cfg::CfgNode; + BasicBlock getImmediateBasicBlockDominator(BasicBlock bb) { result = bb.getImmediateDominator() } BasicBlock getABasicBlockSuccessor(BasicBlock bb) { result = bb.getASuccessor() } - class ExitBasicBlock = BasicBlocks::ExitBasicBlock; + class ExitBasicBlock extends BasicBlock, BasicBlocks::ExitBasicBlock { } class SourceVariable = LocalVariable; @@ -494,8 +497,7 @@ class DefinitionExt extends Impl::DefinitionExt { override string toString() { result = this.(Ssa::Definition).toString() } - /** Gets the location of this definition. */ - Location getLocation() { result = this.(Ssa::Definition).getLocation() } + override Location getLocation() { result = this.(Ssa::Definition).getLocation() } } /** @@ -506,5 +508,5 @@ class DefinitionExt extends Impl::DefinitionExt { class PhiReadNode extends DefinitionExt, Impl::PhiReadNode { override string toString() { result = "SSA phi read(" + this.getSourceVariable() + ")" } - override Location getLocation() { result = this.getBasicBlock().getLocation() } + override Location getLocation() { result = Impl::PhiReadNode.super.getLocation() } } diff --git a/shared/dataflow/codeql/dataflow/VariableCapture.qll b/shared/dataflow/codeql/dataflow/VariableCapture.qll index c48b46e8a7ba..73f22fced737 100644 --- a/shared/dataflow/codeql/dataflow/VariableCapture.qll +++ b/shared/dataflow/codeql/dataflow/VariableCapture.qll @@ -17,6 +17,12 @@ signature module InputSig { /** Gets a textual representation of this basic block. */ string toString(); + /** Gets the `i`th node in this basic block. */ + ControlFlowNode getNode(int i); + + /** Gets the length of this basic block. */ + int length(); + /** Gets the enclosing callable. */ Callable getEnclosingCallable(); @@ -24,6 +30,15 @@ signature module InputSig { Location getLocation(); } + /** A control flow node. */ + class ControlFlowNode { + /** Gets a textual representation of this control flow node. */ + string toString(); + + /** Gets the location of this control flow node. */ + Location getLocation(); + } + /** * Gets the basic block that immediately dominates basic block `bb`, if any. * @@ -672,6 +687,8 @@ module Flow Input> implements OutputSig private module CaptureSsaInput implements Ssa::InputSig { final class BasicBlock = Input::BasicBlock; + final class ControlFlowNode = Input::ControlFlowNode; + BasicBlock getImmediateBasicBlockDominator(BasicBlock bb) { result = Input::getImmediateBasicBlockDominator(bb) } @@ -717,10 +734,10 @@ module Flow Input> implements OutputSig TSynthPhi(CaptureSsa::DefinitionExt phi) { phi instanceof CaptureSsa::PhiNode or phi instanceof CaptureSsa::PhiReadNode } or - TExprNode(Expr expr, boolean isPost) { - expr instanceof VariableRead and isPost = [false, true] + TExprNode(Expr expr, Boolean isPost) { + expr instanceof VariableRead or - synthRead(_, _, _, _, expr) and isPost = [false, true] + synthRead(_, _, _, _, expr) } or TParamNode(CapturedParameter p) or TThisParamNode(Callable c) { captureAccess(_, c) } or diff --git a/shared/ssa/codeql/ssa/Ssa.qll b/shared/ssa/codeql/ssa/Ssa.qll index ee397375e655..4e61d61efa71 100644 --- a/shared/ssa/codeql/ssa/Ssa.qll +++ b/shared/ssa/codeql/ssa/Ssa.qll @@ -15,10 +15,25 @@ signature module InputSig { /** Gets a textual representation of this basic block. */ string toString(); + /** Gets the `i`th node in this basic block. */ + ControlFlowNode getNode(int i); + + /** Gets the length of this basic block. */ + int length(); + /** Gets the location of this basic block. */ Location getLocation(); } + /** A control flow node. */ + class ControlFlowNode { + /** Gets a textual representation of this control flow node. */ + string toString(); + + /** Gets the location of this control flow node. */ + Location getLocation(); + } + /** * Gets the basic block that immediately dominates basic block `bb`, if any. * @@ -905,6 +920,13 @@ module Make Input> { /** Gets a textual representation of this SSA definition. */ string toString() { result = "SSA def(" + this.getSourceVariable() + ")" } + + /** Gets the location of this SSA definition. */ + Location getLocation() { + exists(BasicBlock bb, int i | this.definesAt(_, bb, i) | + if i = -1 then result = bb.getLocation() else result = bb.getNode(i).getLocation() + ) + } } /** An SSA definition that corresponds to a write. */ @@ -961,6 +983,13 @@ module Make Input> { /** Gets a textual representation of this SSA definition. */ string toString() { result = this.(Definition).toString() } + + /** Gets the location of this SSA definition. */ + Location getLocation() { + exists(BasicBlock bb, int i | this.definesAt(_, bb, i, _) | + if i = -1 then result = bb.getLocation() else result = bb.getNode(i).getLocation() + ) + } } /** diff --git a/swift/ql/lib/codeql/swift/dataflow/Ssa.qll b/swift/ql/lib/codeql/swift/dataflow/Ssa.qll index 7a8c5a300d00..971cc8cc705c 100644 --- a/swift/ql/lib/codeql/swift/dataflow/Ssa.qll +++ b/swift/ql/lib/codeql/swift/dataflow/Ssa.qll @@ -8,18 +8,20 @@ module Ssa { private module SsaInput implements SsaImplCommon::InputSig { private import internal.DataFlowPrivate - private import codeql.swift.controlflow.ControlFlowGraph + private import codeql.swift.controlflow.ControlFlowGraph as Cfg private import codeql.swift.controlflow.CfgNodes class BasicBlock = BasicBlocks::BasicBlock; + class ControlFlowNode = Cfg::ControlFlowNode; + BasicBlock getImmediateBasicBlockDominator(BasicBlock bb) { result = bb.getImmediateDominator() } BasicBlock getABasicBlockSuccessor(BasicBlock bb) { result = bb.getASuccessor() } - class ExitBasicBlock = BasicBlocks::ExitBasicBlock; + class ExitBasicBlock extends BasicBlock, BasicBlocks::ExitBasicBlock { } private newtype TSourceVariable = TNormalSourceVariable(VarDecl v) or @@ -138,7 +140,7 @@ module Ssa { cached class Definition extends SsaImpl::Definition { cached - Location getLocation() { none() } + override Location getLocation() { none() } cached ControlFlowNode getARead() { diff --git a/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowPrivate.qll b/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowPrivate.qll index eb2caea8c2f8..de54324e005b 100644 --- a/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowPrivate.qll +++ b/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowPrivate.qll @@ -886,16 +886,23 @@ private predicate closureFlowStep(CaptureInput::Expr e1, CaptureInput::Expr e2) private module CaptureInput implements VariableCapture::InputSig { private import swift as S + private import codeql.swift.controlflow.ControlFlowGraph as Cfg private import codeql.swift.controlflow.BasicBlocks as B class BasicBlock instanceof B::BasicBlock { string toString() { result = super.toString() } + ControlFlowNode getNode(int i) { result = super.getNode(i) } + + int length() { result = super.length() } + Callable getEnclosingCallable() { result = super.getScope() } Location getLocation() { result = super.getLocation() } } + class ControlFlowNode = Cfg::ControlFlowNode; + BasicBlock getImmediateBasicBlockDominator(BasicBlock bb) { result.(B::BasicBlock).immediatelyDominates(bb) }