Skip to content

Commit d624259

Browse files
committed
C++: Add QLDoc to 'flowOutOfAddressStep'.
1 parent a75f195 commit d624259

File tree

1 file changed

+29
-13
lines changed

1 file changed

+29
-13
lines changed

cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/SsaInternals.qll

Lines changed: 29 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)