Skip to content

Commit 8412185

Browse files
committed
C#: Add CFG test
This test exhibits two issues with Boolean CFG splitting: incorrect handling of negated variables and incorrect splitting for variables defined inside a loop.
1 parent 87072df commit 8412185

12 files changed

+485
-0
lines changed

csharp/ql/test/library-tests/controlflow/graph/BasicBlock.expected

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,13 @@
164164
| Conditions.cs:108:13:109:24 | [b (line 102): false] if (...) ... | Conditions.cs:109:17:109:23 | ... = ... | 9 |
165165
| Conditions.cs:108:13:109:24 | [b (line 102): true] if (...) ... | Conditions.cs:108:18:108:18 | [b (line 102): true] access to parameter b | 3 |
166166
| Conditions.cs:110:16:110:16 | access to local variable x | Conditions.cs:102:12:102:13 | exit M8 | 3 |
167+
| Conditions.cs:113:10:113:11 | enter M9 | Conditions.cs:116:24:116:38 | ... < ... | 14 |
168+
| Conditions.cs:113:10:113:11 | exit M9 | Conditions.cs:113:10:113:11 | exit M9 | 1 |
169+
| Conditions.cs:117:9:123:9 | [last (line 118): false] {...} | Conditions.cs:119:18:119:21 | [last (line 118): false] access to local variable last | 13 |
170+
| Conditions.cs:117:9:123:9 | [last (line 118): true] {...} | Conditions.cs:119:18:119:21 | [last (line 118): true] access to local variable last | 13 |
171+
| Conditions.cs:117:9:123:9 | {...} | Conditions.cs:119:18:119:21 | access to local variable last | 13 |
172+
| Conditions.cs:120:17:120:23 | [last (line 118): true] ...; | Conditions.cs:116:24:116:38 | [last (line 118): true] ... < ... | 16 |
173+
| Conditions.cs:121:13:122:25 | [last (line 118): false] if (...) ... | Conditions.cs:116:24:116:38 | [last (line 118): false] ... < ... | 8 |
167174
| ExitMethods.cs:7:10:7:11 | enter M1 | ExitMethods.cs:7:10:7:11 | exit M1 | 7 |
168175
| ExitMethods.cs:13:10:13:11 | enter M2 | ExitMethods.cs:13:10:13:11 | exit M2 | 7 |
169176
| ExitMethods.cs:19:10:19:11 | enter M3 | ExitMethods.cs:19:10:19:11 | exit M3 | 6 |

