Skip to content

Commit 97d9985

Browse files
committed
C#: Add support for flow via object initializer for anonymous types.
1 parent 76a0853 commit 97d9985

File tree

3 files changed

+31
-1
lines changed

3 files changed

+31
-1
lines changed

csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowPrivate.qll

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1481,6 +1481,8 @@ class FieldOrProperty extends Assignable, Modifiable {
14811481
p.isAutoImplemented()
14821482
or
14831483
p.matchesHandle(any(CIL::TrivialProperty tp))
1484+
or
1485+
p.getDeclaringType() instanceof AnonymousClass
14841486
)
14851487
)
14861488
}

csharp/ql/test/library-tests/dataflow/fields/F.cs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ public class F
55

66
static F Create(object o1, object o2) => new F() { Field1 = o1, Field2 = o2 };
77

8-
private void M()
8+
private void M1()
99
{
1010
var o = Source<object>(1);
1111
var f = Create(o, null);
@@ -25,6 +25,15 @@ private void M()
2525
Sink(f.Field2); // $ hasValueFlow=4
2626
}
2727

28+
private void M2()
29+
{
30+
var o = Source<object>(2);
31+
object @null = null;
32+
var a = new { X = o, Y = @null };
33+
Sink(a.X); // $ hasValueFlow=2
34+
Sink(a.Y); // no flow
35+
}
36+
2837
public static void Sink(object o) { }
2938

3039
static T Source<T>(object source) => throw null;

