mirror of
https://github.com/github/codeql.git
synced 2025-12-24 04:36:35 +01:00
JS: Instantiate shared SSA library
JS: Remove with statement comment
This commit is contained in:
@@ -9,6 +9,7 @@ dependencies:
|
||||
codeql/dataflow: ${workspace}
|
||||
codeql/mad: ${workspace}
|
||||
codeql/regex: ${workspace}
|
||||
codeql/ssa: ${workspace}
|
||||
codeql/tutorial: ${workspace}
|
||||
codeql/util: ${workspace}
|
||||
codeql/xml: ${workspace}
|
||||
|
||||
@@ -7,6 +7,11 @@ import javascript
|
||||
private import internal.StmtContainers
|
||||
private import semmle.javascript.internal.CachedStages
|
||||
|
||||
module BasicBlockInternal {
|
||||
// TODO: Expose these as public predicate in a private module instead of this hack.
|
||||
predicate getImmediateBasicBlockDominator = immediateDominator/1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `nd` starts a new basic block.
|
||||
*/
|
||||
@@ -280,6 +285,11 @@ class BasicBlock extends @cfg_node, NodeInStmtContainer {
|
||||
* Gets the basic block that immediately dominates this basic block.
|
||||
*/
|
||||
ReachableBasicBlock getImmediateDominator() { result = immediateDominator(this) }
|
||||
|
||||
/**
|
||||
* Holds if this if a basic block whose last node is an exit node.
|
||||
*/
|
||||
predicate isExitBlock() { exitBB(this) }
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -0,0 +1,68 @@
|
||||
/**
|
||||
* Instantiates the shared SSA library for JavaScript, but only to establish use-use flow.
|
||||
*
|
||||
* JavaScript's old SSA library is still responsible for the ordinary SSA flow.
|
||||
*/
|
||||
|
||||
private import javascript as js
|
||||
private import codeql.ssa.Ssa
|
||||
|
||||
private module SsaConfig implements InputSig<js::DbLocation> {
|
||||
class ControlFlowNode = js::ControlFlowNode;
|
||||
|
||||
class BasicBlock = js::BasicBlock;
|
||||
|
||||
class ExitBasicBlock extends BasicBlock {
|
||||
ExitBasicBlock() { this.isExitBlock() }
|
||||
}
|
||||
|
||||
class SourceVariable = js::PurelyLocalVariable; // TODO: include 'this' as it is relevant for use-use flow
|
||||
|
||||
pragma[nomagic]
|
||||
private js::EntryBasicBlock getEntryBlock(js::StmtContainer container) {
|
||||
result.getContainer() = container
|
||||
}
|
||||
|
||||
predicate variableWrite(BasicBlock bb, int i, SourceVariable v, boolean certain) {
|
||||
certain = true and
|
||||
(
|
||||
bb.defAt(i, v, _)
|
||||
or
|
||||
// Implicit initialization and function parameters
|
||||
bb = getEntryBlock(v.getDeclaringContainer()) and
|
||||
i = -1
|
||||
)
|
||||
}
|
||||
|
||||
predicate variableRead(BasicBlock bb, int i, SourceVariable v, boolean certain) {
|
||||
bb.useAt(i, v, _) and certain = true
|
||||
}
|
||||
|
||||
predicate getImmediateBasicBlockDominator =
|
||||
js::BasicBlockInternal::getImmediateBasicBlockDominator/1;
|
||||
|
||||
pragma[inline]
|
||||
BasicBlock getABasicBlockSuccessor(BasicBlock bb) { result = bb.getASuccessor() }
|
||||
}
|
||||
|
||||
import Make<js::DbLocation, SsaConfig>
|
||||
|
||||
private module SsaDataflowInput implements DataFlowIntegrationInputSig {
|
||||
class Expr extends js::VarUse {
|
||||
predicate hasCfgNode(js::BasicBlock bb, int i) { this = bb.getNode(i) }
|
||||
}
|
||||
|
||||
predicate ssaDefAssigns(WriteDefinition def, Expr value) { none() } // Not handled here
|
||||
|
||||
class Parameter = js::Parameter;
|
||||
|
||||
predicate ssaDefInitializesParam(WriteDefinition def, Parameter p) { none() } // Not handled here
|
||||
|
||||
abstract class Guard extends Expr { } // empty class
|
||||
|
||||
predicate guardControlsBlock(Guard guard, js::BasicBlock bb, boolean branch) { none() }
|
||||
|
||||
js::BasicBlock getAConditionalBasicBlockSuccessor(js::BasicBlock bb, boolean branch) { none() }
|
||||
}
|
||||
|
||||
import DataFlowIntegration<SsaDataflowInput>
|
||||
Reference in New Issue
Block a user