<br><br><div class="gmail_quote">On Tue, Jun 29, 2010 at 1:03 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:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">
<br><div class="im">
>> Why does that matter? Because an ownership_takes() or ownership_holds()<br>
>> function might have a return value! If it's also ownership_returns(),<br>
>> then<br>
>> you're fine, but otherwise you need to set a symbolic return value.<br>
(You<br>
>> can see how this is done in MallocMemAux(), or in StreamChecker.cpp<br>
with<br>
>> fopen.) There should probably be a test for this as well.<br>
><br>
><br>
> It isn't necessarily the case that an ownership_takes() function that<br>
> returns a pointer generated that pointer from an ownership_takes<br>
argument,<br>
> or allocated anything, so what would you set the region to, in the<br>
absence<br>
> of other information?  They default to Unknown, yes?<br>
<br>
</div>I believe so, but for return values from function calls we prefer to use a<br>
"conjured symbol value". This is a kind of value that can be reasoned about<br>
symbolically in later statements -- for example, we can bound its value if<br>
it's an integer, or mark that it's null or non-null if it's a pointer.</blockquote><div><br></div><div>So, I'm still not sure I understand what you mean me to do here... could you elaborate?</div><div><br>
</div><div>Since you seem to be the symbolic value expert, I'll ask about the case I'm trying to solve now.  I added some symbolic checks to the free handling, similar to realloc, to prevent warnings in the common case of error handling for allocation handlers.</div>
<div><br></div><div>So now this works:</div><div><br></div><div><div>char *  __attribute((ownership_returns(malloc))) foo(void) {</div><div>  char *textString = malloc(128*sizeof(char));</div><div>  if(textString == NULL)</div>
<div>    return NULL; // No warning here</div><div>  return textString;</div><div>}</div></div><div><br></div><div>But now I have this:</div><div><br></div><div>struct it {</div><div>  char * s;</div><div>};</div><div><br>
</div><div>struct it *  __attribute((ownership_returns(malloc))) foo(void) {</div><div>  struct it *rv = malloc(sizeof(struct it));</div><div>  if (!rv)</div><div>    return NULL; // Does not warn here.</div><div>  char *textString = malloc(128*sizeof(char));</div>
<div>  if(textString == NULL)</div><div>    free(rv);</div><div>    return NULL; // Warns about a memory leak here</div><div>  rv->s = textString;</div><div>  return rv; // Does NOT warn here</div><div>}</div><div><br>
</div></div>