<html><head><meta http-equiv="Content-Type" content="text/html charset=us-ascii"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;"><br><div><div>On May 12, 2014, at 20:09 , Ivan Reche <<a href="mailto:ivan.reche@gmail.com">ivan.reche@gmail.com</a>> wrote:</div><br class="Apple-interchange-newline"><blockquote type="cite"><div dir="ltr">Hey all,<div><br></div><div><div>Suppose I'm working with the following C snippet:</div><div><br></div><div>void inc(int *num) {*num++;}</div><div>void dec(int *num) {*num--;}</div><div><br></div><div>void f(int var) {</div>
<div> inc(&var);</div><div> dec(&var);</div><div>}</div><div><br></div><div>By using a static analyzer, I want to be able to tell if the value of var didn't change during the function's execution. I know I have to keep its state on my own (that's the point of writing a Clang checker), but I'm having troubles getting a unique reference of this variable.</div>
<div><br></div><div>For example: if I use the following API</div><div><br></div><div>void MySimpleChecker::checkPostCall(const CallEvent &Call,</div><div> CheckerContext &C) const {</div>
<div> SymbolRef MyArg = Call.getArgSVal(0).getAsSymbol();</div><div>}</div><div><br></div><div>I'd expect it to return a pointer to this symbol's representation in my checker's context. However, I always get 0 into MyArg by using it this way. This happens for both inc and dec functions in the pre and post callbacks.</div>
<div><br></div><div>What am I missing here? What concepts did I get wrong?</div><div><br></div><div>Note: I'm currently reading the Clang CFE Internals Manual and I've read the excellent How to Write a Checker in 24 Hours material. I still couldn't find my answer so far.</div>
</div></div></blockquote><br></div><div>Hi, Ivan. The value that gets passed to 'inc' or 'dec' is the address of 'var', yes? And 'var' is a parameter to the function 'f'. While the <i>value</i> of 'var' could be anything, the memory for the <i>parameter itself</i> is something the analyzer can model perfectly, as a VarRegion. The <i>address</i> of that memory would be a loc::MemRegionVal pointing to that VarRegion. And that's the SVal that gets passed to 'inc' and 'dec'. No symbols involved.</div><div><br></div><div>Now, as it turns out the analyzer <i>does</i> track the contents of memory regions (conservatively), so you <i>don't</i> have to keep the state on your own. This is what the Store is for, and you can get at the analyzer's current representation of the contents by using "ProgramState::getSVal", specifically the overload that takes a Loc or a MemRegion. If you pass the region for the parameter here, you'll get the symbolic value representing its contents. If the value for the contents changes between the start and the end of the function, one of three things could have happened:</div><div><br></div><div>- Someone has stored something to the region.</div><div>- Someone has <i>added constraints</i> to the value in the region, and now the analyzer has more information about it.</div><div>- The region has "escaped", and we don't know whether another function is going to modify it. (For example, if you pass the address of the region to a function whose body the analyzer cannot see.)</div><div><br></div><div>That's not bad, but depending on what you want, there's an even more targeted way to do this: the checkBind and checkRegionChanges callbacks. These tell you when any value is assign to a region and when a region changes for <i>any</i> reason, respectively. Using those together might give you a good chance at tracking the information you need.</div><div><br></div><div>Hope that helps,</div><div>Jordan</div><br></body></html>