csharp/ql/test/library-tests/dataflow/fields/FieldFlow.expected

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -456,6 +456,14 @@ edges
456456
| F.cs:23:32:23:48 | call to method Source<Object> : Object | F.cs:23:21:23:50 | { ..., ... } [field Field2] : Object |
457457
| F.cs:25:14:25:14 | access to local variable f [field Field2] : Object | F.cs:25:14:25:21 | access to field Field2 |
458458
| F.cs:25:14:25:14 | access to local variable f [field Field2] : Object | F.cs:25:14:25:21 | access to field Field2 |
459+
| F.cs:30:17:30:33 | call to method Source<Object> : Object | F.cs:32:27:32:27 | access to local variable o : Object |
460+
| F.cs:30:17:30:33 | call to method Source<Object> : Object | F.cs:32:27:32:27 | access to local variable o : Object |
461+
| F.cs:32:17:32:40 | { ..., ... } [property X] : Object | F.cs:33:14:33:14 | access to local variable a [property X] : Object |
462+
| F.cs:32:17:32:40 | { ..., ... } [property X] : Object | F.cs:33:14:33:14 | access to local variable a [property X] : Object |
463+
| F.cs:32:27:32:27 | access to local variable o : Object | F.cs:32:17:32:40 | { ..., ... } [property X] : Object |
464+
| F.cs:32:27:32:27 | access to local variable o : Object | F.cs:32:17:32:40 | { ..., ... } [property X] : Object |
465+
| F.cs:33:14:33:14 | access to local variable a [property X] : Object | F.cs:33:14:33:16 | access to property X |
466+
| F.cs:33:14:33:14 | access to local variable a [property X] : Object | F.cs:33:14:33:16 | access to property X |
459467
| G.cs:7:18:7:32 | call to method Source<Elem> : Elem | G.cs:9:23:9:23 | access to local variable e : Elem |
460468
| G.cs:7:18:7:32 | call to method Source<Elem> : Elem | G.cs:9:23:9:23 | access to local variable e : Elem |
461469
| G.cs:9:9:9:9 | [post] access to local variable b [field Box1, field Elem] : Elem | G.cs:10:18:10:18 | access to local variable b [field Box1, field Elem] : Elem |
@@ -1367,6 +1375,16 @@ nodes
13671375
| F.cs:25:14:25:14 | access to local variable f [field Field2] : Object | semmle.label | access to local variable f [field Field2] : Object |
13681376
| F.cs:25:14:25:21 | access to field Field2 | semmle.label | access to field Field2 |
13691377
| F.cs:25:14:25:21 | access to field Field2 | semmle.label | access to field Field2 |
1378+
| F.cs:30:17:30:33 | call to method Source<Object> : Object | semmle.label | call to method Source<Object> : Object |
1379+
| F.cs:30:17:30:33 | call to method Source<Object> : Object | semmle.label | call to method Source<Object> : Object |
1380+
| F.cs:32:17:32:40 | { ..., ... } [property X] : Object | semmle.label | { ..., ... } [property X] : Object |
1381+
| F.cs:32:17:32:40 | { ..., ... } [property X] : Object | semmle.label | { ..., ... } [property X] : Object |
1382+
| F.cs:32:27:32:27 | access to local variable o : Object | semmle.label | access to local variable o : Object |
1383+
| F.cs:32:27:32:27 | access to local variable o : Object | semmle.label | access to local variable o : Object |
1384+
| F.cs:33:14:33:14 | access to local variable a [property X] : Object | semmle.label | access to local variable a [property X] : Object |
1385+
| F.cs:33:14:33:14 | access to local variable a [property X] : Object | semmle.label | access to local variable a [property X] : Object |
1386+
| F.cs:33:14:33:16 | access to property X | semmle.label | access to property X |
1387+
| F.cs:33:14:33:16 | access to property X | semmle.label | access to property X |
13701388
| G.cs:7:18:7:32 | call to method Source<Elem> : Elem | semmle.label | call to method Source<Elem> : Elem |
13711389
| G.cs:7:18:7:32 | call to method Source<Elem> : Elem | semmle.label | call to method Source<Elem> : Elem |
13721390
| G.cs:9:9:9:9 | [post] access to local variable b [field Box1, field Elem] : Elem | semmle.label | [post] access to local variable b [field Box1, field Elem] : Elem |
@@ -1952,6 +1970,7 @@ subpaths
19521970
| F.cs:17:14:17:21 | access to field Field2 | F.cs:15:26:15:42 | call to method Source<Object> : Object | F.cs:17:14:17:21 | access to field Field2 | $@ | F.cs:15:26:15:42 | call to method Source<Object> : Object | call to method Source<Object> : Object |
19531971
| F.cs:20:14:20:21 | access to field Field1 | F.cs:19:32:19:48 | call to method Source<Object> : Object | F.cs:20:14:20:21 | access to field Field1 | $@ | F.cs:19:32:19:48 | call to method Source<Object> : Object | call to method Source<Object> : Object |
19541972
| F.cs:25:14:25:21 | access to field Field2 | F.cs:23:32:23:48 | call to method Source<Object> : Object | F.cs:25:14:25:21 | access to field Field2 | $@ | F.cs:23:32:23:48 | call to method Source<Object> : Object | call to method Source<Object> : Object |
1973+
| F.cs:33:14:33:16 | access to property X | F.cs:30:17:30:33 | call to method Source<Object> : Object | F.cs:33:14:33:16 | access to property X | $@ | F.cs:30:17:30:33 | call to method Source<Object> : Object | call to method Source<Object> : Object |
19551974
| G.cs:39:14:39:35 | call to method GetElem | G.cs:7:18:7:32 | call to method Source<Elem> : Elem | G.cs:39:14:39:35 | call to method GetElem | $@ | G.cs:7:18:7:32 | call to method Source<Elem> : Elem | call to method Source<Elem> : Elem |
19561975
| G.cs:39:14:39:35 | call to method GetElem | G.cs:15:18:15:32 | call to method Source<Elem> : Elem | G.cs:39:14:39:35 | call to method GetElem | $@ | G.cs:15:18:15:32 | call to method Source<Elem> : Elem | call to method Source<Elem> : Elem |
19571976
| G.cs:39:14:39:35 | call to method GetElem | G.cs:23:18:23:32 | call to method Source<Elem> : Elem | G.cs:39:14:39:35 | call to method GetElem | $@ | G.cs:23:18:23:32 | call to method Source<Elem> : Elem | call to method Source<Elem> : Elem |

0 commit comments

Comments
 (0)