<html><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;" class=""><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="">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></body></html>