Skip to content

Commit ca72c8e

Browse files
authored
Merge pull request #579 from hvitved/csharp/guards-loop
C#: Fix bug in guards library when the guarded expression is in a loop
2 parents 1c53222 + a12a72e commit ca72c8e

File tree

7 files changed

+30
-2
lines changed

7 files changed

+30
-2
lines changed

csharp/ql/src/semmle/code/csharp/commons/Assertions.qll

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,8 @@ class Assertion extends MethodCall {
5555
bb = this.getAControlFlowNode().getBasicBlock() |
5656
result = bb.getASuccessor*()
5757
) and
58-
result.getASuccessor() = jb
58+
result.getASuccessor() = jb and
59+
not jb.dominates(result)
5960
}
6061

6162
pragma[nomagic]
@@ -64,6 +65,8 @@ class Assertion extends MethodCall {
6465
forall(BasicBlock pred |
6566
pred = jb.getAPredecessor() |
6667
pred = this.getAPossiblyDominatedPredecessor(jb)
68+
or
69+
jb.dominates(pred)
6770
)
6871
}
6972

csharp/ql/src/semmle/code/csharp/controlflow/ControlFlowElement.qll

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,8 @@ class ControlFlowElement extends ExprOrStmtParent, @control_flow_element {
106106
this.immediatelyControls(mid, s) |
107107
result = mid.getASuccessor*()
108108
) and
109-
result.getASuccessor() = controlled
109+
result.getASuccessor() = controlled and
110+
not controlled.dominates(result)
110111
}
111112

112113
pragma[nomagic]
@@ -115,6 +116,8 @@ class ControlFlowElement extends ExprOrStmtParent, @control_flow_element {
115116
forall(BasicBlock pred |
116117
pred = controlled.getAPredecessor() |
117118
pred = this.getAPossiblyControlledPredecessor(controlled, s)
119+
or
120+
controlled.dominates(pred)
118121
)
119122
}
120123

csharp/ql/test/library-tests/controlflow/guards/BooleanGuardedExpr.expected

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,8 @@
6262
| Guards.cs:194:31:194:31 | access to parameter s | Guards.cs:193:14:193:25 | call to method NullTest3 | Guards.cs:193:24:193:24 | access to parameter s | false |
6363
| Guards.cs:196:31:196:31 | access to parameter s | Guards.cs:195:13:195:27 | call to method NotNullTest4 | Guards.cs:195:26:195:26 | access to parameter s | true |
6464
| Guards.cs:198:31:198:31 | access to parameter s | Guards.cs:197:14:197:29 | call to method NullTestWrong | Guards.cs:197:28:197:28 | access to parameter s | false |
65+
| Guards.cs:205:13:205:13 | access to parameter o | Guards.cs:203:13:203:21 | ... != ... | Guards.cs:203:13:203:13 | access to parameter o | true |
66+
| Guards.cs:208:17:208:17 | access to parameter o | Guards.cs:203:13:203:21 | ... != ... | Guards.cs:203:13:203:13 | access to parameter o | true |
6567
| Splitting.cs:13:17:13:17 | access to parameter o | Splitting.cs:12:17:12:25 | ... != ... | Splitting.cs:12:17:12:17 | access to parameter o | true |
6668
| Splitting.cs:23:24:23:24 | access to parameter o | Splitting.cs:22:17:22:25 | ... != ... | Splitting.cs:22:17:22:17 | access to parameter o | true |
6769
| Splitting.cs:25:13:25:13 | access to parameter o | Splitting.cs:22:17:22:25 | ... != ... | Splitting.cs:22:17:22:17 | access to parameter o | false |

