[cfe-dev] clang-tidy: Inconsistent chain of reasoning using
Artem Dergachev via cfe-dev
cfe-dev at lists.llvm.org
Thu Sep 19 13:54:47 PDT 2019
+ a couple of folks with whom we've just been talking about these issues.
Had a look, thanks! It's one of those nasty pointer cast representation
bugs:
reg_$1<int Element{SymRegion{reg_$0<const Item * items>},0
S64b,Item}->xxs> : { [-2147483648, 0] }
reg_$2<int SymRegion{reg_$0<const Item * items>}->xxs> : { [1,
2147483647] }
In this case basically the same value has two different representations
in the Static Analyzer, so after dereferencing it thinks that these are
two different values.
I wanted to clean up this mess for a long time but never had time for
it. This time i created https://bugs.llvm.org/show_bug.cgi?id=43364 to
track this problem.
On 9/15/19 2:51 AM, Jakob Kalchik via cfe-dev wrote:
> 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.
>
> 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?
>
> A really puzzling piece is if I change the prototype for ItemCtor from
> void ItemCtor(const Item * const items, int itemlist[])
> to
> void ItemCtor(const Item * items, int itemlist[])
> I do not see the checker warning.
>
> 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?
>
> Thanks - Jakob
>
> The text output from the simple repro case I have is ...
>
> 1) uninit.c:21:11: warning: Assigned value is garbage or undefined
> sum += itemlist[i];
> ^ ~~~~~~~~~~~
> 2) uninit.c:16:4: note: Calling 'ItemCtor'
> ItemCtor(items, itemlist);
> ^~~~~~~~~~~~~~~~~~~~~~~~~
> 3) uninit.c:9:20: note: Assuming 'i' is >= field 'xxs'
> for (int i = 0; i < items->xxs; i++) {
> ^~~~~~~~~~~~~~
> 4) uninit.c:9:4: note: Loop condition is false. Execution continues on
> line 9
> for (int i = 0; i < items->xxs; i++) {
> ^
> 5) uninit.c:16:4: note: Returning from 'ItemCtor'
> ItemCtor(items, itemlist);
> ^~~~~~~~~~~~~~~~~~~~~~~~~
> 6) uninit.c:20:9: note: 'i' initialized to 0
> for (int i = 0; i < items->xxs; i++) {
> ^~~~~
> 7) uninit.c:20:20: note: Assuming 'i' is < field 'xxs'
> for (int i = 0; i < items->xxs; i++) {
> ^~~~~~~~~~~~~~
> 8) uninit.c:20:4: note: Loop condition is true. Entering loop body
> for (int i = 0; i < items->xxs; i++) {
> ^
> 9) uninit.c:21:11: note: Assigned value is garbage or undefined
> sum += itemlist[i];
> ^ ~~~~~~~~~~~
> 1 warning generated.
>
> The command ...
> clang --analyze -Xclang -analyzer-checker=core.uninitialized.Assign
> -Xclang -analyzer-output=text uninit.c
>
> The simple repro case with line numbers...
>
> 1 #include <assert.h>
> 2
> 3 #define ITEMS 2
> 4 typedef struct {
> 5 int xxs;
> 6 } Item;
> 7
> 8 void ItemCtor(const Item * const items, int itemlist[]) {
> 9 for (int i = 0; i < items->xxs; i++) {
> 10 itemlist[i] = 0;
> 11 }
> 12 }
> 13
> 14 int work(Item const *items) {
> 15 int itemlist[ITEMS];
> 16 ItemCtor(items, itemlist);
> 17
> 18 int sum = 0;
> 19
> 20 for (int i = 0; i < items->xxs; i++) {
> 21 sum += itemlist[i];
> 22 }
> 23
> 24 return sum;
> 25 }
>
> _______________________________________________
> cfe-dev mailing list
> cfe-dev at lists.llvm.org
> https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20190919/4b2fd7cd/attachment.html>
More information about the cfe-dev
mailing list