Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 9a7746e

Browse files
committed
C#: Fix bug in BaseSsa library
1 parent 81122ca commit 9a7746e

2 files changed

Lines changed: 27 additions & 51 deletions

File tree

csharp/ql/src/semmle/code/csharp/dataflow/internal/BaseSSA.qll

Lines changed: 27 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,21 +7,39 @@ import csharp
77
*/
88
module BaseSsa {
99
private import ControlFlowGraph
10+
private import AssignableDefinitions
11+
12+
private class SimpleLocalScopeVariable extends LocalScopeVariable {
13+
SimpleLocalScopeVariable() {
14+
not exists(AssignableDefinition def1, AssignableDefinition def2 |
15+
def1.getTarget() = this and
16+
def2.getTarget() = this and
17+
def1.getEnclosingCallable() != def2.getEnclosingCallable()
18+
)
19+
}
20+
}
1021

1122
/**
1223
* Holds if the `i`th node of basic block `bb` is assignable definition `def`,
1324
* targeting local scope variable `v`.
1425
*/
15-
private predicate defAt(BasicBlock bb, int i, AssignableDefinition def, LocalScopeVariable v) {
26+
private predicate defAt(BasicBlock bb, int i, AssignableDefinition def, SimpleLocalScopeVariable v) {
1627
bb.getNode(i) = def.getAControlFlowNode() and
17-
v = def.getTarget()
28+
v = def.getTarget() and
29+
// In cases like `(x, x) = (0, 1)`, we discard the first (dead) definition of `x`
30+
not exists(TupleAssignmentDefinition tdef, TupleAssignmentDefinition other |
31+
tdef = def |
32+
other.getAssignment() = tdef.getAssignment() and
33+
other.getEvaluationOrder() > tdef.getEvaluationOrder() and
34+
other.getTarget() = v
35+
)
1836
}
1937

2038
/**
2139
* Holds if basic block `bb` would need to start with a phi node for local scope
2240
* variable `v` in an SSA representation.
2341
*/
24-
private predicate needsPhiNode(BasicBlock bb, LocalScopeVariable v) {
42+
private predicate needsPhiNode(BasicBlock bb, SimpleLocalScopeVariable v) {
2543
exists(BasicBlock def |
2644
def.inDominanceFrontier(bb) |
2745
defAt(def, _, _, v) or
@@ -36,7 +54,7 @@ module BaseSsa {
3654
* either a read (when `k` is `SsaRead()`) or a write including phi nodes
3755
* (when `k` is `SsaDef()`).
3856
*/
39-
private predicate ssaRef(BasicBlock bb, int i, LocalScopeVariable v, SsaRefKind k) {
57+
private predicate ssaRef(BasicBlock bb, int i, SimpleLocalScopeVariable v, SsaRefKind k) {
4058
bb.getNode(i).getElement() = v.getAnAccess().(VariableRead) and
4159
k = SsaRead()
4260
or
@@ -52,7 +70,7 @@ module BaseSsa {
5270
* Gets the (1-based) rank of the reference to `v` at the `i`th node of basic
5371
* block `bb`, which has the given reference kind `k`.
5472
*/
55-
private int ssaRefRank(BasicBlock bb, int i, LocalScopeVariable v, SsaRefKind k) {
73+
private int ssaRefRank(BasicBlock bb, int i, SimpleLocalScopeVariable v, SsaRefKind k) {
5674
i = rank[result](int j | ssaRef(bb, j, v, _)) and
5775
ssaRef(bb, i, v, k)
5876
}
@@ -62,7 +80,7 @@ module BaseSsa {
6280
* `bb` reaches the reference at rank `rnk`, without passing through another
6381
* definition of `v`, including phi nodes.
6482
*/
65-
private predicate defReachesRank(BasicBlock bb, AssignableDefinition def, LocalScopeVariable v, int rnk) {
83+
private predicate defReachesRank(BasicBlock bb, AssignableDefinition def, SimpleLocalScopeVariable v, int rnk) {
6684
exists(int i |
6785
rnk = ssaRefRank(bb, i, v, SsaDef()) |
6886
defAt(bb, i, def, v)
@@ -77,7 +95,7 @@ module BaseSsa {
7795
* basic block `bb` without passing through another definition of `v`, including
7896
* phi nodes.
7997
*/
80-
private predicate reachesEndOf(AssignableDefinition def, LocalScopeVariable v, BasicBlock bb) {
98+
private predicate reachesEndOf(AssignableDefinition def, SimpleLocalScopeVariable v, BasicBlock bb) {
8199
exists(int rnk |
82100
defReachesRank(bb, def, v, rnk) and
83101
rnk = max(ssaRefRank(bb, _, v, _))
@@ -94,7 +112,7 @@ module BaseSsa {
94112
* Gets a read of the SSA definition for variable `v` at definition `def`. That is,
95113
* a read that is guaranteed to read the value assigned at definition `def`.
96114
*/
97-
cached AssignableRead getARead(AssignableDefinition def, LocalScopeVariable v) {
115+
cached AssignableRead getARead(AssignableDefinition def, SimpleLocalScopeVariable v) {
98116
exists(BasicBlock bb, int i, int rnk |
99117
result.getTarget() = v and
100118
result.getAControlFlowNode() = bb.getNode(i) and
@@ -103,7 +121,7 @@ module BaseSsa {
103121
defReachesRank(bb, def, v, rnk)
104122
or
105123
reachesEndOf(def, v, bb.getAPredecessor()) and
106-
not ssaRefRank(bb, i, v, SsaDef()) < rnk
124+
not ssaRefRank(bb, _, v, SsaDef()) < rnk
107125
)
108126
}
109127
}
Lines changed: 0 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,42 +0,0 @@
1-
| Capture.cs:35:13:35:13 | access to local variable z | Capture.cs:29:13:29:17 | Int32 z = ... |
2-
| Capture.cs:39:13:39:13 | access to parameter i | Capture.cs:6:16:6:16 | i |
3-
| Capture.cs:40:13:40:13 | access to local variable x | Capture.cs:8:13:8:17 | Int32 x = ... |
4-
| Capture.cs:45:13:45:13 | access to local variable x | Capture.cs:43:9:43:13 | ... = ... |
5-
| Capture.cs:47:13:47:13 | access to local variable x | Capture.cs:43:9:43:13 | ... = ... |
6-
| Capture.cs:54:9:54:9 | access to parameter a | Capture.cs:50:20:50:20 | a |
7-
| Capture.cs:62:13:62:13 | access to local variable i | Capture.cs:59:13:59:17 | Int32 i = ... |
8-
| Capture.cs:78:13:78:13 | access to local variable i | Capture.cs:75:13:75:17 | Int32 i = ... |
9-
| Capture.cs:137:13:137:13 | access to local variable c | Capture.cs:130:13:130:18 | Int32 c = ... |
10-
| Capture.cs:145:13:145:13 | access to local variable d | Capture.cs:139:13:139:18 | Int32 d = ... |
11-
| Capture.cs:177:17:177:17 | access to local variable h | Capture.cs:171:13:171:17 | ... = ... |
12-
| Capture.cs:237:34:237:34 | access to local variable i | Capture.cs:232:9:232:13 | ... = ... |
13-
| DefUse.cs:14:17:14:17 | access to local variable y | DefUse.cs:6:14:6:19 | Int64 y = ... |
14-
| DefUse.cs:20:17:20:17 | access to parameter w | DefUse.cs:3:26:3:26 | w |
15-
| DefUse.cs:23:13:23:13 | access to local variable y | DefUse.cs:13:13:13:18 | ... = ... |
16-
| DefUse.cs:23:13:23:13 | access to local variable y | DefUse.cs:18:13:18:18 | ... = ... |
17-
| DefUse.cs:24:13:24:13 | access to parameter w | DefUse.cs:19:13:19:18 | ... = ... |
18-
| DefUse.cs:42:13:42:13 | access to local variable y | DefUse.cs:28:13:28:18 | ... = ... |
19-
| DefUse.cs:42:13:42:13 | access to local variable y | DefUse.cs:39:13:39:18 | ... = ... |
20-
| DefUse.cs:80:30:80:31 | access to local variable x1 | DefUse.cs:79:13:79:18 | Int32 x1 = ... |
21-
| DefUse.cs:98:16:98:17 | access to local variable x5 | DefUse.cs:97:13:97:18 | Int32 x5 = ... |
22-
| DefUse.cs:98:16:98:17 | access to local variable x5 | DefUse.cs:101:13:101:23 | ... = ... |
23-
| DefUse.cs:182:13:182:13 | access to parameter i | DefUse.cs:170:9:170:13 | ... = ... |
24-
| Example.cs:25:13:25:13 | access to parameter p | Example.cs:18:16:18:16 | p |
25-
| Example.cs:25:13:25:13 | access to parameter p | Example.cs:23:13:23:17 | ... = ... |
26-
| Fields.cs:50:13:50:13 | access to local variable f | Fields.cs:30:13:30:28 | Fields f = ... |
27-
| Fields.cs:50:13:50:13 | access to local variable f | Fields.cs:49:13:49:28 | ... = ... |
28-
| Fields.cs:52:13:52:13 | access to local variable f | Fields.cs:30:13:30:28 | Fields f = ... |
29-
| Fields.cs:52:13:52:13 | access to local variable f | Fields.cs:49:13:49:28 | ... = ... |
30-
| Properties.cs:50:13:50:13 | access to local variable f | Properties.cs:30:13:30:32 | Properties f = ... |
31-
| Properties.cs:50:13:50:13 | access to local variable f | Properties.cs:49:13:49:32 | ... = ... |
32-
| Properties.cs:52:13:52:13 | access to local variable f | Properties.cs:30:13:30:32 | Properties f = ... |
33-
| Properties.cs:52:13:52:13 | access to local variable f | Properties.cs:49:13:49:32 | ... = ... |
34-
| Properties.cs:63:16:63:16 | access to parameter i | Properties.cs:61:23:61:23 | i |
35-
| Test.cs:14:19:14:19 | access to local variable x | Test.cs:8:13:8:17 | Int32 x = ... |
36-
| Test.cs:20:13:20:13 | access to local variable y | Test.cs:9:13:9:13 | Int32 y |
37-
| Test.cs:24:13:24:13 | access to local variable z | Test.cs:15:13:15:17 | ... = ... |
38-
| Test.cs:24:13:24:13 | access to local variable z | Test.cs:22:13:22:17 | ... = ... |
39-
| Test.cs:25:20:25:20 | access to local variable y | Test.cs:31:13:31:18 | ... = ... |
40-
| Test.cs:34:25:34:25 | access to local variable i | Test.cs:34:18:34:22 | Int32 i = ... |
41-
| Test.cs:34:25:34:25 | access to local variable i | Test.cs:34:33:34:35 | ...++ |
42-
| Tuples.cs:24:13:24:13 | access to local variable x | Tuples.cs:23:9:23:37 | ... = ... |

0 commit comments

Comments
 (0)