<div dir="ltr"><div dir="ltr"><div dir="ltr">Hello, I'm seeing an inconsistent chain of reasoning for a particular tidy check - core.uninitialized.Assign. This was isolated from a much larger case we found in testing a large code base. I've pasted in the particulars below.</div><div dir="ltr"><br></div><div>I can see that the analyzer is detecting itemlist is uninitialized (step 9). But I would think the analysis should detect that itemlist is initialized in the call to ItemCtor. Indeed, notes 3) and 4) indicate that the path was detected and simulated, but the conditions at steps 3) and 7) are inconsistent with respect to each other. How can 'i' be < 'xxs' and '>=' xxs' in the same simulation path analysis?</div><div dir="ltr"><br></div><div>A really puzzling piece is if I change the prototype for ItemCtor from</div><div>   void ItemCtor(const Item * const items, int itemlist[])<span></span></div><div>to <br></div><div>   void ItemCtor(const Item * items, int itemlist[]) </div><div>I do not see the checker warning. </div><div dir="ltr"><br></div><div>Has anyone else seen this? Is there something I'm missing about this particular code snippet, or is there perhaps some issue with the way cases are generated by the checker? </div><div><br></div><div>Thanks - Jakob </div><div dir="ltr"><br></div><div dir="ltr">The text output from the simple repro case I have is ... </div><div dir="ltr"><br></div><div dir="ltr">1) uninit.c:21:11: warning: Assigned value is garbage or undefined<br>      sum += itemlist[i];<br>          ^  ~~~~~~~~~~~<br>2) uninit.c:16:4: note: Calling 'ItemCtor'<br>   ItemCtor(items, itemlist);<br>   ^~~~~~~~~~~~~~~~~~~~~~~~~<br>3) uninit.c:9:20: note: Assuming 'i' is >= field 'xxs'<br>   for (int i = 0; i < items->xxs; i++) {<br>                   ^~~~~~~~~~~~~~<br>4) uninit.c:9:4: note: Loop condition is false. Execution continues on line 9<br>   for (int i = 0; i < items->xxs; i++) {<br>   ^<br>5) uninit.c:16:4: note: Returning from 'ItemCtor'<br>   ItemCtor(items, itemlist);<br>   ^~~~~~~~~~~~~~~~~~~~~~~~~<br>6) uninit.c:20:9: note: 'i' initialized to 0<br>   for (int i = 0; i < items->xxs; i++) {<br>        ^~~~~<br>7) uninit.c:20:20: note: Assuming 'i' is < field 'xxs'<br>   for (int i = 0; i < items->xxs; i++) {<br>                   ^~~~~~~~~~~~~~<br>8) uninit.c:20:4: note: Loop condition is true.  Entering loop body<br>   for (int i = 0; i < items->xxs; i++) {<br>   ^<br>9) uninit.c:21:11: note: Assigned value is garbage or undefined<br>      sum += itemlist[i];<br>          ^  ~~~~~~~~~~~<br>1 warning generated.</div><div dir="ltr"><br></div><div>The command ... <br></div><div dir="ltr">clang  --analyze -Xclang -analyzer-checker=core.uninitialized.Assign  -Xclang -analyzer-output=text uninit.c</div><div dir="ltr"><br></div><div>The simple repro case with line numbers... </div><div><br></div><div dir="ltr">  1 #include <assert.h><br>  2 <br>  3 #define ITEMS 2<br>  4 typedef struct {<br>  5   int xxs;<br>  6 } Item;<br>  7 <br>  8 void ItemCtor(const Item * const items, int itemlist[]) {<br>  9    for (int i = 0; i < items->xxs; i++) {<br> 10      itemlist[i] = 0;<br> 11    }<br> 12 }<br> 13 <br> 14 int work(Item const *items) {<br> 15    int itemlist[ITEMS];<br> 16    ItemCtor(items, itemlist);<br> 17 <br> 18    int sum = 0;<br> 19 <br> 20    for (int i = 0; i < items->xxs; i++) {<br> 21       sum += itemlist[i];<br> 22    }<br> 23 <br> 24    return sum;<br> 25 }<span><span><div class="gmail-yj6qo"><div class="gmail-adL"><span><span></span></span></div></div></span></span></div></div></div>