<div dir="ltr"><div><div><div><div><div><div>Anna,<br><br></div>> <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. 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? 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>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>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>> <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>Gabor<br></div></div><div class="gmail_extra"><br><br><div class="gmail_quote">2013/7/23 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 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><div><div><div><div><div><div><div><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></div></div></div></div></div></div></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>  int *q = p;</div><div>  if (q)</div><div>    ;</div><div>  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: </b><span style="color:#d53bd3"><b>warning: </b></span><b>Dereference of null pointer (loaded from variable 'p')</b></div>

<div style="margin:0px;font-size:11px;font-family:Menlo">  return *p;  </div><div style="margin:0px;font-size:11px;font-family:Menlo;color:rgb(52,189,38)"><b>         ^~</b></div><div style="margin:0px;font-size:11px;font-family:Menlo">

<b>/Users/zaks/tmp/ex.c:3:7: note: </b>Assuming 'q' is null</div><div style="margin:0px;font-size:11px;font-family:Menlo">  if (q)</div><div style="margin:0px;font-size:11px;font-family:Menlo;color:rgb(52,189,38)">

<b>      ^</b></div><div style="margin:0px;font-size:11px;font-family:Menlo"><b>/Users/zaks/tmp/ex.c:3:3: note: </b>Taking false branch</div><div style="margin:0px;font-size:11px;font-family:Menlo">  if (q)</div><div style="margin:0px;font-size:11px;font-family:Menlo;color:rgb(52,189,38)">

<b>  ^</b></div><div style="margin:0px;font-size:11px;font-family:Menlo"><b>/Users/zaks/tmp/ex.c:5:10: note: </b>Dereference of null pointer (loaded from variable 'p')</div><div style="margin:0px;font-size:11px;font-family:Menlo">

  return *p;  </div><div style="margin:0px;font-size:11px;font-family:Menlo;color:rgb(52,189,38)"><b>         ^</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><br></div></blockquote></div><br></div>