|
14 | 14 |
|
15 | 15 | import csharp |
16 | 16 |
|
17 | | -/** |
18 | | - * Gets a callable that either directly captures local variable `v`, or which |
19 | | - * is enclosed by the callable that declares `v` and encloses a callable that |
20 | | - * captures `v`. |
21 | | - */ |
22 | | -Callable getACapturingCallableAncestor(LocalVariable v) { |
23 | | - result = v.getACapturingCallable() |
24 | | - or |
25 | | - exists(Callable mid | mid = getACapturingCallableAncestor(v) | |
26 | | - result = mid.getEnclosingCallable() and |
27 | | - not v.getEnclosingCallable() = result |
28 | | - ) |
29 | | -} |
30 | | - |
31 | | -Expr getADelegateExpr(Callable c) { |
32 | | - c = result.(CallableAccess).getTarget() |
33 | | - or |
34 | | - result = c.(AnonymousFunctionExpr) |
35 | | -} |
36 | | - |
37 | | -/** |
38 | | - * Holds if `c` is a call where any delegate argument is evaluated immediately. |
39 | | - */ |
40 | | -predicate nonEscapingCall(Call c) { |
41 | | - exists(string name | c.getTarget().hasName(name) | |
42 | | - name = |
43 | | - [ |
44 | | - "ForEach", "Count", "Any", "All", "Average", "Aggregate", "First", "Last", "FirstOrDefault", |
45 | | - "LastOrDefault", "LongCount", "Max", "Single", "SingleOrDefault", "Sum" |
46 | | - ] |
47 | | - ) |
48 | | -} |
49 | | - |
50 | | -/** |
51 | | - * Holds if `v` is a captured local variable, and one of the callables capturing |
52 | | - * `v` may escape the local scope. |
53 | | - */ |
54 | | -predicate mayEscape(LocalVariable v) { |
55 | | - exists(Callable c, Expr e, Expr succ | c = getACapturingCallableAncestor(v) | |
56 | | - e = getADelegateExpr(c) and |
57 | | - DataFlow::localExprFlow(e, succ) and |
58 | | - not succ = any(DelegateCall dc).getExpr() and |
59 | | - not succ = any(Cast cast).getExpr() and |
60 | | - not succ = any(Call call | nonEscapingCall(call)).getAnArgument() and |
61 | | - not succ = any(AssignableDefinition ad | ad.getTarget() instanceof LocalVariable).getSource() |
62 | | - ) |
63 | | -} |
64 | | - |
65 | 17 | class RelevantDefinition extends AssignableDefinition { |
66 | 18 | RelevantDefinition() { |
67 | 19 | this.(AssignableDefinitions::AssignmentDefinition).getAssignment() = |
@@ -94,8 +46,6 @@ class RelevantDefinition extends AssignableDefinition { |
94 | 46 | // SSA definitions are only created for live variables |
95 | 47 | this = any(SsaExplicitWrite ssaDef).getDefinition() |
96 | 48 | or |
97 | | - mayEscape(v) |
98 | | - or |
99 | 49 | v.isCaptured() |
100 | 50 | ) |
101 | 51 | } |
|
0 commit comments