-
Notifications
You must be signed in to change notification settings - Fork 959
Open
Description
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
Labels
No labels