Merge pull request #4543 from tamasvajk/feature/configureawait

C#: Add flow summary for 'Task.ConfigureAwait()'
This commit is contained in:
Tamás Vajk
2020-10-28 10:42:44 +01:00
committed by GitHub
10 changed files with 161 additions and 1 deletions

View File

@@ -1904,6 +1904,53 @@ class SystemThreadingTasksTaskTFlow extends LibraryTypeDataFlow, SystemThreading
sinkAp =
AccessPath::field(any(SystemRuntimeCompilerServicesTaskAwaiterStruct s)
.getUnderlyingTaskField())
or
// var awaitable = task.ConfigureAwait(false); // <-- new ConfiguredTaskAwaitable<>(task, false)
// // m_configuredTaskAwaiter = new ConfiguredTaskAwaiter(task, false)
// // m_task = task
// var awaiter = awaitable.GetAwaiter();
// var result = awaiter.GetResult();
m = this.getConfigureAwaitMethod() and
source = TCallableFlowSourceQualifier() and
sourceAp = AccessPath::empty() and
sink = TCallableFlowSinkReturn() and
sinkAp =
AccessPath::cons(any(FieldContent fc |
fc.getField() =
any(SystemRuntimeCompilerServicesConfiguredTaskAwaitableTStruct t)
.getUnderlyingAwaiterField()
),
AccessPath::field(any(SystemRuntimeCompilerServicesConfiguredTaskAwaitableTConfiguredTaskAwaiterStruct s
).getUnderlyingTaskField()))
}
override predicate requiresAccessPath(Content head, AccessPath tail) {
head.(FieldContent).getField() =
any(SystemRuntimeCompilerServicesConfiguredTaskAwaitableTStruct t).getUnderlyingAwaiterField() and
tail =
AccessPath::field(any(SystemRuntimeCompilerServicesConfiguredTaskAwaitableTConfiguredTaskAwaiterStruct s
).getUnderlyingTaskField())
}
}
/** Data flow for `System.Runtime.CompilerServices.ConfiguredTaskAwaitable<>`. */
private class SystemRuntimeCompilerServicesConfiguredTaskAwaitableTFlow extends LibraryTypeDataFlow,
SystemRuntimeCompilerServicesConfiguredTaskAwaitableTStruct {
override predicate callableFlow(
CallableFlowSource source, AccessPath sourceAp, CallableFlowSink sink, AccessPath sinkAp,
SourceDeclarationCallable c, boolean preservesValue
) {
// var awaitable = task.ConfigureAwait(false);
// var awaiter = awaitable.GetAwaiter(); // <-- awaitable.m_configuredTaskAwaiter
// var result = awaiter.GetResult();
c = this.getGetAwaiterMethod() and
source = TCallableFlowSourceQualifier() and
sourceAp =
AccessPath::field(any(SystemRuntimeCompilerServicesConfiguredTaskAwaitableTStruct s)
.getUnderlyingAwaiterField()) and
sink = TCallableFlowSinkReturn() and
sinkAp = AccessPath::empty() and
preservesValue = true
}
}
@@ -2011,6 +2058,32 @@ class SystemRuntimeCompilerServicesTaskAwaiterFlow extends LibraryTypeDataFlow,
}
}
/** Data flow for `System.Runtime.CompilerServices.ConfiguredTaskAwaitable<>.ConfiguredTaskAwaiter`. */
class SystemRuntimeCompilerServicesConfiguredTaskAwaitableTConfiguredTaskAwaiterFlow extends LibraryTypeDataFlow,
SystemRuntimeCompilerServicesConfiguredTaskAwaitableTConfiguredTaskAwaiterStruct {
override predicate callableFlow(
CallableFlowSource source, AccessPath sourceAp, CallableFlowSink sink, AccessPath sinkAp,
SourceDeclarationCallable c, boolean preservesValue
) {
// var awaitable = task.ConfigureAwait(false);
// var awaiter = awaitable.GetAwaiter();
// var result = awaiter.GetResult(); // <-- task.Result
preservesValue = true and
c = this.getGetResultMethod() and
source = TCallableFlowSourceQualifier() and
sourceAp =
AccessPath::cons(any(FieldContent fc | fc.getField() = this.getUnderlyingTaskField()),
AccessPath::property(any(SystemThreadingTasksTaskTClass t).getResultProperty())) and
sink = TCallableFlowSinkReturn() and
sinkAp = AccessPath::empty()
}
override predicate requiresAccessPath(Content head, AccessPath tail) {
head.(FieldContent).getField() = this.getUnderlyingTaskField() and
tail = AccessPath::property(any(SystemThreadingTasksTaskTClass t).getResultProperty())
}
}
/** Data flow for `System.Text.Encoding`. */
library class SystemTextEncodingFlow extends LibraryTypeDataFlow, SystemTextEncodingClass {
override predicate callableFlow(

View File

@@ -28,3 +28,32 @@ class SystemRuntimeCompilerServicesTaskAwaiterStruct extends SystemRuntimeCompil
/** Gets the field that stores the underlying task. */
Field getUnderlyingTaskField() { result = this.getAField() and result.hasName("m_task") }
}
/** The `System.Runtime.CompilerServices.ConfiguredTaskAwaitable<>` struct. */
class SystemRuntimeCompilerServicesConfiguredTaskAwaitableTStruct extends SystemRuntimeCompilerServicesNamespaceUnboundGenericStruct {
SystemRuntimeCompilerServicesConfiguredTaskAwaitableTStruct() {
this.hasName("ConfiguredTaskAwaitable<>")
}
/** Gets the `GetAwaiter` method. */
Method getGetAwaiterMethod() { result = this.getAMethod("GetAwaiter") }
/** Gets the field that stores the underlying awaiter. */
Field getUnderlyingAwaiterField() {
result = this.getAField() and result.hasName("m_configuredTaskAwaiter")
}
}
/** The `System.Runtime.CompilerServices.ConfiguredTaskAwaitable<>.ConfiguredTaskAwaiter` struct. */
class SystemRuntimeCompilerServicesConfiguredTaskAwaitableTConfiguredTaskAwaiterStruct extends Struct {
SystemRuntimeCompilerServicesConfiguredTaskAwaitableTConfiguredTaskAwaiterStruct() {
this = any(SystemRuntimeCompilerServicesConfiguredTaskAwaitableTStruct n).getANestedType() and
this.hasName("ConfiguredTaskAwaiter")
}
/** Gets the `GetResult` method. */
Method getGetResultMethod() { result = this.getAMethod("GetResult") }
/** Gets the field that stores the underlying task. */
Field getUnderlyingTaskField() { result = this.getAField() and result.hasName("m_task") }
}

View File

@@ -41,4 +41,7 @@ class SystemThreadingTasksTaskTClass extends SystemThreadingTasksUnboundGenericC
/** Gets the `GetAwaiter` method. */
Method getGetAwaiterMethod() { result = this.getAMethod("GetAwaiter") }
/** Gets the `ConfigureAwait` method. */
Method getConfigureAwaitMethod() { result = this.getAMethod("ConfigureAwait") }
}

