https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102671
--- Comment #4 from Paul Eggert <eggert at cs dot ucla.edu> --- Created attachment 56996 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=56996&action=edit marker.i example from GNU Emacs Here is another example of the problem, taken from bleeding-edge GNU Emacs compiled with gcc (Ubuntu 13.2.0-4ubuntu3) 13.2.0. Reproduce the bug via: gcc -O2 -S -fanalyzer marker.i The incorrect output (false positive) is: marker.i: In function ‘BUF_ZV’: marker.i:11203:6: warning: dereference of NULL ‘buf’ [CWE-476] [-Wanalyzer-null-dereference] 11203 | : NILP (((buf)->zv_marker_)) ? buf->zv | ^~~~~~~~~~~~~~~~~~~~~~~~~~ ‘set_marker_restricted’: events 1-2 | |17941 | set_marker_restricted (Lisp_Object marker, Lisp_Object position, | | ^~~~~~~~~~~~~~~~~~~~~ | | | | | (1) entry to ‘set_marker_restricted’ |...... |17944 | return set_marker_internal (marker, position, buffer, | | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | | | | | (2) calling ‘set_marker_internal’ from ‘set_marker_restricted’ |17945 | 1 | | ~ |17946 | ); | | ~ | +--> ‘set_marker_internal’: events 3-4 | |17882 | set_marker_internal (Lisp_Object marker, Lisp_Object position, | | ^~~~~~~~~~~~~~~~~~~ | | | | | (3) entry to ‘set_marker_internal’ |...... |17888 | struct buffer *b = live_buffer (buffer); | | ~ | | | | | (4) inlined call to ‘live_buffer’ from ‘set_marker_internal’ | +--> ‘live_buffer’: event 5 | |17877 | return BUFFER_LIVE_P (b) ? b : | | ~~~~~~~~~~~~~~~~~~~~~~^ | | | | | (5) following ‘false’ branch... |17878 | ((void *)0) | | ~~~~~~~~~~~ | <------+ | ‘set_marker_internal’: event 6 | |cc1: | (6): ...to here | ‘set_marker_internal’: event 7 | |17889 | CHECK_MARKER (marker); | | ^~~~~~~~~~~~~~~~~~~~~ | | | | | (7) calling ‘CHECK_MARKER’ from ‘set_marker_internal’ | +--> ‘CHECK_MARKER’: event 8 | |17584 | CHECK_MARKER (Lisp_Object x) | | ^~~~~~~~~~~~ | | | | | (8) entry to ‘CHECK_MARKER’ | +--> ‘CHECK_MARKER’: event 9 | |17586 | CHECK_TYPE (MARKERP (x), builtin_lisp_symbol (974), x); | | ^ | | | | | (9) inlined call to ‘MARKERP’ from ‘CHECK_MARKER’ | +--> ‘MARKERP’: event 10 | | 8374 | return PSEUDOVECTORP (x, PVEC_MARKER); | | ^ | | | | | (10) inlined call to ‘PSEUDOVECTORP’ from ‘MARKERP’ | +--> ‘PSEUDOVECTORP’: event 11 | | 6413 | return (TAGGEDP ((a), Lisp_Vectorlike) && ((((union vectorlike_header *) ((uintptr_t) XLP ((a)) - (uintptr_t) ((Lisp_Word_tag) (Lisp_Vectorlike) << (((0x7fffffffffffffffL | | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | | | | | (11) following ‘true’ branch... | 6414 | >> (3 - 1)) / 2 < | | ~~~~~~~~~~~~~~~~~ | 6415 | (9223372036854775807L) | | ~~~~~~~~~~~~~~~~~~~~~~ | 6416 | ) ? 0 : VALBITS))))->size & (( | | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | 6417 | (9223372036854775807L) | | ~~~~~~~~~~~~~~~~~~~~~~ | 6418 | - | | ~ | 6419 | (9223372036854775807L) | | ~~~~~~~~~~~~~~~~~~~~~~ | 6420 | / 2) | PVEC_TYPE_MASK)) == (( | | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | 6421 | (9223372036854775807L) | | ~~~~~~~~~~~~~~~~~~~~~~ | 6422 | - | | ~ | 6423 | (9223372036854775807L) | | ~~~~~~~~~~~~~~~~~~~~~~ | 6424 | / 2) | ((code) << PSEUDOVECTOR_AREA_BITS)))); | | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | <--------------------+ | ‘CHECK_MARKER’: event 12 | |17587 | } | | ^ | | | | | (12) ...to here | <------+ | ‘set_marker_internal’: events 13-15 | |17889 | CHECK_MARKER (marker); | | ^~~~~~~~~~~~~~~~~~~~~ | | | | | (13) returning to ‘set_marker_internal’ from ‘CHECK_MARKER’ |17890 | m = XMARKER (marker); |17891 | if (NILP (position) | | ~ | | | | | (14) following ‘false’ branch (when ‘position’ is non-NULL)... |17892 | || (MARKERP (position) && !XMARKER (position)->buffer)) | | ~ | | | | | (15) inlined call to ‘MARKERP’ from ‘set_marker_internal’ | +--> ‘MARKERP’: event 16 | | 8374 | return PSEUDOVECTORP (x, PVEC_MARKER); | | ^ | | | | | (16) inlined call to ‘PSEUDOVECTORP’ from ‘MARKERP’ | +--> ‘PSEUDOVECTORP’: event 17 | | 6413 | return (TAGGEDP ((a), Lisp_Vectorlike) && ((((union vectorlike_header *) ((uintptr_t) XLP ((a)) - (uintptr_t) ((Lisp_Word_tag) (Lisp_Vectorlike) << (((0x7fffffffffffffffL | | ^ | | | | | (17) inlined call to ‘TAGGEDP’ from ‘PSEUDOVECTORP’ | +--> ‘TAGGEDP’: event 18 | | 2352 | return (! (((unsigned) (XLI (a) >> (((0x7fffffffffffffffL | | ^ | | | | | (18) inlined call to ‘XLI’ from ‘TAGGEDP’ | +--> ‘XLI’: event 19 | | 2327 | return ((EMACS_INT) (o)); | | ~^~~~~~~~~~~~~~~~ | | | | | (19) ...to here | <---------------------------+ | ‘set_marker_internal’: events 20-22 | |17914 | charpos = clip_to_bounds | | ^~~~~~~~~~~~~~ | | | | | (20) following ‘true’ branch (when ‘restricted != 0’)... |17915 | (restricted ? BUF_BEGV (b) : BUF_BEG (b), charpos, | | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |17916 | restricted ? BUF_ZV (b) : ((b)->text->z)); | | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | | | | | (21) ...to here | | (22) calling ‘BUF_ZV’ from ‘set_marker_internal’ | +--> ‘BUF_ZV’: events 23-26 | |11200 | BUF_ZV (struct buffer *buf) | | ^~~~~~ | | | | | (23) entry to ‘BUF_ZV’ |11201 | { |11202 | return (buf == (current_thread->m_current_buffer) ? ((current_thread->m_current_buffer)->zv) | | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |11203 | : NILP (((buf)->zv_marker_)) ? buf->zv | | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | | | | | | | (25) ...to here | | | (26) dereference of NULL ‘buf’ | | (24) following ‘false’ branch... |11204 | : marker_position (((buf)->zv_marker_))); | | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | marker.i: In function ‘set_marker_internal’: marker.i:17916:33: warning: dereference of NULL ‘0’ [CWE-476] [-Wanalyzer-null-dereference] 17916 | restricted ? BUF_ZV (b) : ((b)->text->z)); | ~~~^~~~~~ ‘Fcopy_marker’: events 1-2 | |18042 | __attribute__((section (".subrs"))) static union Aligned_Lisp_Subr Scopy_marker = {{{ PVEC_SUBR << PSEUDOVECTOR_AREA_BITS }, { .a2 = Fcopy_marker }, 0, 2, "copy-marker", {0}, 0}}; Lisp_Object Fcopy_marker | | ^~~~~~~~~~~~ | | | | | (1) entry to ‘Fcopy_marker’ |...... |18049 | Fset_marker (new, marker, | | ~ | | | | | (2) inlined call to ‘Fset_marker’ from ‘Fcopy_marker’ | +--> ‘Fset_marker’: event 3 | |17936 | return set_marker_internal (marker, position, buffer, | | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | | | | | (3) calling ‘set_marker_internal’ from ‘Fcopy_marker’ |17937 | 0 | | ~ |17938 | ); | | ~ | ‘set_marker_internal’: events 4-5 | |17882 | set_marker_internal (Lisp_Object marker, Lisp_Object position, | | ^~~~~~~~~~~~~~~~~~~ | | | | | (4) entry to ‘set_marker_internal’ |...... |17888 | struct buffer *b = live_buffer (buffer); | | ~ | | | | | (5) inlined call to ‘live_buffer’ from ‘set_marker_internal’ | +--> ‘live_buffer’: event 6 | |17876 | struct buffer *b = decode_buffer (buffer); | | ^~~~~~~~~~~~~~~~~~~~~~ | | | | | (6) calling ‘decode_buffer’ from ‘set_marker_internal’ | ‘decode_buffer’: events 7-9 | |11413 | decode_buffer (Lisp_Object b) | | ^~~~~~~~~~~~~ | | | | | (7) entry to ‘decode_buffer’ |11414 | { |11415 | return NILP (b) ? (current_thread->m_current_buffer) : (CHECK_BUFFER (b), XBUFFER (b)); | | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | | | | | | (9) ...to here (8) following ‘true’ branch (when ‘b’ is NULL)... | <------+ | ‘set_marker_internal’: event 10 | |17888 | struct buffer *b = live_buffer (buffer); | | ^ | | | | | (10) inlined call to ‘live_buffer’ from ‘set_marker_internal’ | +--> ‘live_buffer’: events 11-12 | |17876 | struct buffer *b = decode_buffer (buffer); | | ^~~~~~~~~~~~~~~~~~~~~~ | | | | | (11) returning to ‘set_marker_internal’ from ‘decode_buffer’ |17877 | return BUFFER_LIVE_P (b) ? b : | | ~~~~~~~~~~~~~~~~~~~~~~~ | | | | | (12) following ‘false’ branch... |17878 | ((void *)0) | | ~~~~~~~~~~~ | <------+ | ‘set_marker_internal’: event 13 | |cc1: | (13): ...to here | ‘set_marker_internal’: event 14 | |17889 | CHECK_MARKER (marker); | | ^~~~~~~~~~~~~~~~~~~~~ | | | | | (14) calling ‘CHECK_MARKER’ from ‘set_marker_internal’ | +--> ‘CHECK_MARKER’: event 15 | |17584 | CHECK_MARKER (Lisp_Object x) | | ^~~~~~~~~~~~ | | | | | (15) entry to ‘CHECK_MARKER’ | +--> ‘CHECK_MARKER’: event 16 | |17586 | CHECK_TYPE (MARKERP (x), builtin_lisp_symbol (974), x); | | ^ | | | | | (16) inlined call to ‘MARKERP’ from ‘CHECK_MARKER’ | +--> ‘MARKERP’: event 17 | | 8374 | return PSEUDOVECTORP (x, PVEC_MARKER); | | ^ | | | | | (17) inlined call to ‘PSEUDOVECTORP’ from ‘MARKERP’ | +--> ‘PSEUDOVECTORP’: event 18 | | 6413 | return (TAGGEDP ((a), Lisp_Vectorlike) && ((((union vectorlike_header *) ((uintptr_t) XLP ((a)) - (uintptr_t) ((Lisp_Word_tag) (Lisp_Vectorlike) << (((0x7fffffffffffffffL | | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | | | | | (18) following ‘true’ branch... | 6414 | >> (3 - 1)) / 2 < | | ~~~~~~~~~~~~~~~~~ | 6415 | (9223372036854775807L) | | ~~~~~~~~~~~~~~~~~~~~~~ | 6416 | ) ? 0 : VALBITS))))->size & (( | | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | 6417 | (9223372036854775807L) | | ~~~~~~~~~~~~~~~~~~~~~~ | 6418 | - | | ~ | 6419 | (9223372036854775807L) | | ~~~~~~~~~~~~~~~~~~~~~~ | 6420 | / 2) | PVEC_TYPE_MASK)) == (( | | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | 6421 | (9223372036854775807L) | | ~~~~~~~~~~~~~~~~~~~~~~ | 6422 | - | | ~ | 6423 | (9223372036854775807L) | | ~~~~~~~~~~~~~~~~~~~~~~ | 6424 | / 2) | ((code) << PSEUDOVECTOR_AREA_BITS)))); | | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | <--------------------+ | ‘CHECK_MARKER’: event 19 | |17587 | } | | ^ | | | | | (19) ...to here | <------+ | ‘set_marker_internal’: events 20-22 | |17889 | CHECK_MARKER (marker); | | ^~~~~~~~~~~~~~~~~~~~~ | | | | | (20) returning to ‘set_marker_internal’ from ‘CHECK_MARKER’ |17890 | m = XMARKER (marker); |17891 | if (NILP (position) | | ~ | | | | | (21) following ‘false’ branch (when ‘position’ is non-NULL)... |17892 | || (MARKERP (position) && !XMARKER (position)->buffer)) | | ~ | | | | | (22) inlined call to ‘MARKERP’ from ‘set_marker_internal’ | +--> ‘MARKERP’: event 23 | | 8374 | return PSEUDOVECTORP (x, PVEC_MARKER); | | ^ | | | | | (23) inlined call to ‘PSEUDOVECTORP’ from ‘MARKERP’ | +--> ‘PSEUDOVECTORP’: event 24 | | 6413 | return (TAGGEDP ((a), Lisp_Vectorlike) && ((((union vectorlike_header *) ((uintptr_t) XLP ((a)) - (uintptr_t) ((Lisp_Word_tag) (Lisp_Vectorlike) << (((0x7fffffffffffffffL | | ^ | | | | | (24) inlined call to ‘TAGGEDP’ from ‘PSEUDOVECTORP’ | +--> ‘TAGGEDP’: event 25 | | 2352 | return (! (((unsigned) (XLI (a) >> (((0x7fffffffffffffffL | | ^ | | | | | (25) inlined call to ‘XLI’ from ‘TAGGEDP’ | +--> ‘XLI’: event 26 | | 2327 | return ((EMACS_INT) (o)); | | ~^~~~~~~~~~~~~~~~ | | | | | (26) ...to here | <---------------------------+ | ‘set_marker_internal’: events 27-29 | |17914 | charpos = clip_to_bounds | | ^~~~~~~~~~~~~~ | | | | | (27) following ‘false’ branch (when ‘restricted == 0’)... |17915 | (restricted ? BUF_BEGV (b) : BUF_BEG (b), charpos, | | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |17916 | restricted ? BUF_ZV (b) : ((b)->text->z)); | | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | | | | | (28) ...to here | | (29) dereference of NULL ‘<unknown>’ |