[cfe-dev] clang-tidy: Inconsistent chain of reasoning using

Jakob Kalchik via cfe-dev cfe-dev at lists.llvm.org
Sun Sep 15 02:51:58 PDT 2019


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 }
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20190915/5ffc9a85/attachment.html>


More information about the cfe-dev mailing list