<html><head><meta http-equiv="Content-Type" content="text/html charset=iso-8859-1"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;"><br><div><div>On Jul 24, 2013, at 7:12 AM, Gábor Kozár <<a href="mailto:kozargabor@gmail.com">kozargabor@gmail.com</a>> wrote:</div><br class="Apple-interchange-newline"><blockquote type="cite"><div style="letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;"><div dir="ltr"><div><div><div><div><div><div>Anna,<br><br></div>><span class="Apple-converted-space"> </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></div></div></div></div></blockquote><div><br></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><br><blockquote type="cite"><div style="letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;"><div dir="ltr"><div><div><div><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></div></div></div></blockquote><div><br></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><br><blockquote type="cite"><div style="letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;"><div dir="ltr"><div><div><div>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></div></div></div></blockquote><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;"> -analyze-function <value></div><div style="margin: 0px; font-size: 11px; font-family: Menlo;"> Run analysis on specific function</div><div style="margin: 0px; font-size: 11px; font-family: Menlo;"> Specify the function selection heuristic used during inlining</div><div style="margin: 0px; font-size: 11px; font-family: Menlo;"> Force the static analyzer to analyze functions defined in header files</div><div style="margin: 0px; font-size: 11px; font-family: Menlo;"> Analyze the definitions of blocks in addition to functions</div><div style="margin: 0px; font-size: 11px; font-family: Menlo;"> Maximum depth of recursive constexpr function calls</div><div style="margin: 0px; font-size: 11px; font-family: Menlo;"> 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;"> 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><blockquote type="cite"><div style="letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 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> fp->baz();<br><div>}<br><br></div></div></div></blockquote><div dir="auto"><br></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;"> 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 style="margin: 0px; font-size: 11px; font-family: Menlo;"> 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;"> if(!fp) {</div><div style="margin: 0px; font-size: 11px; font-family: Menlo;"> fp->baz();</div><div style="margin: 0px; font-size: 11px; font-family: Menlo;"> }</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 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: </b><span style="color: #d53bd3"><b>warning: </b></span><b>Called C++ object pointer is null</b></div><div style="margin: 0px;"> fp->baz();</div><div style="margin: 0px; color: rgb(52, 189, 38);"><b> ^~~~~~~~~</b></div><div style="margin: 0px;">1 warning generated.</div><div style="margin: 0px;"><br></div></div><blockquote type="cite"><div style="letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 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>If you drill down the implementation of isNull, you'll see that it's similar to assume, possibly more efficient and specialized for NULL.<br><br><blockquote type="cite"><div style="letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;"><div dir="ltr"><div>><span class="Apple-converted-space"> </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>We assume that you are developing against TOT unless stated otherwise. Is there a reason why you don't?</div><br><blockquote type="cite"><div style="letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;"><div dir="ltr"><div>Gabor<br></div></div><div class="gmail_extra"><br><br><div class="gmail_quote">2013/7/23 Anna Zaks<span class="Apple-converted-space"> </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 class="im"><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 class="Apple-converted-space"> </span>int *q = p;</div><div> <span class="Apple-converted-space"> </span>if (q)</div><div> <span class="Apple-converted-space"> </span>;</div><div> <span class="Apple-converted-space"> </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 class="Apple-converted-space"> </span></b><span style="color: rgb(213, 59, 211);"><b>warning:<span class="Apple-converted-space"> </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 class="Apple-converted-space"> </span>return *p; </div><div style="margin: 0px; font-size: 11px; font-family: Menlo; color: rgb(52, 189, 38);"><b> <span class="Apple-converted-space"> </span>^~</b></div><div style="margin: 0px; font-size: 11px; font-family: Menlo;"><b>/Users/zaks/tmp/ex.c:3:7: note:<span class="Apple-converted-space"> </span></b>Assuming 'q' is null</div><div style="margin: 0px; font-size: 11px; font-family: Menlo;"> <span class="Apple-converted-space"> </span>if (q)</div><div style="margin: 0px; font-size: 11px; font-family: Menlo; color: rgb(52, 189, 38);"><b> <span class="Apple-converted-space"> </span>^</b></div><div style="margin: 0px; font-size: 11px; font-family: Menlo;"><b>/Users/zaks/tmp/ex.c:3:3: note:<span class="Apple-converted-space"> </span></b>Taking false branch</div><div style="margin: 0px; font-size: 11px; font-family: Menlo;"> <span class="Apple-converted-space"> </span>if (q)</div><div style="margin: 0px; font-size: 11px; font-family: Menlo; color: rgb(52, 189, 38);"><b> <span class="Apple-converted-space"> </span>^</b></div><div style="margin: 0px; font-size: 11px; font-family: Menlo;"><b>/Users/zaks/tmp/ex.c:5:10: note:<span class="Apple-converted-space"> </span></b>Dereference of null pointer (loaded from variable 'p')</div><div style="margin: 0px; font-size: 11px; font-family: Menlo;"> <span class="Apple-converted-space"> </span>return *p; </div><div style="margin: 0px; font-size: 11px; font-family: Menlo; color: rgb(52, 189, 38);"><b> <span class="Apple-converted-space"> </span>^</b></div><div style="margin: 0px; font-size: 11px; font-family: Menlo;">1 warning generated.</div><div><br></div></div></div><div><div class="h5"><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></div></blockquote></div></div></div></blockquote></div><br></body></html>