View File

@@ -51,6 +51,7 @@
| GlobalDataFlow.cs:326:15:326:25 | access to parameter sinkParam11 |
| GlobalDataFlow.cs:401:15:401:20 | access to local variable sink11 |
| GlobalDataFlow.cs:424:41:424:46 | access to local variable sink20 |
| GlobalDataFlow.cs:475:15:475:20 | access to local variable sink45 |
| Splitting.cs:9:15:9:15 | [b (line 3): false] access to local variable x |
| Splitting.cs:9:15:9:15 | [b (line 3): true] access to local variable x |
| Splitting.cs:11:19:11:19 | access to local variable x |

View File

@@ -221,6 +221,14 @@ edges
| GlobalDataFlow.cs:402:16:402:21 | access to local variable sink11 : String | GlobalDataFlow.cs:164:22:164:43 | call to method TaintedParam : String |
| GlobalDataFlow.cs:424:9:424:11 | value : String | GlobalDataFlow.cs:424:41:424:46 | access to local variable sink20 |
| GlobalDataFlow.cs:435:22:435:35 | "taint source" : String | GlobalDataFlow.cs:198:22:198:32 | access to property OutProperty : String |
| GlobalDataFlow.cs:471:20:471:49 | call to method Run [Result] : String | GlobalDataFlow.cs:472:25:472:28 | access to local variable task [Result] : String |
| GlobalDataFlow.cs:471:35:471:48 | "taint source" : String | GlobalDataFlow.cs:471:20:471:49 | call to method Run [Result] : String |
| GlobalDataFlow.cs:472:25:472:28 | access to local variable task [Result] : String | GlobalDataFlow.cs:472:25:472:50 | call to method ConfigureAwait [m_configuredTaskAwaiter, m_task, Result] : String |
| GlobalDataFlow.cs:472:25:472:50 | call to method ConfigureAwait [m_configuredTaskAwaiter, m_task, Result] : String | GlobalDataFlow.cs:473:23:473:31 | access to local variable awaitable [m_configuredTaskAwaiter, m_task, Result] : String |
| GlobalDataFlow.cs:473:23:473:31 | access to local variable awaitable [m_configuredTaskAwaiter, m_task, Result] : String | GlobalDataFlow.cs:473:23:473:44 | call to method GetAwaiter [m_task, Result] : String |
| GlobalDataFlow.cs:473:23:473:44 | call to method GetAwaiter [m_task, Result] : String | GlobalDataFlow.cs:474:22:474:28 | access to local variable awaiter [m_task, Result] : String |
| GlobalDataFlow.cs:474:22:474:28 | access to local variable awaiter [m_task, Result] : String | GlobalDataFlow.cs:474:22:474:40 | call to method GetResult : String |
| GlobalDataFlow.cs:474:22:474:40 | call to method GetResult : String | GlobalDataFlow.cs:475:15:475:20 | access to local variable sink45 |
| Splitting.cs:3:28:3:34 | tainted : String | Splitting.cs:8:24:8:30 | [b (line 3): false] access to parameter tainted : String |
| Splitting.cs:3:28:3:34 | tainted : String | Splitting.cs:8:24:8:30 | [b (line 3): true] access to parameter tainted : String |
| Splitting.cs:8:17:8:31 | [b (line 3): false] call to method Return : String | Splitting.cs:9:15:9:15 | [b (line 3): false] access to local variable x |
@@ -428,6 +436,15 @@ nodes
| GlobalDataFlow.cs:424:9:424:11 | value : String | semmle.label | value : String |
| GlobalDataFlow.cs:424:41:424:46 | access to local variable sink20 | semmle.label | access to local variable sink20 |
| GlobalDataFlow.cs:435:22:435:35 | "taint source" : String | semmle.label | "taint source" : String |
| GlobalDataFlow.cs:471:20:471:49 | call to method Run [Result] : String | semmle.label | call to method Run [Result] : String |
| GlobalDataFlow.cs:471:35:471:48 | "taint source" : String | semmle.label | "taint source" : String |
| GlobalDataFlow.cs:472:25:472:28 | access to local variable task [Result] : String | semmle.label | access to local variable task [Result] : String |
| GlobalDataFlow.cs:472:25:472:50 | call to method ConfigureAwait [m_configuredTaskAwaiter, m_task, Result] : String | semmle.label | call to method ConfigureAwait [m_configuredTaskAwaiter, m_task, Result] : String |
| GlobalDataFlow.cs:473:23:473:31 | access to local variable awaitable [m_configuredTaskAwaiter, m_task, Result] : String | semmle.label | access to local variable awaitable [m_configuredTaskAwaiter, m_task, Result] : String |
| GlobalDataFlow.cs:473:23:473:44 | call to method GetAwaiter [m_task, Result] : String | semmle.label | call to method GetAwaiter [m_task, Result] : String |
| GlobalDataFlow.cs:474:22:474:28 | access to local variable awaiter [m_task, Result] : String | semmle.label | access to local variable awaiter [m_task, Result] : String |
| GlobalDataFlow.cs:474:22:474:40 | call to method GetResult : String | semmle.label | call to method GetResult : String |
| GlobalDataFlow.cs:475:15:475:20 | access to local variable sink45 | semmle.label | access to local variable sink45 |
| Splitting.cs:3:28:3:34 | tainted : String | semmle.label | tainted : String |
| Splitting.cs:8:17:8:31 | [b (line 3): false] call to method Return : String | semmle.label | [b (line 3): false] call to method Return : String |
| Splitting.cs:8:17:8:31 | [b (line 3): true] call to method Return : String | semmle.label | [b (line 3): true] call to method Return : String |
@@ -498,6 +515,7 @@ nodes
| Capture.cs:122:15:122:20 | access to local variable sink40 | Capture.cs:115:26:115:39 | "taint source" : String | Capture.cs:122:15:122:20 | access to local variable sink40 | access to local variable sink40 |
| GlobalDataFlow.cs:240:15:240:20 | access to local variable sink41 | GlobalDataFlow.cs:238:35:238:48 | "taint source" : String | GlobalDataFlow.cs:240:15:240:20 | access to local variable sink41 | access to local variable sink41 |
| GlobalDataFlow.cs:242:15:242:20 | access to local variable sink42 | GlobalDataFlow.cs:238:35:238:48 | "taint source" : String | GlobalDataFlow.cs:242:15:242:20 | access to local variable sink42 | access to local variable sink42 |
| GlobalDataFlow.cs:475:15:475:20 | access to local variable sink45 | GlobalDataFlow.cs:471:35:471:48 | "taint source" : String | GlobalDataFlow.cs:475:15:475:20 | access to local variable sink45 | access to local variable sink45 |
| GlobalDataFlow.cs:145:15:145:19 | access to local variable sink5 | GlobalDataFlow.cs:18:27:18:40 | "taint source" : String | GlobalDataFlow.cs:145:15:145:19 | access to local variable sink5 | access to local variable sink5 |
| GlobalDataFlow.cs:155:15:155:19 | access to local variable sink6 | GlobalDataFlow.cs:338:16:338:29 | "taint source" : String | GlobalDataFlow.cs:155:15:155:19 | access to local variable sink6 | access to local variable sink6 |
| GlobalDataFlow.cs:158:15:158:19 | access to local variable sink7 | GlobalDataFlow.cs:343:13:343:26 | "taint source" : String | GlobalDataFlow.cs:158:15:158:19 | access to local variable sink7 | access to local variable sink7 |

