Skip to content

Commit 7a54a90

Browse files
committed
C#: Fix CFG for C# 6 initializers
1 parent 36e29e0 commit 7a54a90

File tree

7 files changed

+269
-85
lines changed

7 files changed

+269
-85
lines changed

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

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -501,7 +501,7 @@ module ControlFlow {
501501
private class WriteAccessNoNodeExpr extends WriteAccess, NoNodeExpr {
502502
WriteAccessNoNodeExpr() {
503503
// For example a write to a static field, `Foo.Bar = 0`.
504-
forall(Expr e | e = this.(QualifiableExpr).getQualifier() | e instanceof NoNodeExpr)
504+
forall(Expr e | e = this.getAChildExpr() | e instanceof NoNodeExpr)
505505
}
506506
}
507507

@@ -553,7 +553,17 @@ module ControlFlow {
553553
* not evaluated, only the qualifier and the indexer arguments (if any).
554554
*/
555555
private class QualifiedWriteAccess extends WriteAccess, QualifiableExpr {
556-
QualifiedWriteAccess() { this.hasQualifier() }
556+
QualifiedWriteAccess() {
557+
this.hasQualifier()
558+
or
559+
// Member initializers like
560+
// ```
561+
// new Dictionary<int, string>() { [0] = "Zero", [1] = "One", [2] = "Two" }
562+
// ```
563+
// need special treatment, because the the accesses `[0]`, `[1]`, and `[2]`
564+
// have no qualifier.
565+
this = any(MemberInitializer mi).getLValue()
566+
}
557567
}
558568

559569
/** A normal or a (potential) dynamic call to an accessor. */

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -408,7 +408,7 @@
408408
| Initializers.cs:31:9:31:11 | enter Sub | Initializers.cs:31:9:31:11 | exit Sub | 11 |
409409
| Initializers.cs:33:9:33:11 | enter Sub | Initializers.cs:33:9:33:11 | exit Sub | 8 |
410410
| Initializers.cs:35:9:35:11 | enter Sub | Initializers.cs:35:9:35:11 | exit Sub | 18 |
411-
| Initializers.cs:51:10:51:13 | enter Test | Initializers.cs:51:10:51:13 | exit Test | 69 |
411+
| Initializers.cs:51:10:51:13 | enter Test | Initializers.cs:51:10:51:13 | exit Test | 104 |
412412
| LoopUnrolling.cs:7:10:7:11 | enter M1 | LoopUnrolling.cs:9:13:9:28 | ... == ... | 7 |
413413
| LoopUnrolling.cs:7:10:7:11 | exit M1 | LoopUnrolling.cs:7:10:7:11 | exit M1 | 1 |
414414
| LoopUnrolling.cs:10:13:10:19 | return ...; | LoopUnrolling.cs:10:13:10:19 | return ...; | 1 |

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

Lines changed: 104 additions & 34 deletions
Large diffs are not rendered by default.

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

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1915,12 +1915,17 @@ nodeEnclosing
19151915
| Initializers.cs:54:50:54:95 | { ..., ... } | Initializers.cs:51:10:51:13 | Test |
19161916
| Initializers.cs:54:52:54:54 | access to indexer | Initializers.cs:51:10:51:13 | Test |
19171917
| Initializers.cs:54:52:54:63 | ... = ... | Initializers.cs:51:10:51:13 | Test |
1918+
| Initializers.cs:54:53:54:53 | 0 | Initializers.cs:51:10:51:13 | Test |
19181919
| Initializers.cs:54:58:54:63 | "Zero" | Initializers.cs:51:10:51:13 | Test |
19191920
| Initializers.cs:54:66:54:68 | access to indexer | Initializers.cs:51:10:51:13 | Test |
19201921
| Initializers.cs:54:66:54:76 | ... = ... | Initializers.cs:51:10:51:13 | Test |
1922+
| Initializers.cs:54:67:54:67 | 1 | Initializers.cs:51:10:51:13 | Test |
19211923
| Initializers.cs:54:72:54:76 | "One" | Initializers.cs:51:10:51:13 | Test |
19221924
| Initializers.cs:54:79:54:85 | access to indexer | Initializers.cs:51:10:51:13 | Test |
19231925
| Initializers.cs:54:79:54:93 | ... = ... | Initializers.cs:51:10:51:13 | Test |
1926+
| Initializers.cs:54:80:54:80 | access to parameter i | Initializers.cs:51:10:51:13 | Test |
1927+
| Initializers.cs:54:80:54:84 | ... + ... | Initializers.cs:51:10:51:13 | Test |
1928+
| Initializers.cs:54:84:54:84 | 2 | Initializers.cs:51:10:51:13 | Test |
19241929
| Initializers.cs:54:89:54:93 | "Two" | Initializers.cs:51:10:51:13 | Test |
19251930
| Initializers.cs:57:9:65:10 | ... ...; | Initializers.cs:51:10:51:13 | Test |
19261931
| Initializers.cs:57:13:65:9 | Compound compound = ... | Initializers.cs:51:10:51:13 | Test |
@@ -1930,50 +1935,80 @@ nodeEnclosing
19301935
| Initializers.cs:59:31:59:76 | { ..., ... } | Initializers.cs:51:10:51:13 | Test |
19311936
| Initializers.cs:59:33:59:35 | access to indexer | Initializers.cs:51:10:51:13 | Test |
19321937
| Initializers.cs:59:33:59:44 | ... = ... | Initializers.cs:51:10:51:13 | Test |
1938+
| Initializers.cs:59:34:59:34 | 0 | Initializers.cs:51:10:51:13 | Test |
19331939
| Initializers.cs:59:39:59:44 | "Zero" | Initializers.cs:51:10:51:13 | Test |
19341940
| Initializers.cs:59:47:59:49 | access to indexer | Initializers.cs:51:10:51:13 | Test |
19351941
| Initializers.cs:59:47:59:57 | ... = ... | Initializers.cs:51:10:51:13 | Test |
1942+
| Initializers.cs:59:48:59:48 | 1 | Initializers.cs:51:10:51:13 | Test |
19361943
| Initializers.cs:59:53:59:57 | "One" | Initializers.cs:51:10:51:13 | Test |
19371944
| Initializers.cs:59:60:59:66 | access to indexer | Initializers.cs:51:10:51:13 | Test |
19381945
| Initializers.cs:59:60:59:74 | ... = ... | Initializers.cs:51:10:51:13 | Test |
1946+
| Initializers.cs:59:61:59:61 | access to parameter i | Initializers.cs:51:10:51:13 | Test |
1947+
| Initializers.cs:59:61:59:65 | ... + ... | Initializers.cs:51:10:51:13 | Test |
1948+
| Initializers.cs:59:65:59:65 | 2 | Initializers.cs:51:10:51:13 | Test |
19391949
| Initializers.cs:59:70:59:74 | "Two" | Initializers.cs:51:10:51:13 | Test |
19401950
| Initializers.cs:60:13:60:30 | access to property DictionaryProperty | Initializers.cs:51:10:51:13 | Test |
19411951
| Initializers.cs:60:13:60:80 | ... = ... | Initializers.cs:51:10:51:13 | Test |
19421952
| Initializers.cs:60:34:60:80 | { ..., ... } | Initializers.cs:51:10:51:13 | Test |
19431953
| Initializers.cs:60:36:60:38 | access to indexer | Initializers.cs:51:10:51:13 | Test |
19441954
| Initializers.cs:60:36:60:48 | ... = ... | Initializers.cs:51:10:51:13 | Test |
1955+
| Initializers.cs:60:37:60:37 | 3 | Initializers.cs:51:10:51:13 | Test |
19451956
| Initializers.cs:60:42:60:48 | "Three" | Initializers.cs:51:10:51:13 | Test |
19461957
| Initializers.cs:60:51:60:53 | access to indexer | Initializers.cs:51:10:51:13 | Test |
19471958
| Initializers.cs:60:51:60:61 | ... = ... | Initializers.cs:51:10:51:13 | Test |
1959+
| Initializers.cs:60:52:60:52 | 2 | Initializers.cs:51:10:51:13 | Test |
19481960
| Initializers.cs:60:57:60:61 | "Two" | Initializers.cs:51:10:51:13 | Test |
19491961
| Initializers.cs:60:64:60:70 | access to indexer | Initializers.cs:51:10:51:13 | Test |
19501962
| Initializers.cs:60:64:60:78 | ... = ... | Initializers.cs:51:10:51:13 | Test |
1963+
| Initializers.cs:60:65:60:65 | access to parameter i | Initializers.cs:51:10:51:13 | Test |
1964+
| Initializers.cs:60:65:60:69 | ... + ... | Initializers.cs:51:10:51:13 | Test |
1965+
| Initializers.cs:60:69:60:69 | 1 | Initializers.cs:51:10:51:13 | Test |
19511966
| Initializers.cs:60:74:60:78 | "One" | Initializers.cs:51:10:51:13 | Test |
19521967
| Initializers.cs:61:13:61:58 | ... = ... | Initializers.cs:51:10:51:13 | Test |
19531968
| Initializers.cs:61:26:61:58 | { ..., ... } | Initializers.cs:51:10:51:13 | Test |
19541969
| Initializers.cs:61:28:61:39 | ... = ... | Initializers.cs:51:10:51:13 | Test |
1970+
| Initializers.cs:61:29:61:29 | 0 | Initializers.cs:51:10:51:13 | Test |
19551971
| Initializers.cs:61:34:61:39 | "Zero" | Initializers.cs:51:10:51:13 | Test |
19561972
| Initializers.cs:61:42:61:56 | ... = ... | Initializers.cs:51:10:51:13 | Test |
1973+
| Initializers.cs:61:43:61:43 | access to parameter i | Initializers.cs:51:10:51:13 | Test |
1974+
| Initializers.cs:61:43:61:47 | ... + ... | Initializers.cs:51:10:51:13 | Test |
1975+
| Initializers.cs:61:47:61:47 | 1 | Initializers.cs:51:10:51:13 | Test |
19571976
| Initializers.cs:61:52:61:56 | "One" | Initializers.cs:51:10:51:13 | Test |
19581977
| Initializers.cs:62:13:62:60 | ... = ... | Initializers.cs:51:10:51:13 | Test |
19591978
| Initializers.cs:62:27:62:60 | { ..., ... } | Initializers.cs:51:10:51:13 | Test |
19601979
| Initializers.cs:62:29:62:40 | ... = ... | Initializers.cs:51:10:51:13 | Test |
1980+
| Initializers.cs:62:30:62:30 | 0 | Initializers.cs:51:10:51:13 | Test |
1981+
| Initializers.cs:62:33:62:33 | 1 | Initializers.cs:51:10:51:13 | Test |
19611982
| Initializers.cs:62:38:62:40 | "i" | Initializers.cs:51:10:51:13 | Test |
19621983
| Initializers.cs:62:43:62:58 | ... = ... | Initializers.cs:51:10:51:13 | Test |
1984+
| Initializers.cs:62:44:62:44 | 1 | Initializers.cs:51:10:51:13 | Test |
1985+
| Initializers.cs:62:47:62:47 | access to parameter i | Initializers.cs:51:10:51:13 | Test |
1986+
| Initializers.cs:62:47:62:51 | ... + ... | Initializers.cs:51:10:51:13 | Test |
1987+
| Initializers.cs:62:51:62:51 | 0 | Initializers.cs:51:10:51:13 | Test |
19631988
| Initializers.cs:62:56:62:58 | "1" | Initializers.cs:51:10:51:13 | Test |
19641989
| Initializers.cs:63:13:63:25 | access to property ArrayProperty | Initializers.cs:51:10:51:13 | Test |
19651990
| Initializers.cs:63:13:63:60 | ... = ... | Initializers.cs:51:10:51:13 | Test |
19661991
| Initializers.cs:63:29:63:60 | { ..., ... } | Initializers.cs:51:10:51:13 | Test |
19671992
| Initializers.cs:63:31:63:41 | ... = ... | Initializers.cs:51:10:51:13 | Test |
1993+
| Initializers.cs:63:32:63:32 | 1 | Initializers.cs:51:10:51:13 | Test |
19681994
| Initializers.cs:63:37:63:41 | "One" | Initializers.cs:51:10:51:13 | Test |
19691995
| Initializers.cs:63:44:63:58 | ... = ... | Initializers.cs:51:10:51:13 | Test |
1996+
| Initializers.cs:63:45:63:45 | access to parameter i | Initializers.cs:51:10:51:13 | Test |
1997+
| Initializers.cs:63:45:63:49 | ... + ... | Initializers.cs:51:10:51:13 | Test |
1998+
| Initializers.cs:63:49:63:49 | 2 | Initializers.cs:51:10:51:13 | Test |
19701999
| Initializers.cs:63:54:63:58 | "Two" | Initializers.cs:51:10:51:13 | Test |
19712000
| Initializers.cs:64:13:64:26 | access to property ArrayProperty2 | Initializers.cs:51:10:51:13 | Test |
19722001
| Initializers.cs:64:13:64:63 | ... = ... | Initializers.cs:51:10:51:13 | Test |
19732002
| Initializers.cs:64:30:64:63 | { ..., ... } | Initializers.cs:51:10:51:13 | Test |
19742003
| Initializers.cs:64:32:64:43 | ... = ... | Initializers.cs:51:10:51:13 | Test |
2004+
| Initializers.cs:64:33:64:33 | 0 | Initializers.cs:51:10:51:13 | Test |
2005+
| Initializers.cs:64:36:64:36 | 1 | Initializers.cs:51:10:51:13 | Test |
19752006
| Initializers.cs:64:41:64:43 | "i" | Initializers.cs:51:10:51:13 | Test |
19762007
| Initializers.cs:64:46:64:61 | ... = ... | Initializers.cs:51:10:51:13 | Test |
2008+
| Initializers.cs:64:47:64:47 | 1 | Initializers.cs:51:10:51:13 | Test |
2009+
| Initializers.cs:64:50:64:50 | access to parameter i | Initializers.cs:51:10:51:13 | Test |
2010+
| Initializers.cs:64:50:64:54 | ... + ... | Initializers.cs:51:10:51:13 | Test |
2011+
| Initializers.cs:64:54:64:54 | 0 | Initializers.cs:51:10:51:13 | Test |
19772012
| Initializers.cs:64:59:64:61 | "1" | Initializers.cs:51:10:51:13 | Test |
19782013
| LoopUnrolling.cs:7:10:7:11 | enter M1 | LoopUnrolling.cs:7:10:7:11 | M1 |
19792014
| LoopUnrolling.cs:7:10:7:11 | exit M1 | LoopUnrolling.cs:7:10:7:11 | M1 |

0 commit comments

Comments
 (0)