@@ -38,6 +38,22 @@ predicate variableWrite(AstNode write, Variable v) {
38
38
)
39
39
}
40
40
41
+ private predicate variableReadCertain ( BasicBlock bb , int i , VariableAccess va , Variable v ) {
42
+ bb .getNode ( i ) .getAstNode ( ) = va and
43
+ va = v .getAnAccess ( ) and
44
+ (
45
+ va instanceof VariableReadAccess
46
+ or
47
+ // For immutable variables, we model a read when they are borrowed
48
+ // (although the actual read happens later, if at all).
49
+ va = any ( RefExpr re ) .getExpr ( )
50
+ or
51
+ // Although compound assignments, like `x += y`, may in fact not read `x`,
52
+ // it makes sense to treat them as such
53
+ va = any ( CompoundAssignmentExpr cae ) .getLhs ( )
54
+ )
55
+ }
56
+
41
57
module SsaInput implements SsaImplCommon:: InputSig< Location > {
42
58
class BasicBlock = BasicBlocks:: BasicBlock ;
43
59
@@ -66,20 +82,7 @@ module SsaInput implements SsaImplCommon::InputSig<Location> {
66
82
}
67
83
68
84
predicate variableRead ( BasicBlock bb , int i , SourceVariable v , boolean certain ) {
69
- exists ( VariableAccess va |
70
- bb .getNode ( i ) .getAstNode ( ) = va and
71
- va = v .getAnAccess ( )
72
- |
73
- va instanceof VariableReadAccess
74
- or
75
- // For immutable variables, we model a read when they are borrowed
76
- // (although the actual read happens later, if at all).
77
- va = any ( RefExpr re ) .getExpr ( )
78
- or
79
- // Although compound assignments, like `x += y`, may in fact not read `x`,
80
- // it makes sense to treat them as such
81
- va = any ( CompoundAssignmentExpr cae ) .getLhs ( )
82
- ) and
85
+ variableReadCertain ( bb , i , _, v ) and
83
86
certain = true
84
87
or
85
88
capturedCallRead ( _, bb , i , v ) and certain = false
@@ -100,16 +103,6 @@ class PhiDefinition = Impl::PhiNode;
100
103
101
104
module Consistency = Impl:: Consistency;
102
105
103
- /** Holds if `v` is read at index `i` in basic block `bb`. */
104
- private predicate variableReadActual ( BasicBlock bb , int i , Variable v ) {
105
- exists ( VariableAccess read |
106
- read instanceof VariableReadAccess or read = any ( RefExpr re ) .getExpr ( )
107
- |
108
- read .getVariable ( ) = v and
109
- read = bb .getNode ( i ) .getAstNode ( )
110
- )
111
- }
112
-
113
106
/**
114
107
* Holds if captured variable `v` is written directly inside `scope`,
115
108
* or inside a (transitively) nested scope of `scope`.
@@ -125,18 +118,18 @@ private predicate hasCapturedWrite(Variable v, Cfg::CfgScope scope) {
125
118
* immediate outer CFG scope of `scope`.
126
119
*/
127
120
pragma [ noinline]
128
- private predicate variableReadActualInOuterScope (
121
+ private predicate variableReadCertainInOuterScope (
129
122
BasicBlock bb , int i , Variable v , Cfg:: CfgScope scope
130
123
) {
131
- variableReadActual ( bb , i , v ) and bb .getScope ( ) = scope .getEnclosingCfgScope ( )
124
+ variableReadCertain ( bb , i , _ , v ) and bb .getScope ( ) = scope .getEnclosingCfgScope ( )
132
125
}
133
126
134
127
pragma [ noinline]
135
128
private predicate hasVariableReadWithCapturedWrite (
136
129
BasicBlock bb , int i , Variable v , Cfg:: CfgScope scope
137
130
) {
138
131
hasCapturedWrite ( v , scope ) and
139
- variableReadActualInOuterScope ( bb , i , v , scope )
132
+ variableReadCertainInOuterScope ( bb , i , v , scope )
140
133
}
141
134
142
135
private VariableAccess getACapturedVariableAccess ( BasicBlock bb , Variable v ) {
@@ -154,7 +147,7 @@ private predicate writesCapturedVariable(BasicBlock bb, Variable v) {
154
147
/** Holds if `bb` contains a captured read to variable `v`. */
155
148
pragma [ nomagic]
156
149
private predicate readsCapturedVariable ( BasicBlock bb , Variable v ) {
157
- getACapturedVariableAccess ( bb , v ) instanceof VariableReadAccess
150
+ variableReadCertain ( _ , _ , getACapturedVariableAccess ( bb , v ) , _ )
158
151
}
159
152
160
153
/**
@@ -254,7 +247,7 @@ private module Cached {
254
247
CfgNode getARead ( Definition def ) {
255
248
exists ( Variable v , BasicBlock bb , int i |
256
249
Impl:: ssaDefReachesRead ( v , def , bb , i ) and
257
- variableReadActual ( bb , i , v ) and
250
+ variableReadCertain ( bb , i , v . getAnAccess ( ) , v ) and
258
251
result = bb .getNode ( i )
259
252
)
260
253
}
0 commit comments