View File

@@ -191,7 +191,12 @@
| GlobalDataFlow.cs:456:23:456:35 | call to method ToString | return | GlobalDataFlow.cs:456:23:456:35 | call to method ToString |
| GlobalDataFlow.cs:462:22:462:65 | call to method Join | return | GlobalDataFlow.cs:462:22:462:65 | call to method Join |
| GlobalDataFlow.cs:465:23:465:65 | call to method Join | return | GlobalDataFlow.cs:465:23:465:65 | call to method Join |
| GlobalDataFlow.cs:477:44:477:47 | delegate call | return | GlobalDataFlow.cs:477:44:477:47 | delegate call |
| GlobalDataFlow.cs:471:20:471:49 | call to method Run | return | GlobalDataFlow.cs:471:20:471:49 | call to method Run |
| GlobalDataFlow.cs:472:25:472:50 | call to method ConfigureAwait | qualifier | GlobalDataFlow.cs:472:25:472:28 | [post] access to local variable task |
| GlobalDataFlow.cs:472:25:472:50 | call to method ConfigureAwait | return | GlobalDataFlow.cs:472:25:472:50 | call to method ConfigureAwait |
| GlobalDataFlow.cs:473:23:473:44 | call to method GetAwaiter | return | GlobalDataFlow.cs:473:23:473:44 | call to method GetAwaiter |
| GlobalDataFlow.cs:474:22:474:40 | call to method GetResult | return | GlobalDataFlow.cs:474:22:474:40 | call to method GetResult |
| GlobalDataFlow.cs:486:44:486:47 | delegate call | return | GlobalDataFlow.cs:486:44:486:47 | delegate call |
| Splitting.cs:8:17:8:31 | [b (line 3): false] call to method Return | return | Splitting.cs:8:17:8:31 | [b (line 3): false] call to method Return |
| Splitting.cs:8:17:8:31 | [b (line 3): true] call to method Return | return | Splitting.cs:8:17:8:31 | [b (line 3): true] call to method Return |
| Splitting.cs:20:22:20:30 | call to method Return | return | Splitting.cs:20:22:20:30 | call to method Return |

