Predicate ExprFlowCached::asExprInternal
Gets the expression associated with node n
, if any.
Unlike n.asExpr()
, this predicate will also get the
expression *(x + i)
when n
is the indirect node
for x
. This ensures that an assignment in a long chain
of assignments in a macro expansion is properly mapped
to the previous assignment. For example, in:
*x = source();
use(x[0]);
use(x[1]);
...
use(x[i]);
use(x[i+1]);
...
use(x[N]);
To see what the problem would be if asExpr(n)
was replaced
with n.asExpr()
, consider the transitive closure over
localStepFromNonExpr
in localStepsToExpr
. We start at n2
for which n.asExpr()
exists. For example, n2
in the above
example could be a x[i]
in any of the use(x[i])
above.
We then step to a dataflow predecessor of n2
. In the above
code fragment, thats the indirect node corresponding to x
in
x[i-1]
. Since this doesn’t have a result for Node::asExpr()
we continue with the recursion until we reach *x = source()
which does have a result for Node::asExpr()
.
If N
is very large this blows up.
To fix this, we map the indirect node corresponding to x
to
in x[i - 1]
to the x[i - 1]
expression. This ensures that
x[i]
steps to the expression x[i - 1]
without traversing the
entire chain.
Import path
import semmle.code.cpp.ir.dataflow.internal.DataFlowUtil