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
            |

Reply via email to