[cfe-dev] Static Checker: getting svals for a struct field value
Artem Dergachev via cfe-dev
cfe-dev at lists.llvm.org
Mon Jun 6 04:44:57 PDT 2016
Hello,
I think there might be a subtle issue with your approach.
As far as I understand, 'Buff' is a lazy compound value. As such, it
represents an r-value of some structure, which is a result of a deep
copy of an object that was residing in 'BuffReg' (aka
getCVData()->getRegion()) at the moment of copying. Contents of
'BuffReg' might have changed since the copy was obtained. And 'Buff'
itself might have been written into a different region, or maybe into
multiple different regions - after all, that's the whole point of
copying objects. And in your code, you probably cannot obtain the
"current" region for the lazy compound value, from which it was
immediately read; even if you can, that's not the way to go.
If you're sure contents of the region have not changed since copy, then
there's no problem. However, say, consider the following code:
struct S { int x; ... };
S bar();
void baz(S);
int foo() {
S s1 = bar();
// s1: LazyCompoundVal for CXXTempObjectRegion for bar() expression;
S s2 = s1;
// s1: LazyCompoundVal for CXXTempObjectRegion for bar() expression;
// s2: LazyCompoundVal for CXXTempObjectRegion for bar() expression;
s1.x = 42;
// s1: LazyCompoundVal for VarRegion s2;
// s2: LazyCompoundVal for CXXTempObjectRegion for bar() expression;
// s2 doesn't contain 42, but you're likely to read it through your
approach.
baz(s2);
}
If you're interested in contents of the LazyCompoundVal, rather than in
current contents of its origin-region, you should be working with the
second item in the CVData() - the Store thing. Store is a snapshot of
the whole memory at the moment of copying (due to magic, such copies are
very quick to obtain and lightweight to store, so it's a performance
optimization in the analyzer, in a sense).
So the suggestion is to replace St->getSVal(MRMgr.getFieldRegion(F,
BuffReg)) with something like
St->getStateManager().getStoreManager().getBinding(Buff.castAs<nonloc::LazyCompoundVal>().getCVData()->getStore(),
loc::MemRegionVal(MRMgr.getFieldRegion(F, BuffReg)), F->getType()). It
should do the trick.
More information about the cfe-dev
mailing list