<div dir="ltr"><div>I'm not working on analyzer features, just on new checkers for the analyzer. Anyhow, the info is definitely interesting! I forwarded your comments about this to my boss. Thank you!<br><br></div>I'm still stuck though with the original problem I wrote about, most recently in answer to Ted's e-mail. (Sorry, I'm just worried it will get buried under all the others e-mails.)<br>
</div><div class="gmail_extra"><br><br><div class="gmail_quote">2013/7/24 Anna Zaks <span dir="ltr"><<a href="mailto:ganna@apple.com" target="_blank">ganna@apple.com</a>></span><br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<div style="word-wrap:break-word"><br><div><div class="im"><div>On Jul 24, 2013, at 10:08 AM, Gábor Kozár <<a href="mailto:kozargabor@gmail.com" target="_blank">kozargabor@gmail.com</a>> wrote:</div><br><blockquote type="cite">
<div style="letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px"><div dir="ltr"><div><div> Thanks for the info! I missed -analyze-function, because I grep-ed for "analyzer" (-analyzer-checker, -analyzer-checker-help, etc. - I assumed it's a general prefix).<br>
<br>><span> </span><i>This example definitely works for me:<br><br></i></div>Something weird is definitely going on here (see my last e-mail). I'll try to investigate tomorrow.<i><br><br>> We assume that you are developing against TOT unless stated otherwise. Is there a reason why you don't?<br>
<br></i></div>What do you mean by "TOT"?<br>If you're asking why I'm not using the latest SVN version, it's because my boss is concerned about stability. How stable is the current SVN build, in general? Is it reliable, in terms of existing features and functionality? Obviously I don't expect work-in-progress features to work, but it'd be nice if they were disabled by default until they are stable - is this currently done, or what is your policy in this?<br>
</div><div class="gmail_extra"><br></div></div></blockquote><div dir="auto"><br></div></div>We definitely recommend developing new analyzer features on the latest SVN revisions, even though they might be less stable than a released version. We constantly test the compiler and the analyzer and revert any commits that cause regressions. The release compiler receives more testing, but we do not do any additional analyzer tests for the release. The experimental features usually do not get turned on until ready.</div>
<span class="HOEnZb"><font color="#888888"><div><br></div><div>Anna.</div></font></span><div><div class="h5"><div><br><blockquote type="cite"><div style="letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px">
<div class="gmail_extra"><br><div class="gmail_quote">2013/7/24 Anna Zaks<span> </span><span dir="ltr"><<a href="mailto:ganna@apple.com" target="_blank">ganna@apple.com</a>></span><br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
<div style="word-wrap:break-word"><br><div><div><div>On Jul 24, 2013, at 7:12 AM, Gábor Kozár <<a href="mailto:kozargabor@gmail.com" target="_blank">kozargabor@gmail.com</a>> wrote:</div><br><blockquote type="cite">
<div style="letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px"><div dir="ltr"><div><div>Anna,<br><br></div>><span> </span><i>Can this be designed as an extension of the Dereference checker?<br>
<br></i></div>That was my original thought, but looking at the Dereference checker source code, it writes that it's a built-in check in ExprEngine, which discouraged me to try to extend it.</div></div></blockquote><div>
<br></div></div><div>I am not sure which code comment you are referring to but Dereference checker is a very good checker to learn from. I highly recommend to understand how it works before extending it.</div><div><br><blockquote type="cite">
<div style="letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px"><div dir="ltr"><div>I also have no idea how it works or what it does - I've been unable to have it produce any warnings, except for this trivial case:<br>
<br>Foo* fp = nullptr;<br>fp->baz();<br><br></div>And now I tried with your code example, and it also produces a warning. By the way, when analyzing a translation unit, which function(s) are treated as entry points?</div>
</div></blockquote><div><br></div></div><div>AnalysisConsumer.cpp contains code that decides on the order of the functions being analyzed, which ones are analyzed as top level, etc.</div><div><br><blockquote type="cite">
<div style="letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px">
<div dir="ltr">It appears to me that all of them are, but are there any restrictions, or ways to control this? I do not see any promising args with clang++ -cc1 --help.<br><br></div></div></blockquote></div><div>You might find this one helpful:</div>
<div><div style="margin:0px;font-size:11px;font-family:Menlo"> clang -cc1 -help | grep "function"</div><div style="margin:0px;font-size:11px;font-family:Menlo"> <span> </span>-analyze-function <value></div>
<div style="margin:0px;font-size:11px;font-family:Menlo"> <span> </span>Run analysis on specific function</div><div style="margin:0px;font-size:11px;font-family:Menlo"> <span> </span>Specify the function selection heuristic used during inlining</div>
<div style="margin:0px;font-size:11px;font-family:Menlo"> <span> </span>Force the static analyzer to analyze functions defined in header files</div><div style="margin:0px;font-size:11px;font-family:Menlo">
<span> </span>Analyze the definitions of blocks in addition to functions</div><div style="margin:0px;font-size:11px;font-family:Menlo"> <span> </span>Maximum depth of recursive constexpr function calls</div>
<div style="margin:0px;font-size:11px;font-family:Menlo"> <span> </span>Parse templated function definitions at the end of the translation unit </div><div><div style="margin:0px;font-size:11px;font-family:Menlo">
-analyzer-display-progress</div><div style="margin:0px;font-size:11px;font-family:Menlo"> <span> </span>Emit verbose output about the analyzer's progress</div></div><div style="margin:0px;font-size:11px;font-family:Menlo">
<br></div><div>Also, AnalyzerOptions.cpp is a good reference for analyzer options. </div><div><br></div></div><div><blockquote type="cite"><div style="letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px">
<div dir="ltr"><div><div><div>Anyway, this code snippet still does not cause the Dereference checker to raise a warning, even though it is trivial:<br><br></div>Foo* fp = getFooPtr(); // based on runtime data, either returns nullptr, or an allocated object<br>
</div>if(!fp)<br>{<br></div> <span> </span>fp->baz();<br><div>}<br><br></div></div></div></blockquote><div dir="auto"><br></div></div><div dir="auto">This example definitely works for me:</div><div dir="auto"><br>
</div>
<div style="margin:0px;font-size:11px;font-family:Menlo">zaks$ cat ~/tmp/ex.cpp</div><div style="margin:0px;font-size:11px;font-family:Menlo">struct Foo {</div><div style="margin:0px;font-size:11px;font-family:Menlo"> <span> </span>void baz();</div>
<div style="margin:0px;font-size:11px;font-family:Menlo">};</div><div style="margin:0px;font-size:11px;font-family:Menlo">Foo* getFooPtr();</div><div style="margin:0px;font-size:11px;font-family:Menlo">void f() {</div><div>
<div style="margin:0px;font-size:11px;font-family:Menlo"> <span> </span>Foo* fp = getFooPtr(); // based on runtime data, either returns nullptr, or an allocated object</div><div style="margin:0px;font-size:11px;font-family:Menlo">
<span> </span>if(!fp) {</div><div style="margin:0px;font-size:11px;font-family:Menlo"> <span> </span>fp->baz();</div><div style="margin:0px;font-size:11px;font-family:Menlo"> <span> </span>}</div><div style="margin:0px;font-size:11px;font-family:Menlo">
}</div><div style="margin:0px;font-size:11px;font-family:Menlo"><br></div></div><div style="margin:0px;font-size:11px;font-family:Menlo"><div style="margin:0px">$ clang --analyze ~/tmp/ex.cpp</div><div style="margin:0px">
<b>/Users/zaks/tmp/ex.cpp:8:7:<span> </span></b><span style="color:rgb(213,59,211)"><b>warning:<span> </span></b></span><b>Called C++ object pointer is null</b></div><div style="margin:0px"> <span> </span>fp->baz();</div>
<div style="margin:0px;color:rgb(52,189,38)"><b> <span> </span>^~~~~~~~~</b></div><div style="margin:0px">1 warning generated.</div><div style="margin:0px"><br></div></div><div><blockquote type="cite"><div style="letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px">
<div dir="ltr"><div>To the best of my knowledge, the if(!bar) line creates two code paths: one on which the condition is true (i.e. fp == nullptr), and one on which the condition is false (i.e. fp != nullptr). Obviously the first statement on the former code path is the fp->baz() line, analyzing which the Static Analyzer tells me that 'fp' is constrained to be null (using ProgramState::isNull). Therefore, my checker can easily find this issue.<br>
<br></div><div>Browsing through the source code of the DereferenceChecker, I can tell it does not use ProgramState::isNull, but instead ProgramState::assume. However, as far as I can tell, it does exactly nothing - I can see that it's supposed to either raise a warning, or dispatch an ImplicitNullDerefEvent, but neither happens on the code example above (I tested the latter by running both checkers with -analyzer-checker, and in my checker, I subscribe to check::Event<ImplicitNullDerefEvent>).<br>
<br></div><div>So why is ProgramState::assume used instead of ProgramState::isNull?<br><br></div></div></div></blockquote><div><br></div></div>If you drill down the implementation of isNull, you'll see that it's similar to assume, possibly more efficient and specialized for NULL.<div>
<br><br><blockquote type="cite"><div style="letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px"><div dir="ltr"><div>><span> </span><i>Also, the Dereference checker does work fine in presence of aliases... Is there a reason why it's different in your setting?<br>
<br></i></div><div>I'm using Clang 3.3, so unless significant changes have been made to the Static Analyzer or the Dereference checker, things should work the same. I have not modified the Clang source code, except for adding a bunch of custom checkers.<br>
<br></div></div></div></blockquote><div><br></div></div><div>We assume that you are developing against TOT unless stated otherwise. Is there a reason why you don't?</div><div><div><br><blockquote type="cite"><div style="letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px">
<div dir="ltr">Gabor<br></div><div class="gmail_extra"><br><br><div class="gmail_quote">2013/7/23 Anna Zaks<span> </span><span dir="ltr"><<a href="mailto:ganna@apple.com" target="_blank">ganna@apple.com</a>></span><br>
<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div style="word-wrap:break-word"><br><div><div><div>On Jul 23, 2013, at 10:33 AM, Gábor Kozár <<a href="mailto:kozargabor@gmail.com" target="_blank">kozargabor@gmail.com</a>> wrote:</div>
<br><blockquote type="cite"><div style="letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px"><div dir="ltr"><div>Hi Anna,<br><br></div>I'm building a checker that detects inconsistent pointer usages, for example when a pointer is dereferenced, then along the same path is null-checked (without its value changing in between, obviously).</div>
</div></blockquote><div><br></div></div><div>Can this be designed as an extension of the Dereference checker? </div><div><br></div><div>Also, the Dereference checker does work fine in presence of aliases... Is there a reason why it's different in your setting?</div>
<div><br></div><div><div>int foo(int *p) {</div><div> <span> </span>int *q = p;</div><div> <span> </span>if (q)</div><div> <span> </span>;</div><div> <span> </span>return *p; </div><div>}</div><div><br></div><div><div style="margin:0px;font-size:11px;font-family:Menlo">
zaks$ clang --analyze ~/tmp/ex.c -Xclang -analyzer-output=text</div><div style="margin:0px;font-size:11px;font-family:Menlo"><b>/Users/zaks/tmp/ex.c:5:10:<span> </span></b><span style="color:rgb(213,59,211)"><b>warning:<span> </span></b></span><b>Dereference of null pointer (loaded from variable 'p')</b></div>
<div style="margin:0px;font-size:11px;font-family:Menlo"> <span> </span>return *p; </div><div style="margin:0px;font-size:11px;font-family:Menlo;color:rgb(52,189,38)"><b> <span> </span>^~</b></div><div style="margin:0px;font-size:11px;font-family:Menlo">
<b>/Users/zaks/tmp/ex.c:3:7: note:<span> </span></b>Assuming 'q' is null</div><div style="margin:0px;font-size:11px;font-family:Menlo"> <span> </span>if (q)</div><div style="margin:0px;font-size:11px;font-family:Menlo;color:rgb(52,189,38)">
<b> <span> </span>^</b></div><div style="margin:0px;font-size:11px;font-family:Menlo"><b>/Users/zaks/tmp/ex.c:3:3: note:<span> </span></b>Taking false branch</div><div style="margin:0px;font-size:11px;font-family:Menlo">
<span> </span>if (q)</div><div style="margin:0px;font-size:11px;font-family:Menlo;color:rgb(52,189,38)"><b> <span> </span>^</b></div><div style="margin:0px;font-size:11px;font-family:Menlo"><b>/Users/zaks/tmp/ex.c:5:10: note:<span> </span></b>Dereference of null pointer (loaded from variable 'p')</div>
<div style="margin:0px;font-size:11px;font-family:Menlo"> <span> </span>return *p; </div><div style="margin:0px;font-size:11px;font-family:Menlo;color:rgb(52,189,38)"><b> <span> </span>^</b></div><div style="margin:0px;font-size:11px;font-family:Menlo">
1 warning generated.</div><div><br></div></div></div><div><br><blockquote type="cite"><div style="letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px"><div dir="ltr">
<div><div><div><div><div><div><div><div>Code example:<br><br></div>Foo* f = getFoo();<br></div>f->bar();<br><br></div>if(f) // warn<br>{ ... }<br><br></div>I want to be able to do this with aliases as well, for example:<br>
<br></div>Foo* f = getFoo();<br></div>f->bar();<br><br>Foo* g = f;<br>if(g) // warn<br>{ ... }<br><br></div>What I need is to be able to get the SVals representing 'f' and 'g' when checkBind is called on the Foo* g = f; line. Currently, instead of 'f', Clang gives me the value that was bound to 'f'.<br>
<br></div>Thanks for your help!<br></div><div class="gmail_extra"><br><br><div class="gmail_quote">2013/7/23 Anna Zaks<span> </span><span dir="ltr"><<a href="mailto:ganna@apple.com" target="_blank">ganna@apple.com</a>></span><br>
<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div style="word-wrap:break-word"><br><div><div><div>On Jul 23, 2013, at 9:21 AM, Gábor Kozár <<a href="mailto:kozargabor@gmail.com" target="_blank">kozargabor@gmail.com</a>> wrote:</div>
<br><blockquote type="cite"><div style="letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px"><div dir="ltr"><div><div><div><div>During the analysis of a test code, the following two bindings happen (checkBind), with their respective source lines:<br>
<br></div>(Bind: location <= value)<br><br>Bind: &fp <= &SymRegion{conj_$4{struct Foo *}}<br></div>Code: Foo* fp = getFooPtr();<br><br>Bind: &ap <= &SymRegion{conj_$4{struct Foo *}}<br></div>Code: Foo* ap = fp;<br>
<br></div>In the second line, I need to detect that 'ap' is in fact the alias of 'fp'. Unfortunately, I cannot seem to find any way to get Clang SA to tell me that "&SymRegion{conj_$4{struct Foo *}}" is stored in "fp", which seems weird, because the source code is very clear.<br>
</div></div></blockquote><div dir="auto"><br></div></div><div dir="auto">As you observe the two binds you see that the same value is stored in both.</div><div dir="auto"><br></div><div dir="auto">The analyzer does not perform alias analyzes as in it does not build sets of aliases. As it models the execution in presence of aliases, we did not find a need for the alias sets. Can you give a bit more background on why you need this info? Maybe your goal can be achieved differently?</div>
<br><blockquote type="cite"><div style="letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px"><div><div dir="ltr"><div><br></div><div>Some of the information I extracted, but is not really useful to me:<br>
</div><div> - original SVal: &SymRegion{conj_$4{struct Foo *}}<br></div><div> - getAsRegion(): SymRegion{conj_$4{struct Foo *}}<br></div><div> - state->getSVal(): &SymRegion{reg_$6<element{SymRegion{conj_$4{struct Foo *}},0 S32b,struct Foo *}>} -- in fact, I have no idea what this is<br>
</div><div> - getAsSymbol(): conj_$4{struct Foo *}<br></div><div><br></div>As a workaround, I can keep track of this information myself, but there must be a built-in way to do this.<br>Any help would be appreciated. Many thanks!<br>
</div></div>_______________________________________________<br>cfe-dev mailing list<br><a href="mailto:cfe-dev@cs.uiuc.edu" target="_blank">cfe-dev@cs.uiuc.edu</a><br><a href="http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev</a></div>
</blockquote></div></div></blockquote></div></div></div></blockquote></div></div></div></blockquote></div></div></div></blockquote></div></div></div></div></blockquote></div></div></div></blockquote></div><br></div></div>
</div></blockquote></div><br></div>