@@ -459,15 +459,31 @@ private module Cached {
459
459
)
460
460
}
461
461
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 ) {
463
479
// Flow into a read node
464
- exists ( ReadNode readNode | readNode = nTo |
480
+ exists ( ReadNode readNode | readNode = nodeTo |
465
481
readNode .isInitial ( ) and
466
482
operand .getDef ( ) = readNode .getInstruction ( )
467
483
)
468
484
or
469
485
exists ( StoreNodeInstr storeNode , Instruction def |
470
- storeNode = nTo and
486
+ storeNode = nodeTo and
471
487
def = operand .getDef ( )
472
488
|
473
489
storeNode .isTerminal ( ) and
@@ -477,48 +493,48 @@ private module Cached {
477
493
explicitWrite ( false , storeNode .getStoreInstruction ( ) , def )
478
494
)
479
495
or
480
- operand = getSourceAddressOperand ( nTo .asInstruction ( ) )
496
+ operand = getSourceAddressOperand ( nodeTo .asInstruction ( ) )
481
497
or
482
498
exists ( ReturnIndirectionInstruction ret |
483
499
ret .getSourceAddressOperand ( ) = operand and
484
- ret = nTo .asInstruction ( )
500
+ ret = nodeTo .asInstruction ( )
485
501
)
486
502
or
487
503
exists ( ReturnValueInstruction ret |
488
504
ret .getReturnAddressOperand ( ) = operand and
489
- nTo .asInstruction ( ) = ret
505
+ nodeTo .asInstruction ( ) = ret
490
506
)
491
507
or
492
508
exists ( CallInstruction call , int index , ReadSideEffectInstruction read |
493
509
call .getArgumentOperand ( index ) = operand and
494
510
read = getSideEffectFor ( call , index ) and
495
- nTo .asOperand ( ) = read .getSideEffectOperand ( )
511
+ nodeTo .asOperand ( ) = read .getSideEffectOperand ( )
496
512
)
497
513
or
498
514
exists ( CopyInstruction copy |
499
515
not exists ( getSourceAddressOperand ( copy ) ) and
500
516
copy .getSourceValueOperand ( ) = operand and
501
- flowOutOfAddressStep ( copy .getAUse ( ) , nTo )
517
+ flowOutOfAddressStep ( copy .getAUse ( ) , nodeTo )
502
518
)
503
519
or
504
520
exists ( ConvertInstruction convert |
505
521
convert .getUnaryOperand ( ) = operand and
506
- flowOutOfAddressStep ( convert .getAUse ( ) , nTo )
522
+ flowOutOfAddressStep ( convert .getAUse ( ) , nodeTo )
507
523
)
508
524
or
509
525
exists ( CheckedConvertOrNullInstruction convert |
510
526
convert .getUnaryOperand ( ) = operand and
511
- flowOutOfAddressStep ( convert .getAUse ( ) , nTo )
527
+ flowOutOfAddressStep ( convert .getAUse ( ) , nodeTo )
512
528
)
513
529
or
514
530
exists ( InheritanceConversionInstruction convert |
515
531
convert .getUnaryOperand ( ) = operand and
516
- flowOutOfAddressStep ( convert .getAUse ( ) , nTo )
532
+ flowOutOfAddressStep ( convert .getAUse ( ) , nodeTo )
517
533
)
518
534
or
519
535
exists ( PointerArithmeticInstruction arith |
520
536
arith .getLeftOperand ( ) = operand and
521
- flowOutOfAddressStep ( arith .getAUse ( ) , nTo )
537
+ flowOutOfAddressStep ( arith .getAUse ( ) , nodeTo )
522
538
)
523
539
or
524
540
// Flow through a modeled function that has parameter -> return value flow.
@@ -531,7 +547,7 @@ private module Cached {
531
547
not getSideEffectFor ( call , index ) instanceof ReadSideEffectInstruction and
532
548
input .isParameter ( index ) and
533
549
output .isReturnValue ( ) and
534
- flowOutOfAddressStep ( call .getAUse ( ) , nTo )
550
+ flowOutOfAddressStep ( call .getAUse ( ) , nodeTo )
535
551
)
536
552
}
537
553
}
0 commit comments