How can I get a FieldRegion in a CompoundAssignOperator in Static Analyzer?

Hi all,

I want to get a FieldRegion when evaluating a CompoundAssignOperator. The code snippet for my test is like below:

typedef struct {

int a;

int *p;

} Obj;

Obj obj;

obj.a = 0;

obj.a += sizeof(long);

When evaluating the statement ‘obj.a += sizeof(long);’ in the method void checkPostStmt(const BinaryOperator *Op, CheckerContext &C) const, I want to get the FieldRegion of obj.a. But I don’t know how to get it. Is there anyone can provide me a way to get obj.a’s FieldRegion? Thanks a lot.

Hi, Arthur. The value of the BinaryOperator’s LHS should be an SVal representing the FieldRegion. Are you not seeing that?

Jordan

Hi Jordan,

When evaluating a BinaryAssignOperator(obj.a = 1;), if I use state->getSVal(LHS, C.getLocationContext()), I will get the SVal of LHS, which actually is a MemRegionVal. So I can get LHS’s MemRegion via MemRegionVal. However, for my test code snippet above, I’ve tried to use state->getSVal(LHS, C.getLocationContext()) to get the SVal of LHS when evaluating ‘obj.a += sizeof(long);’ in void checkPostStmt(const BinaryOperator *Op, CheckerContext &C) const, the Analyzer gave me ‘0 S32b’. I know that ‘0 S32b’ does be the value for obj.a. But I want to get the FieldRegion of obj.a, not its SVal. However, I don’t know how to get its FieldRegion when evaluating a CompoundAssignOperator.

Ah, interesting. That’s unfortunate: we need to load from the LHS, but that overwrites the location value stored in that expression. Please file a bug; since the value can always be recovered from the location, we should prefer to leave that available for checkers to access. (They’d have to be careful, though, since the LHS could be a C++ reference.)

I’m not completely sure how we’ll do this, but it’d be good to have this in the system. The relevant code is in ExprEngine::VisitBinaryOperator and its call to evalLoad.

A note on terminology: both locations and pure values are represented with SVals, and pointer values are usually region values. The C++ standard uses the term “lvalue” (or “glvalue”) for addresses of memory regions (which can be loaded from or stored to), and “rvalue” for what you’ve been calling “SVal” (the contents of a region). You could use “location” vs. “value” if you want to avoid “lvalue” and “rvalue”.

Jordan

Thank you, Jordan. I’m doing a checker to analyze C programs. Maybe I have to transform the CompoundAssignOperator to AssignOperator manually before analysis.