Merge pull request #18195 from MathiasVP/dynamic-property-field-flow

C#: Add field-flow for dynamic fields
This commit is contained in:
Mathias Vorreiter Pedersen
2024-12-04 10:09:20 +00:00
committed by GitHub
5 changed files with 278 additions and 1 deletions

View File

@@ -1162,6 +1162,54 @@ edges
| K.cs:8:22:8:22 | access to local variable o : String | K.cs:8:9:8:15 | [post] access to field Strings : String[] [element] : String | provenance | |
| K.cs:13:14:13:20 | access to field Strings : String[] [element] : String | K.cs:13:14:13:23 | access to array element | provenance | |
| K.cs:13:14:13:20 | access to field Strings : String[] [element] : String | K.cs:13:14:13:23 | access to array element | provenance | |
| L.cs:17:9:17:10 | [post] access to local variable d1 : Object [dynamic property p1] : String | L.cs:18:14:18:15 | access to local variable d1 : Object [dynamic property p1] : String | provenance | |
| L.cs:17:9:17:10 | [post] access to local variable d1 : Object [dynamic property p1] : String | L.cs:18:14:18:15 | access to local variable d1 : Object [dynamic property p1] : String | provenance | |
| L.cs:17:17:17:33 | call to method Source<String> : String | L.cs:17:9:17:10 | [post] access to local variable d1 : Object [dynamic property p1] : String | provenance | |
| L.cs:17:17:17:33 | call to method Source<String> : String | L.cs:17:9:17:10 | [post] access to local variable d1 : Object [dynamic property p1] : String | provenance | |
| L.cs:18:14:18:15 | access to local variable d1 : Object [dynamic property p1] : String | L.cs:18:14:18:18 | dynamic access to member p1 | provenance | |
| L.cs:18:14:18:15 | access to local variable d1 : Object [dynamic property p1] : String | L.cs:18:14:18:18 | dynamic access to member p1 | provenance | |
| L.cs:22:9:22:10 | [post] access to local variable d2 : Object [dynamic property p2] : String | L.cs:23:16:23:17 | (...) ... : L [dynamic property p2] : String | provenance | |
| L.cs:22:9:22:10 | [post] access to local variable d2 : Object [dynamic property p2] : String | L.cs:23:16:23:17 | (...) ... : L [dynamic property p2] : String | provenance | |
| L.cs:22:17:22:33 | call to method Source<String> : String | L.cs:22:9:22:10 | [post] access to local variable d2 : Object [dynamic property p2] : String | provenance | |
| L.cs:22:17:22:33 | call to method Source<String> : String | L.cs:22:9:22:10 | [post] access to local variable d2 : Object [dynamic property p2] : String | provenance | |
| L.cs:23:11:23:12 | access to local variable l2 : L [dynamic property p2] : String | L.cs:24:14:24:15 | access to local variable l2 : L [dynamic property p2] : String | provenance | |
| L.cs:23:11:23:12 | access to local variable l2 : L [dynamic property p2] : String | L.cs:24:14:24:15 | access to local variable l2 : L [dynamic property p2] : String | provenance | |
| L.cs:23:16:23:17 | (...) ... : L [dynamic property p2] : String | L.cs:23:11:23:12 | access to local variable l2 : L [dynamic property p2] : String | provenance | |
| L.cs:23:16:23:17 | (...) ... : L [dynamic property p2] : String | L.cs:23:11:23:12 | access to local variable l2 : L [dynamic property p2] : String | provenance | |
| L.cs:24:14:24:15 | access to local variable l2 : L [dynamic property p2] : String | L.cs:24:14:24:18 | access to property p2 | provenance | |
| L.cs:24:14:24:15 | access to local variable l2 : L [dynamic property p2] : String | L.cs:24:14:24:18 | access to property p2 | provenance | |
| L.cs:27:9:27:12 | [post] this access : L [property p3] : String | L.cs:28:17:28:18 | access to local variable d3 : L [property p3] : String | provenance | |
| L.cs:27:9:27:12 | [post] this access : L [property p3] : String | L.cs:28:17:28:18 | access to local variable d3 : L [property p3] : String | provenance | |
| L.cs:27:19:27:35 | call to method Source<String> : String | L.cs:27:9:27:12 | [post] this access : L [property p3] : String | provenance | |
| L.cs:27:19:27:35 | call to method Source<String> : String | L.cs:27:9:27:12 | [post] this access : L [property p3] : String | provenance | |
| L.cs:28:17:28:18 | access to local variable d3 : L [property p3] : String | L.cs:29:14:29:15 | access to local variable d3 : L [property p3] : String | provenance | |
| L.cs:28:17:28:18 | access to local variable d3 : L [property p3] : String | L.cs:29:14:29:15 | access to local variable d3 : L [property p3] : String | provenance | |
| L.cs:29:14:29:15 | access to local variable d3 : L [property p3] : String | L.cs:29:14:29:18 | dynamic access to member p3 | provenance | |
| L.cs:29:14:29:15 | access to local variable d3 : L [property p3] : String | L.cs:29:14:29:18 | dynamic access to member p3 | provenance | |
| L.cs:33:9:33:10 | [post] access to local variable d4 : Object [dynamic property f1] : String | L.cs:34:14:34:15 | access to local variable d4 : Object [dynamic property f1] : String | provenance | |
| L.cs:33:9:33:10 | [post] access to local variable d4 : Object [dynamic property f1] : String | L.cs:34:14:34:15 | access to local variable d4 : Object [dynamic property f1] : String | provenance | |
| L.cs:33:17:33:33 | call to method Source<String> : String | L.cs:33:9:33:10 | [post] access to local variable d4 : Object [dynamic property f1] : String | provenance | |
| L.cs:33:17:33:33 | call to method Source<String> : String | L.cs:33:9:33:10 | [post] access to local variable d4 : Object [dynamic property f1] : String | provenance | |
| L.cs:34:14:34:15 | access to local variable d4 : Object [dynamic property f1] : String | L.cs:34:14:34:18 | dynamic access to member f1 | provenance | |
| L.cs:34:14:34:15 | access to local variable d4 : Object [dynamic property f1] : String | L.cs:34:14:34:18 | dynamic access to member f1 | provenance | |
| L.cs:38:9:38:10 | [post] access to local variable d5 : Object [dynamic property f2] : String | L.cs:39:16:39:17 | (...) ... : L [dynamic property f2] : String | provenance | |
| L.cs:38:9:38:10 | [post] access to local variable d5 : Object [dynamic property f2] : String | L.cs:39:16:39:17 | (...) ... : L [dynamic property f2] : String | provenance | |
| L.cs:38:17:38:33 | call to method Source<String> : String | L.cs:38:9:38:10 | [post] access to local variable d5 : Object [dynamic property f2] : String | provenance | |
| L.cs:38:17:38:33 | call to method Source<String> : String | L.cs:38:9:38:10 | [post] access to local variable d5 : Object [dynamic property f2] : String | provenance | |
| L.cs:39:11:39:12 | access to local variable l5 : L [dynamic property f2] : String | L.cs:40:14:40:15 | access to local variable l5 : L [dynamic property f2] : String | provenance | |
| L.cs:39:11:39:12 | access to local variable l5 : L [dynamic property f2] : String | L.cs:40:14:40:15 | access to local variable l5 : L [dynamic property f2] : String | provenance | |
| L.cs:39:16:39:17 | (...) ... : L [dynamic property f2] : String | L.cs:39:11:39:12 | access to local variable l5 : L [dynamic property f2] : String | provenance | |
| L.cs:39:16:39:17 | (...) ... : L [dynamic property f2] : String | L.cs:39:11:39:12 | access to local variable l5 : L [dynamic property f2] : String | provenance | |
| L.cs:40:14:40:15 | access to local variable l5 : L [dynamic property f2] : String | L.cs:40:14:40:18 | access to field f2 | provenance | |
| L.cs:40:14:40:15 | access to local variable l5 : L [dynamic property f2] : String | L.cs:40:14:40:18 | access to field f2 | provenance | |
| L.cs:43:9:43:12 | [post] this access : L [field f3] : String | L.cs:44:17:44:18 | access to local variable d6 : L [field f3] : String | provenance | |
| L.cs:43:9:43:12 | [post] this access : L [field f3] : String | L.cs:44:17:44:18 | access to local variable d6 : L [field f3] : String | provenance | |
| L.cs:43:19:43:35 | call to method Source<String> : String | L.cs:43:9:43:12 | [post] this access : L [field f3] : String | provenance | |
| L.cs:43:19:43:35 | call to method Source<String> : String | L.cs:43:9:43:12 | [post] this access : L [field f3] : String | provenance | |
| L.cs:44:17:44:18 | access to local variable d6 : L [field f3] : String | L.cs:45:14:45:15 | access to local variable d6 : L [field f3] : String | provenance | |
| L.cs:44:17:44:18 | access to local variable d6 : L [field f3] : String | L.cs:45:14:45:15 | access to local variable d6 : L [field f3] : String | provenance | |
| L.cs:45:14:45:15 | access to local variable d6 : L [field f3] : String | L.cs:45:14:45:18 | dynamic access to member f3 | provenance | |
| L.cs:45:14:45:15 | access to local variable d6 : L [field f3] : String | L.cs:45:14:45:18 | dynamic access to member f3 | provenance | |
nodes
| A.cs:5:13:5:13 | access to local variable c : C | semmle.label | access to local variable c : C |
| A.cs:5:13:5:13 | access to local variable c : C | semmle.label | access to local variable c : C |
@@ -2415,6 +2463,66 @@ nodes
| K.cs:13:14:13:20 | access to field Strings : String[] [element] : String | semmle.label | access to field Strings : String[] [element] : String |
| K.cs:13:14:13:23 | access to array element | semmle.label | access to array element |
| K.cs:13:14:13:23 | access to array element | semmle.label | access to array element |
| L.cs:17:9:17:10 | [post] access to local variable d1 : Object [dynamic property p1] : String | semmle.label | [post] access to local variable d1 : Object [dynamic property p1] : String |
| L.cs:17:9:17:10 | [post] access to local variable d1 : Object [dynamic property p1] : String | semmle.label | [post] access to local variable d1 : Object [dynamic property p1] : String |
| L.cs:17:17:17:33 | call to method Source<String> : String | semmle.label | call to method Source<String> : String |
| L.cs:17:17:17:33 | call to method Source<String> : String | semmle.label | call to method Source<String> : String |
| L.cs:18:14:18:15 | access to local variable d1 : Object [dynamic property p1] : String | semmle.label | access to local variable d1 : Object [dynamic property p1] : String |
| L.cs:18:14:18:15 | access to local variable d1 : Object [dynamic property p1] : String | semmle.label | access to local variable d1 : Object [dynamic property p1] : String |
| L.cs:18:14:18:18 | dynamic access to member p1 | semmle.label | dynamic access to member p1 |
| L.cs:18:14:18:18 | dynamic access to member p1 | semmle.label | dynamic access to member p1 |
| L.cs:22:9:22:10 | [post] access to local variable d2 : Object [dynamic property p2] : String | semmle.label | [post] access to local variable d2 : Object [dynamic property p2] : String |
| L.cs:22:9:22:10 | [post] access to local variable d2 : Object [dynamic property p2] : String | semmle.label | [post] access to local variable d2 : Object [dynamic property p2] : String |
| L.cs:22:17:22:33 | call to method Source<String> : String | semmle.label | call to method Source<String> : String |
| L.cs:22:17:22:33 | call to method Source<String> : String | semmle.label | call to method Source<String> : String |
| L.cs:23:11:23:12 | access to local variable l2 : L [dynamic property p2] : String | semmle.label | access to local variable l2 : L [dynamic property p2] : String |
| L.cs:23:11:23:12 | access to local variable l2 : L [dynamic property p2] : String | semmle.label | access to local variable l2 : L [dynamic property p2] : String |
| L.cs:23:16:23:17 | (...) ... : L [dynamic property p2] : String | semmle.label | (...) ... : L [dynamic property p2] : String |
| L.cs:23:16:23:17 | (...) ... : L [dynamic property p2] : String | semmle.label | (...) ... : L [dynamic property p2] : String |
| L.cs:24:14:24:15 | access to local variable l2 : L [dynamic property p2] : String | semmle.label | access to local variable l2 : L [dynamic property p2] : String |
| L.cs:24:14:24:15 | access to local variable l2 : L [dynamic property p2] : String | semmle.label | access to local variable l2 : L [dynamic property p2] : String |
| L.cs:24:14:24:18 | access to property p2 | semmle.label | access to property p2 |
| L.cs:24:14:24:18 | access to property p2 | semmle.label | access to property p2 |
| L.cs:27:9:27:12 | [post] this access : L [property p3] : String | semmle.label | [post] this access : L [property p3] : String |
| L.cs:27:9:27:12 | [post] this access : L [property p3] : String | semmle.label | [post] this access : L [property p3] : String |
| L.cs:27:19:27:35 | call to method Source<String> : String | semmle.label | call to method Source<String> : String |
| L.cs:27:19:27:35 | call to method Source<String> : String | semmle.label | call to method Source<String> : String |
| L.cs:28:17:28:18 | access to local variable d3 : L [property p3] : String | semmle.label | access to local variable d3 : L [property p3] : String |
| L.cs:28:17:28:18 | access to local variable d3 : L [property p3] : String | semmle.label | access to local variable d3 : L [property p3] : String |
| L.cs:29:14:29:15 | access to local variable d3 : L [property p3] : String | semmle.label | access to local variable d3 : L [property p3] : String |
| L.cs:29:14:29:15 | access to local variable d3 : L [property p3] : String | semmle.label | access to local variable d3 : L [property p3] : String |
| L.cs:29:14:29:18 | dynamic access to member p3 | semmle.label | dynamic access to member p3 |
| L.cs:29:14:29:18 | dynamic access to member p3 | semmle.label | dynamic access to member p3 |
| L.cs:33:9:33:10 | [post] access to local variable d4 : Object [dynamic property f1] : String | semmle.label | [post] access to local variable d4 : Object [dynamic property f1] : String |
| L.cs:33:9:33:10 | [post] access to local variable d4 : Object [dynamic property f1] : String | semmle.label | [post] access to local variable d4 : Object [dynamic property f1] : String |
| L.cs:33:17:33:33 | call to method Source<String> : String | semmle.label | call to method Source<String> : String |
| L.cs:33:17:33:33 | call to method Source<String> : String | semmle.label | call to method Source<String> : String |
| L.cs:34:14:34:15 | access to local variable d4 : Object [dynamic property f1] : String | semmle.label | access to local variable d4 : Object [dynamic property f1] : String |
| L.cs:34:14:34:15 | access to local variable d4 : Object [dynamic property f1] : String | semmle.label | access to local variable d4 : Object [dynamic property f1] : String |
| L.cs:34:14:34:18 | dynamic access to member f1 | semmle.label | dynamic access to member f1 |
| L.cs:34:14:34:18 | dynamic access to member f1 | semmle.label | dynamic access to member f1 |
| L.cs:38:9:38:10 | [post] access to local variable d5 : Object [dynamic property f2] : String | semmle.label | [post] access to local variable d5 : Object [dynamic property f2] : String |
| L.cs:38:9:38:10 | [post] access to local variable d5 : Object [dynamic property f2] : String | semmle.label | [post] access to local variable d5 : Object [dynamic property f2] : String |
| L.cs:38:17:38:33 | call to method Source<String> : String | semmle.label | call to method Source<String> : String |
| L.cs:38:17:38:33 | call to method Source<String> : String | semmle.label | call to method Source<String> : String |
| L.cs:39:11:39:12 | access to local variable l5 : L [dynamic property f2] : String | semmle.label | access to local variable l5 : L [dynamic property f2] : String |
| L.cs:39:11:39:12 | access to local variable l5 : L [dynamic property f2] : String | semmle.label | access to local variable l5 : L [dynamic property f2] : String |
| L.cs:39:16:39:17 | (...) ... : L [dynamic property f2] : String | semmle.label | (...) ... : L [dynamic property f2] : String |
| L.cs:39:16:39:17 | (...) ... : L [dynamic property f2] : String | semmle.label | (...) ... : L [dynamic property f2] : String |
| L.cs:40:14:40:15 | access to local variable l5 : L [dynamic property f2] : String | semmle.label | access to local variable l5 : L [dynamic property f2] : String |
| L.cs:40:14:40:15 | access to local variable l5 : L [dynamic property f2] : String | semmle.label | access to local variable l5 : L [dynamic property f2] : String |
| L.cs:40:14:40:18 | access to field f2 | semmle.label | access to field f2 |
| L.cs:40:14:40:18 | access to field f2 | semmle.label | access to field f2 |
| L.cs:43:9:43:12 | [post] this access : L [field f3] : String | semmle.label | [post] this access : L [field f3] : String |
| L.cs:43:9:43:12 | [post] this access : L [field f3] : String | semmle.label | [post] this access : L [field f3] : String |
| L.cs:43:19:43:35 | call to method Source<String> : String | semmle.label | call to method Source<String> : String |
| L.cs:43:19:43:35 | call to method Source<String> : String | semmle.label | call to method Source<String> : String |
| L.cs:44:17:44:18 | access to local variable d6 : L [field f3] : String | semmle.label | access to local variable d6 : L [field f3] : String |
| L.cs:44:17:44:18 | access to local variable d6 : L [field f3] : String | semmle.label | access to local variable d6 : L [field f3] : String |
| L.cs:45:14:45:15 | access to local variable d6 : L [field f3] : String | semmle.label | access to local variable d6 : L [field f3] : String |
| L.cs:45:14:45:15 | access to local variable d6 : L [field f3] : String | semmle.label | access to local variable d6 : L [field f3] : String |
| L.cs:45:14:45:18 | dynamic access to member f3 | semmle.label | dynamic access to member f3 |
| L.cs:45:14:45:18 | dynamic access to member f3 | semmle.label | dynamic access to member f3 |
subpaths
| A.cs:6:24:6:24 | access to local variable c : C | A.cs:147:32:147:32 | c : C | A.cs:149:20:149:27 | object creation of type B : B [field c] : C | A.cs:6:17:6:25 | call to method Make : B [field c] : C |
| A.cs:6:24:6:24 | access to local variable c : C | A.cs:147:32:147:32 | c : C | A.cs:149:20:149:27 | object creation of type B : B [field c] : C | A.cs:6:17:6:25 | call to method Make : B [field c] : C |
@@ -2672,3 +2780,15 @@ testFailures
| J.cs:125:14:125:17 | (...) ... | J.cs:119:20:119:34 | call to method Source<Int32> : Int32 | J.cs:125:14:125:17 | (...) ... | $@ | J.cs:119:20:119:34 | call to method Source<Int32> : Int32 | call to method Source<Int32> : Int32 |
| K.cs:13:14:13:23 | access to array element | K.cs:7:17:7:33 | call to method Source<String> : String | K.cs:13:14:13:23 | access to array element | $@ | K.cs:7:17:7:33 | call to method Source<String> : String | call to method Source<String> : String |
| K.cs:13:14:13:23 | access to array element | K.cs:7:17:7:33 | call to method Source<String> : String | K.cs:13:14:13:23 | access to array element | $@ | K.cs:7:17:7:33 | call to method Source<String> : String | call to method Source<String> : String |
| L.cs:18:14:18:18 | dynamic access to member p1 | L.cs:17:17:17:33 | call to method Source<String> : String | L.cs:18:14:18:18 | dynamic access to member p1 | $@ | L.cs:17:17:17:33 | call to method Source<String> : String | call to method Source<String> : String |
| L.cs:18:14:18:18 | dynamic access to member p1 | L.cs:17:17:17:33 | call to method Source<String> : String | L.cs:18:14:18:18 | dynamic access to member p1 | $@ | L.cs:17:17:17:33 | call to method Source<String> : String | call to method Source<String> : String |
| L.cs:24:14:24:18 | access to property p2 | L.cs:22:17:22:33 | call to method Source<String> : String | L.cs:24:14:24:18 | access to property p2 | $@ | L.cs:22:17:22:33 | call to method Source<String> : String | call to method Source<String> : String |
| L.cs:24:14:24:18 | access to property p2 | L.cs:22:17:22:33 | call to method Source<String> : String | L.cs:24:14:24:18 | access to property p2 | $@ | L.cs:22:17:22:33 | call to method Source<String> : String | call to method Source<String> : String |
| L.cs:29:14:29:18 | dynamic access to member p3 | L.cs:27:19:27:35 | call to method Source<String> : String | L.cs:29:14:29:18 | dynamic access to member p3 | $@ | L.cs:27:19:27:35 | call to method Source<String> : String | call to method Source<String> : String |
| L.cs:29:14:29:18 | dynamic access to member p3 | L.cs:27:19:27:35 | call to method Source<String> : String | L.cs:29:14:29:18 | dynamic access to member p3 | $@ | L.cs:27:19:27:35 | call to method Source<String> : String | call to method Source<String> : String |
| L.cs:34:14:34:18 | dynamic access to member f1 | L.cs:33:17:33:33 | call to method Source<String> : String | L.cs:34:14:34:18 | dynamic access to member f1 | $@ | L.cs:33:17:33:33 | call to method Source<String> : String | call to method Source<String> : String |
| L.cs:34:14:34:18 | dynamic access to member f1 | L.cs:33:17:33:33 | call to method Source<String> : String | L.cs:34:14:34:18 | dynamic access to member f1 | $@ | L.cs:33:17:33:33 | call to method Source<String> : String | call to method Source<String> : String |
| L.cs:40:14:40:18 | access to field f2 | L.cs:38:17:38:33 | call to method Source<String> : String | L.cs:40:14:40:18 | access to field f2 | $@ | L.cs:38:17:38:33 | call to method Source<String> : String | call to method Source<String> : String |
| L.cs:40:14:40:18 | access to field f2 | L.cs:38:17:38:33 | call to method Source<String> : String | L.cs:40:14:40:18 | access to field f2 | $@ | L.cs:38:17:38:33 | call to method Source<String> : String | call to method Source<String> : String |
| L.cs:45:14:45:18 | dynamic access to member f3 | L.cs:43:19:43:35 | call to method Source<String> : String | L.cs:45:14:45:18 | dynamic access to member f3 | $@ | L.cs:43:19:43:35 | call to method Source<String> : String | call to method Source<String> : String |
| L.cs:45:14:45:18 | dynamic access to member f3 | L.cs:43:19:43:35 | call to method Source<String> : String | L.cs:45:14:45:18 | dynamic access to member f3 | $@ | L.cs:43:19:43:35 | call to method Source<String> : String | call to method Source<String> : String |

