<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=us-ascii">
<style type="text/css" style="display:none;"> P {margin-top:0;margin-bottom:0;} </style>
</head>
<body dir="ltr">
<div style="font-family: Calibri, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
Hi Artem,</div>
<div style="font-family: Calibri, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
Thank you for taking the time to give me a detailed explanation. <span>Your answer </span></div>
<div style="font-family: Calibri, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
corrected my misunderstanding of the analyzer engine, especially the engine's </div>
<div style="font-family: Calibri, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
behavior in the face of duplicate nodes. <span>And I ignored that if the </span>caller is not in </div>
<div style="font-family: Calibri, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
the top frame, "runCheckersForEndFunction()" will always be executed. If I can </div>
<div style="font-family: Calibri, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
be aware of this distinction, and continue to think about it, perhaps can </div>
<div style="font-family: Calibri, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
understand.</div>
<div style="font-family: Calibri, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
<span><span><br>
</span></span></div>
<div style="font-family: Calibri, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
Since checkEndAnalysis guarantees that it is always called, I'll consider using it </div>
<div style="font-family: Calibri, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
instead of checkEndFunction.</div>
<div style="font-family: Calibri, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
<br>
</div>
<div id="signature">
<div style="font-family:Calibri,Helvetica,sans-serif; font-size:12pt; color:rgb(0,0,0)">
Henry Wong</div>
<div style="font-family:Calibri,Helvetica,sans-serif; font-size:12pt; color:rgb(0,0,0)">
Qihoo 360 Codesafe Team</div>
</div>
<hr style="display:inline-block;width:98%" tabindex="-1">
<div id="divRplyFwdMsg" dir="ltr"><font face="Calibri, sans-serif" style="font-size:11pt" color="#000000"><b>From:</b> Artem Dergachev <noqnoqneo@gmail.com><br>
<b>Sent:</b> Saturday, November 4, 2017 4:27<br>
<b>To:</b> Henry Wong; cfe-dev@lists.llvm.org<br>
<b>Subject:</b> Re: [cfe-dev] [analyzer] "runCheckersForEndFunction()" is not guaranteed to be called at the end of each path?</font>
<div> </div>
</div>
<div class="BodyFragment"><font size="2"><span style="font-size:10pt;">
<div class="PlainText">Yeah, it's called at the end of every complete path, but there are less
<br>
paths than you'd expect, because the return value is irrelevant and gets <br>
discarded (since we'd never see the caller during analysis), and then <br>
paths get deduplicated based on that. So it's not the correct way to <br>
enumerate possible function exits - it's merely a notification that the <br>
analysis is exiting a function right now. For the same reason, all other <br>
path event callbacks such as PreStmt would not be called separately for <br>
every path that reaches that event, but only for the particular node on <br>
which the event happens.<br>
<br>
You may see how the ExplodedGraph changes when you add a caller, i.e.:<br>
<br>
$ cat -n test.c<br>
      1    int foo(int a, int b) {<br>
      2      if (a && b)<br>
      3        return a + b;<br>
      4      if (b)<br>
      5        return b;<br>
      6      return 0;<br>
      7    }<br>
      8<br>
      9    int bar(int a, int b) {<br>
     10      return foo(a, b);<br>
     11    }<br>
<br>
$ clang -cc1 -analyze -analyzer-display-progress -analyzer-checker <br>
core,debug.DumpTraversal test.c<br>
<br>
ANALYZE (Syntax): test.c foo<br>
ANALYZE (Syntax): test.c bar<br>
ANALYZE (Path,  Inline_Regular): test.c bar<br>
--BEGIN FUNCTION--<br>
--BEGIN FUNCTION--<br>
2 BinaryOperator<br>
4 IfStmt<br>
--END FUNCTION--<br>
--END FUNCTION--<br>
--END FUNCTION--<br>
--END FUNCTION--<br>
2 BinaryOperator<br>
4 IfStmt<br>
--END FUNCTION--<br>
--END FUNCTION--<br>
--END FUNCTION--<br>
<br>
(see -analyzer-viz-egraph-graphviz to visualize the actual exploded graph)<br>
<br>
There may also be incomplete paths, which were terminated before <br>
reaching the end of the function (eg. maximum exploded graph size <br>
exceeded), and there may also be exits from the function that were never <br>
reached during analysis (because all of their respective paths were <br>
terminated before that happened).<br>
<br>
Also your question looks suspicious to me in the sense that you might be <br>
trying to do something that's either not going to work or can be done a <br>
lot easier.<br>
<br>
Also you might want to have a look at checkEndAnalysis which is called <br>
only once per analysis and provides the fully constructed ExplodedGraph <br>
to traverse, explore, or gather whatever statistics you want.<br>
<br>
On 11/3/17 12:02 PM, Henry Wong via cfe-dev wrote:<br>
> Hi all,<br>
> "runCheckersForEndFunction()" is called after <br>
> "removeDeadOnEndOfFunction()" call, see <br>
> <a href="https://github.com/llvm-mirror/clang/blob/master/lib/StaticAnalyzer/Core/ExprEngine.cpp#L1948">
https://github.com/llvm-mirror/clang/blob/master/lib/StaticAnalyzer/Core/ExprEngine.cpp#L1948</a>.
<br>
> "removeDeadOnEndOfFunction()" calls "getNode()", and <br>
> "getNode()"supports node deduplication, so the "Dst" is may be empty <br>
> after "removeDeadOnEndOfFunction(NodeBuilder, Pre, Dst)" has been <br>
> executed. And "runCheckersForEndFunction()" will not be called if <br>
> "Dst" set is empty.<br>
><br>
> =======================================code <br>
> snippets======================================<br>
> int foo(int a, int b)<br>
> {<br>
> if (a && b)<br>
> return a + b;<br>
> if(b)<br>
> return b;<br>
> return 0;<br>
> }<br>
> ========================================================================================<br>
><br>
> For the above code, "runCheckersForEndFunction()" will only be <br>
> executed twice. In view of the fact that the comments of <br>
> "runCheckersForEndFunction()" is "Run Checkers for end of path", is it <br>
> reasonable that "runCheckersForEndFunction()" is not called at the end <br>
> of all paths?<br>
><br>
> Thanks,<br>
> Henry Wong<br>
><br>
><br>
> _______________________________________________<br>
> cfe-dev mailing list<br>
> cfe-dev@lists.llvm.org<br>
> <a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev">http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev</a><br>
<br>
</div>
</span></font></div>
</body>
</html>