<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  </head>
  <body text="#000000" bgcolor="#FFFFFF">
    On 7/31/19 2:01 PM, via cfe-dev wrote:<br>
    <blockquote type="cite"
cite="mid:CAHbXgc0QYWbBXaUhicEj_msgR2yheEtHfCHFT5iZinmhaWEHcg@mail.gmail.com">
      <meta http-equiv="content-type" content="text/html; charset=UTF-8">
      <div dir="ltr">
        <div>Hi list,<br>
        </div>
        <div><br>
        </div>
        <div>I have the following code to analyze:</div>
        <div><br>
        </div>
        <div>struct BoolConvertibleStruct {<br>
              int n;<br>
              BoolConvertibleStruct(int m) : n(m) {}<br>
              operator bool() const { return n != 0; }<br>
          };<br>
          <br>
          BoolConvertibleStruct StructFunc() {<br>
              return 1;<br>
          }</div>
        <div><br>
        </div>
        <div>I have reduced my problem to wanting to analyze
          StructFunc() to figure out the truth value of its return
          value. (The actual problem is more complicated and you might
          recognize that BoolConvertibleStruct is a stand-in for
          std::unique_ptr<T>, among other things :-P)</div>
      </div>
    </blockquote>
    <br>
    That's a very important detail. If it's a struct that you've
    implemented yourself, then all you need to do is extract the value
    from a field of the structure (it's not a problem when you know the
    name of the field).<br>
    <br>
    However, if it's something in the C++ standard library and it's
    implemented differently depending on the particular implementation
    of the standard library that you may be using, then you can't access
    the field because you've no idea what meaning does every field
    carry, so you'll have to treat the structure as an opaque object and
    reason about its contents by modeling every method of the structure.
    I.e.:<br>
    <br>
    1. Subscribe to the constructor of the structure and map (as in
    REGISTER_MAP_WITH_PROGRAMSTATE) the region of the structure to the
    value with which it was constructed.<br>
    2. Subscribe to the copy/move constructor of the structure and map
    the region into which it's copied/moved to the same value.<br>
    3. Subscribe to any method that mutates the value and update your
    maps.<br>
    4. Once you do all of this, you would be able to simply retrieve the
    value from your map when you need to model operator bool.<br>
    <br>
    This approach is costly and annoying and easy to get wrong and i
    wish we had better tools for implementing it but for now it assumes
    a lot of boilerplate. If you want examples, see how the experimental
    IteratorChecker tries to model iterators (which is a harder
    problem).<br>
    <br>
    Generally, i'll be pretty excited to accept patches that improve
    modeling of smart pointers in this manner. If that aligns with your
    interests, please extend our fairly minimal SmartPtrChecker and put
    your work to Phabricator (on an as early of a stage as possible) so
    that we could merge it!<br>
    <blockquote type="cite"
cite="mid:CAHbXgc0QYWbBXaUhicEj_msgR2yheEtHfCHFT5iZinmhaWEHcg@mail.gmail.com">
      <div dir="ltr">
        <div>I have the following sample checker:<br>
        </div>
        <div><br>
        </div>
        <div>class Analyzer : public Checker<check::EndFunction> {<br>
           public:<br>
              void checkEndFunction(const ReturnStmt* ret,
          CheckerContext& cx) const {<br>
        </div>
      </div>
    </blockquote>
    <br>
    checkEndFunction isn't the right place for this sort of stuff. It's
    already too late to see what integer was stuffed into the returned
    BoolConvertibleStruct, but it's too early to actually model the
    effect of the call (what if it wasn't inlined in the first place?).<br>
    <br>
    Regardless of what approach you take, you most likely want to stick
    to checkPostCall.<br>
    <br>
    <blockquote type="cite"
cite="mid:CAHbXgc0QYWbBXaUhicEj_msgR2yheEtHfCHFT5iZinmhaWEHcg@mail.gmail.com">
      <div dir="ltr">
        <div>        const auto* func =
          cast<FunctionDecl>(cx.getStackFrame()->getDecl());<br>
                  if (func->getQualifiedNameAsString() !=
          "StructFunc")<br>
                      return;<br>
          <br>
                  ProgramStateRef state = cx.getState();<br>
                  SValBuilder& builder = cx.getSValBuilder();<br>
                  ASTContext& ast = cx.getASTContext();<br>
          <br>
                  SVal returnValue = cx.getSVal(ret->getRetValue());<br>
                  SVal falseValue = builder.makeZeroVal(ast.BoolTy);<br>
                  SVal returnedFalse = builder.evalEQ(state,
          returnValue, falseValue);<br>
          <br>
                  errs() << "Evaluating (" << returnValue
          << " == " << falseValue<br>
                      << ") -> " << returnedFalse
          << "\n";<br>
              }<br>
          };</div>
        <div><br>
        </div>
        <div>However when I run it on my sample code I get this output:</div>
        <div><br>
        </div>
        <div>Evaluating
          (lazyCompoundVal{0x7f98f1871c70,Element{SymRegion{conj_$0{struct
          BoolConvertibleStruct *, LC1, S973, #1}},0 S64b,struct
          BoolConvertibleStruct}} == 0 U1b) -> Unknown</div>
      </div>
    </blockquote>
    <br>
    lazyCompoundVal is a snapshot of the structure as a whole. You can
    extract values of particular fields from it with the following
    procedure:<br>
    <br>
    - Take the lazyCompoundVal's parent region
    (`LazyCompoundVal::getRegion()`, in your case it's
    `Element{SymRegion{conj_$0{struct BoolConvertibleStruct *, LC1,
    S973, #1}},0 S64b,struct BoolConvertibleStruct}`).<br>
    - Construct a FieldRegion as a sub-region of the parent region with
    the FieldDecl of the field (i.e., State->getLValue(fieldDecl,
    parentRegion)).<br>
    - Ask StoreManager to do a getBinding() for that region from the
    lazyCompoundVal's Store (`LazyCompoundVal::getStore()`, in your case
    it's `0x7f98f1871c70`).<br>
    <br>
    See also my old workbook at
<a class="moz-txt-link-freetext" href="https://github.com/haoNoQ/clang-analyzer-guide/releases/download/v0.1/clang-analyzer-guide-v0.1.pdf">https://github.com/haoNoQ/clang-analyzer-guide/releases/download/v0.1/clang-analyzer-guide-v0.1.pdf</a><br>
    <br>
    <br>
    <blockquote type="cite"
cite="mid:CAHbXgc0QYWbBXaUhicEj_msgR2yheEtHfCHFT5iZinmhaWEHcg@mail.gmail.com">
      <div dir="ltr">
        <div>It seems to me that the result should be able to be easily
          modeled, but I'm not sure how to go about it. (I don't even
          see the "1" stored in the field showing up in the
          LazyCompoundVal.)</div>
      </div>
    </blockquote>
    <br>
    I.e., in order to "see" "1" stored in the field, you need to dump
    the parent Store of the LazyCompoundVal. If you dump the Exploded
    Graph, you can easily search it by the Store pointer (it would, of
    course, change with every run).<br>
    <br>
    <blockquote type="cite"
cite="mid:CAHbXgc0QYWbBXaUhicEj_msgR2yheEtHfCHFT5iZinmhaWEHcg@mail.gmail.com">
      <div dir="ltr">
        <div>Looking at the source code, it looks like I will have to
          somehow transform the LazyCompoundVal to something else
          because evalBinOp will always return Unknown if either side is
          a LazyCompoundVal. I have tried these things so far:<br>
        </div>
        <div><br>
        </div>
        <div>- Getting the CXXConversionDecl for
          BoolConvertibleStruct::operator bool() and creating a
          CXXMemberCallExpr, then calling cx.getSVal() on that; the
          result is Unknown</div>
        <div>- Getting the FieldDecl for BoolConvertibleStruct::n and
          calling state->getLValue(field, returnValue); the resulting
          SVal crashes when I try to print it</div>
        <div>- Using builder.evalCast() to cast returnValue to
          ast.BoolTy; the result of the cast is also Unknown<br>
        </div>
        <div>- Using state->isNull() to query the truth value
          directly; the result is underconstrained</div>
        <div><br>
        </div>
        <div>Some suggestion about what to try next (or even "this
          definitely won't work") would be appreciated.<br>
        </div>
        <div><br>
        </div>
        <div>Regards,<br>
        </div>
        <div>-- <br>
          <div dir="ltr" class="gmail_signature"
            data-smartmail="gmail_signature">Philip</div>
        </div>
      </div>
      <br>
      <fieldset class="mimeAttachmentHeader"></fieldset>
      <pre class="moz-quote-pre" wrap="">_______________________________________________
cfe-dev mailing list
<a class="moz-txt-link-abbreviated" href="mailto:cfe-dev@lists.llvm.org">cfe-dev@lists.llvm.org</a>
<a class="moz-txt-link-freetext" href="https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev">https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev</a>
</pre>
    </blockquote>
    <br>
  </body>
</html>