View File

@@ -465,6 +465,15 @@ public class DataFlow
var nonSink = string.Join(",", "whatever", "not tainted");
Check(nonSink);
}
public void M4()
{
var task = Task.Run(() => "taint source");
var awaitable = task.ConfigureAwait(false);
var awaiter = awaitable.GetAwaiter();
var sink45 = awaiter.GetResult();
Check(sink45);
}
}
static class IEnumerableExtensions

View File

@@ -57,6 +57,7 @@
| GlobalDataFlow.cs:424:41:424:46 | access to local variable sink20 |
| GlobalDataFlow.cs:453:15:453:20 | access to local variable sink43 |
| GlobalDataFlow.cs:463:15:463:20 | access to local variable sink44 |
| GlobalDataFlow.cs:475:15:475:20 | access to local variable sink45 |
| Splitting.cs:9:15:9:15 | [b (line 3): false] access to local variable x |
| Splitting.cs:9:15:9:15 | [b (line 3): true] access to local variable x |
| Splitting.cs:11:19:11:19 | access to local variable x |

View File

@@ -241,6 +241,14 @@ edges
| GlobalDataFlow.cs:452:22:452:34 | call to method ToString : String | GlobalDataFlow.cs:453:15:453:20 | access to local variable sink43 |
| GlobalDataFlow.cs:462:22:462:65 | call to method Join : String | GlobalDataFlow.cs:463:15:463:20 | access to local variable sink44 |
| GlobalDataFlow.cs:462:51:462:64 | "taint source" : String | GlobalDataFlow.cs:462:22:462:65 | call to method Join : String |
| GlobalDataFlow.cs:471:20:471:49 | call to method Run [Result] : String | GlobalDataFlow.cs:472:25:472:28 | access to local variable task [Result] : String |
| GlobalDataFlow.cs:471:35:471:48 | "taint source" : String | GlobalDataFlow.cs:471:20:471:49 | call to method Run [Result] : String |
| GlobalDataFlow.cs:472:25:472:28 | access to local variable task [Result] : String | GlobalDataFlow.cs:472:25:472:50 | call to method ConfigureAwait [m_configuredTaskAwaiter, m_task, Result] : String |
| GlobalDataFlow.cs:472:25:472:50 | call to method ConfigureAwait [m_configuredTaskAwaiter, m_task, Result] : String | GlobalDataFlow.cs:473:23:473:31 | access to local variable awaitable [m_configuredTaskAwaiter, m_task, Result] : String |
| GlobalDataFlow.cs:473:23:473:31 | access to local variable awaitable [m_configuredTaskAwaiter, m_task, Result] : String | GlobalDataFlow.cs:473:23:473:44 | call to method GetAwaiter [m_task, Result] : String |
| GlobalDataFlow.cs:473:23:473:44 | call to method GetAwaiter [m_task, Result] : String | GlobalDataFlow.cs:474:22:474:28 | access to local variable awaiter [m_task, Result] : String |
| GlobalDataFlow.cs:474:22:474:28 | access to local variable awaiter [m_task, Result] : String | GlobalDataFlow.cs:474:22:474:40 | call to method GetResult : String |
| GlobalDataFlow.cs:474:22:474:40 | call to method GetResult : String | GlobalDataFlow.cs:475:15:475:20 | access to local variable sink45 |
| Splitting.cs:3:28:3:34 | tainted : String | Splitting.cs:8:24:8:30 | [b (line 3): false] access to parameter tainted : String |
| Splitting.cs:3:28:3:34 | tainted : String | Splitting.cs:8:24:8:30 | [b (line 3): true] access to parameter tainted : String |
| Splitting.cs:8:17:8:31 | [b (line 3): false] call to method Return : String | Splitting.cs:9:15:9:15 | [b (line 3): false] access to local variable x |
@@ -470,6 +478,15 @@ nodes
| GlobalDataFlow.cs:462:22:462:65 | call to method Join : String | semmle.label | call to method Join : String |
| GlobalDataFlow.cs:462:51:462:64 | "taint source" : String | semmle.label | "taint source" : String |
| GlobalDataFlow.cs:463:15:463:20 | access to local variable sink44 | semmle.label | access to local variable sink44 |
| GlobalDataFlow.cs:471:20:471:49 | call to method Run [Result] : String | semmle.label | call to method Run [Result] : String |
| GlobalDataFlow.cs:471:35:471:48 | "taint source" : String | semmle.label | "taint source" : String |
| GlobalDataFlow.cs:472:25:472:28 | access to local variable task [Result] : String | semmle.label | access to local variable task [Result] : String |
| GlobalDataFlow.cs:472:25:472:50 | call to method ConfigureAwait [m_configuredTaskAwaiter, m_task, Result] : String | semmle.label | call to method ConfigureAwait [m_configuredTaskAwaiter, m_task, Result] : String |
| GlobalDataFlow.cs:473:23:473:31 | access to local variable awaitable [m_configuredTaskAwaiter, m_task, Result] : String | semmle.label | access to local variable awaitable [m_configuredTaskAwaiter, m_task, Result] : String |
| GlobalDataFlow.cs:473:23:473:44 | call to method GetAwaiter [m_task, Result] : String | semmle.label | call to method GetAwaiter [m_task, Result] : String |
| GlobalDataFlow.cs:474:22:474:28 | access to local variable awaiter [m_task, Result] : String | semmle.label | access to local variable awaiter [m_task, Result] : String |
| GlobalDataFlow.cs:474:22:474:40 | call to method GetResult : String | semmle.label | call to method GetResult : String |
| GlobalDataFlow.cs:475:15:475:20 | access to local variable sink45 | semmle.label | access to local variable sink45 |
| Splitting.cs:3:28:3:34 | tainted : String | semmle.label | tainted : String |
| Splitting.cs:8:17:8:31 | [b (line 3): false] call to method Return : String | semmle.label | [b (line 3): false] call to method Return : String |
| Splitting.cs:8:17:8:31 | [b (line 3): true] call to method Return : String | semmle.label | [b (line 3): true] call to method Return : String |
@@ -557,6 +574,7 @@ nodes
| GlobalDataFlow.cs:424:41:424:46 | access to local variable sink20 | GlobalDataFlow.cs:18:27:18:40 | "taint source" : String | GlobalDataFlow.cs:424:41:424:46 | access to local variable sink20 | access to local variable sink20 |
| GlobalDataFlow.cs:453:15:453:20 | access to local variable sink43 | GlobalDataFlow.cs:451:35:451:48 | "taint source" : String | GlobalDataFlow.cs:453:15:453:20 | access to local variable sink43 | access to local variable sink43 |
| GlobalDataFlow.cs:463:15:463:20 | access to local variable sink44 | GlobalDataFlow.cs:462:51:462:64 | "taint source" : String | GlobalDataFlow.cs:463:15:463:20 | access to local variable sink44 | access to local variable sink44 |
| GlobalDataFlow.cs:475:15:475:20 | access to local variable sink45 | GlobalDataFlow.cs:471:35:471:48 | "taint source" : String | GlobalDataFlow.cs:475:15:475:20 | access to local variable sink45 | access to local variable sink45 |
| Splitting.cs:9:15:9:15 | [b (line 3): false] access to local variable x | Splitting.cs:3:28:3:34 | tainted : String | Splitting.cs:9:15:9:15 | [b (line 3): false] access to local variable x | [b (line 3): false] access to local variable x |
| Splitting.cs:9:15:9:15 | [b (line 3): true] access to local variable x | Splitting.cs:3:28:3:34 | tainted : String | Splitting.cs:9:15:9:15 | [b (line 3): true] access to local variable x | [b (line 3): true] access to local variable x |
| Splitting.cs:11:19:11:19 | access to local variable x | Splitting.cs:3:28:3:34 | tainted : String | Splitting.cs:11:19:11:19 | access to local variable x | access to local variable x |

