@@ -26,13 +26,15 @@ private class GvnKindStmt extends GvnKind, TGvnKindStmt {
26
26
}
27
27
28
28
private class GvnKindDeclaration extends GvnKind , TGvnKindDeclaration {
29
- private GvnKindExpr kind ;
29
+ private int kind ;
30
30
private boolean isTargetThis ;
31
31
private Declaration d ;
32
32
33
33
GvnKindDeclaration ( ) { this = TGvnKindDeclaration ( kind , isTargetThis , d ) }
34
34
35
- override string toString ( ) { result = kind .toString ( ) + "," + isTargetThis + "," + d .toString ( ) }
35
+ override string toString ( ) {
36
+ result = "Expr(" + kind .toString ( ) + ")," + isTargetThis + "," + d .toString ( )
37
+ }
36
38
}
37
39
38
40
/** Gets the declaration referenced by the expression `e`, if any. */
@@ -89,21 +91,28 @@ private class GvnStruct extends Gvn, TGvnStruct {
89
91
override string toString ( ) { result = "(" + head .toString ( ) + " :: " + tail .toString ( ) + ")" }
90
92
}
91
93
94
+ pragma [ noinline]
95
+ private predicate gvnKindDeclaration (
96
+ ControlFlowElement cfe , int kind , boolean isTargetThis , Declaration d
97
+ ) {
98
+ isTargetThis = isTargetThis ( cfe ) and
99
+ d = referenceAttribute ( cfe ) and
100
+ expressions ( cfe , kind , _)
101
+ }
102
+
92
103
/**
93
104
* Gets the `GvnKind` of the element `cfe`.
94
105
* In case `cfe` is a reference attribute, we encode the entire declaration and whether
95
106
* the target is semantically equivalent to `this`.
96
107
*/
97
108
private GvnKind getGvnKind ( ControlFlowElement cfe ) {
98
- exists ( GvnKind kind |
99
- kind = getKind ( cfe ) and
100
- (
101
- result = TGvnKindDeclaration ( kind , isTargetThis ( cfe ) , referenceAttribute ( cfe ) )
102
- or
103
- not exists ( referenceAttribute ( cfe ) ) and
104
- result = kind
105
- )
109
+ exists ( int kind , boolean isTargetThis , Declaration d |
110
+ gvnKindDeclaration ( cfe , kind , isTargetThis , d ) and
111
+ result = TGvnKindDeclaration ( kind , isTargetThis , d )
106
112
)
113
+ or
114
+ not exists ( referenceAttribute ( cfe ) ) and
115
+ result = getKind ( cfe )
107
116
}
108
117
109
118
private Gvn gvnConstructed ( ControlFlowElement cfe , GvnKind kind , int index ) {
@@ -156,9 +165,9 @@ private module Cached {
156
165
newtype TGvnKind =
157
166
TGvnKindExpr ( int kind ) { expressions ( _, kind , _) } or
158
167
TGvnKindStmt ( int kind ) { statements ( _, kind ) } or
159
- TGvnKindDeclaration ( GvnKindExpr kind , boolean thisTarget , Declaration d ) {
168
+ TGvnKindDeclaration ( int kind , boolean thisTarget , Declaration d ) {
160
169
exists ( Expr e |
161
- d = referenceAttribute ( e ) and thisTarget = isTargetThis ( e ) and kind = getKind ( e )
170
+ d = referenceAttribute ( e ) and thisTarget = isTargetThis ( e ) and expressions ( e , kind , _ )
162
171
)
163
172
}
164
173
@@ -218,15 +227,18 @@ abstract class StructuralComparisonConfiguration extends string {
218
227
*/
219
228
abstract predicate candidate ( ControlFlowElement x , ControlFlowElement y ) ;
220
229
230
+ pragma [ inline]
231
+ private predicate sameGvn ( ControlFlowElement x , ControlFlowElement y ) {
232
+ pragma [ only_bind_into ] ( toGvn ( pragma [ only_bind_out ] ( x ) ) ) =
233
+ pragma [ only_bind_into ] ( toGvn ( pragma [ only_bind_out ] ( y ) ) )
234
+ }
235
+
221
236
/**
222
237
* Holds if elements `x` and `y` structurally equal. `x` and `y` must be
223
238
* flagged as candidates for structural equality, that is,
224
239
* `candidate(x, y)` must hold.
225
240
*/
226
- predicate same ( ControlFlowElement x , ControlFlowElement y ) {
227
- candidate ( x , y ) and
228
- toGvn ( x ) = toGvn ( y )
229
- }
241
+ predicate same ( ControlFlowElement x , ControlFlowElement y ) { candidate ( x , y ) and sameGvn ( x , y ) }
230
242
}
231
243
232
244
/**
@@ -272,14 +284,17 @@ module Internal {
272
284
*/
273
285
abstract predicate candidate ( ControlFlowElement x , ControlFlowElement y ) ;
274
286
287
+ pragma [ inline]
288
+ private predicate sameGvn ( ControlFlowElement x , ControlFlowElement y ) {
289
+ pragma [ only_bind_into ] ( toGvn ( pragma [ only_bind_out ] ( x ) ) ) =
290
+ pragma [ only_bind_into ] ( toGvn ( pragma [ only_bind_out ] ( y ) ) )
291
+ }
292
+
275
293
/**
276
294
* Holds if elements `x` and `y` structurally equal. `x` and `y` must be
277
295
* flagged as candidates for structural equality, that is,
278
296
* `candidate(x, y)` must hold.
279
297
*/
280
- predicate same ( ControlFlowElement x , ControlFlowElement y ) {
281
- candidate ( x , y ) and
282
- toGvn ( x ) = toGvn ( y )
283
- }
298
+ predicate same ( ControlFlowElement x , ControlFlowElement y ) { candidate ( x , y ) and sameGvn ( x , y ) }
284
299
}
285
300
}
0 commit comments