<html><head></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; "><div><div>On Jul 1, 2010, at 8:08 PM, Andrew McGregor wrote:</div><br class="Apple-interchange-newline"><blockquote type="cite">Ok, I get what you're saying, PreVisit seems the right answer.<br><br><div class="gmail_quote">On Fri, Jul 2, 2010 at 2:41 PM, Jordy Rose <span dir="ltr"><<a href="mailto:jediknil@belkadan.com">jediknil@belkadan.com</a>></span> wrote:<br>
<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; position: static; z-index: auto; "><br>
<div class="im"><br>
> struct it *  __attribute((ownership_returns(malloc))) foo(void) {<br>
>   struct it *rv = malloc(sizeof(struct it));<br>
>   if (!rv)<br>
>     return NULL; // Does not warn here.<br>
>   char *textString = malloc(128*sizeof(char));<br>
>   if(textString == NULL)<br>
>     free(rv);<br>
>     return NULL; // Warns about a memory leak here<br>
>   rv->s = textString;<br>
>   return rv; // Does NOT warn here<br>
> }<br>
<br>
</div>...the code is just missing braces around the second if -- the second<br>
"return NULL" is unconditional!<br>
<br>
Clang should catch this. Filing a bug. *grin*<br>
</blockquote></div><br><div>D'oh!</div><div><br></div><div>So looking at this version:</div><div><br></div><div><div>void  __attribute((ownership_returns(malloc))) foo2(void) {</div><div>  struct it *rv = malloc(sizeof(struct it));</div>
<div>  if (!rv)</div><div>    return NULL;</div><div>  char *textString = malloc(128*sizeof(char));</div><div>  if(textString == NULL) {</div><div>    free(rv);</div><div>    return NULL;</div><div>  }</div><div>  rv->s = textString;</div>
<div>  return rv; // warns of a leak here</div><div>}</div><div><br></div></div><div>How could I make the assignment before the final return relinquish ownership of the pointer?</div></blockquote><br></div><div>CheckerVisitor also supports PreVisitBind (which is callback that occurs before the RHS gets bound to the LHS).  You can use that to monitor ownership transfer.  We can also add PostVisitBind if that would be useful.</div><div><br></div><div>That said, what are the semantics of the ownership algorithm?  Does a leak get flagged here, or does the escape of the value to a field silence the warning?</div><div><br></div><div>FWIW, ownership checking in the presence of data containers has been researched quite a bit.  Here's some off-hand references that might be useful:</div><div><br></div><div>Static Detection of Leaks in Polymorphic Containers, ICSE 2006</div><div><a href="http://suif.stanford.edu/~dlheine/icse06-preprint.pdf">http://suif.stanford.edu/~dlheine/icse06-preprint.pdf</a></div><br><div>A practical flow-sensitive and context-sensitive C and C++ memory leak detector<br><a href="http://portal.acm.org/citation.cfm?doid=781131.781150">http://portal.acm.org/citation.cfm?doid=781131.781150</a></div><div><br></div></body></html>