View File

@@ -1921,6 +1921,8 @@ callableFlowAccessPath
| System.Resources.ResourceReader.GetEnumerator() | qualifier [[]] -> return [Current] | true |
| System.Resources.ResourceSet.GetEnumerator() | qualifier [[]] -> return [Current] | true |
| System.Runtime.CompilerServices.ConditionalWeakTable<,>.GetEnumerator() | qualifier [[]] -> return [Current] | true |
| System.Runtime.CompilerServices.ConfiguredTaskAwaitable<>.ConfiguredTaskAwaiter.GetResult() | qualifier [m_task, Result] -> return [<empty>] | true |
| System.Runtime.CompilerServices.ConfiguredTaskAwaitable<>.GetAwaiter() | qualifier [m_configuredTaskAwaiter] -> return [<empty>] | true |
| System.Runtime.CompilerServices.ReadOnlyCollectionBuilder<>.Add(T) | argument 0 [<empty>] -> qualifier [[]] | true |
| System.Runtime.CompilerServices.ReadOnlyCollectionBuilder<>.Add(object) | argument 0 [<empty>] -> qualifier [[]] | true |
| System.Runtime.CompilerServices.ReadOnlyCollectionBuilder<>.CopyTo(Array, int) | qualifier [[]] -> argument 0 [[]] | true |
@@ -2080,6 +2082,7 @@ callableFlowAccessPath
| System.Threading.Tasks.Task.WhenAll<TResult>(params Task<TResult>[]) | argument 0 [[], Result] -> return [Result, []] | true |
| System.Threading.Tasks.Task.WhenAny<TResult>(IEnumerable<Task<TResult>>) | argument 0 [[], Result] -> return [Result, []] | true |
| System.Threading.Tasks.Task.WhenAny<TResult>(params Task<TResult>[]) | argument 0 [[], Result] -> return [Result, []] | true |
| System.Threading.Tasks.Task<>.ConfigureAwait(bool) | qualifier [<empty>] -> return [m_configuredTaskAwaiter, m_task] | true |
| System.Threading.Tasks.Task<>.ContinueWith<TNewResult>(Func<Task<>, Object, TNewResult>, object) | output from argument 0 [<empty>] -> return [Result] | true |
| System.Threading.Tasks.Task<>.ContinueWith<TNewResult>(Func<Task<>, Object, TNewResult>, object, CancellationToken) | output from argument 0 [<empty>] -> return [Result] | true |
| System.Threading.Tasks.Task<>.ContinueWith<TNewResult>(Func<Task<>, Object, TNewResult>, object, CancellationToken, TaskContinuationOptions, TaskScheduler) | output from argument 0 [<empty>] -> return [Result] | true |