Skip to content

DL_SORT error with gcc 11.2 analyzer #241

@guillaumechereau

Description

@guillaumechereau

Could be a false positive of gcc analyzer. Here is a small code to reproduce:

#include <stdlib.h>
#include "utlist.h"

typedef struct item item_t;
struct item {
    int x;
    item_t *prev, *next;
};

static int sort_cmp(void *a, void *b)
{
    item_t *item1, *item2;
    item1 = a;
    item2 = b;
    return item1->x - item2->x;
}

int func(item_t **items)
{
    DL_SORT(*items, sort_cmp);
}

With gcc 11.2, if I compile with the --analyzer option:

gcc -c test.c --analyzer

I get this error report:

In file included from test.c:3:
test.c: In function ‘func’:
utlist.h:101:33: warning: dereference of NULL ‘_ls_tail’ [CWE-476] [-Wanalyzer-null-dereference]
  101 | #define UTLIST_CASTASGN(a,b) (a)=(b)
      |                              ~~~^~~~
utlist.h:225:7: note: in expansion of macro ‘UTLIST_CASTASGN’
  225 |       UTLIST_CASTASGN((list)->prev, _ls_tail);                                                 \
      |       ^~~~~~~~~~~~~~~
utlist.h:173:5: note: in expansion of macro ‘DL_SORT2’
  173 |     DL_SORT2(list, cmp, prev, next)
      |     ^~~~~~~~
