<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  </head>
  <body text="#000000" bgcolor="#FFFFFF">
    You shouldn't do the "StoreMgr.getBinding(St,
    loc::MemRegionVal(Arg0Reg)) --> Undefined" part; it's not what i
    suggested and it doesn't work because Arg0Reg is already "dead" and
    its value has been garbage-collected (i assume that by Arg0Reg you
    mean the VarRegion for pos2).<br>
    <br>
    Like, if pos2 is never used later in the program, then we don't need
    to remember its value. So if move_to_pos(pos2) is the last use of
    pos2, we'll drop the binding and the Store would be empty.<br>
    <br>
    Accessing dead regions will produce unexpected results; the code for
    getSVal()/getBinding() assumes that the region is live (or that the
    expression is active when you try to retrieve a value of an
    expression).<br>
    <br>
    In this case it's like "hmm, the user is reading from a local
    variable, but it has no bindings, which means it has never been
    written to (otherwise i would have remembered it), which means that
    it's undefined behavior and contents of the variable are undefined".
    The real reason why Store doesn't remember any bindings is because
    it has correctly forgot about them.<br>
    <br>
    This is why we include the (lazy) copy of the old Store with the
    LazyCompoundValue. In order to extract data from
    lazyCompoundVal{0x4182e58,pos2}, you need to load the variable from
    the Store 0x4182e58, *not* from the current Store. The region is
    still live in that old store, but in the current store it's no
    longer there.<br>
    <br>
    <br>
    This is why in order to obtain <br>
    <br>
    <div class="moz-cite-prefix">On 6/26/19 3:22 PM, Torry Chen wrote:<br>
    </div>
    <blockquote type="cite"
