@@ -1331,6 +1331,7 @@ private import GetConvertedResultExpression
13311331
13321332/** Holds if `node` is an `OperandNode` that should map `node.asExpr()` to `e`. */
13331333predicate exprNodeShouldBeOperand ( OperandNode node , Expr e , int n ) {
1334+ not exprNodeShouldBeIndirectOperand ( _, e , n ) and
13341335 exists ( Instruction def |
13351336 unique( | | getAUse ( def ) ) = node .getOperand ( ) and
13361337 e = getConvertedResultExpression ( def , n )
@@ -1347,6 +1348,22 @@ private predicate indirectExprNodeShouldBeIndirectOperand(
13471348 )
13481349}
13491350
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+
13501367private predicate exprNodeShouldBeIndirectOutNode ( IndirectArgumentOutNode node , Expr e , int n ) {
13511368 exists ( CallInstruction call |
13521369 call .getStaticCallTarget ( ) instanceof Constructor and
@@ -1359,6 +1376,7 @@ private predicate exprNodeShouldBeIndirectOutNode(IndirectArgumentOutNode node,
13591376predicate exprNodeShouldBeInstruction ( Node node , Expr e , int n ) {
13601377 not exprNodeShouldBeOperand ( _, e , n ) and
13611378 not exprNodeShouldBeIndirectOutNode ( _, e , n ) and
1379+ not exprNodeShouldBeIndirectOperand ( _, e , n ) and
13621380 e = getConvertedResultExpression ( node .asInstruction ( ) , n )
13631381}
13641382
@@ -1391,7 +1409,8 @@ abstract private class ExprNodeBase extends Node {
13911409private predicate exprNodeShouldBe ( Expr e , int n ) {
13921410 exprNodeShouldBeInstruction ( _, e , n ) or
13931411 exprNodeShouldBeOperand ( _, e , n ) or
1394- exprNodeShouldBeIndirectOutNode ( _, e , n )
1412+ exprNodeShouldBeIndirectOutNode ( _, e , n ) or
1413+ exprNodeShouldBeIndirectOperand ( _, e , n )
13951414}
13961415
13971416private class InstructionExprNode extends ExprNodeBase , InstructionNode {
@@ -1533,6 +1552,12 @@ private class IndirectArgumentOutExprNode extends ExprNodeBase, IndirectArgument
15331552 final override Expr getConvertedExpr ( int n ) { exprNodeShouldBeIndirectOutNode ( this , result , n ) }
15341553}
15351554
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+
15361561/**
15371562 * An expression, viewed as a node in a data flow graph.
15381563 */
0 commit comments