[cfe-dev] How to extract a symbol stored in LazyCompoundVal?

Torry Chen via cfe-dev cfe-dev at lists.llvm.org
Thu Jun 27 15:45:14 PDT 2019


I build my Clang in Release mode without assertions. For pos2, LCVal =
StoreMgr.getDefaultBinding(*LCV) indeed returns None. I'm surprised
LCVal->dump() didn't crash.

So this seems to be an expected behavior for getDefaultBinding() due to
small struct optimization. Can I retrieve the two field symbols for pos2 in
this case (in evalCall or checkPreCall)? Or you could point me to the code
where the small struct optimization happens with unwrapped binds.

On Thu, 27 Jun 2019 at 14:32, Artem Dergachev <noqnoqneo at gmail.com> wrote:

> (in my case it's None because of small struct optimization; you see the
> value as lazyCompoundVal{0x5d4bb38,pos1} in checkBind but during the actual
> bind it gets unwrapped into two symbols)
>
> On 6/27/19 2:22 PM, Artem Dergachev wrote:
>
> Mmm, weird. I tried and for me it crashes unwrapping an empty optional. My
> only guess is - do you build your clang with assertions enabled? Otherwise
> your checker would behave in undefined manner in this scenario. Could you
> check if the optional actually does contain a value?
>
> On 6/25/19 9:10 PM, Torry Chen wrote:
>
> Thank you Artem! It seems StoreManager::getDefaultBinding() won't work if
> the struct variable is copied. As shown below, getDefaultBinding() returns
> an undefined SVal.
>
> I could go down into fields to get the derived symbols for X and Y
> respectively, and then use getParentSymbol() to get the symbol for the
> whole struct. This looks cumbersome though. Is there a more convenient way
> to get the symbol for the whole struct in this case?
>
> // checkBind: pos1 -> conj_$3{struct XY, LC1, S45418, #1}
> struct XY pos1 = next_pos(10, 20);
>
> // checkBind: pos2 -> lazyCompoundVal{0x5d4bb38,pos1}
> struct XY pos2 = pos1;
>
> move_to_pos(pos2);
>
> /** evalCall for move_to_pos():
>   SVal Pos = C.getSVal(CE->getArg(0));
>   ProgramStateRef State = C.getState();
>   StoreManager &StoreMgr = State->getStateManager().getStoreManager();
>   auto LCV = Pos.getAs<nonloc::LazyCompoundVal>();
>   SVal LCSVal = *StoreMgr.getDefaultBinding(*LCV);
>   LCSVal.dump() // <- Undefined
>   ...
>   const Store St = LCV->getCVData()->getStore();
>   const SVal FieldSVal = StoreMgr.getBinding(St,
> loc::MemRegionVal(FieldReg));
>   FieldSVal.dump(); // <- derived_$4{conj_$3{struct XY, LC1, S45418,
> #1},pos1->X}
>
>   const auto *SD = dyn_cast<SymbolDerived>(FieldSVal.getAsSymbol());
>   const auto ParentSym = SD->getParentSymbol();
>   ParentSym.dump(); // <- conj_$3{struct XY, LC1, S45418, #1}
> **/
>
> On Tue, 25 Jun 2019 at 14:06, Artem Dergachev <noqnoqneo at gmail.com> wrote:
>
>> The "0x4aa1c58" part of "lazyCompoundVal{0x4aa1c58,pos1}" is a Store
>> object. You can access it with getStore() and then read it with the help of
>> a StoreManager.
>>
>> Hmm, we seem to already have a convenient API for that, you can do
>> StoreManager::getDefaultBinding(nonloc::LazyCompoundVal) directly if all
>> you need is a default-bound conjured symbol. But if you want to lookup,
>> say, specific fields in the structure (X and Y separately), you'll need to
>> do getBinding() on manually constructed FieldRegions (in your case it
>> doesn't look very useful because the whole structure is conjured anyway).
>>
>> I guess at this point you might like the chapter 5 of my old workbook (
>> https://github.com/haoNoQ/clang-analyzer-guide/releases/download/v0.1/clang-analyzer-guide-v0.1.pdf),
>> as for now it seems to be the only place where different kinds of values
>> are explained.
>>
>>
>> On 6/25/19 2:35 AM, Torry Chen via cfe-dev wrote:
>>
>> My project has a struct type as follows and I'm writing a checker for
>> some functions that take the struct value as an argument. In the
>> checkPreCall function I see the argument is an LazyCompoundVal, not a
>> symbol as it would be for a primitive type. I tried a few ways to extract
>> the symbol from the LazyCompountVal with no luck. Hope to get some help
>> here.
>>
>> struct XY {
>>   uint64_t X;
>>   uint64_t Y;
>> };
>>
>> ...
>> // checkBind: pos1 -> conj_$3{struct XY, LC1, S63346, #1}
>> struct XY pos1 = next_pos(...);
>>
>> // checkPreCall: Arg0: lazyCompoundVal{0x4aa1c58,pos1}
>> move_to_pos(pos1);
>>
>> _______________________________________________
>> cfe-dev mailing listcfe-dev at lists.llvm.orghttps://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
>>
>>
>>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20190627/2a8c61f0/attachment.html>


More information about the cfe-dev mailing list