csharp/ql/test/library-tests/controlflow/graph/BasicBlockDominance.expected

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -360,6 +360,21 @@
360360
| post | Conditions.cs:110:16:110:16 | access to local variable x | Conditions.cs:108:13:109:24 | [b (line 102): false] if (...) ... |
361361
| post | Conditions.cs:110:16:110:16 | access to local variable x | Conditions.cs:108:13:109:24 | [b (line 102): true] if (...) ... |
362362
| post | Conditions.cs:110:16:110:16 | access to local variable x | Conditions.cs:110:16:110:16 | access to local variable x |
363+
| post | Conditions.cs:113:10:113:11 | enter M9 | Conditions.cs:113:10:113:11 | enter M9 |
364+
| post | Conditions.cs:113:10:113:11 | exit M9 | Conditions.cs:113:10:113:11 | enter M9 |
365+
| post | Conditions.cs:113:10:113:11 | exit M9 | Conditions.cs:113:10:113:11 | exit M9 |
366+
| post | Conditions.cs:113:10:113:11 | exit M9 | Conditions.cs:117:9:123:9 | [last (line 118): false] {...} |
367+
| post | Conditions.cs:113:10:113:11 | exit M9 | Conditions.cs:117:9:123:9 | [last (line 118): true] {...} |
368+
| post | Conditions.cs:113:10:113:11 | exit M9 | Conditions.cs:117:9:123:9 | {...} |
369+
| post | Conditions.cs:113:10:113:11 | exit M9 | Conditions.cs:120:17:120:23 | [last (line 118): true] ...; |
370+
| post | Conditions.cs:113:10:113:11 | exit M9 | Conditions.cs:121:13:122:25 | [last (line 118): false] if (...) ... |
371+
| post | Conditions.cs:117:9:123:9 | [last (line 118): false] {...} | Conditions.cs:117:9:123:9 | [last (line 118): false] {...} |
372+
| post | Conditions.cs:117:9:123:9 | [last (line 118): true] {...} | Conditions.cs:117:9:123:9 | [last (line 118): true] {...} |
373+
| post | Conditions.cs:117:9:123:9 | {...} | Conditions.cs:117:9:123:9 | {...} |
374+
| post | Conditions.cs:120:17:120:23 | [last (line 118): true] ...; | Conditions.cs:117:9:123:9 | [last (line 118): true] {...} |
375+
| post | Conditions.cs:120:17:120:23 | [last (line 118): true] ...; | Conditions.cs:120:17:120:23 | [last (line 118): true] ...; |
376+
| post | Conditions.cs:121:13:122:25 | [last (line 118): false] if (...) ... | Conditions.cs:117:9:123:9 | [last (line 118): false] {...} |
377+
| post | Conditions.cs:121:13:122:25 | [last (line 118): false] if (...) ... | Conditions.cs:121:13:122:25 | [last (line 118): false] if (...) ... |
363378
| post | ExitMethods.cs:7:10:7:11 | enter M1 | ExitMethods.cs:7:10:7:11 | enter M1 |
364379
| post | ExitMethods.cs:13:10:13:11 | enter M2 | ExitMethods.cs:13:10:13:11 | enter M2 |
365380
| post | ExitMethods.cs:19:10:19:11 | enter M3 | ExitMethods.cs:19:10:19:11 | enter M3 |
@@ -1705,6 +1720,25 @@
17051720
| pre | Conditions.cs:108:13:109:24 | [b (line 102): false] if (...) ... | Conditions.cs:108:13:109:24 | [b (line 102): false] if (...) ... |
17061721
| pre | Conditions.cs:108:13:109:24 | [b (line 102): true] if (...) ... | Conditions.cs:108:13:109:24 | [b (line 102): true] if (...) ... |
17071722
| pre | Conditions.cs:110:16:110:16 | access to local variable x | Conditions.cs:110:16:110:16 | access to local variable x |
1723+
| pre | Conditions.cs:113:10:113:11 | enter M9 | Conditions.cs:113:10:113:11 | enter M9 |
1724+
| pre | Conditions.cs:113:10:113:11 | enter M9 | Conditions.cs:113:10:113:11 | exit M9 |
1725+
| pre | Conditions.cs:113:10:113:11 | enter M9 | Conditions.cs:117:9:123:9 | [last (line 118): false] {...} |
1726+
| pre | Conditions.cs:113:10:113:11 | enter M9 | Conditions.cs:117:9:123:9 | [last (line 118): true] {...} |
1727+
| pre | Conditions.cs:113:10:113:11 | enter M9 | Conditions.cs:117:9:123:9 | {...} |
1728+
| pre | Conditions.cs:113:10:113:11 | enter M9 | Conditions.cs:120:17:120:23 | [last (line 118): true] ...; |
1729+
| pre | Conditions.cs:113:10:113:11 | enter M9 | Conditions.cs:121:13:122:25 | [last (line 118): false] if (...) ... |
1730+
| pre | Conditions.cs:113:10:113:11 | exit M9 | Conditions.cs:113:10:113:11 | exit M9 |
1731+
| pre | Conditions.cs:117:9:123:9 | [last (line 118): false] {...} | Conditions.cs:117:9:123:9 | [last (line 118): false] {...} |
1732+
| pre | Conditions.cs:117:9:123:9 | [last (line 118): true] {...} | Conditions.cs:117:9:123:9 | [last (line 118): true] {...} |
1733+
| pre | Conditions.cs:117:9:123:9 | {...} | Conditions.cs:117:9:123:9 | [last (line 118): false] {...} |
1734+
| pre | Conditions.cs:117:9:123:9 | {...} | Conditions.cs:117:9:123:9 | [last (line 118): true] {...} |
1735+
| pre | Conditions.cs:117:9:123:9 | {...} | Conditions.cs:117:9:123:9 | {...} |
1736+
| pre | Conditions.cs:117:9:123:9 | {...} | Conditions.cs:120:17:120:23 | [last (line 118): true] ...; |
1737+
| pre | Conditions.cs:117:9:123:9 | {...} | Conditions.cs:121:13:122:25 | [last (line 118): false] if (...) ... |
1738+
| pre | Conditions.cs:120:17:120:23 | [last (line 118): true] ...; | Conditions.cs:117:9:123:9 | [last (line 118): true] {...} |
1739+
| pre | Conditions.cs:120:17:120:23 | [last (line 118): true] ...; | Conditions.cs:120:17:120:23 | [last (line 118): true] ...; |
1740+
| pre | Conditions.cs:121:13:122:25 | [last (line 118): false] if (...) ... | Conditions.cs:117:9:123:9 | [last (line 118): false] {...} |
1741+
| pre | Conditions.cs:121:13:122:25 | [last (line 118): false] if (...) ... | Conditions.cs:121:13:122:25 | [last (line 118): false] if (...) ... |
17081742
| pre | ExitMethods.cs:7:10:7:11 | enter M1 | ExitMethods.cs:7:10:7:11 | enter M1 |
17091743
| pre | ExitMethods.cs:13:10:13:11 | enter M2 | ExitMethods.cs:13:10:13:11 | enter M2 |
17101744
| pre | ExitMethods.cs:19:10:19:11 | enter M3 | ExitMethods.cs:19:10:19:11 | enter M3 |

