[analyzer] VisitIncDecOp store


While developing a checker I have noticed that in the checkLocation callback I received an unexpected Expr. It was an UnaryOperator of non-pointer type and its SVal was a loc::ConcreteInt which doesn't really make sense in my opinion.

When looking into this in ExprEngineC.cpp ExprEngine::VisitIncrementDecrementOperator I noticed that the calls to evalStore pass the whole UnaryOperator Expr as third argument LocationE. This LocationE is documented as "The location expression that is stored to". I would have understood this as the sub-expression of the UnaryOp instead of the Op itself.

In particular:

-evalStore(Dst3, U, U, ...);
+evalStore(Dst3, U, Ex, ...);


volatile int *p;

UnaryOperator 0x1bad960 'int' postfix '++'
`-ParenExpr 0x1bad940 'volatile int' lvalue
`-UnaryOperator 0x1bad920 'volatile int' lvalue prefix '*' cannot overflow
`-ImplicitCastExpr 0x1bad908 'volatile int *' <LValueToRValue>
`-DeclRefExpr 0x1bad8e0 'volatile int *' lvalue Var 0x1bad320 'p' 'volatile int *'

Here the outer UnaryOp is passed as SVal in checkLocation instead of the inner one.

Is my understanding correct? In that case I'm able to submit a patch.

Best regards

Looks like a bug, yeah. Though it's probable that some checkers have already "adapted" to it.

That said, a non-pointer prvalue expression that has a value of loc::ConcreteInt kind sounds like a bigger bug (regardless of whether it's the expression that we're looking for). Is it the value that was supplied in the callback, or is it the actual value of the unary operator expression (i.e. `State->getSVal(UnaryOp, LCtx)`)?

The SVal argument of checkLocation is a loc::ConcreteInt and has the value of the pointer p in my example. This is some address and seems correct (it is statically determinable). The only thing that seems inconsistent/misleading is that the Stmt argument of checkLocation is pointing to the IncDecOp instead of the dereference.