<div dir="ltr">Hi Max,<div>Consider the following (somewhat contrived) example:</div><div><div style="color:rgb(235,219,178);background-color:rgb(40,40,40);font-family:"Fira Code","Droid Sans Mono",monospace,monospace,"Droid Sans Fallback";font-size:14px;line-height:19px;white-space:pre"><div><span style="color:rgb(168,153,132)">#</span><span style="color:rgb(142,192,124)">include</span><span style="color:rgb(254,128,25)"> </span><span style="color:rgb(168,153,132)"><</span><span style="color:rgb(184,187,38)">stddef.h</span><span style="color:rgb(168,153,132)">></span></div><br><div><span style="color:rgb(251,73,52)">struct</span> <span style="color:rgb(250,189,47)">foo</span> <span style="color:rgb(168,153,132)">{</span></div><div> <span style="color:rgb(251,73,52)">int</span> <span style="color:rgb(131,165,152)">val1</span><span style="color:rgb(168,153,132)">;</span></div><div> <span style="color:rgb(251,73,52)">int</span> <span style="color:rgb(131,165,152)">val2</span><span style="color:rgb(168,153,132)">;</span></div><div><span style="color:rgb(168,153,132)">};</span></div><br><div><span style="color:rgb(251,73,52)">void</span> <span style="color:rgb(250,189,47)">sneaky</span><span style="color:rgb(168,153,132)">(</span><span style="color:rgb(251,73,52)">int</span> <span style="color:rgb(142,192,124)">*</span><span style="color:rgb(131,165,152)">val</span><span style="color:rgb(168,153,132)">)</span> <span style="color:rgb(168,153,132)">{</span></div><div><span style="color:rgb(168,153,132)"> </span><span style="color:rgb(146,131,116);font-style:italic">// Suppose I know I am always going to be passed</span></div><div><span style="color:rgb(168,153,132)"> </span><span style="color:rgb(146,131,116);font-style:italic">// val2 of an instance of struct foo here</span></div><div> <span style="color:rgb(250,189,47)">size_t</span> <span style="color:rgb(131,165,152)">val2_off</span><span style="color:rgb(168,153,132)">;</span></div><div> <span style="color:rgb(251,73,52)">char</span> <span style="color:rgb(142,192,124)">*</span><span style="color:rgb(131,165,152)">val2_ptr</span><span style="color:rgb(168,153,132)">,</span> <span style="color:rgb(142,192,124)">*</span><span style="color:rgb(131,165,152)">base_ptr</span><span style="color:rgb(168,153,132)">;</span></div><div> <span style="color:rgb(251,73,52)">struct</span> <span style="color:rgb(250,189,47)">foo</span> <span style="color:rgb(142,192,124)">*</span><span style="color:rgb(131,165,152)">foo_ptr</span><span style="color:rgb(168,153,132)">;</span></div><div> </div><div> <span style="color:rgb(131,165,152)">val2_off</span> <span style="color:rgb(142,192,124)">=</span> <span style="color:rgb(250,189,47)">offsetof</span><span style="color:rgb(168,153,132)">(</span><span style="color:rgb(251,73,52)">struct</span> foo<span style="color:rgb(168,153,132)">,</span> val2<span style="color:rgb(168,153,132)">);</span></div><div> <span style="color:rgb(131,165,152)">val2_ptr</span> <span style="color:rgb(142,192,124)">=</span> <span style="color:rgb(168,153,132)">(</span><span style="color:rgb(251,73,52)">char</span> <span style="color:rgb(142,192,124)">*</span><span style="color:rgb(168,153,132)">)</span> <span style="color:rgb(131,165,152)">val</span><span style="color:rgb(168,153,132)">;</span></div><div><span style="color:rgb(168,153,132)"> </span><span style="color:rgb(146,131,116);font-style:italic">// Sneak level: 100</span></div><div> <span style="color:rgb(131,165,152)">base_ptr</span> <span style="color:rgb(142,192,124)">=</span> <span style="color:rgb(131,165,152)">val2_ptr</span> <span style="color:rgb(142,192,124)">-</span> <span style="color:rgb(131,165,152)">val2_off</span><span style="color:rgb(168,153,132)">;</span></div><div><span style="color:rgb(168,153,132)"> </span><span style="color:rgb(146,131,116);font-style:italic">// I have found the struct instance pointer!</span></div><div> <span style="color:rgb(131,165,152)">foo_ptr</span> <span style="color:rgb(142,192,124)">=</span> <span style="color:rgb(168,153,132)">(</span><span style="color:rgb(251,73,52)">struct</span> <span style="color:rgb(250,189,47)">foo</span> <span style="color:rgb(142,192,124)">*</span><span style="color:rgb(168,153,132)">)</span> <span style="color:rgb(131,165,152)">base_ptr</span><span style="color:rgb(168,153,132)">;</span></div><div> </div><div><span style="color:rgb(168,153,132)"> </span><span style="color:rgb(146,131,116);font-style:italic">// And now I can mangle every field of the</span></div><div><span style="color:rgb(168,153,132)"> </span><span style="color:rgb(146,131,116);font-style:italic">// struct instance as I please.</span></div><div> <span style="color:rgb(131,165,152)">foo_ptr</span><span style="color:rgb(168,153,132)">-></span><span style="color:rgb(131,165,152)">val1</span> <span style="color:rgb(142,192,124)">=</span> <span style="color:rgb(250,189,47)">rand</span><span style="color:rgb(168,153,132)">();</span></div><div><span style="color:rgb(168,153,132)">}</span></div><br><div><span style="color:rgb(251,73,52)">void</span> <span style="color:rgb(250,189,47)">bar</span><span style="color:rgb(168,153,132)">()</span> <span style="color:rgb(168,153,132)">{</span></div><div> <span style="color:rgb(251,73,52)">struct</span> <span style="color:rgb(250,189,47)">foo</span> <span style="color:rgb(131,165,152)">fooer</span> <span style="color:rgb(142,192,124)">=</span> <span style="color:rgb(168,153,132)">{</span> .val1 <span style="color:rgb(142,192,124)">=</span> <span style="color:rgb(211,134,155)">100</span><span style="color:rgb(168,153,132)">,</span> .val2 <span style="color:rgb(142,192,124)">=</span> <span style="color:rgb(211,134,155)">200</span> <span style="color:rgb(168,153,132)">};</span></div><div> </div><div> <span style="color:rgb(250,189,47)">sneaky</span><span style="color:rgb(168,153,132)">(</span><span style="color:rgb(142,192,124)">&</span><span style="color:rgb(168,153,132)">(</span><span style="color:rgb(131,165,152)">fooer</span><span style="color:rgb(168,153,132)">.</span><span style="color:rgb(131,165,152)">val2</span><span style="color:rgb(168,153,132)">));</span></div><div><span style="color:rgb(168,153,132)"> </span><span style="color:rgb(146,131,116);font-style:italic">// If CSA were to perform conservative eval of sneaky,</span></div><div><span style="color:rgb(168,153,132)"> </span><span style="color:rgb(146,131,116);font-style:italic">// it can have no idea what happened to the other fields</span></div><div><span style="color:rgb(168,153,132)"> </span><span style="color:rgb(146,131,116);font-style:italic">// of the struct instance.</span></div><div><span style="color:rgb(168,153,132)"> </span></div></div></div><div>As you can see, conservative evaluation has no choice but to invalidate all struct members.</div><div>Btw, the example I have given is less contrived than it seems. In C, with intrusive data structures, usually something very similar is done. The "linked-list", which is an ubiquitous data-structure in the Linux kernel, uses something like this (as a macro) to reach the struct from the list node.</div><div>Warm regards,</div><div>Deep</div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Sun, Oct 3, 2021 at 12:47 PM Max Schrötter via cfe-dev <<a href="mailto:cfe-dev@lists.llvm.org">cfe-dev@lists.llvm.org</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">Hi,<br>
<br>
I noticed that conservativeEvallCall invalidates all items in a<br>
cluster(struct) in the example below instead of invalidating <br>
only the item passed as argument.<br>
<br>
I think the following Code should report a NonNullParamChecker warning.<br>
However t.mem is invalidated in the conservativeEvallCall of the scanf<br>
call.<br>
<br>
Example:<br>
<br>
#include <stdio.h><br>
#include <stdlib.h><br>
#include <string.h><br>
<br>
struct test{<br>
int* mem;<br>
int value;<br>
};<br>
<br>
<br>
int main(int argc, char** argv, char** envp)<br>
{<br>
struct test t;<br>
t.value=8;<br>
t.mem = NULL;<br>
scanf("%d",&t.value);<br>
memcpy(t.mem,&t.value,sizeof(int)); <br>
free(t.mem);<br>
}<br>
<br>
Is this a known limitation?<br>
<br>
I'm trying to debug this, but haven't fully understood the RegionStore<br>
yet. Is there more documentation besides the RegionStore.rst? <br>
<br>
Thanks<br>
Max<br>
_______________________________________________<br>
cfe-dev mailing list<br>
<a href="mailto:cfe-dev@lists.llvm.org" target="_blank">cfe-dev@lists.llvm.org</a><br>
<a href="https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev" rel="noreferrer" target="_blank">https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev</a><br>
</blockquote></div>