csharp/ql/test/library-tests/controlflow/graph/BooleanNode.expected

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,3 +98,53 @@
9898
| inc (line 3): true | Conditions.cs:7:9:8:16 | [inc (line 3): true] if (...) ... |
9999
| inc (line 3): true | Conditions.cs:7:13:7:16 | [inc (line 3): true] !... |
100100
| inc (line 3): true | Conditions.cs:7:14:7:16 | [inc (line 3): true] access to parameter inc |
101+
| last (line 118): false | Conditions.cs:116:24:116:24 | [last (line 118): false] access to local variable i |
102+
| last (line 118): false | Conditions.cs:116:24:116:38 | [last (line 118): false] ... < ... |
103+
| last (line 118): false | Conditions.cs:116:28:116:31 | [last (line 118): false] access to parameter args |
104+
| last (line 118): false | Conditions.cs:116:28:116:38 | [last (line 118): false] access to property Length |
105+
| last (line 118): false | Conditions.cs:116:41:116:41 | [last (line 118): false] access to local variable i |
106+
| last (line 118): false | Conditions.cs:116:41:116:43 | [last (line 118): false] ...++ |
107+
| last (line 118): false | Conditions.cs:117:9:123:9 | [last (line 118): false] {...} |
108+
| last (line 118): false | Conditions.cs:118:13:118:44 | [last (line 118): false] ... ...; |
109+
| last (line 118): false | Conditions.cs:118:17:118:20 | [last (line 118): false] access to local variable last |
110+
| last (line 118): false | Conditions.cs:118:17:118:43 | [last (line 118): false] Boolean last = ... |
111+
| last (line 118): false | Conditions.cs:118:24:118:24 | [last (line 118): false] access to local variable i |
112+
| last (line 118): false | Conditions.cs:118:24:118:43 | [last (line 118): false] ... == ... |
113+
| last (line 118): false | Conditions.cs:118:29:118:32 | [last (line 118): false] access to parameter args |
114+
| last (line 118): false | Conditions.cs:118:29:118:39 | [last (line 118): false] access to property Length |
115+
| last (line 118): false | Conditions.cs:118:29:118:43 | [last (line 118): false] ... - ... |
116+
| last (line 118): false | Conditions.cs:118:43:118:43 | [last (line 118): false] 1 |
117+
| last (line 118): false | Conditions.cs:119:13:120:23 | [last (line 118): false] if (...) ... |
118+
| last (line 118): false | Conditions.cs:119:17:119:21 | [last (line 118): false] !... |
119+
| last (line 118): false | Conditions.cs:119:18:119:21 | [last (line 118): false] access to local variable last |
120+
| last (line 118): false | Conditions.cs:121:13:122:25 | [last (line 118): false] if (...) ... |
121+
| last (line 118): false | Conditions.cs:121:17:121:20 | [last (line 118): false] access to local variable last |
122+
| last (line 118): true | Conditions.cs:116:24:116:24 | [last (line 118): true] access to local variable i |
123+
| last (line 118): true | Conditions.cs:116:24:116:38 | [last (line 118): true] ... < ... |
124+
| last (line 118): true | Conditions.cs:116:28:116:31 | [last (line 118): true] access to parameter args |
125+
| last (line 118): true | Conditions.cs:116:28:116:38 | [last (line 118): true] access to property Length |
126+
| last (line 118): true | Conditions.cs:116:41:116:41 | [last (line 118): true] access to local variable i |
127+
| last (line 118): true | Conditions.cs:116:41:116:43 | [last (line 118): true] ...++ |
128+
| last (line 118): true | Conditions.cs:117:9:123:9 | [last (line 118): true] {...} |
129+
| last (line 118): true | Conditions.cs:118:13:118:44 | [last (line 118): true] ... ...; |
130+
| last (line 118): true | Conditions.cs:118:17:118:20 | [last (line 118): true] access to local variable last |
131+
| last (line 118): true | Conditions.cs:118:17:118:43 | [last (line 118): true] Boolean last = ... |
132+
| last (line 118): true | Conditions.cs:118:24:118:24 | [last (line 118): true] access to local variable i |
133+
| last (line 118): true | Conditions.cs:118:24:118:43 | [last (line 118): true] ... == ... |
134+
| last (line 118): true | Conditions.cs:118:29:118:32 | [last (line 118): true] access to parameter args |
135+
| last (line 118): true | Conditions.cs:118:29:118:39 | [last (line 118): true] access to property Length |
136+
| last (line 118): true | Conditions.cs:118:29:118:43 | [last (line 118): true] ... - ... |
137+
| last (line 118): true | Conditions.cs:118:43:118:43 | [last (line 118): true] 1 |
138+
| last (line 118): true | Conditions.cs:119:13:120:23 | [last (line 118): true] if (...) ... |
139+
| last (line 118): true | Conditions.cs:119:17:119:21 | [last (line 118): true] !... |
140+
| last (line 118): true | Conditions.cs:119:18:119:21 | [last (line 118): true] access to local variable last |
141+
| last (line 118): true | Conditions.cs:120:17:120:17 | [last (line 118): true] access to local variable s |
142+
| last (line 118): true | Conditions.cs:120:17:120:22 | [last (line 118): true] ... = ... |
143+
| last (line 118): true | Conditions.cs:120:17:120:23 | [last (line 118): true] ...; |
144+
| last (line 118): true | Conditions.cs:120:21:120:22 | [last (line 118): true] "" |
145+
| last (line 118): true | Conditions.cs:121:13:122:25 | [last (line 118): true] if (...) ... |
146+
| last (line 118): true | Conditions.cs:121:17:121:20 | [last (line 118): true] access to local variable last |
147+
| last (line 118): true | Conditions.cs:122:17:122:17 | [last (line 118): true] access to local variable s |
148+
| last (line 118): true | Conditions.cs:122:17:122:24 | [last (line 118): true] ... = ... |
149+
| last (line 118): true | Conditions.cs:122:17:122:25 | [last (line 118): true] ...; |
150+
| last (line 118): true | Conditions.cs:122:21:122:24 | [last (line 118): true] null |