csharp/ql/test/library-tests/controlflow/guards/GuardedExpr.expected

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,10 @@
155155
| Guards.cs:196:31:196:31 | access to parameter s | Guards.cs:195:13:195:27 | call to method NotNullTest4 | Guards.cs:195:26:195:26 | access to parameter s | true |
156156
| Guards.cs:196:31:196:31 | access to parameter s | Guards.cs:195:26:195:26 | access to parameter s | Guards.cs:195:26:195:26 | access to parameter s | non-null |
157157
| Guards.cs:198:31:198:31 | access to parameter s | Guards.cs:197:14:197:29 | call to method NullTestWrong | Guards.cs:197:28:197:28 | access to parameter s | false |
158+
| Guards.cs:205:13:205:13 | access to parameter o | Guards.cs:203:13:203:13 | access to parameter o | Guards.cs:203:13:203:13 | access to parameter o | non-null |
159+
| Guards.cs:205:13:205:13 | access to parameter o | Guards.cs:203:13:203:21 | ... != ... | Guards.cs:203:13:203:13 | access to parameter o | true |
160+
| Guards.cs:208:17:208:17 | access to parameter o | Guards.cs:203:13:203:13 | access to parameter o | Guards.cs:203:13:203:13 | access to parameter o | non-null |
161+
| Guards.cs:208:17:208:17 | access to parameter o | Guards.cs:203:13:203:21 | ... != ... | Guards.cs:203:13:203:13 | access to parameter o | true |
158162
| Splitting.cs:13:17:13:17 | access to parameter o | Splitting.cs:12:17:12:17 | access to parameter o | Splitting.cs:12:17:12:17 | access to parameter o | non-null |
159163
| Splitting.cs:13:17:13:17 | access to parameter o | Splitting.cs:12:17:12:25 | ... != ... | Splitting.cs:12:17:12:17 | access to parameter o | true |
160164
| Splitting.cs:23:24:23:24 | access to parameter o | Splitting.cs:22:17:22:17 | access to parameter o | Splitting.cs:22:17:22:17 | access to parameter o | non-null |

csharp/ql/test/library-tests/controlflow/guards/Guards.cs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -197,4 +197,16 @@ void M16(string s)
197197
if (!NullTestWrong(s))
198198
Console.WriteLine(s); // not null guarded
199199
}
200+
201+
void M17(object o, string[] args)
202+
{
203+
if (o != null)
204+
{
205+
o.ToString(); // null guarded
206+
foreach (var arg in args)
207+
{
208+
o.ToString(); // null guarded
209+
}
210+
}
211+
}
200212
}

csharp/ql/test/library-tests/controlflow/guards/Implications.expected

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,8 @@
200200
| Guards.cs:195:13:195:27 | call to method NotNullTest4 | true | Guards.cs:195:26:195:26 | access to parameter s | non-null |
201201
| Guards.cs:197:13:197:29 | !... | false | Guards.cs:197:14:197:29 | call to method NullTestWrong | true |
202202
| Guards.cs:197:13:197:29 | !... | true | Guards.cs:197:14:197:29 | call to method NullTestWrong | false |
203+
| Guards.cs:203:13:203:21 | ... != ... | false | Guards.cs:203:13:203:13 | access to parameter o | null |
204+
| Guards.cs:203:13:203:21 | ... != ... | true | Guards.cs:203:13:203:13 | access to parameter o | non-null |
203205
| Splitting.cs:12:17:12:25 | ... != ... | false | Splitting.cs:12:17:12:17 | access to parameter o | null |
204206
| Splitting.cs:12:17:12:25 | ... != ... | true | Splitting.cs:12:17:12:17 | access to parameter o | non-null |
205207
| Splitting.cs:22:17:22:25 | ... != ... | false | Splitting.cs:22:17:22:17 | access to parameter o | null |

csharp/ql/test/library-tests/controlflow/guards/NullGuardedExpr.expected

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,8 @@
3939
| Guards.cs:192:31:192:31 | access to parameter s |
4040
| Guards.cs:194:31:194:31 | access to parameter s |
4141
| Guards.cs:196:31:196:31 | access to parameter s |
42+
| Guards.cs:205:13:205:13 | access to parameter o |
43+
| Guards.cs:208:17:208:17 | access to parameter o |
4244
| Splitting.cs:13:17:13:17 | access to parameter o |
4345
| Splitting.cs:23:24:23:24 | access to parameter o |
4446
| Splitting.cs:35:13:35:13 | access to parameter o |

0 commit comments

Comments
 (0)