@@ -1331,6 +1331,7 @@ private import GetConvertedResultExpression
1331
1331
1332
1332
/** Holds if `node` is an `OperandNode` that should map `node.asExpr()` to `e`. */
1333
1333
predicate exprNodeShouldBeOperand ( OperandNode node , Expr e , int n ) {
1334
+ not exprNodeShouldBeIndirectOperand ( _, e , n ) and
1334
1335
exists ( Instruction def |
1335
1336
unique( | | getAUse ( def ) ) = node .getOperand ( ) and
1336
1337
e = getConvertedResultExpression ( def , n )
@@ -1347,6 +1348,22 @@ private predicate indirectExprNodeShouldBeIndirectOperand(
1347
1348
)
1348
1349
}
1349
1350
1351
+ /** Holds if `node` should be an `IndirectOperand` that maps `node.asExpr()` to `e`. */
1352
+ private predicate exprNodeShouldBeIndirectOperand ( IndirectOperand node , Expr e , int n ) {
1353
+ exists ( ArgumentOperand operand |
1354
+ // When an argument (qualifier or positional) is a prvalue and the
1355
+ // parameter (qualifier or positional) is a (const) reference, IR
1356
+ // construction introduces a temporary `IRVariable`. The `VariableAddress`
1357
+ // instruction has the argument as its `getConvertedResultExpression`
1358
+ // result. However, the instruction actually represents the _address_ of
1359
+ // the argument. So to fix this mismatch, we have the indirection of the
1360
+ // `VariableAddressInstruction` map to the expression.
1361
+ node .hasOperandAndIndirectionIndex ( operand , 1 ) and
1362
+ e = getConvertedResultExpression ( operand .getDef ( ) , n ) and
1363
+ operand .getDef ( ) .( VariableAddressInstruction ) .getIRVariable ( ) instanceof IRTempVariable
1364
+ )
1365
+ }
1366
+
1350
1367
private predicate exprNodeShouldBeIndirectOutNode ( IndirectArgumentOutNode node , Expr e , int n ) {
1351
1368
exists ( CallInstruction call |
1352
1369
call .getStaticCallTarget ( ) instanceof Constructor and
@@ -1359,6 +1376,7 @@ private predicate exprNodeShouldBeIndirectOutNode(IndirectArgumentOutNode node,
1359
1376
predicate exprNodeShouldBeInstruction ( Node node , Expr e , int n ) {
1360
1377
not exprNodeShouldBeOperand ( _, e , n ) and
1361
1378
not exprNodeShouldBeIndirectOutNode ( _, e , n ) and
1379
+ not exprNodeShouldBeIndirectOperand ( _, e , n ) and
1362
1380
e = getConvertedResultExpression ( node .asInstruction ( ) , n )
1363
1381
}
1364
1382
@@ -1391,7 +1409,8 @@ abstract private class ExprNodeBase extends Node {
1391
1409
private predicate exprNodeShouldBe ( Expr e , int n ) {
1392
1410
exprNodeShouldBeInstruction ( _, e , n ) or
1393
1411
exprNodeShouldBeOperand ( _, e , n ) or
1394
- exprNodeShouldBeIndirectOutNode ( _, e , n )
1412
+ exprNodeShouldBeIndirectOutNode ( _, e , n ) or
1413
+ exprNodeShouldBeIndirectOperand ( _, e , n )
1395
1414
}
1396
1415
1397
1416
private class InstructionExprNode extends ExprNodeBase , InstructionNode {
@@ -1533,6 +1552,12 @@ private class IndirectArgumentOutExprNode extends ExprNodeBase, IndirectArgument
1533
1552
final override Expr getConvertedExpr ( int n ) { exprNodeShouldBeIndirectOutNode ( this , result , n ) }
1534
1553
}
1535
1554
1555
+ private class IndirectTemporaryExpr extends ExprNodeBase instanceof IndirectOperand {
1556
+ IndirectTemporaryExpr ( ) { exprNodeShouldBeIndirectOperand ( this , _, _) }
1557
+
1558
+ final override Expr getConvertedExpr ( int n ) { exprNodeShouldBeIndirectOperand ( this , result , n ) }
1559
+ }
1560
+
1536
1561
/**
1537
1562
* An expression, viewed as a node in a data flow graph.
1538
1563
*/
0 commit comments