Merge pull request #5415 from tamasvajk/feature/async-flow

C#: add store step for return statements inside async methods
This commit is contained in:
Tom Hvitved
2021-03-23 13:59:19 +01:00
committed by GitHub
7 changed files with 195 additions and 48 deletions

View File

@@ -206,7 +206,11 @@ class Callable extends DotNet::Callable, Parameterizable, ExprOrStmtParent, @cal
exists(ReturnStmt ret | ret.getEnclosingCallable() = this | e = ret.getExpr())
or
e = this.getExpressionBody() and
not this.getReturnType() instanceof VoidType
not this.getReturnType() instanceof VoidType and
(
not this.(Modifiable).isAsync() or
this.getReturnType() instanceof Generic
)
}
/** Holds if this callable can yield return the expression `e`. */

View File

@@ -82,7 +82,6 @@ private module Cached {
cached
newtype TReturnKind =
TNormalReturnKind() { Stages::DataFlowStage::forceCachingInSameStage() } or
TYieldReturnKind() or
TOutReturnKind(int i) {
exists(Parameter p | callableReturnsOutOrRef(_, p, _) and p.isOut() | i = p.getPosition())
} or
@@ -179,11 +178,6 @@ class NormalReturnKind extends ReturnKind, TNormalReturnKind {
override string toString() { result = "return" }
}
/** A value returned from a callable using a `yield return` statement. */
class YieldReturnKind extends ReturnKind, TYieldReturnKind {
override string toString() { result = "yield return" }
}
/** A value returned from a callable using an `out` or a `ref` parameter. */
abstract class OutRefReturnKind extends ReturnKind {
/** Gets the position of the `out`/`ref` parameter. */

View File

@@ -631,6 +631,9 @@ private module Cached {
TYieldReturnNode(ControlFlow::Nodes::ElementNode cfn) {
any(Callable c).canYieldReturn(cfn.getElement())
} or
TAsyncReturnNode(ControlFlow::Nodes::ElementNode cfn) {
any(Callable c | c.(Modifiable).isAsync()).canReturn(cfn.getElement())
} or
TImplicitCapturedArgumentNode(ControlFlow::Nodes::ElementNode cfn, LocalScopeVariable v) {
exists(Ssa::ExplicitDefinition def | def.isCapturedVariableDefinitionFlowIn(_, cfn, _) |
v = def.getSourceVariable().getAssignable()
@@ -782,6 +785,12 @@ private module Cached {
c instanceof ElementContent
)
or
exists(Expr e |
e = node1.asExpr() and
node2.(AsyncReturnNode).getExpr() = e and
c = getResultContent()
)
or
FlowSummaryImpl::Private::storeStep(node1, c, node2)
}
@@ -961,6 +970,8 @@ private module Cached {
or
n instanceof YieldReturnNode
or
n instanceof AsyncReturnNode
or
n instanceof ImplicitCapturedArgumentNode
or
n instanceof MallocNode
@@ -1342,14 +1353,12 @@ abstract class ReturnNode extends Node {
private module ReturnNodes {
/**
* A data-flow node that represents an expression returned by a callable,
* either using a (`yield`) `return` statement or an expression body (`=>`).
* either using a `return` statement or an expression body (`=>`).
*/
class ExprReturnNode extends ReturnNode, ExprNode {
ExprReturnNode() {
exists(DotNet::Callable c, DotNet::Expr e | e = this.getExpr() |
c.canReturn(e)
or
c.(Callable).canYieldReturn(e)
c.canReturn(e) and not c.(Modifiable).isAsync()
)
}
@@ -1383,7 +1392,7 @@ private module ReturnNodes {
YieldReturnStmt getYieldReturnStmt() { result = yrs }
override YieldReturnKind getKind() { any() }
override NormalReturnKind getKind() { any() }
override Callable getEnclosingCallableImpl() { result = yrs.getEnclosingCallable() }
@@ -1396,6 +1405,30 @@ private module ReturnNodes {
override string toStringImpl() { result = yrs.toString() }
}
/**
* A synthesized `return` node for returned expressions inside `async` methods.
*/
class AsyncReturnNode extends ReturnNode, NodeImpl, TAsyncReturnNode {
private ControlFlow::Nodes::ElementNode cfn;
private Expr expr;
AsyncReturnNode() { this = TAsyncReturnNode(cfn) and expr = cfn.getElement() }
Expr getExpr() { result = expr }
override NormalReturnKind getKind() { any() }
override Callable getEnclosingCallableImpl() { result = expr.getEnclosingCallable() }
override Type getTypeImpl() { result = expr.getEnclosingCallable().getReturnType() }
override ControlFlow::Node getControlFlowNodeImpl() { result = cfn }
override Location getLocationImpl() { result = expr.getLocation() }
override string toStringImpl() { result = expr.toString() }
}
/**
* The value of a captured variable as an implicit return from a call, viewed
* as a node in a data flow graph.
@@ -1482,21 +1515,6 @@ private module OutNodes {
result = TExplicitDelegateLikeCall(cfn, e)
}
/** A valid return type for a method that uses `yield return`. */
private class YieldReturnType extends Type {
YieldReturnType() {
exists(Type t | t = this.getUnboundDeclaration() |
t instanceof SystemCollectionsIEnumerableInterface
or
t instanceof SystemCollectionsIEnumeratorInterface
or
t instanceof SystemCollectionsGenericIEnumerableTInterface
or
t instanceof SystemCollectionsGenericIEnumeratorInterface
)
}
}
/**
* A data-flow node that reads a value returned directly by a callable,
* either via a C# call or a CIL call.
@@ -1517,9 +1535,6 @@ private module OutNodes {
(
kind instanceof NormalReturnKind and
not call.getExpr().getType() instanceof VoidType
or
kind instanceof YieldReturnKind and
call.getExpr().getType() instanceof YieldReturnType
)
}
}

View File

@@ -0,0 +1,52 @@
using System.Threading.Tasks;
class Test
{
private void Sink(string s)
{
}
public void TestNonAwait(string input)
{
Sink(Return(input));
}
private string Return(string x)
{
return x;
}
public async Task TestAwait1(string input)
{
Sink(await ReturnAwait(input));
}
public async Task TestAwait2(string input)
{
var x = await ReturnAwait(input);
Sink(x);
}
public void TestAwait3(string input)
{
Sink(ReturnAwait2(input).Result);
}
private async Task<string> ReturnAwait(string x)
{
await Task.Delay(1);
return x;
}
public void TestTask(string input)
{
Sink(ReturnTask(input).Result);
}
private Task<string> ReturnTask(string x)
{
return Task.FromResult(x);
}
private async Task<string> ReturnAwait2(string x) => x;
}

View File

@@ -0,0 +1,67 @@
edges
| Async.cs:9:37:9:41 | input : String | Async.cs:11:21:11:25 | access to parameter input : String |
| Async.cs:11:21:11:25 | access to parameter input : String | Async.cs:11:14:11:26 | call to method Return |
| Async.cs:14:34:14:34 | x : String | Async.cs:16:16:16:16 | access to parameter x : String |
| Async.cs:16:16:16:16 | access to parameter x : String | Async.cs:11:14:11:26 | call to method Return |
| Async.cs:19:41:19:45 | input : String | Async.cs:21:32:21:36 | access to parameter input : String |
| Async.cs:21:20:21:37 | call to method ReturnAwait [Result] : String | Async.cs:21:14:21:37 | await ... |
| Async.cs:21:32:21:36 | access to parameter input : String | Async.cs:21:20:21:37 | call to method ReturnAwait [Result] : String |
| Async.cs:24:41:24:45 | input : String | Async.cs:26:35:26:39 | access to parameter input : String |
| Async.cs:26:17:26:40 | await ... : String | Async.cs:27:14:27:14 | access to local variable x |
| Async.cs:26:23:26:40 | call to method ReturnAwait [Result] : String | Async.cs:26:17:26:40 | await ... : String |
| Async.cs:26:35:26:39 | access to parameter input : String | Async.cs:26:23:26:40 | call to method ReturnAwait [Result] : String |
| Async.cs:30:35:30:39 | input : String | Async.cs:32:27:32:31 | access to parameter input : String |
| Async.cs:32:14:32:32 | call to method ReturnAwait2 [Result] : String | Async.cs:32:14:32:39 | access to property Result |
| Async.cs:32:27:32:31 | access to parameter input : String | Async.cs:32:14:32:32 | call to method ReturnAwait2 [Result] : String |
| Async.cs:35:51:35:51 | x : String | Async.cs:38:16:38:16 | access to parameter x : String |
| Async.cs:38:16:38:16 | access to parameter x : String | Async.cs:21:20:21:37 | call to method ReturnAwait [Result] : String |
| Async.cs:38:16:38:16 | access to parameter x : String | Async.cs:26:23:26:40 | call to method ReturnAwait [Result] : String |
| Async.cs:41:33:41:37 | input : String | Async.cs:43:25:43:29 | access to parameter input : String |
| Async.cs:43:14:43:30 | call to method ReturnTask [Result] : String | Async.cs:43:14:43:37 | access to property Result |
| Async.cs:43:25:43:29 | access to parameter input : String | Async.cs:43:14:43:30 | call to method ReturnTask [Result] : String |
| Async.cs:46:44:46:44 | x : String | Async.cs:48:32:48:32 | access to parameter x : String |
| Async.cs:48:16:48:33 | call to method FromResult [Result] : String | Async.cs:43:14:43:30 | call to method ReturnTask [Result] : String |
| Async.cs:48:32:48:32 | access to parameter x : String | Async.cs:48:16:48:33 | call to method FromResult [Result] : String |
| Async.cs:51:52:51:52 | x : String | Async.cs:51:58:51:58 | access to parameter x : String |
| Async.cs:51:58:51:58 | access to parameter x : String | Async.cs:32:14:32:32 | call to method ReturnAwait2 [Result] : String |
nodes
| Async.cs:9:37:9:41 | input : String | semmle.label | input : String |
| Async.cs:11:14:11:26 | call to method Return | semmle.label | call to method Return |
| Async.cs:11:21:11:25 | access to parameter input : String | semmle.label | access to parameter input : String |
| Async.cs:14:34:14:34 | x : String | semmle.label | x : String |
| Async.cs:16:16:16:16 | access to parameter x : String | semmle.label | access to parameter x : String |
| Async.cs:19:41:19:45 | input : String | semmle.label | input : String |
| Async.cs:21:14:21:37 | await ... | semmle.label | await ... |
| Async.cs:21:20:21:37 | call to method ReturnAwait [Result] : String | semmle.label | call to method ReturnAwait [Result] : String |
| Async.cs:21:32:21:36 | access to parameter input : String | semmle.label | access to parameter input : String |
| Async.cs:24:41:24:45 | input : String | semmle.label | input : String |
| Async.cs:26:17:26:40 | await ... : String | semmle.label | await ... : String |
| Async.cs:26:23:26:40 | call to method ReturnAwait [Result] : String | semmle.label | call to method ReturnAwait [Result] : String |
| Async.cs:26:35:26:39 | access to parameter input : String | semmle.label | access to parameter input : String |
| Async.cs:27:14:27:14 | access to local variable x | semmle.label | access to local variable x |
| Async.cs:30:35:30:39 | input : String | semmle.label | input : String |
| Async.cs:32:14:32:32 | call to method ReturnAwait2 [Result] : String | semmle.label | call to method ReturnAwait2 [Result] : String |
| Async.cs:32:14:32:39 | access to property Result | semmle.label | access to property Result |
| Async.cs:32:27:32:31 | access to parameter input : String | semmle.label | access to parameter input : String |
| Async.cs:35:51:35:51 | x : String | semmle.label | x : String |
| Async.cs:38:16:38:16 | access to parameter x : String | semmle.label | access to parameter x : String |
| Async.cs:41:33:41:37 | input : String | semmle.label | input : String |
| Async.cs:43:14:43:30 | call to method ReturnTask [Result] : String | semmle.label | call to method ReturnTask [Result] : String |
| Async.cs:43:14:43:37 | access to property Result | semmle.label | access to property Result |
| Async.cs:43:25:43:29 | access to parameter input : String | semmle.label | access to parameter input : String |
| Async.cs:46:44:46:44 | x : String | semmle.label | x : String |
| Async.cs:48:16:48:33 | call to method FromResult [Result] : String | semmle.label | call to method FromResult [Result] : String |
| Async.cs:48:32:48:32 | access to parameter x : String | semmle.label | access to parameter x : String |
| Async.cs:51:52:51:52 | x : String | semmle.label | x : String |
| Async.cs:51:58:51:58 | access to parameter x : String | semmle.label | access to parameter x : String |
#select
| Async.cs:11:14:11:26 | call to method Return | Async.cs:9:37:9:41 | input : String | Async.cs:11:14:11:26 | call to method Return | $@ flows to here and is used. | Async.cs:9:37:9:41 | input | User-provided value |
| Async.cs:11:14:11:26 | call to method Return | Async.cs:14:34:14:34 | x : String | Async.cs:11:14:11:26 | call to method Return | $@ flows to here and is used. | Async.cs:14:34:14:34 | x | User-provided value |
| Async.cs:21:14:21:37 | await ... | Async.cs:19:41:19:45 | input : String | Async.cs:21:14:21:37 | await ... | $@ flows to here and is used. | Async.cs:19:41:19:45 | input | User-provided value |
| Async.cs:21:14:21:37 | await ... | Async.cs:35:51:35:51 | x : String | Async.cs:21:14:21:37 | await ... | $@ flows to here and is used. | Async.cs:35:51:35:51 | x | User-provided value |
| Async.cs:27:14:27:14 | access to local variable x | Async.cs:24:41:24:45 | input : String | Async.cs:27:14:27:14 | access to local variable x | $@ flows to here and is used. | Async.cs:24:41:24:45 | input | User-provided value |
| Async.cs:27:14:27:14 | access to local variable x | Async.cs:35:51:35:51 | x : String | Async.cs:27:14:27:14 | access to local variable x | $@ flows to here and is used. | Async.cs:35:51:35:51 | x | User-provided value |
| Async.cs:32:14:32:39 | access to property Result | Async.cs:30:35:30:39 | input : String | Async.cs:32:14:32:39 | access to property Result | $@ flows to here and is used. | Async.cs:30:35:30:39 | input | User-provided value |
| Async.cs:32:14:32:39 | access to property Result | Async.cs:51:52:51:52 | x : String | Async.cs:32:14:32:39 | access to property Result | $@ flows to here and is used. | Async.cs:51:52:51:52 | x | User-provided value |
| Async.cs:43:14:43:37 | access to property Result | Async.cs:41:33:41:37 | input : String | Async.cs:43:14:43:37 | access to property Result | $@ flows to here and is used. | Async.cs:41:33:41:37 | input | User-provided value |
| Async.cs:43:14:43:37 | access to property Result | Async.cs:46:44:46:44 | x : String | Async.cs:43:14:43:37 | access to property Result | $@ flows to here and is used. | Async.cs:46:44:46:44 | x | User-provided value |

View File

@@ -0,0 +1,33 @@
import csharp
import semmle.code.csharp.dataflow.DataFlow::DataFlow::PathGraph
class MySink extends DataFlow::ExprNode {
MySink() {
exists(Method m, MethodCall mc |
mc.getTarget() = m and
m.getName() = "Sink" and
this.getExpr() = mc.getArgumentForName("s")
)
}
}
class MySource extends DataFlow::ParameterNode {
MySource() {
exists(Parameter p | p = this.getParameter() |
p = any(Class c | c.hasQualifiedName("Test")).getAMethod().getAParameter()
)
}
}
class MyConfig extends TaintTracking::Configuration {
MyConfig() { this = "MyConfig" }
override predicate isSource(DataFlow::Node source) { source instanceof MySource }
override predicate isSink(DataFlow::Node sink) { sink instanceof MySink }
}
from MyConfig c, DataFlow::PathNode source, DataFlow::PathNode sink
where c.hasFlowPath(source, sink)
select sink.getNode(), source, sink, "$@ flows to here and is used.", source.getNode(),
"User-provided value"

View File

@@ -1,11 +1,9 @@
| Capture.cs:33:9:33:40 | call to method Select | return | Capture.cs:33:9:33:40 | call to method Select |
| Capture.cs:33:9:33:40 | call to method Select | yield return | Capture.cs:33:9:33:40 | call to method Select |
| Capture.cs:33:9:33:50 | call to method ToArray | return | Capture.cs:33:9:33:50 | call to method ToArray |
| Capture.cs:71:9:71:21 | call to local function CaptureOut1 | captured sink30 | Capture.cs:71:9:71:21 | SSA call def(sink30) |
| Capture.cs:83:9:83:21 | [transitive] call to local function CaptureOut2 | captured sink31 | Capture.cs:83:9:83:21 | SSA call def(sink31) |
| Capture.cs:92:9:92:41 | [transitive] call to method Select | captured sink32 | Capture.cs:92:9:92:41 | SSA call def(sink32) |
| Capture.cs:92:9:92:41 | call to method Select | return | Capture.cs:92:9:92:41 | call to method Select |
| Capture.cs:92:9:92:41 | call to method Select | yield return | Capture.cs:92:9:92:41 | call to method Select |
| Capture.cs:92:9:92:51 | call to method ToArray | return | Capture.cs:92:9:92:51 | call to method ToArray |
| Capture.cs:121:9:121:35 | [transitive] call to local function CaptureOutMultipleLambdas | captured nonSink0 | Capture.cs:121:9:121:35 | SSA call def(nonSink0) |
| Capture.cs:121:9:121:35 | [transitive] call to local function CaptureOutMultipleLambdas | captured sink40 | Capture.cs:121:9:121:35 | SSA call def(sink40) |
@@ -13,7 +11,6 @@
| Capture.cs:144:9:144:25 | [transitive] call to local function CaptureThrough2 | captured sink34 | Capture.cs:144:9:144:25 | SSA call def(sink34) |
| Capture.cs:153:9:153:45 | [transitive] call to method Select | captured sink35 | Capture.cs:153:9:153:45 | SSA call def(sink35) |
| Capture.cs:153:9:153:45 | call to method Select | return | Capture.cs:153:9:153:45 | call to method Select |
| Capture.cs:153:9:153:45 | call to method Select | yield return | Capture.cs:153:9:153:45 | call to method Select |
| Capture.cs:153:9:153:55 | call to method ToArray | return | Capture.cs:153:9:153:55 | call to method ToArray |
| Capture.cs:160:22:160:38 | call to local function CaptureThrough4 | return | Capture.cs:160:22:160:38 | call to local function CaptureThrough4 |
| Capture.cs:168:9:168:32 | call to local function CaptureThrough5 | captured sink37 | Capture.cs:168:9:168:32 | SSA call def(sink37) |
@@ -52,16 +49,12 @@
| GlobalDataFlow.cs:79:9:79:46 | call to method ReturnRef | out | GlobalDataFlow.cs:79:30:79:34 | SSA def(sink3) |
| GlobalDataFlow.cs:79:9:79:46 | call to method ReturnRef | ref | GlobalDataFlow.cs:79:30:79:34 | SSA def(sink3) |
| GlobalDataFlow.cs:81:22:81:85 | call to method SelectEven | return | GlobalDataFlow.cs:81:22:81:85 | call to method SelectEven |
| GlobalDataFlow.cs:81:22:81:85 | call to method SelectEven | yield return | GlobalDataFlow.cs:81:22:81:85 | call to method SelectEven |
| GlobalDataFlow.cs:81:22:81:93 | call to method First | return | GlobalDataFlow.cs:81:22:81:93 | call to method First |
| GlobalDataFlow.cs:83:22:83:87 | call to method Select | return | GlobalDataFlow.cs:83:22:83:87 | call to method Select |
| GlobalDataFlow.cs:83:22:83:87 | call to method Select | yield return | GlobalDataFlow.cs:83:22:83:87 | call to method Select |
| GlobalDataFlow.cs:83:22:83:95 | call to method First | return | GlobalDataFlow.cs:83:22:83:95 | call to method First |
| GlobalDataFlow.cs:85:22:85:128 | call to method Zip | return | GlobalDataFlow.cs:85:22:85:128 | call to method Zip |
| GlobalDataFlow.cs:85:22:85:128 | call to method Zip | yield return | GlobalDataFlow.cs:85:22:85:128 | call to method Zip |
| GlobalDataFlow.cs:85:22:85:136 | call to method First | return | GlobalDataFlow.cs:85:22:85:136 | call to method First |
| GlobalDataFlow.cs:87:22:87:128 | call to method Zip | return | GlobalDataFlow.cs:87:22:87:128 | call to method Zip |
| GlobalDataFlow.cs:87:22:87:128 | call to method Zip | yield return | GlobalDataFlow.cs:87:22:87:128 | call to method Zip |
| GlobalDataFlow.cs:87:22:87:136 | call to method First | return | GlobalDataFlow.cs:87:22:87:136 | call to method First |
| GlobalDataFlow.cs:89:22:89:110 | call to method Aggregate | return | GlobalDataFlow.cs:89:22:89:110 | call to method Aggregate |
| GlobalDataFlow.cs:91:22:91:110 | call to method Aggregate | return | GlobalDataFlow.cs:91:22:91:110 | call to method Aggregate |
@@ -83,16 +76,12 @@
| GlobalDataFlow.cs:111:9:111:49 | call to method ReturnRef | out | GlobalDataFlow.cs:111:30:111:34 | SSA def(sink1) |
| GlobalDataFlow.cs:111:9:111:49 | call to method ReturnRef | ref | GlobalDataFlow.cs:111:30:111:34 | SSA def(sink1) |
| GlobalDataFlow.cs:113:20:113:86 | call to method SelectEven | return | GlobalDataFlow.cs:113:20:113:86 | call to method SelectEven |
| GlobalDataFlow.cs:113:20:113:86 | call to method SelectEven | yield return | GlobalDataFlow.cs:113:20:113:86 | call to method SelectEven |
| GlobalDataFlow.cs:113:20:113:94 | call to method First | return | GlobalDataFlow.cs:113:20:113:94 | call to method First |
| GlobalDataFlow.cs:115:20:115:82 | call to method Select | return | GlobalDataFlow.cs:115:20:115:82 | call to method Select |
| GlobalDataFlow.cs:115:20:115:82 | call to method Select | yield return | GlobalDataFlow.cs:115:20:115:82 | call to method Select |
| GlobalDataFlow.cs:115:20:115:90 | call to method First | return | GlobalDataFlow.cs:115:20:115:90 | call to method First |
| GlobalDataFlow.cs:117:20:117:126 | call to method Zip | return | GlobalDataFlow.cs:117:20:117:126 | call to method Zip |
| GlobalDataFlow.cs:117:20:117:126 | call to method Zip | yield return | GlobalDataFlow.cs:117:20:117:126 | call to method Zip |
| GlobalDataFlow.cs:117:20:117:134 | call to method First | return | GlobalDataFlow.cs:117:20:117:134 | call to method First |
| GlobalDataFlow.cs:119:20:119:126 | call to method Zip | return | GlobalDataFlow.cs:119:20:119:126 | call to method Zip |
| GlobalDataFlow.cs:119:20:119:126 | call to method Zip | yield return | GlobalDataFlow.cs:119:20:119:126 | call to method Zip |
| GlobalDataFlow.cs:119:20:119:134 | call to method First | return | GlobalDataFlow.cs:119:20:119:134 | call to method First |
| GlobalDataFlow.cs:121:20:121:104 | call to method Aggregate | return | GlobalDataFlow.cs:121:20:121:104 | call to method Aggregate |
| GlobalDataFlow.cs:123:20:123:109 | call to method Aggregate | return | GlobalDataFlow.cs:123:20:123:109 | call to method Aggregate |
@@ -119,7 +108,6 @@
| GlobalDataFlow.cs:160:9:160:25 | call to method OutRef | ref | GlobalDataFlow.cs:160:20:160:24 | SSA def(sink8) |
| GlobalDataFlow.cs:162:22:162:31 | call to method OutYield | qualifier | GlobalDataFlow.cs:162:22:162:31 | [post] this access |
| GlobalDataFlow.cs:162:22:162:31 | call to method OutYield | return | GlobalDataFlow.cs:162:22:162:31 | call to method OutYield |
| GlobalDataFlow.cs:162:22:162:31 | call to method OutYield | yield return | GlobalDataFlow.cs:162:22:162:31 | call to method OutYield |
| GlobalDataFlow.cs:162:22:162:39 | call to method First | return | GlobalDataFlow.cs:162:22:162:39 | call to method First |
| GlobalDataFlow.cs:164:22:164:43 | call to method TaintedParam | return | GlobalDataFlow.cs:164:22:164:43 | call to method TaintedParam |
| GlobalDataFlow.cs:168:20:168:27 | call to method NonOut | qualifier | GlobalDataFlow.cs:168:20:168:27 | [post] this access |
@@ -132,7 +120,6 @@
| GlobalDataFlow.cs:172:9:172:31 | call to method NonOutRef | ref | GlobalDataFlow.cs:172:23:172:30 | SSA def(nonSink0) |
| GlobalDataFlow.cs:174:20:174:32 | call to method NonOutYield | qualifier | GlobalDataFlow.cs:174:20:174:32 | [post] this access |
| GlobalDataFlow.cs:174:20:174:32 | call to method NonOutYield | return | GlobalDataFlow.cs:174:20:174:32 | call to method NonOutYield |
| GlobalDataFlow.cs:174:20:174:32 | call to method NonOutYield | yield return | GlobalDataFlow.cs:174:20:174:32 | call to method NonOutYield |
| GlobalDataFlow.cs:174:20:174:40 | call to method First | return | GlobalDataFlow.cs:174:20:174:40 | call to method First |
| GlobalDataFlow.cs:176:20:176:44 | call to method NonTaintedParam | return | GlobalDataFlow.cs:176:20:176:44 | call to method NonTaintedParam |
| GlobalDataFlow.cs:181:21:181:26 | delegate call | return | GlobalDataFlow.cs:181:21:181:26 | delegate call |
@@ -151,26 +138,21 @@
| GlobalDataFlow.cs:209:41:209:77 | call to method AsQueryable | return | GlobalDataFlow.cs:209:41:209:77 | call to method AsQueryable |
| GlobalDataFlow.cs:212:76:212:90 | call to method ReturnCheck2 | return | GlobalDataFlow.cs:212:76:212:90 | call to method ReturnCheck2 |
| GlobalDataFlow.cs:213:22:213:39 | call to method Select | return | GlobalDataFlow.cs:213:22:213:39 | call to method Select |
| GlobalDataFlow.cs:213:22:213:39 | call to method Select | yield return | GlobalDataFlow.cs:213:22:213:39 | call to method Select |
| GlobalDataFlow.cs:213:22:213:47 | call to method First | return | GlobalDataFlow.cs:213:22:213:47 | call to method First |
| GlobalDataFlow.cs:215:22:215:39 | call to method Select | return | GlobalDataFlow.cs:215:22:215:39 | call to method Select |
| GlobalDataFlow.cs:215:22:215:47 | call to method First | return | GlobalDataFlow.cs:215:22:215:47 | call to method First |
| GlobalDataFlow.cs:217:22:217:49 | call to method Select | return | GlobalDataFlow.cs:217:22:217:49 | call to method Select |
| GlobalDataFlow.cs:217:22:217:49 | call to method Select | yield return | GlobalDataFlow.cs:217:22:217:49 | call to method Select |
| GlobalDataFlow.cs:217:22:217:57 | call to method First | return | GlobalDataFlow.cs:217:22:217:57 | call to method First |
| GlobalDataFlow.cs:222:76:222:92 | call to method NonReturnCheck | return | GlobalDataFlow.cs:222:76:222:92 | call to method NonReturnCheck |
| GlobalDataFlow.cs:223:23:223:43 | call to method Select | return | GlobalDataFlow.cs:223:23:223:43 | call to method Select |
| GlobalDataFlow.cs:223:23:223:43 | call to method Select | yield return | GlobalDataFlow.cs:223:23:223:43 | call to method Select |
| GlobalDataFlow.cs:223:23:223:51 | call to method First | return | GlobalDataFlow.cs:223:23:223:51 | call to method First |
| GlobalDataFlow.cs:225:19:225:39 | call to method Select | return | GlobalDataFlow.cs:225:19:225:39 | call to method Select |
| GlobalDataFlow.cs:225:19:225:47 | call to method First | return | GlobalDataFlow.cs:225:19:225:47 | call to method First |
| GlobalDataFlow.cs:227:19:227:39 | call to method Select | return | GlobalDataFlow.cs:227:19:227:39 | call to method Select |
| GlobalDataFlow.cs:227:19:227:39 | call to method Select | yield return | GlobalDataFlow.cs:227:19:227:39 | call to method Select |
| GlobalDataFlow.cs:227:19:227:47 | call to method First | return | GlobalDataFlow.cs:227:19:227:47 | call to method First |
| GlobalDataFlow.cs:229:19:229:39 | call to method Select | return | GlobalDataFlow.cs:229:19:229:39 | call to method Select |
| GlobalDataFlow.cs:229:19:229:47 | call to method First | return | GlobalDataFlow.cs:229:19:229:47 | call to method First |
| GlobalDataFlow.cs:231:19:231:49 | call to method Select | return | GlobalDataFlow.cs:231:19:231:49 | call to method Select |
| GlobalDataFlow.cs:231:19:231:49 | call to method Select | yield return | GlobalDataFlow.cs:231:19:231:49 | call to method Select |
| GlobalDataFlow.cs:231:19:231:57 | call to method First | return | GlobalDataFlow.cs:231:19:231:57 | call to method First |
| GlobalDataFlow.cs:238:20:238:49 | call to method Run | return | GlobalDataFlow.cs:238:20:238:49 | call to method Run |
| GlobalDataFlow.cs:239:22:239:32 | access to property Result | qualifier | GlobalDataFlow.cs:239:22:239:25 | [post] access to local variable task |