Ok, here's a version that I think has the state transitions right.<div><br></div><div>Andrew<br><br><div class="gmail_quote">On Tue, Jul 27, 2010 at 10:45 PM, Ted Kremenek <span dir="ltr"><<a href="mailto:kremenek@apple.com">kremenek@apple.com</a>></span> wrote:<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"><div><div class="im"><div>On Jul 27, 2010, at 3:11 PM, Andrew McGregor wrote:</div><br>
<blockquote type="cite"><span style="border-collapse:separate;font-family:Helvetica;font-style:normal;font-variant:normal;font-weight:normal;letter-spacing:normal;line-height:normal;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;font-size:medium"><div>
 </div><blockquote class="gmail_quote" style="margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left: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">
<div><div><br></div><div>+</div><div>+  SymbolRef Sym = val.getLocSymbolInBase();</div><div>+  if (Sym) {</div><div>+    const RefState *RS = state->get<RegionState>(Sym);</div><div><br></div><div>I think you want to use 'notNullState' here, since your assumption is that this transition occurs only when the value is non-null.  When 'nullState' is not null, you'll also probably want a transition so that path has consistent checking of the nullity of the symbol.</div>
</div></div></blockquote><div><br></div><div>Not sure I understand... the RegionState is used because I'm getting at and assuming forward the semantics of the memory region being assigned away, and not touching the null or otherwise assumptions.  </div>
</span></blockquote><div><br></div></div><div>But the non-nullness is a precondition for the checker state to change, so this should be recorded as part of the "assumptions".</div><div class="im"><br><blockquote type="cite">
<span style="border-collapse:separate;font-family:Helvetica;font-style:normal;font-variant:normal;font-weight:normal;letter-spacing:normal;line-height:normal;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;font-size:medium"><div>
Should I be using notNullState to assert that the assignee is not null?</div></span></blockquote><br></div></div><div>Yes basically.</div><br><div>I'll try and explain with an example.  Suppose we were analyzing:</div>
<div><br></div><div>  foo(p);</div><div>  bar(p);</div><div><br></div><div>and 'foo' and 'bar' modified some checker-state (like your checker does) associated with p, but only if p is not null.  Conceptually there are only two possible 'nullity' cases for 'p':</div>
<div><br></div><div>(1)</div><div><br></div><div>  foo(p); // we check if 'p' is null, and assume it is null</div><div>  bar(p); // 'p' is still null</div><div><br></div><div>(2)</div><div><br></div><div>  foo(p); // we check if 'p' is null, and assume it isn't; go modify checker state</div>
<div>  bar(p); // 'p' is not null; go modify checker state</div><div><br></div><div>However, with what you have, we basically have 4 possibilities; I'll list the two additional ones:</div><div><br></div><div>(3)</div>
<div><br></div><div>  foo(p); // we check if 'p' is null, and assume it is null</div><div>  bar(p); // we don't record that we checked if 'p' is null, we check again and assume that it isn't null; modify state</div>
<div><br></div><div>(4)</div><div><br></div><div>  foo(p); // we check if 'p' is null, and assume it isn't; go modify checker state</div><div>  bar(p); // we don't record that we checked if 'p' is null, we check again and assume that it is null and do nothing</div>
<div><br></div><div>What you are seeing from (3) and (4) is part of (I believe) the "frame problem" from AI.  By having the following statement use 'state' instead of 'notNullState', you are forgetting the nullity check:</div>
<div><br></div><div>   // We no longer own this pointer.<br>  state = state->set<RegionState>(Sym, RefState::getRelinquished(StoreE));</div><div><br></div><div>When you use the 'assume' function, 'state' is not modified.  Instead it returns two new states; one where the assumption is true and the other where it is false.  If your modification to the checker state implies that the pointer was non-null, you should be using the 'notNullState' here instead of 'state' as that is a requirement for the checker state to change.</div>
<div><br></div><div>Similarly, if you add a transition where 'notNullState' is non-null and don't add a transition for 'nullState', then you will prune out paths where 'p' is null.  Essentially this would prune out path (1).</div>
<div><br></div><div>Does this make any more sense?</div></div></blockquote></div><br></div>