<html><head><meta http-equiv="Content-Type" content="text/html charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><br class=""><div><blockquote type="cite" class=""><div class="">On Jul 14, 2017, at 12:31 PM, Malhar Thakkar <<a href="mailto:cs13b1031@iith.ac.in" class="">cs13b1031@iith.ac.in</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><div dir="ltr" class="">evalCall-ing a function based on annotations worked for the most part except for the following scenario.<div class=""><br class=""></div><div class="">If the definition of the annotated function is <i style="font-weight:bold" class="">after </i>it is called somewhere in the code, the RetainCountChecker is unable to "see" the annotation on this function (I checked this by printing debug messages in evalCall to see if the RetainCountChecker is able to find the annotation).</div><div class=""><br class=""></div><div class="">Consider the following examples.</div><div class=""><b class=""><font class=""><br class=""></font></b></div><div class="">
<h2 class=""></h2>
<div class="gmail-highlight" style="background:rgb(248,248,248)"><pre class=""><b class=""><font class="">// Definition of annotated function after it is called.</font></b></pre><pre class=""><span style="color:rgb(188,122,0)" class="">#define NULL 0</span>
<span style="color:rgb(0,128,0);font-weight:bold" class="">typedef</span> <span style="color:rgb(0,128,0);font-weight:bold" class="">struct</span>
{
<span style="color:rgb(176,0,64)" class="">int</span> ref;
} isl_basic_map;
<span style="color:rgb(176,0,64)" class="">void</span> <span style="color:rgb(0,0,255)" class="">free</span>(<span style="color:rgb(176,0,64)" class="">void</span> <span style="color:rgb(102,102,102)" class="">*</span>);
__isl_give isl_basic_map <span style="color:rgb(102,102,102)" class="">*</span><span style="color:rgb(0,0,255)" class="">foo</span>(__isl_take isl_basic_map <span style="color:rgb(102,102,102)" class="">*</span>bmap);
isl_basic_map <span style="color:rgb(102,102,102)" class="">*</span><span style="color:rgb(0,0,255)" class="">isl_basic_map_free</span>(__isl_take isl_basic_map <span style="color:rgb(102,102,102)" class="">*</span>bmap);
__isl_give isl_basic_map <span style="color:rgb(102,102,102)" class="">*</span><span style="color:rgb(0,0,255)" class="">bar</span>(__isl_take isl_basic_map <span style="color:rgb(102,102,102)" class="">*</span>bmap) {
bmap <span style="color:rgb(102,102,102)" class="">=</span> foo(bmap);
<span style="color:rgb(0,128,0);font-weight:bold" class="">return</span> isl_basic_map_free(bmap); <b class="">// Leak warning for 'bmap' raised here.</b>
}
__attribute__((annotate(<span style="color:rgb(186,33,33)" class="">"rc_ownership_trusted_implementation"</span>))) isl_basic_map <span style="color:rgb(102,102,102)" class="">*</span>isl_basic_map_free(__isl_take isl_basic_map <span style="color:rgb(102,102,102)" class="">*</span>bmap)
{
<span style="color:rgb(0,128,0);font-weight:bold" class="">if</span> (<span style="color:rgb(102,102,102)" class="">!</span>bmap)
<span style="color:rgb(0,128,0);font-weight:bold" class="">return</span> <span style="color:rgb(0,128,0)" class="">NULL</span>;
<span style="color:rgb(0,128,0);font-weight:bold" class="">if</span> (<span style="color:rgb(102,102,102)" class="">--</span>bmap<span style="color:rgb(102,102,102)" class="">-></span>ref <span style="color:rgb(102,102,102)" class="">></span> <span style="color:rgb(102,102,102)" class="">0</span>)
<span style="color:rgb(0,128,0);font-weight:bold" class="">return</span> <span style="color:rgb(0,128,0)" class="">NULL</span>;
free(bmap);
<span style="color:rgb(0,128,0);font-weight:bold" class="">return</span> <span style="color:rgb(0,128,0)" class="">NULL</span>;
}</pre></div></div><div class="gmail_extra"><b class=""><font class=""><br class=""></font></b></div><div class="gmail_extra">
<h2 class=""></h2>
<div class="gmail-highlight" style="background:rgb(248,248,248)"><pre class=""><b class=""><font class="">// Definition of annotated function before it is called.</font></b></pre><pre class=""><span style="color:rgb(188,122,0)" class="">#define NULL 0</span>
<span style="color:rgb(0,128,0);font-weight:bold" class="">typedef</span> <span style="color:rgb(0,128,0);font-weight:bold" class="">struct</span>
{
<span style="color:rgb(176,0,64)" class="">int</span> ref;
} isl_basic_map;
<span style="color:rgb(176,0,64)" class="">void</span> <span style="color:rgb(0,0,255)" class="">free</span>(<span style="color:rgb(176,0,64)" class="">void</span> <span style="color:rgb(102,102,102)" class="">*</span>);
__isl_give isl_basic_map <span style="color:rgb(102,102,102)" class="">*</span><span style="color:rgb(0,0,255)" class="">foo</span>(__isl_take isl_basic_map <span style="color:rgb(102,102,102)" class="">*</span>bmap);
isl_basic_map <span style="color:rgb(102,102,102)" class="">*</span><span style="color:rgb(0,0,255)" class="">isl_basic_map_free</span>(__isl_take isl_basic_map <span style="color:rgb(102,102,102)" class="">*</span>bmap);
__attribute__((annotate(<span style="color:rgb(186,33,33)" class="">"rc_ownership_trusted_implementation"</span>))) isl_basic_map <span style="color:rgb(102,102,102)" class="">*</span>isl_basic_map_free(__isl_take isl_basic_map <span style="color:rgb(102,102,102)" class="">*</span>bmap)
{
<span style="color:rgb(0,128,0);font-weight:bold" class="">if</span> (<span style="color:rgb(102,102,102)" class="">!</span>bmap)
<span style="color:rgb(0,128,0);font-weight:bold" class="">return</span> <span style="color:rgb(0,128,0)" class="">NULL</span>;
<span style="color:rgb(0,128,0);font-weight:bold" class="">if</span> (<span style="color:rgb(102,102,102)" class="">--</span>bmap<span style="color:rgb(102,102,102)" class="">-></span>ref <span style="color:rgb(102,102,102)" class="">></span> <span style="color:rgb(102,102,102)" class="">0</span>)
<span style="color:rgb(0,128,0);font-weight:bold" class="">return</span> <span style="color:rgb(0,128,0)" class="">NULL</span>;
free(bmap);
<span style="color:rgb(0,128,0);font-weight:bold" class="">return</span> <span style="color:rgb(0,128,0)" class="">NULL</span>;
}
__isl_give isl_basic_map <span style="color:rgb(102,102,102)" class="">*</span>bar(__isl_take isl_basic_map <span style="color:rgb(102,102,102)" class="">*</span>bmap) {
bmap <span style="color:rgb(102,102,102)" class="">=</span> foo(bmap);
<span style="color:rgb(0,128,0);font-weight:bold" class="">return</span> <span style="color:rgb(0,0,255)" class="">isl_basic_map_free</span>(bmap); <b class="">// No leak warning for 'bmap' raised here.</b>
}
</pre></div></div><div class="gmail_extra">It would really help me if someone could point out why the RetainCountChecker behaves this way.</div></div></div></blockquote><div><br class=""></div><div>I don’t know. One thing to note is that unlike most annotations, this one seems like it belongs on the definition of the function and not its interface, so you probably want to use getDefinition() to get the FuncDecl corresponding to the definition of the function body.</div><br class=""><blockquote type="cite" class=""><div class=""><div dir="ltr" class=""><div class="gmail_extra">Also, I have a few queries directed to Dr. Alexandre and Dr. Sven.</div><div class="gmail_extra">I applied these trusted annotations to obj_free(), obj_cow() and obj_copy() as they have a pattern (__isl.*free, __isl.*cow and __isl.*copy). </div><div class="gmail_extra"><br class=""></div><div class="gmail_extra">Do, functions of the type obj_alloc_* have the same pattern if at all they do? Also, are there any other functions which require such annotations? </div></div></div></blockquote><div><br class=""></div><div>It would be helpful if you explained what the obj_alloc_* functions do. Do they malloc memory directly and return as __isl_give? Do they manipulate reference counts directly?</div><div><br class=""></div><blockquote type="cite" class=""><div class=""><div dir="ltr" class=""><div class="gmail_extra">I feel that I'll have to add annotations to obj_dup() as well because although adding an annotation to obj_cow() guarantees that the RetainCountChecker will not enter obj_cow's body when it is called, the analyzer might begin its analysis from obj_cow() which may lead it to call obj_dup() and result in leak warnings.</div></div></div></blockquote><div><br class=""></div><div>What does obj_dup() do?</div><div><br class=""></div><div>Devin</div><div><br class=""></div></div></body></html>