C#: Use CFG nodes instead of AST nodes in sign/modulus analysis

This commit is contained in:
Tom Hvitved
2020-10-09 11:24:10 +02:00
parent 952b2da7d4
commit 2af7e1c213
23 changed files with 906 additions and 478 deletions

View File

@@ -111,18 +111,6 @@ private predicate evenlyDivisibleExpr(Expr e, int factor) {
)
}
/**
* 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`.
*/
private 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()))
}
/**
* Holds if `rix` is the number of input edges to `phi`.
*/

View File

@@ -4,6 +4,7 @@ module Private {
private import semmle.code.java.dataflow.RangeUtils as RU
private import semmle.code.java.controlflow.Guards as G
private import semmle.code.java.controlflow.BasicBlocks as BB
private import SsaReadPositionCommon
class BasicBlock = BB::BasicBlock;
@@ -115,5 +116,19 @@ module Private {
private predicate idOf(BasicBlock x, int y) = equivalenceRelation(id/2)(x, y)
int getId(BasicBlock bb) { idOf(bb, result) }
private int getId(BasicBlock bb) { idOf(bb, 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())
)
}
}

View File

@@ -51,7 +51,7 @@ private predicate unknownSign(Expr e) {
or
exists(CastExpr cast, Type fromtyp |
cast = e and
fromtyp = cast.getExpr().getType() and
fromtyp = cast.getSourceType() and
not fromtyp instanceof NumericOrCharType
)
or

View File

@@ -27,7 +27,10 @@ module Private {
class LongLiteral = J::LongLiteral;
class CastExpr = J::CastExpr;
class CastExpr extends J::CastExpr {
/** Gets the source type of this cast. */
J::Type getSourceType() { result = this.getExpr().getType() }
}
class Type = J::Type;

View File

@@ -104,4 +104,32 @@
| ModulusAnalysis.java:49:25:49:25 | 3 | 0 | 3 | 0 |
| ModulusAnalysis.java:50:32:50:32 | x | 0 | 3 | 16 |
| ModulusAnalysis.java:50:32:50:32 | x | SSA init(x) | 0 | 0 |
| ModulusAnalysis.java:54:38:54:39 | 42 | 0 | 42 | 0 |
| ModulusAnalysis.java:56:22:56:22 | 0 | 0 | 0 | 0 |
| ModulusAnalysis.java:56:25:56:25 | i | SSA phi(i) | 0 | 0 |
| ModulusAnalysis.java:56:29:56:31 | cap | SSA init(cap) | 0 | 0 |
| ModulusAnalysis.java:56:34:56:34 | i | SSA phi(i) | 0 | 0 |
| ModulusAnalysis.java:56:34:56:36 | ...++ | SSA phi(i) | 0 | 0 |
| ModulusAnalysis.java:57:32:57:32 | i | SSA phi(i) | 0 | 0 |
| ModulusAnalysis.java:59:22:59:22 | 0 | 0 | 0 | 0 |
| ModulusAnalysis.java:59:25:59:25 | j | SSA phi(j) | 0 | 0 |
| ModulusAnalysis.java:59:29:59:31 | cap | SSA init(cap) | 0 | 0 |
| ModulusAnalysis.java:59:34:59:34 | j | SSA phi(j) | 0 | 0 |
| ModulusAnalysis.java:59:34:59:39 | ...+=... | SSA phi(j) | 1 | 0 |
| ModulusAnalysis.java:59:39:59:39 | 1 | 0 | 1 | 0 |
| ModulusAnalysis.java:60:32:60:32 | j | SSA phi(j) | 0 | 0 |
| ModulusAnalysis.java:62:22:62:22 | 0 | 0 | 0 | 0 |
| ModulusAnalysis.java:62:25:62:25 | k | 0 | 0 | 3 |
| ModulusAnalysis.java:62:25:62:25 | k | SSA def(k) | 0 | 3 |
| ModulusAnalysis.java:62:25:62:25 | k | SSA phi(k) | 0 | 0 |
| ModulusAnalysis.java:62:29:62:31 | cap | SSA init(cap) | 0 | 0 |
| ModulusAnalysis.java:62:34:62:34 | k | 0 | 0 | 3 |
| ModulusAnalysis.java:62:34:62:34 | k | SSA def(k) | 0 | 3 |
| ModulusAnalysis.java:62:34:62:34 | k | SSA phi(k) | 0 | 0 |
| ModulusAnalysis.java:62:34:62:39 | ...+=... | 0 | 0 | 3 |
| ModulusAnalysis.java:62:34:62:39 | ...+=... | SSA def(k) | 0 | 3 |
| ModulusAnalysis.java:62:34:62:39 | ...+=... | SSA phi(k) | 3 | 0 |
| ModulusAnalysis.java:62:39:62:39 | 3 | 0 | 3 | 0 |
| ModulusAnalysis.java:63:32:63:32 | k | 0 | 0 | 3 |
| ModulusAnalysis.java:63:32:63:32 | k | SSA def(k) | 0 | 3 |
| ModulusAnalysis.java:63:32:63:32 | k | SSA phi(k) | 0 | 0 |
| ModulusAnalysis.java:66:38:66:39 | 42 | 0 | 42 | 0 |

View File

@@ -51,5 +51,17 @@ class ModulusAnalysis
}
}
void loops(int cap)
{
for (int i = 0; i < cap; i++)
System.out.println(i);
for (int j = 0; j < cap; j += 1)
System.out.println(j);
for (int k = 0; k < cap; k += 3)
System.out.println(k); // congruent 0 mod 3
}
int[] getArray(){ return new int[42]; }
}