C++: Make 'hasSize' slightly smarter when handling ternary operators.

This commit is contained in:
Mathias Vorreiter Pedersen
2023-10-16 10:48:28 +01:00
parent 6a7b2e4aa4
commit 7e6857d36b

View File

@@ -60,17 +60,31 @@ private import semmle.code.cpp.rangeanalysis.new.RangeAnalysisUtil
private VariableAccess getAVariableAccess(Expr e) { e.getAChild*() = result }
/**
* Gets a (sub)expression that may be the result of evaluating `size`.
*
* For example, `getASizeCandidate(a ? b : c)` gives `a ? b : c`, `b` and `c`.
*/
bindingset[size]
pragma[inline_late]
private Expr getASizeCandidate(Expr size) {
result = size
or
result = [size.(ConditionalExpr).getThen(), size.(ConditionalExpr).getElse()]
}
/**
* Holds if the `(n, state)` pair represents the source of flow for the size
* expression associated with `alloc`.
*/
predicate hasSize(HeuristicAllocationExpr alloc, DataFlow::Node n, int state) {
exists(VariableAccess va, Expr size, int delta |
exists(VariableAccess va, Expr size, int delta, Expr s |
size = alloc.getSizeExpr() and
s = getASizeCandidate(size) and
// Get the unique variable in a size expression like `x` in `malloc(x + 1)`.
va = unique( | | getAVariableAccess(size)) and
va = unique( | | getAVariableAccess(s)) and
// Compute `delta` as the constant difference between `x` and `x + 1`.
bounded1(any(Instruction instr | instr.getUnconvertedResultExpression() = size),
bounded1(any(Instruction instr | instr.getUnconvertedResultExpression() = s),
any(LoadInstruction load | load.getUnconvertedResultExpression() = va), delta) and
n.asExpr() = va and
state = delta