https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109613
Bug ID: 109613 Summary: -Wanalyzer-null-dereference false positive involving __builtin_unreachable Product: gcc Version: 13.0 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 54914 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=54914&action=edit compile with "gcc -fanalyzer -S -O2 u.i" to reproduce the bug I ran into this problem compiling GNU coreutils with gcc (GCC) 13.0.1 20230401 (Red Hat 13.0.1-0) on x86-64. Compile the attached program with: gzip -d u.i.gz gcc -fanalyzer -S -O2 u.i The output is shown below. The first warning is wrong, since 'mode' is not null there. Although this should be deducible even without the __builtin_unreachable calls in lines 9025, 9027, 9029 (because xpalloc returns nonnull), it's clearly deducible with those three lines, since if new_mode_len is nonnegative (checked by line 9029) then xpalloc must be called and therefore 'mode' cannot be null. If I remove line 9027, which is merely "((0 <= mode_comma_len) ? (void) 0 : __builtin_unreachable ());", the false positive goes away. There must be something wrong there too, as that line merely adds a constraint. u.i: In function ‘main’: u.i:9033:28: warning: dereference of NULL ‘mode’ [CWE-476] [-Wanalyzer-null-dereference] 9033 | mode[mode_len] = ','; | ~~~~~~~~~~~~~~~^~~~~ ‘main’: events 1-11 | | 8988 | while ((c = getopt_long (argc, argv, | | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | 8989 | ("Rcfvr::w::x::X::s::t::u::g::o::a::,::+::=::" | | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | 8990 | "0::1::2::3::4::5::6::7::"), | | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | 8991 | long_options, | | ~~~~~~~~~~~~~ | 8992 | ((void *)0) | | ~~~~~~~~~~~ | 8993 | )) | | ~~ | 8994 | != -1) | | ^~~~~ | | | | | (1) following ‘true’ branch (when ‘c != -1’)... | 8995 | { | 8996 | switch (c) | | ~~~~~~ | | | | | (2) ...to here | | (3) following ‘case 43 ... 44:, case 48 ... 55:, case 61:, case 88:, case 97:, case 103:, case 111:, case 114 ... 117:, case 119 ... 120:’ branch... | 8997 | { | 8998 | case 'r': | | ~~~~ | | | | | (4) ...to here |...... | 9027 | ((0 <= mode_comma_len) ? (void) 0 : __builtin_unreachable ()); | | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | | | | | (5) following ‘false’ branch (when ‘mode_comma_len >= 0’)... | 9028 | idx_t new_mode_len = mode_comma_len + arg_len; | | ~~~~~~~~~~~~ | | | | | (6) ...to here | 9029 | ((0 <= new_mode_len) ? (void) 0 : __builtin_unreachable ()); | 9030 | if (mode_alloc <= new_mode_len) | | ~ | | | | | (7) following ‘false’ branch... |...... | 9033 | mode[mode_len] = ','; | | ~~~~~~~~~~~~~~~~~~~~ | | | | | | | (11) dereference of NULL ‘mode + (sizetype)mode_len’ | | (8) ...to here | | (9) ‘mode’ is NULL | 9034 | memcpy (mode + mode_comma_len, arg, arg_len + 1); | | ~~~~~~~~~~~~~~~~~~~~~ | | | | | (10) ‘mode’ is NULL |