test.c:21:5: note: in expansion of macro ‘DL_SORT’
   21 |     DL_SORT(*items, sort_cmp);
      |     ^~~~~~~
  ‘func’: event 1
    |
    |utlist.h:183:6:
    |  183 |   if (list) {                                                                                  \
    |      |      ^
    |      |      |
    |      |      (1) following ‘true’ branch...
utlist.h:173:5: note: in expansion of macro ‘DL_SORT2’
    |  173 |     DL_SORT2(list, cmp, prev, next)
    |      |     ^~~~~~~~
test.c:21:5: note: in expansion of macro ‘DL_SORT’
    |   21 |     DL_SORT(*items, sort_cmp);
    |      |     ^~~~~~~
    |
  ‘func’: event 2
    |
    |utlist.h:101:33:
    |  101 | #define UTLIST_CASTASGN(a,b) (a)=(b)
    |      |                              ~~~^~~~
    |      |                                 |
    |      |                                 (2) ...to here
utlist.h:187:7: note: in expansion of macro ‘UTLIST_CASTASGN’
    |  187 |       UTLIST_CASTASGN(_ls_p,list);                                                             \
    |      |       ^~~~~~~~~~~~~~~
utlist.h:173:5: note: in expansion of macro ‘DL_SORT2’
    |  173 |     DL_SORT2(list, cmp, prev, next)
    |      |     ^~~~~~~~
test.c:21:5: note: in expansion of macro ‘DL_SORT’
    |   21 |     DL_SORT(*items, sort_cmp);
    |      |     ^~~~~~~
    |
  ‘func’: event 3
    |
    |utlist.h:188:14:
    |  188 |       (list) = NULL;                                                                           \
    |      |              ^
    |      |              |
    |      |              (3) ‘*items’ is NULL
utlist.h:173:5: note: in expansion of macro ‘DL_SORT2’
    |  173 |     DL_SORT2(list, cmp, prev, next)
    |      |     ^~~~~~~~
test.c:21:5: note: in expansion of macro ‘DL_SORT’
    |   21 |     DL_SORT(*items, sort_cmp);
    |      |     ^~~~~~~
    |
  ‘func’: event 4
    |
    |utlist.h:189:16:
    |  189 |       _ls_tail = NULL;                                                                         \
    |      |                ^
    |      |                |
    |      |                (4) ‘_ls_tail’ is NULL
utlist.h:173:5: note: in expansion of macro ‘DL_SORT2’
    |  173 |     DL_SORT2(list, cmp, prev, next)
    |      |     ^~~~~~~~
test.c:21:5: note: in expansion of macro ‘DL_SORT’
    |   21 |     DL_SORT(*items, sort_cmp);
    |      |     ^~~~~~~
    |
  ‘func’: event 5
    |
    |utlist.h:191:14:
    |  191 |       while (_ls_p) {                                                                          \
    |      |              ^~~~~
    |      |              |
    |      |              (5) following ‘true’ branch...
utlist.h:173:5: note: in expansion of macro ‘DL_SORT2’
    |  173 |     DL_SORT2(list, cmp, prev, next)
    |      |     ^~~~~~~~
test.c:21:5: note: in expansion of macro ‘DL_SORT’
    |   21 |     DL_SORT(*items, sort_cmp);
    |      |     ^~~~~~~
    |
  ‘func’: event 6
    |
    |utlist.h:196:20:
    |  196 |           _ls_psize++;                                                                         \
    |      |           ~~~~~~~~~^~
    |      |                    |
    |      |                    (6) ...to here
utlist.h:173:5: note: in expansion of macro ‘DL_SORT2’
    |  173 |     DL_SORT2(list, cmp, prev, next)
    |      |     ^~~~~~~~
test.c:21:5: note: in expansion of macro ‘DL_SORT’
    |   21 |     DL_SORT(*items, sort_cmp);
    |      |     ^~~~~~~
    |
  ‘func’: event 7
    |
    |utlist.h:201:32:
    |  201 |         while ((_ls_psize > 0) || ((_ls_qsize > 0) && _ls_q)) {                                \
    |      |                ~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    |      |                                |
    |      |                                (7) following ‘false’ branch (when ‘_ls_psize <= 0’)...
utlist.h:173:5: note: in expansion of macro ‘DL_SORT2’
    |  173 |     DL_SORT2(list, cmp, prev, next)
    |      |     ^~~~~~~~
test.c:21:5: note: in expansion of macro ‘DL_SORT’
    |   21 |     DL_SORT(*items, sort_cmp);
    |      |     ^~~~~~~
    |
  ‘func’: event 8
    |
    |utlist.h:201:32:
    |  201 |         while ((_ls_psize > 0) || ((_ls_qsize > 0) && _ls_q)) {                                \
    |      |                ~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    |      |                                |
    |      |                                (8) ...to here
utlist.h:173:5: note: in expansion of macro ‘DL_SORT2’
    |  173 |     DL_SORT2(list, cmp, prev, next)
    |      |     ^~~~~~~~
test.c:21:5: note: in expansion of macro ‘DL_SORT’
    |   21 |     DL_SORT(*items, sort_cmp);
    |      |     ^~~~~~~
    |
  ‘func’: event 9
    |
    |utlist.h:201:32:
    |  201 |         while ((_ls_psize > 0) || ((_ls_qsize > 0) && _ls_q)) {                                \
    |      |                ~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    |      |                                |
    |      |                                (9) following ‘true’ branch (when ‘_ls_qsize > 0’)...
utlist.h:173:5: note: in expansion of macro ‘DL_SORT2’
    |  173 |     DL_SORT2(list, cmp, prev, next)
    |      |     ^~~~~~~~
test.c:21:5: note: in expansion of macro ‘DL_SORT’
    |   21 |     DL_SORT(*items, sort_cmp);
    |      |     ^~~~~~~
    |
  ‘func’: event 10
    |
    |utlist.h:201:52:
    |  201 |         while ((_ls_psize > 0) || ((_ls_qsize > 0) && _ls_q)) {                                \
    |      |                                   ~~~~~~~~~~~~~~~~~^~~~~~~~~
    |      |                                                    |
    |      |                                                    (10) ...to here
utlist.h:173:5: note: in expansion of macro ‘DL_SORT2’
    |  173 |     DL_SORT2(list, cmp, prev, next)
    |      |     ^~~~~~~~
test.c:21:5: note: in expansion of macro ‘DL_SORT’
    |   21 |     DL_SORT(*items, sort_cmp);
    |      |     ^~~~~~~
    |
  ‘func’: event 11
    |
    |utlist.h:201:52:
    |  201 |         while ((_ls_psize > 0) || ((_ls_qsize > 0) && _ls_q)) {                                \
    |      |                                   ~~~~~~~~~~~~~~~~~^~~~~~~~~
    |      |                                                    |
    |      |                                                    (11) following ‘false’ branch (when ‘_ls_q’ is NULL)...
utlist.h:173:5: note: in expansion of macro ‘DL_SORT2’
    |  173 |     DL_SORT2(list, cmp, prev, next)
    |      |     ^~~~~~~~
test.c:21:5: note: in expansion of macro ‘DL_SORT’
    |   21 |     DL_SORT(*items, sort_cmp);
    |      |     ^~~~~~~
    |
  ‘func’: event 12
    |
    |utlist.h:223:15:
    |  223 |         _ls_p = _ls_q;                                                                         \
    |      |         ~~~~~~^~~~~~~
    |      |               |
    |      |               (12) ...to here
utlist.h:173:5: note: in expansion of macro ‘DL_SORT2’
    |  173 |     DL_SORT2(list, cmp, prev, next)
    |      |     ^~~~~~~~
test.c:21:5: note: in expansion of macro ‘DL_SORT’
    |   21 |     DL_SORT(*items, sort_cmp);
    |      |     ^~~~~~~
    |
  ‘func’: event 13
    |
    |   21 |     DL_SORT(*items, sort_cmp);
utlist.h:101:31: note: in definition of macro ‘UTLIST_CASTASGN’
    |  101 | #define UTLIST_CASTASGN(a,b) (a)=(b)
    |      |                               ^
utlist.h:173:5: note: in expansion of macro ‘DL_SORT2’
    |  173 |     DL_SORT2(list, cmp, prev, next)
    |      |     ^~~~~~~~
test.c:21:5: note: in expansion of macro ‘DL_SORT’
    |   21 |     DL_SORT(*items, sort_cmp);
    |      |     ^~~~~~~
    |
  ‘func’: event 14
    |
    |utlist.h:101:33:
    |  101 | #define UTLIST_CASTASGN(a,b) (a)=(b)
    |      |                              ~~~^~~~
    |      |                                 |
    |      |                                 (14) ‘_ls_tail’ is NULL
utlist.h:225:7: note: in expansion of macro ‘UTLIST_CASTASGN’
    |  225 |       UTLIST_CASTASGN((list)->prev, _ls_tail);                                                 \
    |      |       ^~~~~~~~~~~~~~~
utlist.h:173:5: note: in expansion of macro ‘DL_SORT2’
    |  173 |     DL_SORT2(list, cmp, prev, next)
    |      |     ^~~~~~~~
test.c:21:5: note: in expansion of macro ‘DL_SORT’
    |   21 |     DL_SORT(*items, sort_cmp);
    |      |     ^~~~~~~
    |
  ‘func’: event 15
    |
    |utlist.h:97:56:
    |   97 | #define UTLIST_NEXTASGN(elt,list,to,next) ((elt)->next)=(to)
    |      |                                           ~~~~~~~~~~~~~^~~~~
    |      |                                                        |
    |      |                                                        (15) ‘_ls_tail’ is NULL
utlist.h:226:33: note: in expansion of macro ‘UTLIST_NEXTASGN’
    |  226 |       UTLIST_SV(_ls_tail,list); UTLIST_NEXTASGN(_ls_tail,list,NULL,next); UTLIST_RS(list);     \
    |      |                                 ^~~~~~~~~~~~~~~
utlist.h:173:5: note: in expansion of macro ‘DL_SORT2’
    |  173 |     DL_SORT2(list, cmp, prev, next)
    |      |     ^~~~~~~~
test.c:21:5: note: in expansion of macro ‘DL_SORT’
    |   21 |     DL_SORT(*items, sort_cmp);
    |      |     ^~~~~~~
    |
  ‘func’: event 16
    |
    |utlist.h:101:33:
    |  101 | #define UTLIST_CASTASGN(a,b) (a)=(b)
    |      |                              ~~~^~~~
    |      |                                 |
    |      |                                 (16) dereference of NULL ‘*items’
utlist.h:225:7: note: in expansion of macro ‘UTLIST_CASTASGN’
    |  225 |       UTLIST_CASTASGN((list)->prev, _ls_tail);                                                 \
    |      |       ^~~~~~~~~~~~~~~
utlist.h:173:5: note: in expansion of macro ‘DL_SORT2’
    |  173 |     DL_SORT2(list, cmp, prev, next)
    |      |     ^~~~~~~~
test.c:21:5: note: in expansion of macro ‘DL_SORT’
    |   21 |     DL_SORT(*items, sort_cmp);
    |      |     ^~~~~~~
    |

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions