<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  </head>
  <body text="#000000" bgcolor="#FFFFFF">
    The analyzer constructs only one exploded graph for every top-level
    function. It's the same graph used by all checkers. This is why we
    have dozens of checkers enabled simultaneously without significant
    performance regressions - we are designed to scale really well in
    this sense. But it also means that different checkers cannot have
    different ideas of what functions they need to inline.<br>
    <br>
    You really do want to inline as much as possible. Even if nothing
    interesting happens within the function with respect to your
    checker, the analyzer will be able to model everything else
    correctly, and the ultimate goal of that would be to make sure that
    the execution path on which a bug is found by your checker is indeed
    a valid path through the program. For instance, if the function does
    not ever return null on any path, the analyzer will not proceed to
    explore the path on which the return value of that function is
    assumed to be null; if it did explore such path, any bugs found on
    such path would immediately be classified as false positives.<br>
    <br>
    Still, the analyzer cannot inline everything, because sometimes the
    source code of the function is not available, and in other cases it
    needs to make difficult choices on whether it's worth it to inline a
    huge function and make the user wait forever for the analysis to
    complete, or skip the function and risk producing false positives.
    And the *lack* of inlining often *does* indeed requiring a special
    care on the checker side to carefully assume that the inlined
    function is indeed doing something sane (that's why checkers are
    subscribing for "pointer escapes" and/or "invalidations").<br>
    <br>
    That said, i don't think i understand your question. Controlling
    inlining by the checker is definitely not possible, but what makes
    you think it's necessary? Because for now no checkers have ever
    needed that. Just in case - you might be thinking about a situation
    like this:<br>
    <br>
      // calls the block and exits<br>
      void call_block(^(*block)());<br>
    <br>
      void foo() {<br>
        call_block(^{});<br>
      }<br>
    <br>
    In this case if call_block isn't inlined, there's no way for the
    analyzer to understand that the block will be called within
    call_block(). Letting the checker model such call_block() call by
    explaining to the analyzer core that this function does indeed call
    the block is currently an open problem for the analyzer. It should
    be possible, but nobody had it implemented. Some such functions are
    modeled with the "body farm" technique - eg. dispatch_once(), but
    there's no way of doing it in the checker.<br>
    <br>
    <br>
    <div class="moz-cite-prefix">On 4/27/18 5:21 PM, Timothy J. Wood
      wrote:<br>
    </div>
    <blockquote type="cite"
      cite="mid:FB77191E-9591-4BD1-8466-351A37E746C7@omnigroup.com">
      <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
      <br class="">
      <div><br class="">
        <blockquote type="cite" class="">
          <div class="">On Apr 27, 2018, at 4:03 PM, Artem Dergachev
            <<a href="mailto:noqnoqneo@gmail.com" class=""
              moz-do-not-send="true">noqnoqneo@gmail.com</a>> wrote:</div>
          <br class="Apple-interchange-newline">
          <div class="">
            <div class="">Yep, indeed, this interface could be improved
              dramatically with a bit of work.<br class="">
              <br class="">
              I'm usually getting away pretty well by searching the
              graph in clever manners. If your dot viewer doesn't
              support text search across the graph (most don't), you
              might want to convert it to .svg (eg. dot -Tsvg graph.dot
              -o graph.svg) and open the svg in a web browser and then
              use the find-on-page feature.<br class="">
              <br class="">
            </div>
          </div>
        </blockquote>
      </div>
      <div class=""><br class="">
      </div>
      Thanks for the hints!
      <div class=""><br class="">
        <div class="">I started printing the state pointers in my log
          output and that’s helping match up my log messages with where
          I am in the graph.</div>
        <div class=""><br class="">
        </div>
        <div class="">One other thing that occurred to me is that some
          of the large graphs I’m seeing are due to inlining across ObjC
          methods:</div>
        <div class=""><br class="">
        </div>
        <div class=""><span class="Apple-tab-span" style="white-space:pre">   </span>-
          (BOOL)inner:(NSError **)outError; {…}</div>
        <div class=""><span class="Apple-tab-span" style="white-space:pre">   </span>-
          (BOOL)outer:(NSError **)outError; {</div>
        <div class=""><span class="Apple-tab-span" style="white-space:pre">           </span>return
          [self inner: outError];</div>
        <div class=""><span class="Apple-tab-span" style="white-space:pre">   </span>}</div>
        <div class=""><br class="">
        </div>
        <div class="">Here I’ll get something like:</div>
        <div class=""><br class="">
        </div>
        <blockquote style="margin: 0 0 0 40px; border: none; padding:
          0px;" class="">
          <div class="">begin function</div>
          <div class=""><span class="Apple-tab-span" style="white-space:pre"> </span>begin
            call</div>
          <div class=""><span class="Apple-tab-span" style="white-space:pre">         </span>begin
            function</div>
          <div class=""><span class="Apple-tab-span" style="white-space:pre">                 </span>…</div>
          <div class=""><span class="Apple-tab-span" style="white-space:pre">         </span>end
            function</div>
          <div class=""><span class="Apple-tab-span" style="white-space:pre"> </span>end
            call</div>
          <div class=""><span class="Apple-tab-span" style="white-space:pre"> </span>…</div>
          <div class="">end function</div>
          <div class=""><br class="">
          </div>
        </blockquote>
        but I don’t need this sort of inlining for my checker. When
        processing -outer: I can assume that the call to -inner: does
        the right thing (writes to outError if its result is null, and
        leaves it undefined if it is non-null), and then -inner: can be
        independently checked.
        <div class=""><br class="">
        </div>
        <div class="">But, if a method calls a block literal, I do need
          to let the inner function be processed. I haven’t yet arrived
          at a way using generateSink() that doesn’t just end the whole
          checking pass — is there a way to conditionally stop inline
          checking that I can use here?</div>
        <div class=""><br class="">
        </div>
        <div class="">
          <div class="">void
            NSErrorWriteChecker::checkBeginFunction(CheckerContext
            &C) const {</div>
        </div>
        <div class=""><br class="">
        </div>
        <div class="">
          <div class="">  if (!C.inTopFrame()) {</div>
          <div class="">    const LocationContext *LocCtxt =
            C.getLocationContext();</div>
          <div class="">    if
            (dyn_cast<BlockDecl>(LocCtxt->getDecl()) == NULL) {</div>
          <div class="">      // ???</div>
        </div>
      </div>
      <div class="">      return;</div>
      <div class="">    }</div>
      <div class="">  }</div>
      <div class=""><br class="">
      </div>
      <div class="">  …</div>
      <div class="">}</div>
      <div class=""><br class="">
      </div>
      <div class="">Thanks!</div>
      <div class=""><br class="">
      </div>
      <div class="">
        <div class="">-Tim</div>
        <div class=""><br class="">
        </div>
      </div>
    </blockquote>
    <br>
  </body>
</html>