|
1 | 1 | module Private { |
2 | 2 | private import csharp as CS |
3 | 3 | private import ConstantUtils as CU |
4 | | - private import semmle.code.csharp.controlflow.Guards as G |
5 | 4 | private import semmle.code.csharp.dataflow.internal.rangeanalysis.RangeUtils as RU |
6 | 5 | private import SsaUtils as SU |
7 | | - private import SignAnalysisSpecific::Private as SA |
| 6 | + private import SsaReadPositionCommon |
8 | 7 |
|
9 | 8 | class BasicBlock = CS::Ssa::BasicBlock; |
10 | 9 |
|
11 | | - class SsaVariable extends CS::Ssa::Definition { |
12 | | - CS::AssignableRead getAUse() { result = this.getARead() } |
13 | | - } |
| 10 | + class SsaVariable = SU::SsaVariable; |
14 | 11 |
|
15 | 12 | class SsaPhiNode = CS::Ssa::PhiNode; |
16 | 13 |
|
17 | | - class Expr = CS::Expr; |
| 14 | + class Expr = CS::ControlFlow::Nodes::ExprNode; |
18 | 15 |
|
19 | | - class Guard = G::Guard; |
| 16 | + class Guard = RU::Guard; |
20 | 17 |
|
21 | 18 | class ConstantIntegerExpr = CU::ConstantIntegerExpr; |
22 | 19 |
|
23 | | - class ConditionalExpr extends CS::ConditionalExpr { |
24 | | - /** Gets the "then" expression of this conditional expression. */ |
25 | | - Expr getTrueExpr() { result = this.getThen() } |
| 20 | + class ConditionalExpr = RU::ExprNode::ConditionalExpr; |
26 | 21 |
|
27 | | - /** Gets the "else" expression of this conditional expression. */ |
28 | | - Expr getFalseExpr() { result = this.getElse() } |
29 | | - } |
| 22 | + class AddExpr = RU::ExprNode::AddExpr; |
30 | 23 |
|
31 | | - /** Represent an addition expression. */ |
32 | | - class AddExpr extends CS::AddExpr { |
33 | | - /** Gets the LHS operand of this add expression. */ |
34 | | - Expr getLhs() { result = this.getLeftOperand() } |
| 24 | + class SubExpr = RU::ExprNode::SubExpr; |
35 | 25 |
|
36 | | - /** Gets the RHS operand of this add expression. */ |
37 | | - Expr getRhs() { result = this.getRightOperand() } |
38 | | - } |
| 26 | + class RemExpr = RU::ExprNode::RemExpr; |
39 | 27 |
|
40 | | - /** Represent a subtraction expression. */ |
41 | | - class SubExpr extends CS::SubExpr { |
42 | | - /** Gets the LHS operand of this subtraction expression. */ |
43 | | - Expr getLhs() { result = this.getLeftOperand() } |
| 28 | + class BitwiseAndExpr = RU::ExprNode::BitwiseAndExpr; |
44 | 29 |
|
45 | | - /** Gets the RHS operand of this subtraction expression. */ |
46 | | - Expr getRhs() { result = this.getRightOperand() } |
47 | | - } |
| 30 | + class MulExpr = RU::ExprNode::MulExpr; |
48 | 31 |
|
49 | | - class RemExpr = CS::RemExpr; |
50 | | - |
51 | | - /** Represent a bitwise and or an assign-and expression. */ |
52 | | - class BitwiseAndExpr extends CS::Expr { |
53 | | - BitwiseAndExpr() { this instanceof CS::BitwiseAndExpr or this instanceof CS::AssignAndExpr } |
54 | | - |
55 | | - /** Gets an operand of this bitwise and operation. */ |
56 | | - Expr getAnOperand() { |
57 | | - result = this.(CS::BitwiseAndExpr).getAnOperand() or |
58 | | - result = this.(CS::AssignAndExpr).getRValue() or |
59 | | - result = this.(CS::AssignAndExpr).getLValue() |
60 | | - } |
61 | | - |
62 | | - /** Holds if this expression has operands `e1` and `e2`. */ |
63 | | - predicate hasOperands(Expr e1, Expr e2) { |
64 | | - this.getAnOperand() = e1 and |
65 | | - this.getAnOperand() = e2 and |
66 | | - e1 != e2 |
67 | | - } |
68 | | - } |
| 32 | + class LShiftExpr = RU::ExprNode::LShiftExpr; |
69 | 33 |
|
70 | | - /** Represent a multiplication or an assign-mul expression. */ |
71 | | - class MulExpr extends CS::Expr { |
72 | | - MulExpr() { this instanceof CS::MulExpr or this instanceof CS::AssignMulExpr } |
| 34 | + predicate guardDirectlyControlsSsaRead = RU::guardControlsSsaRead/3; |
73 | 35 |
|
74 | | - /** Gets an operand of this multiplication. */ |
75 | | - Expr getAnOperand() { |
76 | | - result = this.(CS::MulExpr).getAnOperand() or |
77 | | - result = this.(CS::AssignMulExpr).getRValue() or |
78 | | - result = this.(CS::AssignMulExpr).getLValue() |
79 | | - } |
80 | | - } |
| 36 | + predicate guardControlsSsaRead = RU::guardControlsSsaRead/3; |
81 | 37 |
|
82 | | - /** Represent a left shift or an assign-lshift expression. */ |
83 | | - class LShiftExpr extends CS::Expr { |
84 | | - LShiftExpr() { this instanceof CS::LShiftExpr or this instanceof CS::AssignLShiftExpr } |
| 38 | + predicate valueFlowStep = RU::valueFlowStep/3; |
85 | 39 |
|
86 | | - /** Gets the RHS operand of this shift. */ |
87 | | - Expr getRhs() { |
88 | | - result = this.(CS::LShiftExpr).getRightOperand() or |
89 | | - result = this.(CS::AssignLShiftExpr).getRValue() |
90 | | - } |
91 | | - } |
| 40 | + predicate eqFlowCond = RU::eqFlowCond/5; |
92 | 41 |
|
93 | | - predicate guardDirectlyControlsSsaRead = SA::guardControlsSsaRead/3; |
| 42 | + predicate ssaUpdateStep = RU::ssaUpdateStep/3; |
94 | 43 |
|
95 | | - predicate guardControlsSsaRead = SA::guardControlsSsaRead/3; |
| 44 | + Expr getABasicBlockExpr(BasicBlock bb) { result = bb.getANode() } |
96 | 45 |
|
97 | | - predicate valueFlowStep = RU::valueFlowStep/3; |
| 46 | + private class CallableOrCFE extends CS::Element { |
| 47 | + CallableOrCFE() { this instanceof CS::Callable or this instanceof CS::ControlFlowElement } |
| 48 | + } |
98 | 49 |
|
99 | | - predicate eqFlowCond = RU::eqFlowCond/5; |
| 50 | + private predicate id(CallableOrCFE x, CallableOrCFE y) { x = y } |
100 | 51 |
|
101 | | - predicate ssaUpdateStep = RU::ssaUpdateStep/3; |
| 52 | + private predicate idOf(CallableOrCFE x, int y) = equivalenceRelation(id/2)(x, y) |
102 | 53 |
|
103 | | - Expr getABasicBlockExpr(BasicBlock bb) { result = bb.getANode().getElement() } |
| 54 | + private class PhiInputEdgeBlock extends BasicBlock { |
| 55 | + PhiInputEdgeBlock() { this = any(SsaReadPositionPhiInputEdge edge).getOrigBlock() } |
| 56 | + } |
104 | 57 |
|
105 | | - private predicate id(CS::ControlFlowElement x, CS::ControlFlowElement y) { x = y } |
| 58 | + int getId(PhiInputEdgeBlock bb) { |
| 59 | + idOf(bb.getFirstNode().getElement(), result) |
| 60 | + or |
| 61 | + idOf(bb.(CS::ControlFlow::BasicBlocks::EntryBlock).getCallable(), result) |
| 62 | + } |
106 | 63 |
|
107 | | - private predicate idOf(CS::ControlFlowElement x, int y) = equivalenceRelation(id/2)(x, y) |
| 64 | + private string getSplitString(PhiInputEdgeBlock bb) { |
| 65 | + result = bb.getFirstNode().(CS::ControlFlow::Nodes::ElementNode).getSplitsString() |
| 66 | + or |
| 67 | + not exists(bb.getFirstNode().(CS::ControlFlow::Nodes::ElementNode).getSplitsString()) and |
| 68 | + result = "" |
| 69 | + } |
108 | 70 |
|
109 | | - int getId(BasicBlock bb) { idOf(bb.getFirstNode().getElement(), result) } |
| 71 | + /** |
| 72 | + * Holds if `inp` is an input to `phi` along `edge` and this input has index `r` |
| 73 | + * in an arbitrary 1-based numbering of the input edges to `phi`. |
| 74 | + */ |
| 75 | + predicate rankedPhiInput(SsaPhiNode phi, SsaVariable inp, SsaReadPositionPhiInputEdge edge, int r) { |
| 76 | + edge.phiInput(phi, inp) and |
| 77 | + edge = |
| 78 | + rank[r](SsaReadPositionPhiInputEdge e | |
| 79 | + e.phiInput(phi, _) |
| 80 | + | |
| 81 | + e order by getId(e.getOrigBlock()), getSplitString(e.getOrigBlock()) |
| 82 | + ) |
| 83 | + } |
110 | 84 | } |
0 commit comments