Skip to content

Commit b2c22da

Browse files
authored
Merge pull request #9769 from tamasvajk/fix/ctor-field-flow
C#: Fix dataflow for default constructors
2 parents cbd6d24 + dd465e7 commit b2c22da

File tree

3 files changed

+103
-1
lines changed

3 files changed

+103
-1
lines changed

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

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,13 @@ private import semmle.code.csharp.frameworks.system.collections.Generic
2121
*/
2222
DotNet::Callable getCallableForDataFlow(DotNet::Callable c) {
2323
exists(DotNet::Callable unboundDecl | unboundDecl = c.getUnboundDeclaration() |
24-
result.hasBody() and
24+
(
25+
result.hasBody()
26+
or
27+
// take synthesized bodies into account, e.g. implicit constructors
28+
// with field initializer assignments
29+
result = any(ControlFlow::Nodes::ElementNode n).getEnclosingCallable()
30+
) and
2531
if unboundDecl.getFile().fromSource()
2632
then
2733
// C# callable with C# implementation in the database
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
public class C_no_ctor
2+
{
3+
private Elem s1 = Util.Source<Elem>(1);
4+
5+
void M1()
6+
{
7+
C_no_ctor c = new C_no_ctor();
8+
c.M2();
9+
}
10+
11+
public void M2()
12+
{
13+
Util.Sink(s1); // $ hasValueFlow=1
14+
}
15+
}
16+
17+
public class C_with_ctor
18+
{
19+
private Elem s1 = Util.Source<Elem>(1);
20+
21+
void M1()
22+
{
23+
C_with_ctor c = new C_with_ctor();
24+
c.M2();
25+
}
26+
27+
public C_with_ctor() { }
28+
29+
public void M2()
30+
{
31+
Util.Sink(s1); // $ hasValueFlow=1
32+
}
33+
}
34+
35+
class Util
36+
{
37+
public static void Sink(object o) { }
38+
39+
public static T Source<T>(object source) => throw null;
40+
}
41+
42+
public class Elem { }

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

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -308,6 +308,30 @@ edges
308308
| C.cs:25:14:25:15 | this access [field s3] : Elem | C.cs:25:14:25:15 | access to field s3 |
309309
| C.cs:27:14:27:15 | this access [property s5] : Elem | C.cs:27:14:27:15 | access to property s5 |
310310
| C.cs:27:14:27:15 | this access [property s5] : Elem | C.cs:27:14:27:15 | access to property s5 |
311+
| C_ctor.cs:3:18:3:19 | [post] this access [field s1] : Elem | C_ctor.cs:7:23:7:37 | object creation of type C_no_ctor [field s1] : Elem |
312+
| C_ctor.cs:3:18:3:19 | [post] this access [field s1] : Elem | C_ctor.cs:7:23:7:37 | object creation of type C_no_ctor [field s1] : Elem |
313+
| C_ctor.cs:3:23:3:42 | call to method Source<Elem> : Elem | C_ctor.cs:3:18:3:19 | [post] this access [field s1] : Elem |
314+
| C_ctor.cs:3:23:3:42 | call to method Source<Elem> : Elem | C_ctor.cs:3:18:3:19 | [post] this access [field s1] : Elem |
315+
| C_ctor.cs:7:23:7:37 | object creation of type C_no_ctor [field s1] : Elem | C_ctor.cs:8:9:8:9 | access to local variable c [field s1] : Elem |
316+
| C_ctor.cs:7:23:7:37 | object creation of type C_no_ctor [field s1] : Elem | C_ctor.cs:8:9:8:9 | access to local variable c [field s1] : Elem |
317+
| C_ctor.cs:8:9:8:9 | access to local variable c [field s1] : Elem | C_ctor.cs:11:17:11:18 | this [field s1] : Elem |
318+
| C_ctor.cs:8:9:8:9 | access to local variable c [field s1] : Elem | C_ctor.cs:11:17:11:18 | this [field s1] : Elem |
319+
| C_ctor.cs:11:17:11:18 | this [field s1] : Elem | C_ctor.cs:13:19:13:20 | this access [field s1] : Elem |
320+
| C_ctor.cs:11:17:11:18 | this [field s1] : Elem | C_ctor.cs:13:19:13:20 | this access [field s1] : Elem |
321+
| C_ctor.cs:13:19:13:20 | this access [field s1] : Elem | C_ctor.cs:13:19:13:20 | access to field s1 |
322+
| C_ctor.cs:13:19:13:20 | this access [field s1] : Elem | C_ctor.cs:13:19:13:20 | access to field s1 |
323+
| C_ctor.cs:19:18:19:19 | [post] this access [field s1] : Elem | C_ctor.cs:23:25:23:41 | object creation of type C_with_ctor [field s1] : Elem |
324+
| C_ctor.cs:19:18:19:19 | [post] this access [field s1] : Elem | C_ctor.cs:23:25:23:41 | object creation of type C_with_ctor [field s1] : Elem |
325+
| C_ctor.cs:19:23:19:42 | call to method Source<Elem> : Elem | C_ctor.cs:19:18:19:19 | [post] this access [field s1] : Elem |
326+
| C_ctor.cs:19:23:19:42 | call to method Source<Elem> : Elem | C_ctor.cs:19:18:19:19 | [post] this access [field s1] : Elem |
327+
| C_ctor.cs:23:25:23:41 | object creation of type C_with_ctor [field s1] : Elem | C_ctor.cs:24:9:24:9 | access to local variable c [field s1] : Elem |
328+
| C_ctor.cs:23:25:23:41 | object creation of type C_with_ctor [field s1] : Elem | C_ctor.cs:24:9:24:9 | access to local variable c [field s1] : Elem |
329+
| C_ctor.cs:24:9:24:9 | access to local variable c [field s1] : Elem | C_ctor.cs:29:17:29:18 | this [field s1] : Elem |
330+
| C_ctor.cs:24:9:24:9 | access to local variable c [field s1] : Elem | C_ctor.cs:29:17:29:18 | this [field s1] : Elem |
331+
| C_ctor.cs:29:17:29:18 | this [field s1] : Elem | C_ctor.cs:31:19:31:20 | this access [field s1] : Elem |
332+
| C_ctor.cs:29:17:29:18 | this [field s1] : Elem | C_ctor.cs:31:19:31:20 | this access [field s1] : Elem |
333+
| C_ctor.cs:31:19:31:20 | this access [field s1] : Elem | C_ctor.cs:31:19:31:20 | access to field s1 |
334+
| C_ctor.cs:31:19:31:20 | this access [field s1] : Elem | C_ctor.cs:31:19:31:20 | access to field s1 |
311335
| D.cs:8:9:8:11 | this [field trivialPropField] : Object | D.cs:8:22:8:25 | this access [field trivialPropField] : Object |
312336
| D.cs:8:9:8:11 | this [field trivialPropField] : Object | D.cs:8:22:8:25 | this access [field trivialPropField] : Object |
313337
| D.cs:8:22:8:25 | this access [field trivialPropField] : Object | D.cs:8:22:8:42 | access to field trivialPropField : Object |
@@ -1235,6 +1259,34 @@ nodes
12351259
| C.cs:27:14:27:15 | this access [property s5] : Elem | semmle.label | this access [property s5] : Elem |
12361260
| C.cs:28:14:28:15 | access to property s6 | semmle.label | access to property s6 |
12371261
| C.cs:28:14:28:15 | access to property s6 | semmle.label | access to property s6 |
1262+
| C_ctor.cs:3:18:3:19 | [post] this access [field s1] : Elem | semmle.label | [post] this access [field s1] : Elem |
1263+
| C_ctor.cs:3:18:3:19 | [post] this access [field s1] : Elem | semmle.label | [post] this access [field s1] : Elem |
1264+
| C_ctor.cs:3:23:3:42 | call to method Source<Elem> : Elem | semmle.label | call to method Source<Elem> : Elem |
1265+
| C_ctor.cs:3:23:3:42 | call to method Source<Elem> : Elem | semmle.label | call to method Source<Elem> : Elem |
1266+
| C_ctor.cs:7:23:7:37 | object creation of type C_no_ctor [field s1] : Elem | semmle.label | object creation of type C_no_ctor [field s1] : Elem |
1267+
| C_ctor.cs:7:23:7:37 | object creation of type C_no_ctor [field s1] : Elem | semmle.label | object creation of type C_no_ctor [field s1] : Elem |
1268+
| C_ctor.cs:8:9:8:9 | access to local variable c [field s1] : Elem | semmle.label | access to local variable c [field s1] : Elem |
1269+
| C_ctor.cs:8:9:8:9 | access to local variable c [field s1] : Elem | semmle.label | access to local variable c [field s1] : Elem |
1270+
| C_ctor.cs:11:17:11:18 | this [field s1] : Elem | semmle.label | this [field s1] : Elem |
1271+
| C_ctor.cs:11:17:11:18 | this [field s1] : Elem | semmle.label | this [field s1] : Elem |
1272+
| C_ctor.cs:13:19:13:20 | access to field s1 | semmle.label | access to field s1 |
1273+
| C_ctor.cs:13:19:13:20 | access to field s1 | semmle.label | access to field s1 |
1274+
| C_ctor.cs:13:19:13:20 | this access [field s1] : Elem | semmle.label | this access [field s1] : Elem |
1275+
| C_ctor.cs:13:19:13:20 | this access [field s1] : Elem | semmle.label | this access [field s1] : Elem |
1276+
| C_ctor.cs:19:18:19:19 | [post] this access [field s1] : Elem | semmle.label | [post] this access [field s1] : Elem |
1277+
| C_ctor.cs:19:18:19:19 | [post] this access [field s1] : Elem | semmle.label | [post] this access [field s1] : Elem |
1278+
| C_ctor.cs:19:23:19:42 | call to method Source<Elem> : Elem | semmle.label | call to method Source<Elem> : Elem |
1279+
| C_ctor.cs:19:23:19:42 | call to method Source<Elem> : Elem | semmle.label | call to method Source<Elem> : Elem |
1280+
| C_ctor.cs:23:25:23:41 | object creation of type C_with_ctor [field s1] : Elem | semmle.label | object creation of type C_with_ctor [field s1] : Elem |
1281+
| C_ctor.cs:23:25:23:41 | object creation of type C_with_ctor [field s1] : Elem | semmle.label | object creation of type C_with_ctor [field s1] : Elem |
1282+
| C_ctor.cs:24:9:24:9 | access to local variable c [field s1] : Elem | semmle.label | access to local variable c [field s1] : Elem |
1283+
| C_ctor.cs:24:9:24:9 | access to local variable c [field s1] : Elem | semmle.label | access to local variable c [field s1] : Elem |
1284+
| C_ctor.cs:29:17:29:18 | this [field s1] : Elem | semmle.label | this [field s1] : Elem |
1285+
| C_ctor.cs:29:17:29:18 | this [field s1] : Elem | semmle.label | this [field s1] : Elem |
1286+
| C_ctor.cs:31:19:31:20 | access to field s1 | semmle.label | access to field s1 |
1287+
| C_ctor.cs:31:19:31:20 | access to field s1 | semmle.label | access to field s1 |
1288+
| C_ctor.cs:31:19:31:20 | this access [field s1] : Elem | semmle.label | this access [field s1] : Elem |
1289+
| C_ctor.cs:31:19:31:20 | this access [field s1] : Elem | semmle.label | this access [field s1] : Elem |
12381290
| D.cs:8:9:8:11 | this [field trivialPropField] : Object | semmle.label | this [field trivialPropField] : Object |
12391291
| D.cs:8:9:8:11 | this [field trivialPropField] : Object | semmle.label | this [field trivialPropField] : Object |
12401292
| D.cs:8:22:8:25 | this access [field trivialPropField] : Object | semmle.label | this access [field trivialPropField] : Object |
@@ -1998,6 +2050,8 @@ subpaths
19982050
| C.cs:26:14:26:15 | access to field s4 | C.cs:6:30:6:44 | call to method Source<Elem> : Elem | C.cs:26:14:26:15 | access to field s4 | $@ | C.cs:6:30:6:44 | call to method Source<Elem> : Elem | call to method Source<Elem> : Elem |
19992051
| C.cs:27:14:27:15 | access to property s5 | C.cs:7:37:7:51 | call to method Source<Elem> : Elem | C.cs:27:14:27:15 | access to property s5 | $@ | C.cs:7:37:7:51 | call to method Source<Elem> : Elem | call to method Source<Elem> : Elem |
20002052
| C.cs:28:14:28:15 | access to property s6 | C.cs:8:30:8:44 | call to method Source<Elem> : Elem | C.cs:28:14:28:15 | access to property s6 | $@ | C.cs:8:30:8:44 | call to method Source<Elem> : Elem | call to method Source<Elem> : Elem |
2053+
| C_ctor.cs:13:19:13:20 | access to field s1 | C_ctor.cs:3:23:3:42 | call to method Source<Elem> : Elem | C_ctor.cs:13:19:13:20 | access to field s1 | $@ | C_ctor.cs:3:23:3:42 | call to method Source<Elem> : Elem | call to method Source<Elem> : Elem |
2054+
| C_ctor.cs:31:19:31:20 | access to field s1 | C_ctor.cs:19:23:19:42 | call to method Source<Elem> : Elem | C_ctor.cs:31:19:31:20 | access to field s1 | $@ | C_ctor.cs:19:23:19:42 | call to method Source<Elem> : Elem | call to method Source<Elem> : Elem |
20012055
| D.cs:32:14:32:23 | access to property AutoProp | D.cs:29:17:29:33 | call to method Source<Object> : Object | D.cs:32:14:32:23 | access to property AutoProp | $@ | D.cs:29:17:29:33 | call to method Source<Object> : Object | call to method Source<Object> : Object |
20022056
| D.cs:39:14:39:26 | access to property TrivialProp | D.cs:37:26:37:42 | call to method Source<Object> : Object | D.cs:39:14:39:26 | access to property TrivialProp | $@ | D.cs:37:26:37:42 | call to method Source<Object> : Object | call to method Source<Object> : Object |
20032057
| D.cs:40:14:40:31 | access to field trivialPropField | D.cs:37:26:37:42 | call to method Source<Object> : Object | D.cs:40:14:40:31 | access to field trivialPropField | $@ | D.cs:37:26:37:42 | call to method Source<Object> : Object | call to method Source<Object> : Object |

0 commit comments

Comments
 (0)