@@ -1273,31 +1273,90 @@ abstract private class IndirectExprNodeBase extends Node {
12731273 }
12741274}
12751275
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 ) {
12791317 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+ )
12821323 )
12831324 }
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 ) }
12841339
12851340 final override Expr getConvertedExpr ( int n , int index ) {
1286- indirectExprNodeShouldBeIndirectOperand ( this , result , n , index )
1341+ IndirectOperandToIndirectExpr :: indirectNodeHasIndirectExpr ( this , result , n , index )
12871342 }
12881343}
12891344
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+
12901354private class IndirectInstructionIndirectExprNode extends IndirectExprNodeBase instanceof IndirectInstruction
12911355{
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 ) }
12981357
12991358 final override Expr getConvertedExpr ( int n , int index ) {
1300- indirectExprNodeShouldBeIndirectInstruction ( this , result , n , index )
1359+ IndirectInstructionToIndirectExpr :: indirectNodeHasIndirectExpr ( this , result , n , index )
13011360 }
13021361}
13031362
0 commit comments