mirror of
https://github.com/github/codeql.git
synced 2026-04-28 18:25:24 +02:00
Merge pull request #8405 from smowton/smowton/fix/range-analysis-use-ranked-phi-nodes
C#/Java: Range analysis: use ranked phi nodes
This commit is contained in:
@@ -111,13 +111,6 @@ private predicate evenlyDivisibleExpr(Expr e, int factor) {
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `rix` is the number of input edges to `phi`.
|
||||
*/
|
||||
private predicate maxPhiInputRank(SsaPhiNode phi, int rix) {
|
||||
rix = max(int r | rankedPhiInput(phi, _, _, r))
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the remainder of `val` modulo `mod`.
|
||||
*
|
||||
|
||||
@@ -43,37 +43,4 @@ module Private {
|
||||
predicate ssaUpdateStep = RU::ssaUpdateStep/3;
|
||||
|
||||
Expr getABasicBlockExpr(BasicBlock bb) { result = bb.getANode() }
|
||||
|
||||
private class PhiInputEdgeBlock extends BasicBlock {
|
||||
PhiInputEdgeBlock() { this = any(SsaReadPositionPhiInputEdge edge).getOrigBlock() }
|
||||
}
|
||||
|
||||
int getId(PhiInputEdgeBlock bb) {
|
||||
exists(CfgImpl::ControlFlowTree::Range_ t | CfgImpl::ControlFlowTree::idOf(t, result) |
|
||||
t = bb.getFirstNode().getElement()
|
||||
or
|
||||
t = bb.(CS::ControlFlow::BasicBlocks::EntryBlock).getCallable()
|
||||
)
|
||||
}
|
||||
|
||||
private string getSplitString(PhiInputEdgeBlock bb) {
|
||||
result = bb.getFirstNode().(CS::ControlFlow::Nodes::ElementNode).getSplitsString()
|
||||
or
|
||||
not exists(bb.getFirstNode().(CS::ControlFlow::Nodes::ElementNode).getSplitsString()) and
|
||||
result = ""
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `inp` is an input to `phi` along `edge` and this input has index `r`
|
||||
* in an arbitrary 1-based numbering of the input edges to `phi`.
|
||||
*/
|
||||
predicate rankedPhiInput(SsaPhiNode phi, SsaVariable inp, SsaReadPositionPhiInputEdge edge, int r) {
|
||||
edge.phiInput(phi, inp) and
|
||||
edge =
|
||||
rank[r](SsaReadPositionPhiInputEdge e |
|
||||
e.phiInput(phi, _)
|
||||
|
|
||||
e order by getId(e.getOrigBlock()), getSplitString(e.getOrigBlock())
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
*/
|
||||
|
||||
private import SsaReadPositionSpecific
|
||||
import SsaReadPositionSpecific::Public
|
||||
|
||||
private newtype TSsaReadPosition =
|
||||
TSsaReadPositionBlock(BasicBlock bb) { bb = getAReadBasicBlock(_) } or
|
||||
@@ -55,3 +56,10 @@ class SsaReadPositionPhiInputEdge extends SsaReadPosition, TSsaReadPositionPhiIn
|
||||
|
||||
override string toString() { result = "edge" }
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `rix` is the number of input edges to `phi`.
|
||||
*/
|
||||
predicate maxPhiInputRank(SsaPhiNode phi, int rix) {
|
||||
rix = max(int r | rankedPhiInput(phi, _, _, r))
|
||||
}
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
*/
|
||||
|
||||
private import csharp
|
||||
private import SsaReadPositionCommon
|
||||
private import semmle.code.csharp.controlflow.internal.ControlFlowGraphImpl as CfgImpl
|
||||
|
||||
class SsaVariable = Ssa::Definition;
|
||||
|
||||
@@ -14,3 +16,41 @@ class BasicBlock = ControlFlow::BasicBlock;
|
||||
BasicBlock getAReadBasicBlock(SsaVariable v) {
|
||||
result = v.getARead().getAControlFlowNode().getBasicBlock()
|
||||
}
|
||||
|
||||
private class PhiInputEdgeBlock extends BasicBlock {
|
||||
PhiInputEdgeBlock() { this = any(SsaReadPositionPhiInputEdge edge).getOrigBlock() }
|
||||
}
|
||||
|
||||
private int getId(PhiInputEdgeBlock bb) {
|
||||
exists(CfgImpl::ControlFlowTree::Range_ t | CfgImpl::ControlFlowTree::idOf(t, result) |
|
||||
t = bb.getFirstNode().getElement()
|
||||
or
|
||||
t = bb.(ControlFlow::BasicBlocks::EntryBlock).getCallable()
|
||||
)
|
||||
}
|
||||
|
||||
private string getSplitString(PhiInputEdgeBlock bb) {
|
||||
result = bb.getFirstNode().(ControlFlow::Nodes::ElementNode).getSplitsString()
|
||||
or
|
||||
not exists(bb.getFirstNode().(ControlFlow::Nodes::ElementNode).getSplitsString()) and
|
||||
result = ""
|
||||
}
|
||||
|
||||
/**
|
||||
* Declarations to be exposed to users of SsaReadPositionCommon.
|
||||
*/
|
||||
module Public {
|
||||
/**
|
||||
* Holds if `inp` is an input to `phi` along `edge` and this input has index `r`
|
||||
* in an arbitrary 1-based numbering of the input edges to `phi`.
|
||||
*/
|
||||
predicate rankedPhiInput(SsaPhiNode phi, SsaVariable inp, SsaReadPositionPhiInputEdge edge, int r) {
|
||||
edge.phiInput(phi, inp) and
|
||||
edge =
|
||||
rank[r](SsaReadPositionPhiInputEdge e |
|
||||
e.phiInput(phi, _)
|
||||
|
|
||||
e order by getId(e.getOrigBlock()), getSplitString(e.getOrigBlock())
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user