csharp/ql/test/library-tests/controlflow/graph/ConditionBlock.expected

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,17 @@
155155
| Conditions.cs:105:13:105:13 | access to parameter b | Conditions.cs:108:13:109:24 | [b (line 102): true] if (...) ... | true |
156156
| Conditions.cs:107:13:107:24 | [b (line 102): false] ... > ... | Conditions.cs:108:13:109:24 | [b (line 102): false] if (...) ... | true |
157157
| Conditions.cs:107:13:107:24 | [b (line 102): true] ... > ... | Conditions.cs:108:13:109:24 | [b (line 102): true] if (...) ... | true |
158+
| Conditions.cs:116:24:116:38 | ... < ... | Conditions.cs:117:9:123:9 | [last (line 118): false] {...} | true |
159+
| Conditions.cs:116:24:116:38 | ... < ... | Conditions.cs:117:9:123:9 | [last (line 118): true] {...} | true |
160+
| Conditions.cs:116:24:116:38 | ... < ... | Conditions.cs:117:9:123:9 | {...} | true |
161+
| Conditions.cs:116:24:116:38 | ... < ... | Conditions.cs:120:17:120:23 | [last (line 118): true] ...; | true |
162+
| Conditions.cs:116:24:116:38 | ... < ... | Conditions.cs:121:13:122:25 | [last (line 118): false] if (...) ... | true |
163+
| Conditions.cs:116:24:116:38 | [last (line 118): false] ... < ... | Conditions.cs:117:9:123:9 | [last (line 118): false] {...} | true |
164+
| Conditions.cs:116:24:116:38 | [last (line 118): true] ... < ... | Conditions.cs:117:9:123:9 | [last (line 118): true] {...} | true |
165+
| Conditions.cs:119:18:119:21 | access to local variable last | Conditions.cs:117:9:123:9 | [last (line 118): false] {...} | true |
166+
| Conditions.cs:119:18:119:21 | access to local variable last | Conditions.cs:117:9:123:9 | [last (line 118): true] {...} | false |
167+
| Conditions.cs:119:18:119:21 | access to local variable last | Conditions.cs:120:17:120:23 | [last (line 118): true] ...; | false |
168+
| Conditions.cs:119:18:119:21 | access to local variable last | Conditions.cs:121:13:122:25 | [last (line 118): false] if (...) ... | true |
158169
| ExitMethods.cs:43:9:46:9 | [exception: Exception] catch (...) {...} | ExitMethods.cs:47:9:50:9 | [exception: Exception] catch (...) {...} | false |
159170
| ExitMethods.cs:55:13:55:13 | access to parameter b | ExitMethods.cs:56:19:56:33 | object creation of type Exception | true |
160171
| ExitMethods.cs:61:13:61:13 | access to parameter b | ExitMethods.cs:62:19:62:33 | object creation of type Exception | true |

