[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