CodeQL library for C/C++
codeql/cpp-all 3.0.1-dev (changelog, source)
Search

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
Expr asExprInternal(Node n)