https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105755
Bug ID: 105755
Summary: -Wanalyzer-null-dereference regression compiling Emacs
Product: gcc
Version: 12.1.1
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: analyzer
Assignee: dmalcolm at gcc dot gnu.org
Reporter: eggert at cs dot ucla.edu
Target Milestone: ---
Created attachment 53047
--> https://gcc.gnu.org/bugzilla/attachment.cgi?id=53047&action=edit
compile with 'gcc -fanalyzer -O2 -S' to see the false positive
GCC 12.1.1 20220507 (Red Hat 12.1.1-1) on x86-64 has a false positive compiling
the attached program w.i, which is a stripped-down version of GNU Emacs master.
Compile it this way:
gcc -fanalyzer -O2 -S w.i
and it generates the following incorrect output. GCC 11.2 compiles the code
cleanly so this is a regression.
In function ‘PSEUDOVECTORP’,
inlined from ‘SUB_CHAR_TABLE_P’ at w.i:154:10,
inlined from ‘CHAR_TABLE_REF_ASCII’ at w.i:169:28:
w.i:53:56: warning: dereference of NULL ‘*tbl.ascii’ [CWE-476]
[-Wanalyzer-null-dereference]
52 | && ((((union vectorlike_header *)
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
53 | ((char *) XLP ((a)) - Lisp_Vectorlike))->size
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~
‘word_boundary_p’: events 1-2
|
| 187 | word_boundary_p (Lisp_Object char_script_table, int c1, int c2)
| | ^~~~~~~~~~~~~~~
| | |
| | (1) entry to ‘word_boundary_p’
| 188 | {
| 189 | return EQ (CHAR_TABLE_REF (char_script_table, c1),
| | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
| | |
| | (2) calling ‘CHAR_TABLE_REF’ from ‘word_boundary_p’
| 190 | CHAR_TABLE_REF (char_script_table, c2));
| | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
+--> ‘CHAR_TABLE_REF’: events 3-6
|
| 179 | CHAR_TABLE_REF (Lisp_Object ct, int idx)
| | ^~~~~~~~~~~~~~
| | |
| | (3) entry to ‘CHAR_TABLE_REF’
| 180 | {
| 181 | return (ASCII_CHAR_P (idx)
| | ~~~~~~~~~~~~~~~~~~~
| 182 | ? CHAR_TABLE_REF_ASCII (ct, idx)
| | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
| | |
| | (5) ...to here
| | (6) calling ‘CHAR_TABLE_REF_ASCII’ from
‘CHAR_TABLE_REF’
| 183 | : char_table_ref (ct, idx));
| | ~~~~~~~~~~~~~~~~~~~~~~~~~~~
| | |
| | (4) following ‘true’ branch...
|
+--> ‘CHAR_TABLE_REF_ASCII’: events 7-15
|
| 164 | CHAR_TABLE_REF_ASCII (Lisp_Object ct, ptrdiff_t idx)
| | ^~~~~~~~~~~~~~~~~~~~
| | |
| | (7) entry to ‘CHAR_TABLE_REF_ASCII’
|......
| 169 | Lisp_Object val = (! SUB_CHAR_TABLE_P
(tbl->ascii) ? tbl->ascii
| |
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
| 170 | : XSUB_CHAR_TABLE
(tbl->ascii)->contents[idx]);
| |
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
| | |
| | (8) following ‘false’
branch...
| 171 | if (NILP (val))
| | ~
| | |
| | (9) ...to here
| | (10) following ‘true’ branch...
| 172 | val = tbl->defalt;
| | ~~~~~~~~~~~~~~~~~
| | |
| | (11) ...to here
| 173 | if (!NILP (val) || NILP (tbl->parent))
| | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
| | | | |
| | | | (13) ...to here
| | | (14) following ‘true’
branch...
| | (12) following ‘false’ branch (when ‘val’
is NULL)...
| 174 | return val;
| | ~~~
| | |
| | (15) ...to here
|
<------+
|
‘CHAR_TABLE_REF’: event 16
|
| 182 | ? CHAR_TABLE_REF_ASCII (ct, idx)
| | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
| | |
| | (16) returning to ‘CHAR_TABLE_REF’ from
‘CHAR_TABLE_REF_ASCII’
|
<------+
|
‘word_boundary_p’: events 17-18
|
| 189 | return EQ (CHAR_TABLE_REF (char_script_table, c1),
| | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
| | |
| | (17) returning to ‘word_boundary_p’ from ‘CHAR_TABLE_REF’
| | (18) calling ‘CHAR_TABLE_REF’ from ‘word_boundary_p’
| 190 | CHAR_TABLE_REF (char_script_table, c2));
| | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
+--> ‘CHAR_TABLE_REF’: events 19-22
|
| 179 | CHAR_TABLE_REF (Lisp_Object ct, int idx)
| | ^~~~~~~~~~~~~~
| | |
| | (19) entry to ‘CHAR_TABLE_REF’
| 180 | {
| 181 | return (ASCII_CHAR_P (idx)
| | ~~~~~~~~~~~~~~~~~~~
| 182 | ? CHAR_TABLE_REF_ASCII (ct, idx)
| | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
| | |
| | (21) ...to here
| | (22) calling ‘CHAR_TABLE_REF_ASCII’ from
‘CHAR_TABLE_REF’
| 183 | : char_table_ref (ct, idx));
| | ~~~~~~~~~~~~~~~~~~~~~~~~~~~
| | |
| | (20) following ‘true’ branch...
|
+--> ‘CHAR_TABLE_REF_ASCII’: events 23-26
|
| 51 | return (TAGGEDP (a, Lisp_Vectorlike)
| | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
| 52 | && ((((union vectorlike_header *)
| | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
| | |
| | (24) following ‘true’ branch...
| 53 | ((char *) XLP ((a)) -
Lisp_Vectorlike))->size
| |
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
| |
|
| |
(25) ...to here
| |
(26) dereference of NULL ‘*tbl.ascii’
| 54 | & 0x400000003f000000)
| | ~~~~~~~~~~~~~~~~~~~~~
| 55 | == (0x4000000000000000 | (code <<
24))));
| |
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|......
| 164 | CHAR_TABLE_REF_ASCII (Lisp_Object ct, ptrdiff_t idx)
| | ^~~~~~~~~~~~~~~~~~~~
| | |
| | (23) entry to ‘CHAR_TABLE_REF_ASCII’
|