csharp/ql/test/library-tests/controlflow/graph/ConditionalFlow.expected

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,10 +187,22 @@
187187
| 108 | 18 | Conditions.cs:108:18:108:18 | [b (line 102): false] access to parameter b | false | 109 | 17 | Conditions.cs:109:17:109:24 | ...; |
188188
| 108 | 18 | Conditions.cs:108:18:108:18 | [b (line 102): true] access to parameter b | true | 110 | 16 | Conditions.cs:110:16:110:16 | access to local variable x |
189189
| 110 | 20 | cflow.cs:110:20:110:23 | true | true | 111 | 13 | cflow.cs:111:13:113:13 | {...} |
190+
| 116 | 24 | Conditions.cs:116:24:116:38 | ... < ... | false | 113 | 10 | Conditions.cs:113:10:113:11 | exit M9 |
191+
| 116 | 24 | Conditions.cs:116:24:116:38 | ... < ... | true | 117 | 9 | Conditions.cs:117:9:123:9 | {...} |
192+
| 116 | 24 | Conditions.cs:116:24:116:38 | [last (line 118): false] ... < ... | false | 113 | 10 | Conditions.cs:113:10:113:11 | exit M9 |
193+
| 116 | 24 | Conditions.cs:116:24:116:38 | [last (line 118): false] ... < ... | true | 117 | 9 | Conditions.cs:117:9:123:9 | [last (line 118): false] {...} |
194+
| 116 | 24 | Conditions.cs:116:24:116:38 | [last (line 118): true] ... < ... | false | 113 | 10 | Conditions.cs:113:10:113:11 | exit M9 |
195+
| 116 | 24 | Conditions.cs:116:24:116:38 | [last (line 118): true] ... < ... | true | 117 | 9 | Conditions.cs:117:9:123:9 | [last (line 118): true] {...} |
190196
| 117 | 25 | Switch.cs:117:25:117:32 | ... == ... | false | 118 | 13 | Switch.cs:118:13:118:33 | case ...: |
191197
| 117 | 25 | Switch.cs:117:25:117:32 | ... == ... | true | 117 | 43 | Switch.cs:117:43:117:43 | 1 |
192198
| 118 | 25 | Switch.cs:118:25:118:31 | ... == ... | false | 120 | 17 | Switch.cs:120:17:120:17 | 1 |
193199
| 118 | 25 | Switch.cs:118:25:118:31 | ... == ... | true | 118 | 42 | Switch.cs:118:42:118:42 | 2 |
200+
| 119 | 18 | Conditions.cs:119:18:119:21 | [last (line 118): false] access to local variable last | true | 121 | 13 | Conditions.cs:121:13:122:25 | [last (line 118): false] if (...) ... |
201+
| 119 | 18 | Conditions.cs:119:18:119:21 | [last (line 118): true] access to local variable last | false | 120 | 17 | Conditions.cs:120:17:120:23 | [last (line 118): true] ...; |
202+
| 119 | 18 | Conditions.cs:119:18:119:21 | access to local variable last | false | 120 | 17 | Conditions.cs:120:17:120:23 | [last (line 118): true] ...; |
203+
| 119 | 18 | Conditions.cs:119:18:119:21 | access to local variable last | true | 121 | 13 | Conditions.cs:121:13:122:25 | [last (line 118): false] if (...) ... |
204+
| 121 | 17 | Conditions.cs:121:17:121:20 | [last (line 118): false] access to local variable last | false | 116 | 41 | Conditions.cs:116:41:116:41 | [last (line 118): false] access to local variable i |
205+
| 121 | 17 | Conditions.cs:121:17:121:20 | [last (line 118): true] access to local variable last | true | 122 | 17 | Conditions.cs:122:17:122:25 | [last (line 118): true] ...; |
194206
| 127 | 32 | cflow.cs:127:32:127:44 | ... == ... | false | 127 | 53 | cflow.cs:127:53:127:57 | this access |
195207
| 127 | 32 | cflow.cs:127:32:127:44 | ... == ... | true | 127 | 48 | cflow.cs:127:48:127:49 | "" |
196208
| 162 | 48 | cflow.cs:162:48:162:51 | [exception: Exception] true | true | 163 | 9 | cflow.cs:163:9:165:9 | {...} |

csharp/ql/test/library-tests/controlflow/graph/Conditions.cs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,4 +109,17 @@ string M8(bool b)
109109
x += "";
110110
return x;
111111
}
112+
113+
void M9(string[] args)
114+
{
115+
string s = null;
116+
for(var i = 0; i < args.Length; i++)
117+
{
118+
var last = i == args.Length - 1;
119+
if (!last)
120+
s = "";
121+
if (last)
122+
s = null;
123+
}
124+
}
112125
}

0 commit comments

Comments
 (0)