Skip to content

Commit ab7a094

Browse files
committed
C#: Include CFG splits in Ssa::Definition::toString()
Just like syntax elements can be split in the control flow graph, so can SSA definitions. To make this clear, and to make debugging easier, this commit adds the splits as a prefix in the textual representation of SSA definitions.
1 parent 41edd61 commit ab7a094

File tree

8 files changed

+45
-20
lines changed

8 files changed

+45
-20
lines changed

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -353,6 +353,12 @@ module ControlFlow {
353353
)
354354
}
355355

356+
/** Gets a comma-separated list of strings for each split in this node, if any. */
357+
string getSplitsString() {
358+
result = splits.toString() and
359+
result != ""
360+
}
361+
356362
/** Gets a split for this control flow node, if any. */
357363
Split getASplit() {
358364
result = splits.getASplit()

csharp/ql/src/semmle/code/csharp/dataflow/SSA.qll

Lines changed: 27 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1975,6 +1975,25 @@ module Ssa {
19751975

19761976
private import SsaImpl
19771977

1978+
private string getSplitString(Definition def) {
1979+
exists(BasicBlock bb, int i, ControlFlow::Node cfn |
1980+
definesAt(def, bb, i, _) and
1981+
result = cfn.(ControlFlow::Nodes::ElementNode).getSplitsString()
1982+
|
1983+
cfn = bb.getNode(i)
1984+
or
1985+
not exists(bb.getNode(i)) and
1986+
cfn = bb.getFirstNode()
1987+
)
1988+
}
1989+
1990+
private string getToStringPrefix(Definition def) {
1991+
result = "[" + getSplitString(def) + "] "
1992+
or
1993+
not exists(getSplitString(def)) and
1994+
result = ""
1995+
}
1996+
19781997
/**
19791998
* A static single assignment (SSA) definition. Either an explicit variable
19801999
* definition (`ExplicitDefinition`), an implicit variable definition
@@ -2311,9 +2330,9 @@ module Ssa {
23112330

23122331
override string toString() {
23132332
if this.getADefinition() instanceof AssignableDefinitions::ImplicitParameterDefinition then
2314-
result = "SSA param(" + this.getSourceVariable() + ")"
2333+
result = getToStringPrefix(this) + "SSA param(" + this.getSourceVariable() + ")"
23152334
else
2316-
result = "SSA def(" + this.getSourceVariable() + ")"
2335+
result = getToStringPrefix(this) + "SSA def(" + this.getSourceVariable() + ")"
23172336
}
23182337

23192338
override Location getLocation() {
@@ -2354,9 +2373,9 @@ module Ssa {
23542373

23552374
override string toString() {
23562375
if this.getSourceVariable().getAssignable() instanceof LocalScopeVariable then
2357-
result = "SSA capture def(" + this.getSourceVariable() + ")"
2376+
result = getToStringPrefix(this) + "SSA capture def(" + this.getSourceVariable() + ")"
23582377
else
2359-
result = "SSA entry def(" + this.getSourceVariable() + ")"
2378+
result = getToStringPrefix(this) + "SSA entry def(" + this.getSourceVariable() + ")"
23602379
}
23612380

23622381
override Location getLocation() {
@@ -2391,7 +2410,7 @@ module Ssa {
23912410
}
23922411

23932412
override string toString() {
2394-
result = "SSA call def(" + getSourceVariable() + ")"
2413+
result = getToStringPrefix(this) + "SSA call def(" + getSourceVariable() + ")"
23952414
}
23962415

23972416
override Location getLocation() {
@@ -2410,7 +2429,7 @@ module Ssa {
24102429
}
24112430

24122431
override string toString() {
2413-
result = "SSA qualifier def(" + getSourceVariable() + ")"
2432+
result = getToStringPrefix(this) + "SSA qualifier def(" + getSourceVariable() + ")"
24142433
}
24152434

24162435
override Location getLocation() {
@@ -2435,7 +2454,7 @@ module Ssa {
24352454
}
24362455

24372456
override string toString() {
2438-
result = "SSA untracked def(" + getSourceVariable() + ")"
2457+
result = getToStringPrefix(this) + "SSA untracked def(" + getSourceVariable() + ")"
24392458
}
24402459

24412460
override Location getLocation() {
@@ -2497,7 +2516,7 @@ module Ssa {
24972516
}
24982517

24992518
override string toString() {
2500-
result = "SSA phi(" + getSourceVariable() + ")"
2519+
result = getToStringPrefix(this) + "SSA phi(" + getSourceVariable() + ")"
25012520
}
25022521

25032522
/*

csharp/ql/test/library-tests/dataflow/ssa/SsaAdjacentUncertainRead.expected

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ WARNING: Predicate getAFirstUncertainRead has been deprecated and may be removed
6969
| Capture.cs:236:9:236:12 | SSA call def(i) | Capture.cs:237:34:237:34 | access to local variable i |
7070
| Consistency.cs:7:25:7:25 | SSA param(b) | Consistency.cs:11:17:11:17 | access to parameter b |
7171
| Consistency.cs:15:17:15:21 | SSA def(i) | Consistency.cs:16:17:16:17 | access to local variable i |
72-
| Consistency.cs:15:17:15:21 | SSA def(i) | Consistency.cs:16:17:16:17 | access to local variable i |
72+
| Consistency.cs:15:17:15:21 | [finally: exception(Exception)] SSA def(i) | Consistency.cs:16:17:16:17 | access to local variable i |
7373
| Consistency.cs:25:29:25:29 | SSA def(c) | Consistency.cs:26:13:26:13 | access to local variable c |
7474
| Consistency.cs:25:29:25:29 | SSA qualifier def(c.Field) | Consistency.cs:26:13:26:19 | access to field Field |
7575
| Consistency.cs:32:9:32:29 | SSA def(c) | Consistency.cs:33:9:33:9 | access to parameter c |
@@ -318,7 +318,7 @@ WARNING: Predicate getAFirstUncertainRead has been deprecated and may be removed
318318
| Test.cs:46:10:46:10 | SSA entry def(this.field) | Test.cs:56:13:56:17 | access to field field |
319319
| Test.cs:46:16:46:18 | SSA param(in) | Test.cs:48:13:48:15 | access to parameter in |
320320
| Test.cs:57:9:57:17 | SSA def(this.field) | Test.cs:58:13:58:17 | access to field field |
321-
| Test.cs:68:45:68:45 | SSA def(e) | Test.cs:70:17:70:17 | access to local variable e |
321+
| Test.cs:68:45:68:45 | [exception: DivideByZeroException] SSA def(e) | Test.cs:70:17:70:17 | access to local variable e |
322322
| Tuples.cs:10:9:10:54 | SSA def(b) | Tuples.cs:12:13:12:13 | access to local variable b |
323323
| Tuples.cs:10:9:10:54 | SSA def(s) | Tuples.cs:13:13:13:13 | access to local variable s |
324324
| Tuples.cs:10:9:10:54 | SSA def(x) | Tuples.cs:11:13:11:13 | access to local variable x |

csharp/ql/test/library-tests/dataflow/ssa/SsaDef.expected

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@
8484
| Capture.cs:229:13:229:13 | i | Capture.cs:236:9:236:12 | SSA call def(i) |
8585
| Consistency.cs:7:25:7:25 | b | Consistency.cs:7:25:7:25 | SSA param(b) |
8686
| Consistency.cs:15:17:15:17 | i | Consistency.cs:15:17:15:21 | SSA def(i) |
87-
| Consistency.cs:15:17:15:17 | i | Consistency.cs:15:17:15:21 | SSA def(i) |
87+
| Consistency.cs:15:17:15:17 | i | Consistency.cs:15:17:15:21 | [finally: exception(Exception)] SSA def(i) |
8888
| Consistency.cs:25:29:25:29 | c | Consistency.cs:25:29:25:29 | SSA def(c) |
8989
| Consistency.cs:26:13:26:19 | c.Field | Consistency.cs:25:29:25:29 | SSA qualifier def(c.Field) |
9090
| Consistency.cs:30:30:30:30 | c | Consistency.cs:32:9:32:29 | SSA def(c) |
@@ -342,7 +342,7 @@
342342
| Test.cs:46:29:46:32 | out | Test.cs:56:9:56:19 | SSA phi(out) |
343343
| Test.cs:56:13:56:17 | this.field | Test.cs:46:10:46:10 | SSA entry def(this.field) |
344344
| Test.cs:56:13:56:17 | this.field | Test.cs:57:9:57:17 | SSA def(this.field) |
345-
| Test.cs:68:45:68:45 | e | Test.cs:68:45:68:45 | SSA def(e) |
345+
| Test.cs:68:45:68:45 | e | Test.cs:68:45:68:45 | [exception: DivideByZeroException] SSA def(e) |
346346
| Tuples.cs:10:14:10:14 | x | Tuples.cs:10:9:10:54 | SSA def(x) |
347347
| Tuples.cs:10:14:10:14 | x | Tuples.cs:14:9:14:32 | SSA def(x) |
348348
| Tuples.cs:10:14:10:14 | x | Tuples.cs:23:9:23:37 | SSA def(x) |

csharp/ql/test/library-tests/dataflow/ssa/SsaDefLastRead.expected

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@
5353
| Capture.cs:229:13:229:13 | i | Capture.cs:236:9:236:12 | SSA call def(i) | Capture.cs:237:34:237:34 | access to local variable i |
5454
| Consistency.cs:7:25:7:25 | b | Consistency.cs:7:25:7:25 | SSA param(b) | Consistency.cs:11:17:11:17 | access to parameter b |
5555
| Consistency.cs:15:17:15:17 | i | Consistency.cs:15:17:15:21 | SSA def(i) | Consistency.cs:16:17:16:17 | access to local variable i |
56-
| Consistency.cs:15:17:15:17 | i | Consistency.cs:15:17:15:21 | SSA def(i) | Consistency.cs:16:17:16:17 | access to local variable i |
56+
| Consistency.cs:15:17:15:17 | i | Consistency.cs:15:17:15:21 | [finally: exception(Exception)] SSA def(i) | Consistency.cs:16:17:16:17 | access to local variable i |
5757
| Consistency.cs:25:29:25:29 | c | Consistency.cs:25:29:25:29 | SSA def(c) | Consistency.cs:27:13:27:13 | access to local variable c |
5858
| Consistency.cs:26:13:26:19 | c.Field | Consistency.cs:25:29:25:29 | SSA qualifier def(c.Field) | Consistency.cs:27:13:27:19 | access to field Field |
5959
| Consistency.cs:44:11:44:11 | s | Consistency.cs:44:11:44:11 | SSA def(s) | Consistency.cs:46:13:46:13 | access to local variable s |
@@ -235,7 +235,7 @@
235235
| Test.cs:46:16:46:18 | in | Test.cs:46:16:46:18 | SSA param(in) | Test.cs:48:13:48:15 | access to parameter in |
236236
| Test.cs:56:13:56:17 | this.field | Test.cs:46:10:46:10 | SSA entry def(this.field) | Test.cs:56:13:56:17 | access to field field |
237237
| Test.cs:56:13:56:17 | this.field | Test.cs:57:9:57:17 | SSA def(this.field) | Test.cs:58:13:58:17 | access to field field |
238-
| Test.cs:68:45:68:45 | e | Test.cs:68:45:68:45 | SSA def(e) | Test.cs:70:17:70:17 | access to local variable e |
238+
| Test.cs:68:45:68:45 | e | Test.cs:68:45:68:45 | [exception: DivideByZeroException] SSA def(e) | Test.cs:70:17:70:17 | access to local variable e |
239239
| Tuples.cs:10:14:10:14 | x | Tuples.cs:10:9:10:54 | SSA def(x) | Tuples.cs:11:13:11:13 | access to local variable x |
240240
| Tuples.cs:10:14:10:14 | x | Tuples.cs:14:9:14:32 | SSA def(x) | Tuples.cs:15:13:15:13 | access to local variable x |
241241
| Tuples.cs:10:14:10:14 | x | Tuples.cs:23:9:23:37 | SSA def(x) | Tuples.cs:24:13:24:13 | access to local variable x |

csharp/ql/test/library-tests/dataflow/ssa/SsaExplicitDef.expected

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@
5656
| Capture.cs:229:13:229:13 | i | Capture.cs:235:21:235:25 | SSA def(i) | Capture.cs:235:21:235:25 | ... = ... |
5757
| Consistency.cs:7:25:7:25 | b | Consistency.cs:7:25:7:25 | SSA param(b) | Consistency.cs:7:25:7:25 | b |
5858
| Consistency.cs:15:17:15:17 | i | Consistency.cs:15:17:15:21 | SSA def(i) | Consistency.cs:15:17:15:21 | Int32 i = ... |
59-
| Consistency.cs:15:17:15:17 | i | Consistency.cs:15:17:15:21 | SSA def(i) | Consistency.cs:15:17:15:21 | Int32 i = ... |
59+
| Consistency.cs:15:17:15:17 | i | Consistency.cs:15:17:15:21 | [finally: exception(Exception)] SSA def(i) | Consistency.cs:15:17:15:21 | Int32 i = ... |
6060
| Consistency.cs:25:29:25:29 | c | Consistency.cs:25:29:25:29 | SSA def(c) | Consistency.cs:25:29:25:29 | Consistency c |
6161
| Consistency.cs:30:30:30:30 | c | Consistency.cs:32:9:32:29 | SSA def(c) | Consistency.cs:32:9:32:29 | ... = ... |
6262
| Consistency.cs:38:13:38:13 | i | Consistency.cs:39:28:39:32 | SSA def(i) | Consistency.cs:39:28:39:32 | ... = ... |
@@ -209,7 +209,7 @@
209209
| Test.cs:46:29:46:32 | out | Test.cs:50:13:50:20 | SSA def(out) | Test.cs:50:13:50:20 | ... = ... |
210210
| Test.cs:46:29:46:32 | out | Test.cs:54:13:54:20 | SSA def(out) | Test.cs:54:13:54:20 | ... = ... |
211211
| Test.cs:56:13:56:17 | this.field | Test.cs:57:9:57:17 | SSA def(this.field) | Test.cs:57:9:57:17 | ... = ... |
212-
| Test.cs:68:45:68:45 | e | Test.cs:68:45:68:45 | SSA def(e) | Test.cs:68:45:68:45 | DivideByZeroException e |
212+
| Test.cs:68:45:68:45 | e | Test.cs:68:45:68:45 | [exception: DivideByZeroException] SSA def(e) | Test.cs:68:45:68:45 | DivideByZeroException e |
213213
| Tuples.cs:10:14:10:14 | x | Tuples.cs:10:9:10:54 | SSA def(x) | Tuples.cs:10:9:10:54 | ... = ... |
214214
| Tuples.cs:10:14:10:14 | x | Tuples.cs:14:9:14:32 | SSA def(x) | Tuples.cs:14:9:14:32 | ... = ... |
215215
| Tuples.cs:10:14:10:14 | x | Tuples.cs:23:9:23:37 | SSA def(x) | Tuples.cs:23:9:23:37 | ... = ... |

csharp/ql/test/library-tests/dataflow/ssa/SsaRead.expected

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@
6565
| Capture.cs:229:13:229:13 | i | Capture.cs:236:9:236:12 | SSA call def(i) | Capture.cs:237:34:237:34 | access to local variable i |
6666
| Consistency.cs:7:25:7:25 | b | Consistency.cs:7:25:7:25 | SSA param(b) | Consistency.cs:11:17:11:17 | access to parameter b |
6767
| Consistency.cs:15:17:15:17 | i | Consistency.cs:15:17:15:21 | SSA def(i) | Consistency.cs:16:17:16:17 | access to local variable i |
68-
| Consistency.cs:15:17:15:17 | i | Consistency.cs:15:17:15:21 | SSA def(i) | Consistency.cs:16:17:16:17 | access to local variable i |
68+
| Consistency.cs:15:17:15:17 | i | Consistency.cs:15:17:15:21 | [finally: exception(Exception)] SSA def(i) | Consistency.cs:16:17:16:17 | access to local variable i |
6969
| Consistency.cs:25:29:25:29 | c | Consistency.cs:25:29:25:29 | SSA def(c) | Consistency.cs:26:13:26:13 | access to local variable c |
7070
| Consistency.cs:25:29:25:29 | c | Consistency.cs:25:29:25:29 | SSA def(c) | Consistency.cs:27:13:27:13 | access to local variable c |
7171
| Consistency.cs:26:13:26:19 | c.Field | Consistency.cs:25:29:25:29 | SSA qualifier def(c.Field) | Consistency.cs:26:13:26:19 | access to field Field |
@@ -356,7 +356,7 @@
356356
| Test.cs:46:16:46:18 | in | Test.cs:46:16:46:18 | SSA param(in) | Test.cs:48:13:48:15 | access to parameter in |
357357
| Test.cs:56:13:56:17 | this.field | Test.cs:46:10:46:10 | SSA entry def(this.field) | Test.cs:56:13:56:17 | access to field field |
358358
| Test.cs:56:13:56:17 | this.field | Test.cs:57:9:57:17 | SSA def(this.field) | Test.cs:58:13:58:17 | access to field field |
359-
| Test.cs:68:45:68:45 | e | Test.cs:68:45:68:45 | SSA def(e) | Test.cs:70:17:70:17 | access to local variable e |
359+
| Test.cs:68:45:68:45 | e | Test.cs:68:45:68:45 | [exception: DivideByZeroException] SSA def(e) | Test.cs:70:17:70:17 | access to local variable e |
360360
| Tuples.cs:10:14:10:14 | x | Tuples.cs:10:9:10:54 | SSA def(x) | Tuples.cs:11:13:11:13 | access to local variable x |
361361
| Tuples.cs:10:14:10:14 | x | Tuples.cs:14:9:14:32 | SSA def(x) | Tuples.cs:15:13:15:13 | access to local variable x |
362362
| Tuples.cs:10:14:10:14 | x | Tuples.cs:23:9:23:37 | SSA def(x) | Tuples.cs:24:13:24:13 | access to local variable x |

csharp/ql/test/library-tests/dataflow/ssa/SsaUltimateDef.expected

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@
9595
| Capture.cs:229:13:229:13 | i | Capture.cs:236:9:236:12 | SSA call def(i) | Capture.cs:236:9:236:12 | SSA call def(i) |
9696
| Consistency.cs:7:25:7:25 | b | Consistency.cs:7:25:7:25 | SSA param(b) | Consistency.cs:7:25:7:25 | SSA param(b) |
9797
| Consistency.cs:15:17:15:17 | i | Consistency.cs:15:17:15:21 | SSA def(i) | Consistency.cs:15:17:15:21 | SSA def(i) |
98-
| Consistency.cs:15:17:15:17 | i | Consistency.cs:15:17:15:21 | SSA def(i) | Consistency.cs:15:17:15:21 | SSA def(i) |
98+
| Consistency.cs:15:17:15:17 | i | Consistency.cs:15:17:15:21 | [finally: exception(Exception)] SSA def(i) | Consistency.cs:15:17:15:21 | [finally: exception(Exception)] SSA def(i) |
9999
| Consistency.cs:25:29:25:29 | c | Consistency.cs:25:29:25:29 | SSA def(c) | Consistency.cs:25:29:25:29 | SSA def(c) |
100100
| Consistency.cs:26:13:26:19 | c.Field | Consistency.cs:25:29:25:29 | SSA qualifier def(c.Field) | Consistency.cs:25:29:25:29 | SSA qualifier def(c.Field) |
101101
| Consistency.cs:30:30:30:30 | c | Consistency.cs:32:9:32:29 | SSA def(c) | Consistency.cs:32:9:32:29 | SSA def(c) |
@@ -455,7 +455,7 @@
455455
| Test.cs:46:29:46:32 | out | Test.cs:56:9:56:19 | SSA phi(out) | Test.cs:54:13:54:20 | SSA def(out) |
456456
| Test.cs:56:13:56:17 | this.field | Test.cs:46:10:46:10 | SSA entry def(this.field) | Test.cs:46:10:46:10 | SSA entry def(this.field) |
457457
| Test.cs:56:13:56:17 | this.field | Test.cs:57:9:57:17 | SSA def(this.field) | Test.cs:57:9:57:17 | SSA def(this.field) |
458-
| Test.cs:68:45:68:45 | e | Test.cs:68:45:68:45 | SSA def(e) | Test.cs:68:45:68:45 | SSA def(e) |
458+
| Test.cs:68:45:68:45 | e | Test.cs:68:45:68:45 | [exception: DivideByZeroException] SSA def(e) | Test.cs:68:45:68:45 | [exception: DivideByZeroException] SSA def(e) |
459459
| Tuples.cs:10:14:10:14 | x | Tuples.cs:10:9:10:54 | SSA def(x) | Tuples.cs:10:9:10:54 | SSA def(x) |
460460
| Tuples.cs:10:14:10:14 | x | Tuples.cs:14:9:14:32 | SSA def(x) | Tuples.cs:14:9:14:32 | SSA def(x) |
461461
| Tuples.cs:10:14:10:14 | x | Tuples.cs:23:9:23:37 | SSA def(x) | Tuples.cs:23:9:23:37 | SSA def(x) |

0 commit comments

Comments
 (0)