View File

@@ -0,0 +1,51 @@
using System;
public class L
{
public string p1 { get; set; }
public string p2 { get; set; }
public string p3 { get; set; }
private string f1;
private string f2;
private string f3;
private void M1()
{
// dynamic property write followed by dynamic property read
dynamic d1 = this;
d1.p1 = Source<string>(1);
Sink(d1.p1); // $ hasValueFlow=1
// dynamic property write followed by static property read
dynamic d2 = this;
d2.p2 = Source<string>(2);
L l2 = d2;
Sink(l2.p2); // $ hasValueFlow=2
// static property write followed by dynamic property read
this.p3 = Source<string>(3);
dynamic d3 = this;
Sink(d3.p3); // $ hasValueFlow=3
// dynamic property write followed by dynamic field read
dynamic d4 = this;
d4.f1 = Source<string>(4);
Sink(d4.f1); // $ hasValueFlow=4
// dynamic property write followed by static field read
dynamic d5 = this;
d5.f2 = Source<string>(5);
L l5 = d5;
Sink(l5.f2); // $ hasValueFlow=5
// static field write followed by dynamic property read
this.f3 = Source<string>(6);
dynamic d6 = this;
Sink(d6.f3); // $ hasValueFlow=6
}
public static void Sink(object o) { }
static T Source<T>(object source) => throw null;
}