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 76741dfc5cc8a..5c0174be32d46 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 @@ -59,6 +59,9 @@ private module SourceVariables { then result = base.getType() else result = getTypeImpl(base.getType(), ind - 1) } + + /** Gets the location of this variable. */ + Location getLocation() { result = this.getBaseVariable().getLocation() } } } @@ -869,7 +872,7 @@ private predicate sourceVariableIsGlobal( ) } -private module SsaInput implements SsaImplCommon::InputSig { +private module SsaInput implements SsaImplCommon::InputSig { import InputSigCommon import SourceVariables @@ -1092,7 +1095,7 @@ class Def extends DefOrUse { predicate isCertain() { defOrUse.isCertain() } } -private module SsaImpl = SsaImplCommon::Make; +private module SsaImpl = SsaImplCommon::Make; class PhiNode extends SsaImpl::DefinitionExt { PhiNode() { 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 920172e429a52..0ea5c45df4f84 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 @@ -377,6 +377,9 @@ abstract private class AbstractBaseSourceVariable extends TBaseSourceVariable { /** Gets a textual representation of this element. */ abstract string toString(); + /** Gets the location of this variable. */ + abstract Location getLocation(); + /** Gets the type of this base source variable. */ final DataFlowType getType() { this.getLanguageType().hasUnspecifiedType(result, _) } @@ -395,6 +398,8 @@ class BaseIRVariable extends AbstractBaseSourceVariable, TBaseIRVariable { override string toString() { result = var.toString() } + override Location getLocation() { result = var.getLocation() } + override CppType getLanguageType() { result = var.getLanguageType() } } @@ -407,6 +412,8 @@ class BaseCallVariable extends AbstractBaseSourceVariable, TBaseCallVariable { override string toString() { result = call.toString() } + override Location getLocation() { result = call.getLocation() } + override CppType getLanguageType() { result = getResultLanguageType(call) } } diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/ssa0/SsaInternals.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/ssa0/SsaInternals.qll index fd27a4e354f3b..ce53005470d7f 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/ssa0/SsaInternals.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/ssa0/SsaInternals.qll @@ -229,7 +229,7 @@ private class FinalParameterUse extends UseImpl, TFinalParameterUse { override predicate isCertain() { any() } } -private module SsaInput implements SsaImplCommon::InputSig { +private module SsaInput implements SsaImplCommon::InputSig { import InputSigCommon import SourceVariables @@ -335,7 +335,7 @@ class Def extends DefOrUse { predicate isIteratorDef() { defOrUse instanceof IteratorDef } } -private module SsaImpl = SsaImplCommon::Make; +private module SsaImpl = SsaImplCommon::Make; class PhiNode extends SsaImpl::DefinitionExt { PhiNode() { diff --git a/csharp/ql/lib/semmle/code/cil/internal/SsaImpl.qll b/csharp/ql/lib/semmle/code/cil/internal/SsaImpl.qll index 2f8fde205fd8e..3aafaa00baace 100644 --- a/csharp/ql/lib/semmle/code/cil/internal/SsaImpl.qll +++ b/csharp/ql/lib/semmle/code/cil/internal/SsaImpl.qll @@ -1,7 +1,7 @@ private import cil private import codeql.ssa.Ssa as SsaImplCommon -private module SsaInput implements SsaImplCommon::InputSig { +private module SsaInput implements SsaImplCommon::InputSig { class BasicBlock = CIL::BasicBlock; BasicBlock getImmediateBasicBlockDominator(BasicBlock bb) { result = bb.getImmediateDominator() } @@ -29,7 +29,7 @@ private module SsaInput implements SsaImplCommon::InputSig { } } -import SsaImplCommon::Make +import SsaImplCommon::Make cached private module Cached { 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 2c61592778aec..42d9c21102a46 100644 --- a/csharp/ql/lib/semmle/code/csharp/controlflow/internal/PreSsa.qll +++ b/csharp/ql/lib/semmle/code/csharp/controlflow/internal/PreSsa.qll @@ -36,7 +36,7 @@ module PreSsa { scopeFirst(c, bb) } - module SsaInput implements SsaImplCommon::InputSig { + module SsaInput implements SsaImplCommon::InputSig { class BasicBlock = PreBasicBlocks::PreBasicBlock; BasicBlock getImmediateBasicBlockDominator(BasicBlock bb) { result.immediatelyDominates(bb) } @@ -137,7 +137,7 @@ module PreSsa { } } - private module SsaImpl = SsaImplCommon::Make; + private module SsaImpl = SsaImplCommon::Make; class Definition extends SsaImpl::Definition { final AssignableRead getARead() { 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 cb737200a02dc..0933559347ef3 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/BaseSSA.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/BaseSSA.qll @@ -24,7 +24,7 @@ module BaseSsa { ) } - private module SsaInput implements SsaImplCommon::InputSig { + private module SsaInput implements SsaImplCommon::InputSig { class BasicBlock = ControlFlow::BasicBlock; BasicBlock getImmediateBasicBlockDominator(BasicBlock bb) { @@ -60,7 +60,7 @@ module BaseSsa { } } - private module SsaImpl = SsaImplCommon::Make; + private module SsaImpl = SsaImplCommon::Make; class Definition extends SsaImpl::Definition { final AssignableRead getARead() { 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 596ddde0f55e9..cf7bb8b83c2ff 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/SsaImpl.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/SsaImpl.qll @@ -6,7 +6,7 @@ import csharp private import codeql.ssa.Ssa as SsaImplCommon private import AssignableDefinitions -private module SsaInput implements SsaImplCommon::InputSig { +private module SsaInput implements SsaImplCommon::InputSig { class BasicBlock = ControlFlow::BasicBlock; BasicBlock getImmediateBasicBlockDominator(BasicBlock bb) { result = bb.getImmediateDominator() } @@ -49,7 +49,7 @@ private module SsaInput implements SsaImplCommon::InputSig { } } -private import SsaImplCommon::Make as Impl +private import SsaImplCommon::Make as Impl class Definition = Impl::Definition; 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 01ba8cfd26aa6..79e507dd59843 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowPrivate.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowPrivate.qll @@ -61,11 +61,9 @@ private predicate closureFlowStep(Expr e1, Expr e2) { ) } -private module CaptureInput implements VariableCapture::InputSig { +private module CaptureInput implements VariableCapture::InputSig { private import java as J - class Location = J::Location; - class BasicBlock instanceof J::BasicBlock { string toString() { result = super.toString() } @@ -146,7 +144,7 @@ class CapturedVariable = CaptureInput::CapturedVariable; class CapturedParameter = CaptureInput::CapturedParameter; -module CaptureFlow = VariableCapture::Flow; +module CaptureFlow = VariableCapture::Flow; private CaptureFlow::ClosureNode asClosureNode(Node n) { result = n.(CaptureNode).getSynthesizedCaptureNode() diff --git a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowPrivate.qll b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowPrivate.qll index 1341ed667926d..c7c5ce31dff70 100644 --- a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowPrivate.qll +++ b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowPrivate.qll @@ -278,14 +278,12 @@ module VariableCapture { ) } - private module CaptureInput implements Shared::InputSig { + private module CaptureInput implements Shared::InputSig { private import ruby as R private import codeql.ruby.controlflow.ControlFlowGraph private import codeql.ruby.controlflow.BasicBlocks as BasicBlocks private import TaintTrackingPrivate as TaintTrackingPrivate - class Location = R::Location; - class BasicBlock extends BasicBlocks::BasicBlock { Callable getEnclosingCallable() { result = this.getScope() } } @@ -366,7 +364,7 @@ module VariableCapture { class ClosureExpr = CaptureInput::ClosureExpr; - module Flow = Shared::Flow; + module Flow = Shared::Flow; private Flow::ClosureNode asClosureNode(Node n) { result = n.(CaptureNode).getSynthesizedCaptureNode() diff --git a/ruby/ql/lib/codeql/ruby/dataflow/internal/SsaImpl.qll b/ruby/ql/lib/codeql/ruby/dataflow/internal/SsaImpl.qll index 771c0f0bc393b..e1a3607a43ea4 100644 --- a/ruby/ql/lib/codeql/ruby/dataflow/internal/SsaImpl.qll +++ b/ruby/ql/lib/codeql/ruby/dataflow/internal/SsaImpl.qll @@ -6,7 +6,7 @@ private import codeql.ruby.dataflow.SSA private import codeql.ruby.ast.Variable private import Cfg::CfgNodes::ExprNodes -private module SsaInput implements SsaImplCommon::InputSig { +private module SsaInput implements SsaImplCommon::InputSig { private import codeql.ruby.controlflow.BasicBlocks as BasicBlocks class BasicBlock = BasicBlocks::BasicBlock; @@ -62,7 +62,7 @@ private module SsaInput implements SsaImplCommon::InputSig { } } -private import SsaImplCommon::Make as Impl +private import SsaImplCommon::Make as Impl class Definition = Impl::Definition; diff --git a/shared/dataflow/codeql/dataflow/VariableCapture.qll b/shared/dataflow/codeql/dataflow/VariableCapture.qll index 4a68f0563bc2f..6e1ae6bf1048e 100644 --- a/shared/dataflow/codeql/dataflow/VariableCapture.qll +++ b/shared/dataflow/codeql/dataflow/VariableCapture.qll @@ -5,15 +5,10 @@ private import codeql.util.Boolean private import codeql.util.Unit +private import codeql.util.Location private import codeql.ssa.Ssa as Ssa -signature module InputSig { - class Location { - predicate hasLocationInfo( - string filepath, int startline, int startcolumn, int endline, int endcolumn - ); - } - +signature module InputSig { /** * A basic block, that is, a maximal straight-line sequence of control flow nodes * without branches or joins. @@ -144,7 +139,7 @@ signature module InputSig { } } -signature module OutputSig { +signature module OutputSig I> { /** * A data flow node that we need to reference in the step relations for * captured variables. @@ -165,7 +160,7 @@ signature module OutputSig { string toString(); /** Gets the location of this node. */ - I::Location getLocation(); + Location getLocation(); /** Gets the enclosing callable. */ I::Callable getEnclosingCallable(); @@ -243,7 +238,7 @@ signature module OutputSig { * Constructs the type `ClosureNode` and associated step relations, which are * intended to be included in the data-flow node and step relations. */ -module Flow implements OutputSig { +module Flow Input> implements OutputSig { private import Input additional module ConsistencyChecks { @@ -638,6 +633,10 @@ module Flow implements OutputSig { or result = "this" and this = TThis(_) } + + Location getLocation() { + exists(CapturedVariable v | this = TVariable(v) and result = v.getLocation()) + } } /** Holds if `cc` needs a definition at the entry of its callable scope. */ @@ -659,7 +658,7 @@ module Flow implements OutputSig { ) } - private module CaptureSsaInput implements Ssa::InputSig { + private module CaptureSsaInput implements Ssa::InputSig { final class BasicBlock = Input::BasicBlock; BasicBlock getImmediateBasicBlockDominator(BasicBlock bb) { @@ -697,7 +696,7 @@ module Flow implements OutputSig { } } - private module CaptureSsa = Ssa::Make; + private module CaptureSsa = Ssa::Make; private newtype TClosureNode = TSynthRead(CapturedVariable v, BasicBlock bb, int i, Boolean isPost) { diff --git a/shared/ssa/codeql/ssa/Ssa.qll b/shared/ssa/codeql/ssa/Ssa.qll index 54e713d71177f..40ee155b61804 100644 --- a/shared/ssa/codeql/ssa/Ssa.qll +++ b/shared/ssa/codeql/ssa/Ssa.qll @@ -3,8 +3,10 @@ * (SSA) form. */ +private import codeql.util.Location + /** Provides the input specification of the SSA implementation. */ -signature module InputSig { +signature module InputSig { /** * A basic block, that is, a maximal straight-line sequence of control flow nodes * without branches or joins. @@ -12,6 +14,9 @@ signature module InputSig { class BasicBlock { /** Gets a textual representation of this basic block. */ string toString(); + + /** Gets the location of this basic block. */ + Location getLocation(); } /** @@ -49,6 +54,9 @@ signature module InputSig { class SourceVariable { /** Gets a textual representation of this variable. */ string toString(); + + /** Gets the location of this variable. */ + Location getLocation(); } /** @@ -88,7 +96,7 @@ signature module InputSig { * NB: If this predicate is exposed, it should be cached. * ``` */ -module Make { +module Make Input> { private import Input private BasicBlock getABasicBlockPredecessor(BasicBlock bb) { diff --git a/shared/ssa/qlpack.yml b/shared/ssa/qlpack.yml index ec8a04ef6850e..28b798b0efe47 100644 --- a/shared/ssa/qlpack.yml +++ b/shared/ssa/qlpack.yml @@ -2,4 +2,6 @@ name: codeql/ssa version: 0.2.4-dev groups: shared library: true +dependencies: + codeql/util: ${workspace} warnOnImplicitThis: true diff --git a/swift/ql/lib/codeql/swift/dataflow/Ssa.qll b/swift/ql/lib/codeql/swift/dataflow/Ssa.qll index ffe86b34cbefd..7a8c5a300d004 100644 --- a/swift/ql/lib/codeql/swift/dataflow/Ssa.qll +++ b/swift/ql/lib/codeql/swift/dataflow/Ssa.qll @@ -6,7 +6,7 @@ module Ssa { private import codeql.swift.controlflow.ControlFlowGraph private import codeql.swift.controlflow.BasicBlocks as BasicBlocks - private module SsaInput implements SsaImplCommon::InputSig { + private module SsaInput implements SsaImplCommon::InputSig { private import internal.DataFlowPrivate private import codeql.swift.controlflow.ControlFlowGraph private import codeql.swift.controlflow.CfgNodes @@ -33,6 +33,12 @@ module Ssa { EntryNode asKeyPath() { none() } DeclRefExpr getAnAccess() { result.getDecl() = this.asVarDecl() } + + Location getLocation() { + result = this.asVarDecl().getLocation() + or + result = this.asKeyPath().getLocation() + } } private class NormalSourceVariable extends SourceVariable, TNormalSourceVariable { @@ -127,7 +133,7 @@ module Ssa { /** * INTERNAL: Do not use. */ - module SsaImpl = SsaImplCommon::Make; + module SsaImpl = SsaImplCommon::Make; cached class Definition extends SsaImpl::Definition { diff --git a/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowPrivate.qll b/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowPrivate.qll index 8b417a74cae68..35632d703833e 100644 --- a/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowPrivate.qll +++ b/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowPrivate.qll @@ -862,7 +862,7 @@ private predicate closureFlowStep(CaptureInput::Expr e1, CaptureInput::Expr e2) e2.(Pattern).getImmediateMatchingExpr() = e1 } -private module CaptureInput implements VariableCapture::InputSig { +private module CaptureInput implements VariableCapture::InputSig { private import swift as S private import codeql.swift.controlflow.BasicBlocks as B @@ -976,7 +976,7 @@ class CapturedVariable = CaptureInput::CapturedVariable; class CapturedParameter = CaptureInput::CapturedParameter; -module CaptureFlow = VariableCapture::Flow; +module CaptureFlow = VariableCapture::Flow; private CaptureFlow::ClosureNode asClosureNode(Node n) { result = n.(CaptureNode).getSynthesizedCaptureNode()