mirror of
https://github.com/github/codeql.git
synced 2025-12-24 04:36:35 +01:00
Merge pull request #10203 from hvitved/ssa/param-module
SSA: Make shared library a parameterized module
This commit is contained in:
@@ -2,55 +2,131 @@ cached
|
||||
module Ssa {
|
||||
private import swift
|
||||
private import internal.SsaImplCommon as SsaImplCommon
|
||||
private import internal.SsaImplSpecific as SsaImplSpecific
|
||||
private import codeql.swift.controlflow.CfgNodes
|
||||
private import codeql.swift.controlflow.ControlFlowGraph
|
||||
private import codeql.swift.controlflow.BasicBlocks
|
||||
private import codeql.swift.controlflow.BasicBlocks as BasicBlocks
|
||||
|
||||
private module SsaInput implements SsaImplCommon::InputSig {
|
||||
private import internal.DataFlowPrivate
|
||||
private import codeql.swift.controlflow.ControlFlowGraph
|
||||
private import codeql.swift.controlflow.CfgNodes
|
||||
|
||||
class BasicBlock = BasicBlocks::BasicBlock;
|
||||
|
||||
BasicBlock getImmediateBasicBlockDominator(BasicBlock bb) {
|
||||
result = bb.getImmediateDominator()
|
||||
}
|
||||
|
||||
BasicBlock getABasicBlockSuccessor(BasicBlock bb) { result = bb.getASuccessor() }
|
||||
|
||||
class ExitBasicBlock = BasicBlocks::ExitBasicBlock;
|
||||
|
||||
class SourceVariable = VarDecl;
|
||||
|
||||
predicate variableWrite(BasicBlock bb, int i, SourceVariable v, boolean certain) {
|
||||
exists(AssignExpr assign |
|
||||
bb.getNode(i).getNode().asAstNode() = assign and
|
||||
assign.getDest() = v.getAnAccess() and
|
||||
certain = true
|
||||
)
|
||||
or
|
||||
exists(PatternBindingDecl decl, Pattern pattern |
|
||||
bb.getNode(i).getNode().asAstNode() = pattern and
|
||||
decl.getAPattern() = pattern and
|
||||
v.getParentPattern() = pattern and
|
||||
certain = true
|
||||
)
|
||||
or
|
||||
v instanceof ParamDecl and
|
||||
bb.getNode(i).getNode().asAstNode() = v and
|
||||
certain = true
|
||||
or
|
||||
// Mark the subexpression as a write of the local variable declared in the `TapExpr`.
|
||||
exists(TapExpr tap |
|
||||
v = tap.getVar() and
|
||||
bb.getNode(i).getNode().asAstNode() = tap.getSubExpr() and
|
||||
certain = true
|
||||
)
|
||||
}
|
||||
|
||||
predicate variableRead(BasicBlock bb, int i, SourceVariable v, boolean certain) {
|
||||
exists(DeclRefExpr ref |
|
||||
not isLValue(ref) and
|
||||
bb.getNode(i).getNode().asAstNode() = ref and
|
||||
v = ref.getDecl() and
|
||||
certain = true
|
||||
)
|
||||
or
|
||||
exists(InOutExpr expr |
|
||||
bb.getNode(i).getNode().asAstNode() = expr and
|
||||
expr.getSubExpr() = v.getAnAccess() and
|
||||
certain = true
|
||||
)
|
||||
or
|
||||
exists(ExitNode exit, AbstractFunctionDecl func |
|
||||
func.getAParam() = v or func.getSelfParam() = v
|
||||
|
|
||||
bb.getNode(i) = exit and
|
||||
modifiableParam(v) and
|
||||
bb.getScope() = func and
|
||||
certain = true
|
||||
)
|
||||
or
|
||||
// Mark the `TapExpr` as a read of the of the local variable.
|
||||
exists(TapExpr tap |
|
||||
v = tap.getVar() and
|
||||
bb.getNode(i).getNode().asAstNode() = tap and
|
||||
certain = true
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private module SsaImpl = SsaImplCommon::Make<SsaInput>;
|
||||
|
||||
cached
|
||||
class Definition extends SsaImplCommon::Definition {
|
||||
class Definition extends SsaImpl::Definition {
|
||||
cached
|
||||
Location getLocation() { none() }
|
||||
|
||||
cached
|
||||
ControlFlowNode getARead() {
|
||||
exists(VarDecl v, BasicBlock bb, int i |
|
||||
SsaImplCommon::ssaDefReachesRead(v, this, bb, i) and
|
||||
SsaImplSpecific::variableRead(bb, i, v, true) and
|
||||
exists(VarDecl v, SsaInput::BasicBlock bb, int i |
|
||||
SsaImpl::ssaDefReachesRead(v, this, bb, i) and
|
||||
SsaInput::variableRead(bb, i, v, true) and
|
||||
result = bb.getNode(i)
|
||||
)
|
||||
}
|
||||
|
||||
cached
|
||||
ControlFlowNode getAFirstRead() {
|
||||
exists(BasicBlock bb1, int i1, BasicBlock bb2, int i2 |
|
||||
exists(SsaInput::BasicBlock bb1, int i1, SsaInput::BasicBlock bb2, int i2 |
|
||||
this.definesAt(_, bb1, i1) and
|
||||
SsaImplCommon::adjacentDefNoUncertainReads(this, bb1, i1, bb2, i2) and
|
||||
SsaImpl::adjacentDefNoUncertainReads(this, bb1, i1, bb2, i2) and
|
||||
result = bb2.getNode(i2)
|
||||
)
|
||||
}
|
||||
|
||||
cached
|
||||
predicate adjacentReadPair(ControlFlowNode read1, ControlFlowNode read2) {
|
||||
exists(BasicBlock bb1, int i1, BasicBlock bb2, int i2 |
|
||||
exists(SsaInput::BasicBlock bb1, int i1, SsaInput::BasicBlock bb2, int i2 |
|
||||
read1 = bb1.getNode(i1) and
|
||||
SsaImplSpecific::variableRead(bb1, i1, _, true) and
|
||||
SsaImplCommon::adjacentDefNoUncertainReads(this, bb1, i1, bb2, i2) and
|
||||
SsaInput::variableRead(bb1, i1, _, true) and
|
||||
SsaImpl::adjacentDefNoUncertainReads(this, bb1, i1, bb2, i2) and
|
||||
read2 = bb2.getNode(i2)
|
||||
)
|
||||
}
|
||||
|
||||
cached
|
||||
predicate lastRefRedef(BasicBlock bb, int i, Definition next) {
|
||||
SsaImplCommon::lastRefRedef(this, bb, i, next)
|
||||
predicate lastRefRedef(SsaInput::BasicBlock bb, int i, Definition next) {
|
||||
SsaImpl::lastRefRedef(this, bb, i, next)
|
||||
}
|
||||
}
|
||||
|
||||
cached
|
||||
class WriteDefinition extends Definition, SsaImplCommon::WriteDefinition {
|
||||
class WriteDefinition extends Definition, SsaImpl::WriteDefinition {
|
||||
cached
|
||||
override Location getLocation() {
|
||||
exists(BasicBlock bb, int i |
|
||||
exists(SsaInput::BasicBlock bb, int i |
|
||||
this.definesAt(_, bb, i) and
|
||||
result = bb.getNode(i).getLocation()
|
||||
)
|
||||
@@ -63,14 +139,16 @@ module Ssa {
|
||||
cached
|
||||
predicate assigns(CfgNode value) {
|
||||
exists(
|
||||
AssignExpr a, BasicBlock bb, int i // TODO: use CFG node for assignment expr
|
||||
AssignExpr a, SsaInput::BasicBlock bb, int i // TODO: use CFG node for assignment expr
|
||||
|
|
||||
this.definesAt(_, bb, i) and
|
||||
a = bb.getNode(i).getNode().asAstNode() and
|
||||
value.getNode().asAstNode() = a.getSource()
|
||||
)
|
||||
or
|
||||
exists(VarDecl var, BasicBlock bb, int blockIndex, PatternBindingDecl pbd, Expr init |
|
||||
exists(
|
||||
VarDecl var, SsaInput::BasicBlock bb, int blockIndex, PatternBindingDecl pbd, Expr init
|
||||
|
|
||||
this.definesAt(var, bb, blockIndex) and
|
||||
pbd.getAPattern() = bb.getNode(blockIndex).getNode().asAstNode() and
|
||||
init = var.getParentInitializer()
|
||||
@@ -84,17 +162,19 @@ module Ssa {
|
||||
}
|
||||
|
||||
cached
|
||||
class PhiDefinition extends Definition, SsaImplCommon::PhiNode {
|
||||
class PhiDefinition extends Definition, SsaImpl::PhiNode {
|
||||
cached
|
||||
override Location getLocation() {
|
||||
exists(BasicBlock bb, int i |
|
||||
exists(SsaInput::BasicBlock bb, int i |
|
||||
this.definesAt(_, bb, i) and
|
||||
result = bb.getLocation()
|
||||
)
|
||||
}
|
||||
|
||||
cached
|
||||
Definition getPhiInput(BasicBlock bb) { SsaImplCommon::phiHasInputFromBlock(this, result, bb) }
|
||||
Definition getPhiInput(SsaInput::BasicBlock bb) {
|
||||
SsaImpl::phiHasInputFromBlock(this, result, bb)
|
||||
}
|
||||
|
||||
cached
|
||||
Definition getAPhiInput() { result = this.getPhiInput(_) }
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,74 +0,0 @@
|
||||
/** Provides the Swift specific parameters for `SsaImplCommon.qll`. */
|
||||
|
||||
private import swift
|
||||
private import codeql.swift.controlflow.BasicBlocks as BasicBlocks
|
||||
private import codeql.swift.controlflow.ControlFlowGraph
|
||||
private import codeql.swift.controlflow.CfgNodes
|
||||
private import DataFlowPrivate
|
||||
|
||||
class BasicBlock = BasicBlocks::BasicBlock;
|
||||
|
||||
BasicBlock getImmediateBasicBlockDominator(BasicBlock bb) { result = bb.getImmediateDominator() }
|
||||
|
||||
BasicBlock getABasicBlockSuccessor(BasicBlock bb) { result = bb.getASuccessor() }
|
||||
|
||||
class ExitBasicBlock = BasicBlocks::ExitBasicBlock;
|
||||
|
||||
class SourceVariable = VarDecl;
|
||||
|
||||
predicate variableWrite(BasicBlock bb, int i, SourceVariable v, boolean certain) {
|
||||
exists(AssignExpr assign |
|
||||
bb.getNode(i).getNode().asAstNode() = assign and
|
||||
assign.getDest() = v.getAnAccess() and
|
||||
certain = true
|
||||
)
|
||||
or
|
||||
exists(PatternBindingDecl decl, Pattern pattern |
|
||||
bb.getNode(i).getNode().asAstNode() = pattern and
|
||||
decl.getAPattern() = pattern and
|
||||
v.getParentPattern() = pattern and
|
||||
certain = true
|
||||
)
|
||||
or
|
||||
v instanceof ParamDecl and
|
||||
bb.getNode(i).getNode().asAstNode() = v and
|
||||
certain = true
|
||||
or
|
||||
// Mark the subexpression as a write of the local variable declared in the `TapExpr`.
|
||||
exists(TapExpr tap |
|
||||
v = tap.getVar() and
|
||||
bb.getNode(i).getNode().asAstNode() = tap.getSubExpr() and
|
||||
certain = true
|
||||
)
|
||||
}
|
||||
|
||||
predicate variableRead(BasicBlock bb, int i, SourceVariable v, boolean certain) {
|
||||
exists(DeclRefExpr ref |
|
||||
not isLValue(ref) and
|
||||
bb.getNode(i).getNode().asAstNode() = ref and
|
||||
v = ref.getDecl() and
|
||||
certain = true
|
||||
)
|
||||
or
|
||||
exists(InOutExpr expr |
|
||||
bb.getNode(i).getNode().asAstNode() = expr and
|
||||
expr.getSubExpr() = v.getAnAccess() and
|
||||
certain = true
|
||||
)
|
||||
or
|
||||
exists(ExitNode exit, AbstractFunctionDecl func |
|
||||
func.getAParam() = v or func.getSelfParam() = v
|
||||
|
|
||||
bb.getNode(i) = exit and
|
||||
modifiableParam(v) and
|
||||
bb.getScope() = func and
|
||||
certain = true
|
||||
)
|
||||
or
|
||||
// Mark the `TapExpr` as a read of the of the local variable.
|
||||
exists(TapExpr tap |
|
||||
v = tap.getVar() and
|
||||
bb.getNode(i).getNode().asAstNode() = tap and
|
||||
certain = true
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user