C#: Handle async data flow in expression bodied callables

This commit is contained in:
Tamas Vajk
2021-03-16 16:32:47 +01:00
parent 048c72a0f2
commit 2541e9cb6a
4 changed files with 29 additions and 19 deletions

View File

@@ -11,6 +11,7 @@ private import dotnet
private import semmle.code.csharp.ExprOrStmtParent
private import semmle.code.csharp.metrics.Complexity
private import TypeRef
private import semmle.code.csharp.frameworks.system.threading.Tasks
/**
* An element that can be called.
@@ -206,7 +207,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
not this.getReturnType() instanceof SystemThreadingTasksTaskClass
)
}
/** Holds if this callable can yield return the expression `e`. */

View File

@@ -788,7 +788,7 @@ private module Cached {
or
exists(Expr e |
e = node1.asExpr() and
node2.(AsyncReturnNode).getReturnStmt().getExpr() = e and
node2.(AsyncReturnNode).getExpr() = e and
c = getResultContent()
)
or
@@ -1411,23 +1411,23 @@ private module ReturnNodes {
*/
class AsyncReturnNode extends ReturnNode, NodeImpl, TAsyncReturnNode {
private ControlFlow::Nodes::ElementNode cfn;
private ReturnStmt rs;
private Expr expr;
AsyncReturnNode() { this = TAsyncReturnNode(cfn) and rs.getExpr().getAControlFlowNode() = cfn }
AsyncReturnNode() { this = TAsyncReturnNode(cfn) and expr = cfn.getElement() }
ReturnStmt getReturnStmt() { result = rs }
Expr getExpr() { result = expr }
override NormalReturnKind getKind() { any() }
override Callable getEnclosingCallableImpl() { result = rs.getEnclosingCallable() }
override Callable getEnclosingCallableImpl() { result = expr.getEnclosingCallable() }
override Type getTypeImpl() { result = rs.getEnclosingCallable().getReturnType() }
override Type getTypeImpl() { result = expr.getEnclosingCallable().getReturnType() }
override ControlFlow::Node getControlFlowNodeImpl() { result = cfn }
override Location getLocationImpl() { result = rs.getLocation() }
override Location getLocationImpl() { result = expr.getLocation() }
override string toStringImpl() { result = rs.toString() }
override string toStringImpl() { result = expr.toString() }
}
/**