@@ -1273,31 +1273,90 @@ abstract private class IndirectExprNodeBase extends Node {
1273
1273
}
1274
1274
}
1275
1275
1276
- private class IndirectOperandIndirectExprNode extends IndirectExprNodeBase instanceof IndirectOperand
1277
- {
1278
- IndirectOperandIndirectExprNode ( ) {
1276
+ /** A signature for converting an indirect node to an expression. */
1277
+ private signature module IndirectNodeToIndirectExprSig {
1278
+ /** The indirect node class to be converted to an expression */
1279
+ class IndirectNode ;
1280
+
1281
+ /**
1282
+ * Holds if the indirect expression at indirection index `indirectionIndex`
1283
+ * of `node` is `e`. The integer `n` specifies how many conversions has been
1284
+ * applied to `node`.
1285
+ */
1286
+ predicate indirectNodeHasIndirectExpr ( IndirectNode node , Expr e , int n , int indirectionIndex ) ;
1287
+ }
1288
+
1289
+ /**
1290
+ * A module that implements the logic for deciding whether an indirect node
1291
+ * should be an `IndirectExprNode`.
1292
+ */
1293
+ private module IndirectNodeToIndirectExpr< IndirectNodeToIndirectExprSig Sig> {
1294
+ import Sig
1295
+
1296
+ /**
1297
+ * This predicate shifts the indirection index by one when `conv` is a
1298
+ * `ReferenceDereferenceExpr`.
1299
+ *
1300
+ * This is necessary because `ReferenceDereferenceExpr` is a conversion
1301
+ * in the AST, but appears as a `LoadInstruction` in the IR.
1302
+ */
1303
+ bindingset [ e, indirectionIndex]
1304
+ private predicate adjustForReference (
1305
+ Expr e , int indirectionIndex , Expr conv , int adjustedIndirectionIndex
1306
+ ) {
1307
+ conv .( ReferenceDereferenceExpr ) .getExpr ( ) = e and
1308
+ adjustedIndirectionIndex = indirectionIndex - 1
1309
+ or
1310
+ not conv instanceof ReferenceDereferenceExpr and
1311
+ conv = e and
1312
+ adjustedIndirectionIndex = indirectionIndex
1313
+ }
1314
+
1315
+ /** Holds if `node` should be an `IndirectExprNode`. */
1316
+ predicate charpred ( IndirectNode node ) {
1279
1317
exists ( Expr e , int n , int indirectionIndex |
1280
- indirectExprNodeShouldBeIndirectOperand ( this , e , n , indirectionIndex ) and
1281
- not indirectExprNodeShouldBeIndirectOperand ( _, e , n + 1 , indirectionIndex )
1318
+ indirectNodeHasIndirectExpr ( node , e , n , indirectionIndex ) and
1319
+ not exists ( Expr conv , int adjustedIndirectionIndex |
1320
+ adjustForReference ( e , indirectionIndex , conv , adjustedIndirectionIndex ) and
1321
+ indirectNodeHasIndirectExpr ( _, conv , n + 1 , adjustedIndirectionIndex )
1322
+ )
1282
1323
)
1283
1324
}
1325
+ }
1326
+
1327
+ private module IndirectOperandIndirectExprNodeImpl implements IndirectNodeToIndirectExprSig {
1328
+ class IndirectNode = IndirectOperand ;
1329
+
1330
+ predicate indirectNodeHasIndirectExpr = indirectExprNodeShouldBeIndirectOperand / 4 ;
1331
+ }
1332
+
1333
+ module IndirectOperandToIndirectExpr =
1334
+ IndirectNodeToIndirectExpr< IndirectOperandIndirectExprNodeImpl > ;
1335
+
1336
+ private class IndirectOperandIndirectExprNode extends IndirectExprNodeBase instanceof IndirectOperand
1337
+ {
1338
+ IndirectOperandIndirectExprNode ( ) { IndirectOperandToIndirectExpr:: charpred ( this ) }
1284
1339
1285
1340
final override Expr getConvertedExpr ( int n , int index ) {
1286
- indirectExprNodeShouldBeIndirectOperand ( this , result , n , index )
1341
+ IndirectOperandToIndirectExpr :: indirectNodeHasIndirectExpr ( this , result , n , index )
1287
1342
}
1288
1343
}
1289
1344
1345
+ private module IndirectInstructionIndirectExprNodeImpl implements IndirectNodeToIndirectExprSig {
1346
+ class IndirectNode = IndirectInstruction ;
1347
+
1348
+ predicate indirectNodeHasIndirectExpr = indirectExprNodeShouldBeIndirectInstruction / 4 ;
1349
+ }
1350
+
1351
+ module IndirectInstructionToIndirectExpr =
1352
+ IndirectNodeToIndirectExpr< IndirectInstructionIndirectExprNodeImpl > ;
1353
+
1290
1354
private class IndirectInstructionIndirectExprNode extends IndirectExprNodeBase instanceof IndirectInstruction
1291
1355
{
1292
- IndirectInstructionIndirectExprNode ( ) {
1293
- exists ( Expr e , int n , int indirectionIndex |
1294
- indirectExprNodeShouldBeIndirectInstruction ( this , e , n , indirectionIndex ) and
1295
- not indirectExprNodeShouldBeIndirectInstruction ( _, e , n + 1 , indirectionIndex )
1296
- )
1297
- }
1356
+ IndirectInstructionIndirectExprNode ( ) { IndirectInstructionToIndirectExpr:: charpred ( this ) }
1298
1357
1299
1358
final override Expr getConvertedExpr ( int n , int index ) {
1300
- indirectExprNodeShouldBeIndirectInstruction ( this , result , n , index )
1359
+ IndirectInstructionToIndirectExpr :: indirectNodeHasIndirectExpr ( this , result , n , index )
1301
1360
}
1302
1361
}
1303
1362
0 commit comments