@@ -1273,49 +1273,90 @@ abstract private class IndirectExprNodeBase extends Node {
12731273 }
12741274}
12751275
1276- bindingset [ e, indirectionIndex]
1277- private predicate adjustForReference (
1278- Expr e , int indirectionIndex , Expr conv , int adjustedIndirectionIndex
1279- ) {
1280- conv .( ReferenceDereferenceExpr ) .getExpr ( ) = e and
1281- adjustedIndirectionIndex = indirectionIndex - 1
1282- or
1283- not conv instanceof ReferenceDereferenceExpr and
1284- conv = e and
1285- adjustedIndirectionIndex = indirectionIndex
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 ) ;
12861287}
12871288
1288- private class IndirectOperandIndirectExprNode extends IndirectExprNodeBase instanceof IndirectOperand
1289- {
1290- IndirectOperandIndirectExprNode ( ) {
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 ) {
12911317 exists ( Expr e , int n , int indirectionIndex |
1292- indirectExprNodeShouldBeIndirectOperand ( this , e , n , indirectionIndex ) and
1318+ indirectNodeHasIndirectExpr ( node , e , n , indirectionIndex ) and
12931319 not exists ( Expr conv , int adjustedIndirectionIndex |
12941320 adjustForReference ( e , indirectionIndex , conv , adjustedIndirectionIndex ) and
1295- indirectExprNodeShouldBeIndirectOperand ( _, conv , n + 1 , adjustedIndirectionIndex )
1321+ indirectNodeHasIndirectExpr ( _, conv , n + 1 , adjustedIndirectionIndex )
12961322 )
12971323 )
12981324 }
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 ) }
12991339
13001340 final override Expr getConvertedExpr ( int n , int index ) {
1301- indirectExprNodeShouldBeIndirectOperand ( this , result , n , index )
1341+ IndirectOperandToIndirectExpr :: indirectNodeHasIndirectExpr ( this , result , n , index )
13021342 }
13031343}
13041344
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+
13051354private class IndirectInstructionIndirectExprNode extends IndirectExprNodeBase instanceof IndirectInstruction
13061355{
1307- IndirectInstructionIndirectExprNode ( ) {
1308- exists ( Expr e , int n , int indirectionIndex |
1309- indirectExprNodeShouldBeIndirectInstruction ( this , e , n , indirectionIndex ) and
1310- not exists ( Expr conv , int adjustedIndirectionIndex |
1311- adjustForReference ( e , indirectionIndex , conv , adjustedIndirectionIndex ) and
1312- not indirectExprNodeShouldBeIndirectInstruction ( _, conv , n + 1 , adjustedIndirectionIndex )
1313- )
1314- )
1315- }
1356+ IndirectInstructionIndirectExprNode ( ) { IndirectInstructionToIndirectExpr:: charpred ( this ) }
13161357
13171358 final override Expr getConvertedExpr ( int n , int index ) {
1318- indirectExprNodeShouldBeIndirectInstruction ( this , result , n , index )
1359+ IndirectInstructionToIndirectExpr :: indirectNodeHasIndirectExpr ( this , result , n , index )
13191360 }
13201361}
13211362
0 commit comments