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’ |