@@ -459,15 +459,31 @@ private module Cached {
459459 )
460460 }
461461
462- private predicate flowOutOfAddressStep ( Operand operand , Node nTo ) {
462+ /**
463+ * The role of `flowOutOfAddressStep` is to select the node for which we want dataflow to end up in
464+ * after the shared SSA library's `adjacentDefRead` predicate has determined that `operand` is the
465+ * next use of some variable.
466+ *
467+ * More precisely, this predicate holds if `operand` is an operand that represents an address, and:
468+ * - `nodeTo` is the next load of that address, or
469+ * - `nodeTo` is a `ReadNode` that uses the definition of `operand` to start a sequence of reads, or
470+ * - `nodeTo` is the outer-most `StoreNode` that uses the address represented by `operand`. We obtain
471+ * use-use flow in this case since `StoreNodeFlow::flowOutOf` will then provide flow to the next of
472+ * of `operand`.
473+ *
474+ * There is one final (slightly annoying) case: When `operand` is a an argument to a modeled function
475+ * without any `ReadSideEffect` (such as `std::move`). Here, the address flows from the argument to
476+ * the return value, which might then be read later.
477+ */
478+ private predicate flowOutOfAddressStep ( Operand operand , Node nodeTo ) {
463479 // Flow into a read node
464- exists ( ReadNode readNode | readNode = nTo |
480+ exists ( ReadNode readNode | readNode = nodeTo |
465481 readNode .isInitial ( ) and
466482 operand .getDef ( ) = readNode .getInstruction ( )
467483 )
468484 or
469485 exists ( StoreNodeInstr storeNode , Instruction def |
470- storeNode = nTo and
486+ storeNode = nodeTo and
471487 def = operand .getDef ( )
472488 |
473489 storeNode .isTerminal ( ) and
@@ -477,48 +493,48 @@ private module Cached {
477493 explicitWrite ( false , storeNode .getStoreInstruction ( ) , def )
478494 )
479495 or
480- operand = getSourceAddressOperand ( nTo .asInstruction ( ) )
496+ operand = getSourceAddressOperand ( nodeTo .asInstruction ( ) )
481497 or
482498 exists ( ReturnIndirectionInstruction ret |
483499 ret .getSourceAddressOperand ( ) = operand and
484- ret = nTo .asInstruction ( )
500+ ret = nodeTo .asInstruction ( )
485501 )
486502 or
487503 exists ( ReturnValueInstruction ret |
488504 ret .getReturnAddressOperand ( ) = operand and
489- nTo .asInstruction ( ) = ret
505+ nodeTo .asInstruction ( ) = ret
490506 )
491507 or
492508 exists ( CallInstruction call , int index , ReadSideEffectInstruction read |
493509 call .getArgumentOperand ( index ) = operand and
494510 read = getSideEffectFor ( call , index ) and
495- nTo .asOperand ( ) = read .getSideEffectOperand ( )
511+ nodeTo .asOperand ( ) = read .getSideEffectOperand ( )
496512 )
497513 or
498514 exists ( CopyInstruction copy |
499515 not exists ( getSourceAddressOperand ( copy ) ) and
500516 copy .getSourceValueOperand ( ) = operand and
501- flowOutOfAddressStep ( copy .getAUse ( ) , nTo )
517+ flowOutOfAddressStep ( copy .getAUse ( ) , nodeTo )
502518 )
503519 or
504520 exists ( ConvertInstruction convert |
505521 convert .getUnaryOperand ( ) = operand and
506- flowOutOfAddressStep ( convert .getAUse ( ) , nTo )
522+ flowOutOfAddressStep ( convert .getAUse ( ) , nodeTo )
507523 )
508524 or
509525 exists ( CheckedConvertOrNullInstruction convert |
510526 convert .getUnaryOperand ( ) = operand and
511- flowOutOfAddressStep ( convert .getAUse ( ) , nTo )
527+ flowOutOfAddressStep ( convert .getAUse ( ) , nodeTo )
512528 )
513529 or
514530 exists ( InheritanceConversionInstruction convert |
515531 convert .getUnaryOperand ( ) = operand and
516- flowOutOfAddressStep ( convert .getAUse ( ) , nTo )
532+ flowOutOfAddressStep ( convert .getAUse ( ) , nodeTo )
517533 )
518534 or
519535 exists ( PointerArithmeticInstruction arith |
520536 arith .getLeftOperand ( ) = operand and
521- flowOutOfAddressStep ( arith .getAUse ( ) , nTo )
537+ flowOutOfAddressStep ( arith .getAUse ( ) , nodeTo )
522538 )
523539 or
524540 // Flow through a modeled function that has parameter -> return value flow.
@@ -531,7 +547,7 @@ private module Cached {
531547 not getSideEffectFor ( call , index ) instanceof ReadSideEffectInstruction and
532548 input .isParameter ( index ) and
533549 output .isReturnValue ( ) and
534- flowOutOfAddressStep ( call .getAUse ( ) , nTo )
550+ flowOutOfAddressStep ( call .getAUse ( ) , nodeTo )
535551 )
536552 }
537553}
0 commit comments