cite="mid:CADmWND_yThU38XqkBxDD8=ruWs+QvMVQ4EgQoLEJgDEV7Ek8rA@mail.gmail.com">
      <meta http-equiv="content-type" content="text/html; charset=UTF-8">
      <div dir="ltr">I tried State->dump() and it shows there is no
        default binding for a struct variable that copies another. See
        below. I certainly can (and should) use the field symbols for my
        work. I was curious about the internals of the analyzer engine.
        Thank you for the detailed explanation!<br>
        <br>
        struct XY pos1 = next_pos(10, 20); // Binding: pos1 ->
        conj_$3{struct XY, LC1, S45538, #1}<br>
        move_to_pos(pos1);<br>
        // evalCall, State->dump():<br>
        //<br>
        // Store (direct and default bindings), 0x4176b88 :<br>
        // (GlobalInternalSpaceRegion,0,default) : conj_$1{int, LC1,
        S45538, #1}<br>
        // (GlobalSystemSpaceRegion,0,default) : conj_$2{int, LC1,
        S45538, #1}<br>
        // (pos1,0,default) : conj_$3{struct XY, LC1, S45538, #1}<br>
        //<br>
        // Expressions by stack frame:<br>
        // #0 Calling main                                              
                                                  <br>
        // (LC1, S45573) move_to_pos : &code{move_to_pos}<br>
        // (LC1, S45581) pos1 : lazyCompoundVal{0x4176b88,pos1}<br>
        //<br>
        // Ranges are empty.<br>
        //<br>
        // StoreMgr.getBinding(St, loc::MemRegionVal(Arg0Reg)) --> <b>conj_$3{struct
          XY, LC1, S45538, #1}</b><br>
        <br>
        struct XY pos2 = pos1; // Binding: pos2 ->
        lazyCompoundVal{0x4176b88,pos1}<br>
        move_to_pos(pos2);<br>
        // evalCall, State->dump():<br>
        //<br>
        // Store (direct and default bindings), 0x4176b88 :<br>
        // (GlobalInternalSpaceRegion,0,default) : conj_$1{int, LC1,
        S45538, #1}<br>
        // (GlobalSystemSpaceRegion,0,default) : conj_$2{int, LC1,
        S45538, #1}<br>
        // (pos1,0,default) : conj_$3{struct XY, LC1, S45538, #1}<br>
        //<br>
        // Expressions by stack frame:<br>
        // #0 Calling main<br>
        // (LC1, S45618) move_to_pos : &code{move_to_pos}<br>
        // (LC1, S45626) pos2 : lazyCompoundVal{0x4182e58,pos2}<br>
        //<br>
        // Ranges are empty.<br>
        //<br>
        // StoreMgr.getBinding(St, loc::MemRegionVal(Arg0Reg)) --> <b>Undefined</b><br>
      </div>
      <br>
      <div class="gmail_quote">
        <div dir="ltr" class="gmail_attr">On Wed, 26 Jun 2019 at 12:15,
          Artem Dergachev <<a href="mailto:noqnoqneo@gmail.com"
            moz-do-not-send="true">noqnoqneo@gmail.com</a>> wrote:<br>
        </div>
        <blockquote class="gmail_quote" style="margin:0px 0px 0px
          0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
          <div bgcolor="#FFFFFF"> Hmm, weird.<br>
            <br>
            I suspect that assignment was handled with "small struct
            optimization", i.e. field-by-field rather than lazily (cf.
            RegionStoreManager::tryBindSmallStruct).<br>
            <br>
            Could you do a State->dump() to verify that? If it shows
            that there's no default binding but instead there are two
            derived symbols bound to two different offsets, then the
            information about the "whole struct symbol" is already more
            or less lost: the static analyzer no longer remembers that
            this whole structure is the same as pos1, but it does
            remember that its fields, separately, are exactly the same
            as they were in pos1, which is what you see by looking at
            the fields separately.<br>
            <br>
            Generally we don't have many checkers that track structures
            as a whole and we don't really know how *should* the checker
            API look like in order to make such checkers easy to
            implement. The only such checker that we have is
            IteratorChecker and it kinda tries to do something but it's
            not very convenient. For C++ objects i'm thinking of
            tracking a "whole structure symbol" artificially, so that it
            didn't have anything to do with the actual contents of the
            structure but more with its semantic meaning: it would be
            preserved by const operations (even if they mutate memory
            contents of mutable fields) or through copies/moves and
            additionally you would be able to attach state traits to it
            without thinking about manually modeling copies/moves.<br>
            <br>
            I guess in your case, which seems to be more like a C world,
            the ad-hoc solution would be to do something like<br>
            <br>
                let's see...<br>
                pos2.x comes from pos1...<br>
                pos2.y also comes from pos1...<br>
                aha, got it!<br>
                the whole pos2 comes from pos1!<br>
            <br>
            You will *anyway* have to do this because the programmer is
            free to copy the structure field-by-field manually instead
            of just assigning the structure. This would also happen in
            C++ if the structure has a non-trivial constructor. For the
            same reason it's not enough to check only 'x' but skip 'y':
            the programmer can easily overwrite one field but not the
            other field.<br>
            <br>
            Finally, i'm surprised that it returns a UndefinedVal (i.e.,
            in particular, it allows you to unwrap the Optional) instead
            of None. This sounds like a bug. But it might be because the
            structure does indeed have an undefined default binding
            (eg., this happens when it's allocated by malloc() or
            operator new). It'd make sense because assigning every field
            wouldn't overwrite the default binding. Which, in turn,
            should remind you that relying on the "structure symbol" in
            order to figure out what the contents of the structure are
            is not a good idea unless your structure is immutable and
            completely opaque or you somehow know that it's freshly
            created. But direct bindings to fields are actually always
            trustworthy. That's how our memory model works.<br>
            <br>
            <br>
            <div class="gmail-m_-910006867637439416moz-cite-prefix">On
              6/25/19 9:10 PM, Torry Chen wrote:<br>
            </div>
            <blockquote type="cite">
              <div dir="ltr">Thank you Artem! It seems
                StoreManager::getDefaultBinding() won't work if the
                struct variable is copied. As shown below,
                getDefaultBinding() returns an undefined SVal.<br>
                <br>
                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?<br>
                <br>
                <font face="courier new, monospace">// checkBind: pos1
                  -> conj_$3{struct XY, LC1, S45418, #1}<br>
                  struct XY pos1 = next_pos(10, 20);<br>
                  <br>
                  // checkBind: pos2 ->
                  lazyCompoundVal{0x5d4bb38,pos1}<br>
                  struct XY pos2 = pos1;<br>
                  <br>
                  move_to_pos(pos2);</font><br>
                <br>
                <font face="courier new, monospace">/** evalCall for
                  move_to_pos():<br>
                    SVal Pos = C.getSVal(CE->getArg(0));<br>
                    ProgramStateRef State = C.getState();<br>
                    StoreManager &StoreMgr =
                  State->getStateManager().getStoreManager();<br>
                    auto LCV =
                  Pos.getAs<nonloc::LazyCompoundVal>();<br>
                    SVal LCSVal = *StoreMgr.getDefaultBinding(*LCV);<br>
                    LCSVal.dump() // <- Undefined<br>
                    ...<br>
                    const Store St = LCV->getCVData()->getStore();<br>
                    const SVal FieldSVal = StoreMgr.getBinding(St,
                  loc::MemRegionVal(FieldReg));<br>
                    FieldSVal.dump(); // <- derived_$4{conj_$3{struct
                  XY, LC1, S45418, #1},pos1->X}<br>
                  <br>
                    const auto *SD =
                  dyn_cast<SymbolDerived>(FieldSVal.getAsSymbol());<br>
                    const auto ParentSym = SD->getParentSymbol();<br>
                    ParentSym.dump(); // <- conj_$3{struct XY, LC1,
                  S45418, #1}<br>
                  **/</font><br>
              </div>
              <br>
              <div class="gmail_quote">
                <div dir="ltr" class="gmail_attr">On Tue, 25 Jun 2019 at
                  14:06, Artem Dergachev <<a
                    href="mailto:noqnoqneo@gmail.com" target="_blank"
                    moz-do-not-send="true">noqnoqneo@gmail.com</a>>
                  wrote:<br>
                </div>
                <blockquote class="gmail_quote" style="margin:0px 0px
                  0px 0.8ex;border-left:1px solid
                  rgb(204,204,204);padding-left:1ex">
                  <div bgcolor="#FFFFFF"> 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.<br>
                    <br>
                    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).<br>
                    <br>
                    I guess at this point you might like the chapter 5
                    of my old workbook (<a
class="gmail-m_-910006867637439416gmail-m_-4861931114608865060moz-txt-link-freetext"
href="https://github.com/haoNoQ/clang-analyzer-guide/releases/download/v0.1/clang-analyzer-guide-v0.1.pdf"
                      target="_blank" moz-do-not-send="true">https://github.com/haoNoQ/clang-analyzer-guide/releases/download/v0.1/clang-analyzer-guide-v0.1.pdf</a>),
                    as for now it seems to be the only place where
                    different kinds of values are explained.<br>
                    <br>
                    <br>
                    <div
class="gmail-m_-910006867637439416gmail-m_-4861931114608865060moz-cite-prefix">On
                      6/25/19 2:35 AM, Torry Chen via cfe-dev wrote:<br>
                    </div>
                    <blockquote type="cite">
                      <div dir="ltr">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.<br>
                        <br>
                        <font face="courier new, monospace">struct XY {<br>
                            uint64_t X;<br>
                            uint64_t Y;<br>
                          };<br>
                          <br>
                          ...<br>
                          // checkBind: pos1 -> conj_$3{struct XY,
                          LC1, S63346, #1}</font>
                        <div><span>struct XY pos1 = next_pos(...);</span>  <font
                            face="courier new, monospace"><br>
                            <br>
                            // checkPreCall: Arg0:
                            lazyCompoundVal{0x4aa1c58,pos1}<br>
                            move_to_pos(pos1);</font><br>
                        </div>
                      </div>
                      <br>
                      <fieldset
class="gmail-m_-910006867637439416gmail-m_-4861931114608865060mimeAttachmentHeader"></fieldset>
                      <pre class="gmail-m_-910006867637439416gmail-m_-4861931114608865060moz-quote-pre">_______________________________________________
cfe-dev mailing list
<a class="gmail-m_-910006867637439416gmail-m_-4861931114608865060moz-txt-link-abbreviated" href="mailto:cfe-dev@lists.llvm.org" target="_blank" moz-do-not-send="true">cfe-dev@lists.llvm.org</a>
<a class="gmail-m_-910006867637439416gmail-m_-4861931114608865060moz-txt-link-freetext" href="https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev" target="_blank" moz-do-not-send="true">https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev</a>
</pre>
                    </blockquote>
                    <br>
                  </div>
                </blockquote>
              </div>
            </blockquote>
            <br>
          </div>
        </blockquote>
      </div>
    </blockquote>
    <br>
  </body>
</html>