public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug analyzer/109614] New: -Wanalyzer-use-after-free gets confused about a free function in Coreutils
@ 2023-04-25  0:17 eggert at cs dot ucla.edu
  0 siblings, 0 replies; only message in thread
From: eggert at cs dot ucla.edu @ 2023-04-25  0:17 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109614

            Bug ID: 109614
           Summary: -Wanalyzer-use-after-free gets confused about a free
                    function in Coreutils
           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 54915
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=54915&action=edit
bug reproducer

This is (GCC) 13.0.1 20230401 (Red Hat 13.0.1-0) on x86-64. Compile the
attached file (derived from GNU coreutils csplit) with:

  gzip -d a.i.gz
  gcc -fanalyzer -S a.i

The first warning is a false positive. As near as I can make out, -fanalyzer
got confused and is treating free_buffer as if it calls itself or was called
twice, which is obviously wrong (the diagnostic is confusing at any rate). The
full set of diagnostics is shown below.

        a.i: In function ‘free_buffer’:
        a.i:4491:21: warning: use after ‘free_buffer’ of ‘buf’ [CWE-416]
[-Wanalyzer-use-after-free]
         4491 |   for (struct line *l = buf->line_start; l;)
              |                     ^
          ‘main’: events 1-6
            |
            | 5509 | main (int argc, char **argv)
            |      | ^~~~
            |      | |
            |      | (1) entry to ‘main’
            |......
            | 5588 |   if (argc - optind < 2)
            |      |      ~
            |      |      |
            |      |      (2) following ‘false’ branch...
            |......
            | 5598 |   idx_t prefix_len = strlen (prefix);
            |      |                      ~~~~~~~~~~~~~~~
            |      |                      |
            |      |                      (3) ...to here
            |......
            | 5616 |   if (__builtin_add_overflow (prefix_len,
max_digit_string_len + 1, &filename_size))
            |      |      ~
            |      |      |
            |      |      (4) following ‘false’ branch...
            | 5617 |     xalloc_die ();
            | 5618 |   filename_space = ximalloc (filename_size);
            |      |                    ~~~~~~~~~~~~~~~~~~~~~~~~
            |      |                    |
            |      |                    (5) ...to here
            | 5619 |   set_input_file (argv[optind++]);
            |      |   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
            |      |   |
            |      |   (6) calling ‘set_input_file’ from ‘main’
            |
            +--> ‘set_input_file’: events 7-11
                   |
                   | 4708 | set_input_file (char const *name)
                   |      | ^~~~~~~~~~~~~~
                   |      | |
                   |      | (7) entry to ‘set_input_file’
                   | 4709 | {
                   | 4710 |   if (! (strcmp (name, "-") == 0) && fd_reopen (
                   |      |      ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
                   |      |      |                            |  |
                   |      |      |                            |  (9) ...to here
                   |      |      |                            (10) following
‘false’ branch...
                   |      |      (8) following ‘true’ branch (when the strings
are non-equal)...
                   | 4711 |                                        0
                   |      |                                        ~
                   | 4712 |                                                   
, name,
                   |      |                                                   
~~~~~~~
                   | 4713 |                                                    
       00
                   |      |                                                    
       ~~
                   | 4714 |                                                    
               , 0) < 0)
                   |      |                                                    
               ~~~~~~~~
                   |......
                   | 4731 | }
                   |      | ~
                   |      | |
                   |      | (11) ...to here
                   |
            <------+
            |
          ‘main’: events 12-21
            |
            | 5619 |   set_input_file (argv[optind++]);
            |      |   ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
            |      |   |
            |      |   (12) returning to ‘main’ from ‘set_input_file’
            |......
            | 5651 |     for (i = 0; i < nsigs; i++)
            |      |                 ~~~~~~~~~
            |      |                   |
            |      |                   (13) following ‘true’ branch (when ‘i <=
10’)...
            |      |                   (15) following ‘true’ branch (when ‘i <=
10’)...
            | 5652 |       {
            | 5653 |         sigaction (sig[i],
            |      |                    ~~~~~~
            |      |                       |
            |      |                       (14) ...to here
            |      |                       (16) ...to here
            |......
            | 5668 |     for (i = 0; i < nsigs; i++)
            |      |                 ~~~~~~~~~
            |      |                   |
            |      |                   (17) following ‘true’ branch (when ‘i <=
10’)...
            |      |                   (19) following ‘true’ branch (when ‘i <=
10’)...
            | 5669 |       if (sigismember (&caught_signals, sig[i]))
            |      |                                         ~~~~~~
            |      |                                            |
            |      |                                            (18) ...to here
            |      |                                            (20) ...to here
            |......
            | 5674 |   split_file ();
            |      |   ~~~~~~~~~~~~~
            |      |   |
            |      |   (21) calling ‘split_file’ from ‘main’
            |
            +--> ‘split_file’: events 22-29
                   |
                   | 4953 | split_file (void)
                   |      | ^~~~~~~~~~
                   |      | |
                   |      | (22) entry to ‘split_file’
                   | 4954 | {
                   | 4955 |   for (idx_t i = 0; i < control_used; i++)
                   |      |                     ~~~~~~~~~~~~~~~~
                   |      |                       |
                   |      |                       (23) following ‘true’
branch...
                   |......
                   | 4958 |       if (controls[i].regexpr)
                   |      |          ~        ~
                   |      |          |        |
                   |      |          |        (24) ...to here
                   |      |          (25) following ‘true’ branch...
                   | 4959 |         {
                   | 4960 |           for (j = 0; (controls[i].repeat_forever
                   |      |                ~~~~~  ~~~~~~~~~~~~~~~~~~~~~~~~~~~
                   |      |                  |
                   |      |                  (26) ...to here
                   | 4961 |                        || j <= controls[i].repeat);
j++)
                   |      |                        ~~~~~~~~~~~~~~~~~~~~~~~~~~~
                   |      |                        |
                   |      |                        (27) following ‘true’
branch...
                   | 4962 |             process_regexp (&controls[i], j);
                   |      |             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
                   |      |             |
                   |      |             (28) ...to here
                   |      |             (29) calling ‘process_regexp’ from
‘split_file’
                   |
                   +--> ‘process_regexp’: events 30-33
                          |
                          | 4845 | process_regexp (struct control *p, intmax_t
repetition)
                          |      | ^~~~~~~~~~~~~~
                          |      | |
                          |      | (30) entry to ‘process_regexp’
                          |......
                          | 4853 |   if (!ignore)
                          |      |      ~
                          |      |      |
                          |      |      (31) following ‘true’ branch...
                          | 4854 |     create_output_file ();
                          |      |     ~~~~~~~~~~~~~~~~~~~~~
                          |      |     |
                          |      |     (32) ...to here
                          |      |     (33) calling ‘create_output_file’ from
‘process_regexp’
                          |
                          +--> ‘create_output_file’: events 34-38
                                 |
                                 | 4986 | create_output_file (void)
                                 |      | ^~~~~~~~~~~~~~~~~~
                                 |      | |
                                 |      | (34) entry to ‘create_output_file’
                                 |......
                                 | 4993 |   if (nfiles == 0x7fffffff
                                 |      |      ~
                                 |      |      |
                                 |      |      (35) following ‘false’ branch
(when ‘nfiles != 2147483647’)...
                                 |......
                                 | 5006 |       sigprocmask (
                                 |      |       ~~~~~~~~~~~~~
                                 |      |       |
                                 |      |       (36) ...to here
                                 | 5007 |                   0
                                 |      |                   ~
                                 | 5008 |                            ,
&caught_signals, &oldset);
                                 |      |                           
~~~~~~~~~~~~~~~~~~~~~~~~~~~
                                 |......
                                 | 5023 |   if (! fopen_ok)
                                 |      |      ~
                                 |      |      |
                                 |      |      (37) following ‘false’ branch...
                                 |......
                                 | 5028 |   bytes_written = 0;
                                 |      |   ~~~~~~~~~~~~~~~~~
                                 |      |                 |
                                 |      |                 (38) ...to here
                                 |
                          <------+
                          |
                        ‘process_regexp’: events 39-42
                          |
                          | 4854 |     create_output_file ();
                          |      |     ^~~~~~~~~~~~~~~~~~~~~
                          |      |     |
                          |      |     (39) returning to ‘process_regexp’ from
‘create_output_file’
                          | 4855 |   if (p->offset >= 0)
                          |      |      ~
                          |      |      |
                          |      |      (40) following ‘true’ branch...
                          |......
                          | 4861 |           line = find_line (++current_line);
                          |      |                  ~~~~~~~~~~~~~~~~~~~~~~~~~~
                          |      |                  |
                          |      |                  (41) ...to here
                          |      |                  (42) calling ‘find_line’
from ‘process_regexp’
                          |
                          +--> ‘find_line’: events 43-46
                                 |
                                 | 4654 | find_line (intmax_t linenum)
                                 |      | ^~~~~~~~~
                                 |      | |
                                 |      | (43) entry to ‘find_line’
                                 |......
                                 | 4657 |   if (head ==
                                 |      |      ~
                                 |      |      |
                                 |      |      (44) following ‘true’ branch...
                                 | 4658 |              ((void *)0)
                                 | 4659 |                   && !load_buffer ())
                                 |      |                       ~~~~~~~~~~~~~~
                                 |      |                       |
                                 |      |                       (45) ...to here
                                 |      |                       (46) calling
‘load_buffer’ from ‘find_line’
                                 |
                                 +--> ‘load_buffer’: events 47-50
                                        |
                                        | 4542 | load_buffer (void)
                                        |      | ^~~~~~~~~~~
                                        |      | |
                                        |      | (47) entry to ‘load_buffer’
                                        | 4543 | {
                                        | 4544 |   if (have_read_eof)
                                        |      |      ~
                                        |      |      |
                                        |      |      (48) following ‘false’
branch...
                                        |......
                                        | 4549 |                       (((
                                        |      |                       ~~~
                                        | 4550 |                       8191
                                        |      |                       ~~~~
                                        | 4551 |                       )>(
                                        |      |                       ~~~
                                        | 4552 |                      
hold_count + 1
                                        |      |                      
~~~~~~~~~~~~~~
                                        | 4553 |                       ))?(
                                        |      |                       ~~~~
                                        | 4554 |                       8191
                                        |      |                       ~~~~
                                        | 4555 |                       ):(
                                        |      |                       ~~~
                                        |      |                        |
                                        |      |                        (49)
...to here
                                        | 4556 |                      
hold_count + 1
                                        |      |                      
~~~~~~~~~~~~~~
                                        | 4557 |                       ))
                                        |      |                       ~~
                                        |......
                                        | 4563 |       struct buffer_record *b
= get_new_buffer (bytes_wanted);
                                        |      |                               
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
                                        |      |                               
 |
                                        |      |                               
 (50) calling ‘get_new_buffer’ from ‘load_buffer’
                                        |
                                        +--> ‘get_new_buffer’: events 51-52
                                               |
                                               | 4502 | get_new_buffer (idx_t
min_size)
                                               |      | ^~~~~~~~~~~~~~
                                               |      | |
                                               |      | (51) entry to
‘get_new_buffer’
                                               | 4503 | {
                                               | 4504 |   struct buffer_record
*new_buffer = xmalloc (sizeof *new_buffer);
                                               |      |                        
             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
                                               |      |                        
             |
                                               |      |                        
             (52) state of ‘&HEAP_ALLOCATED_REGION(1452)’: ‘start’ -> ‘nonnull’
(NULL origin)
                                               |
                                        <------+
                                        |
                                      ‘load_buffer’: events 53-56
                                        |
                                        | 4563 |       struct buffer_record *b
= get_new_buffer (bytes_wanted);
                                        |      |                               
 ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
                                        |      |                               
 |
                                        |      |                               
 (53) returning to ‘load_buffer’ from ‘get_new_buffer’
                                        |......
                                        | 4567 |       if (hold_count)
                                        |      |          ~
                                        |      |          |
                                        |      |          (54) following
‘false’ branch...
                                        |......
                                        | 4574 |       b->bytes_used +=
read_input (p, bytes_avail - 1);
                                        |      |                       
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
                                        |      |                        |
                                        |      |                        (55)
...to here
                                        |      |                        (56)
calling ‘read_input’ from ‘load_buffer’
                                        |
                                        +--> ‘read_input’: events 57-59
                                               |
                                               | 4391 | read_input (char *dest,
idx_t max_n_bytes)
                                               |      | ^~~~~~~~~~
                                               |      | |
                                               |      | (57) entry to
‘read_input’
                                               |......
                                               | 4394 |   if (max_n_bytes == 0)
                                               |      |      ~
                                               |      |      |
                                               |      |      (58) following
‘true’ branch (when ‘max_n_bytes == 0’)...
                                               | 4395 |     return 0;
                                               |      |            ~
                                               |      |            |
                                               |      |            (59) ...to
here
                                               |
                                        <------+
                                        |
                                      ‘load_buffer’: events 60-61
                                        |
                                        | 4574 |       b->bytes_used +=
read_input (p, bytes_avail - 1);
                                        |      |                       
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
                                        |      |                        |
                                        |      |                        (60)
returning to ‘load_buffer’ from ‘read_input’
                                        | 4575 |       if (record_line_starts
(b) != 0)
                                        |      |          
~~~~~~~~~~~~~~~~~~~~~~
                                        |      |           |
                                        |      |           (61) calling
‘record_line_starts’ from ‘load_buffer’
                                        |
                                        +--> ‘record_line_starts’: events 62-64
                                               |
                                               | 4449 | record_line_starts
(struct buffer_record *b)
                                               |      | ^~~~~~~~~~~~~~~~~~
                                               |      | |
                                               |      | (62) entry to
‘record_line_starts’
                                               |......
                                               | 4454 |   if (b->bytes_used ==
0)
                                               |      |      ~
                                               |      |      |
                                               |      |      (63) following
‘true’ branch...
                                               | 4455 |     return 0;
                                               |      |            ~
                                               |      |            |
                                               |      |            (64) ...to
here
                                               |
                                        <------+
                                        |
                                      ‘load_buffer’: events 65-69
                                        |
                                        | 4575 |       if (record_line_starts
(b) != 0)
                                        |      |         
~^~~~~~~~~~~~~~~~~~~~~~
                                        |      |          ||
                                        |      |          |(65) returning to
‘load_buffer’ from ‘record_line_starts’
                                        |      |          (66) following
‘false’ branch...
                                        |......
                                        | 4582 |       free_buffer (b);
                                        |      |       ~~~~~~~~~~~~~~~
                                        |      |       |
                                        |      |       (67) ...to here
                                        |      |       (68) deallocated here
                                        |      |       (69) calling
‘free_buffer’ from ‘load_buffer’
                                        |
                                        +--> ‘free_buffer’: events 70-71
                                               |
                                               | 4489 | free_buffer (struct
buffer_record *buf)
                                               |      | ^~~~~~~~~~~
                                               |      | |
                                               |      | (70) entry to
‘free_buffer’
                                               | 4490 | {
                                               | 4491 |   for (struct line *l =
buf->line_start; l;)
                                               |      |                     ~
                                               |      |                     |
                                               |      |                    
(71) use after ‘free_buffer’ of ‘buf’; deallocated at (68)
                                               |
        a.i: In function ‘get_new_buffer’:
        a.i:4519:10: warning: leak of ‘b’ [CWE-401] [-Wanalyzer-malloc-leak]
         4519 |   return new_buffer;
              |          ^~~~~~~~~~
          ‘main’: events 1-6
            |
            | 5509 | main (int argc, char **argv)
            |      | ^~~~
            |      | |
            |      | (1) entry to ‘main’
            |......
            | 5588 |   if (argc - optind < 2)
            |      |      ~
            |      |      |
            |      |      (2) following ‘false’ branch...
            |......
            | 5598 |   idx_t prefix_len = strlen (prefix);
            |      |                      ~~~~~~~~~~~~~~~
            |      |                      |
            |      |                      (3) ...to here
            |......
            | 5616 |   if (__builtin_add_overflow (prefix_len,
max_digit_string_len + 1, &filename_size))
            |      |      ~
            |      |      |
            |      |      (4) following ‘false’ branch...
            | 5617 |     xalloc_die ();
            | 5618 |   filename_space = ximalloc (filename_size);
            |      |                    ~~~~~~~~~~~~~~~~~~~~~~~~
            |      |                    |
            |      |                    (5) ...to here
            | 5619 |   set_input_file (argv[optind++]);
            |      |   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
            |      |   |
            |      |   (6) calling ‘set_input_file’ from ‘main’
            |
            +--> ‘set_input_file’: events 7-11
                   |
                   | 4708 | set_input_file (char const *name)
                   |      | ^~~~~~~~~~~~~~
                   |      | |
                   |      | (7) entry to ‘set_input_file’
                   | 4709 | {
                   | 4710 |   if (! (strcmp (name, "-") == 0) && fd_reopen (
                   |      |      ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
                   |      |      |                            |  |
                   |      |      |                            |  (9) ...to here
                   |      |      |                            (10) following
‘false’ branch...
                   |      |      (8) following ‘true’ branch (when the strings
are non-equal)...
                   | 4711 |                                        0
                   |      |                                        ~
                   | 4712 |                                                   
, name,
                   |      |                                                   
~~~~~~~
                   | 4713 |                                                    
       00
                   |      |                                                    
       ~~
                   | 4714 |                                                    
               , 0) < 0)
                   |      |                                                    
               ~~~~~~~~
                   |......
                   | 4731 | }
                   |      | ~
                   |      | |
                   |      | (11) ...to here
                   |
            <------+
            |
          ‘main’: events 12-21
            |
            | 5619 |   set_input_file (argv[optind++]);
            |      |   ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
            |      |   |
            |      |   (12) returning to ‘main’ from ‘set_input_file’
            |......
            | 5651 |     for (i = 0; i < nsigs; i++)
            |      |                 ~~~~~~~~~
            |      |                   |
            |      |                   (13) following ‘true’ branch (when ‘i <=
10’)...
            |      |                   (15) following ‘true’ branch (when ‘i <=
10’)...
            | 5652 |       {
            | 5653 |         sigaction (sig[i],
            |      |                    ~~~~~~
            |      |                       |
            |      |                       (14) ...to here
            |      |                       (16) ...to here
            |......
            | 5668 |     for (i = 0; i < nsigs; i++)
            |      |                 ~~~~~~~~~
            |      |                   |
            |      |                   (17) following ‘true’ branch (when ‘i <=
10’)...
            |      |                   (19) following ‘true’ branch (when ‘i <=
10’)...
            | 5669 |       if (sigismember (&caught_signals, sig[i]))
            |      |                                         ~~~~~~
            |      |                                            |
            |      |                                            (18) ...to here
            |      |                                            (20) ...to here
            |......
            | 5674 |   split_file ();
            |      |   ~~~~~~~~~~~~~
            |      |   |
            |      |   (21) calling ‘split_file’ from ‘main’
            |
            +--> ‘split_file’: events 22-29
                   |
                   | 4953 | split_file (void)
                   |      | ^~~~~~~~~~
                   |      | |
                   |      | (22) entry to ‘split_file’
                   | 4954 | {
                   | 4955 |   for (idx_t i = 0; i < control_used; i++)
                   |      |                     ~~~~~~~~~~~~~~~~
                   |      |                       |
                   |      |                       (23) following ‘true’
branch...
                   |......
                   | 4958 |       if (controls[i].regexpr)
                   |      |          ~        ~
                   |      |          |        |
                   |      |          |        (24) ...to here
                   |      |          (25) following ‘true’ branch...
                   | 4959 |         {
                   | 4960 |           for (j = 0; (controls[i].repeat_forever
                   |      |                ~~~~~  ~~~~~~~~~~~~~~~~~~~~~~~~~~~
                   |      |                  |
                   |      |                  (26) ...to here
                   | 4961 |                        || j <= controls[i].repeat);
j++)
                   |      |                        ~~~~~~~~~~~~~~~~~~~~~~~~~~~
                   |      |                        |
                   |      |                        (27) following ‘true’
branch...
                   | 4962 |             process_regexp (&controls[i], j);
                   |      |             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
                   |      |             |
                   |      |             (28) ...to here
                   |      |             (29) calling ‘process_regexp’ from
‘split_file’
                   |
                   +--> ‘process_regexp’: events 30-33
                          |
                          | 4845 | process_regexp (struct control *p, intmax_t
repetition)
                          |      | ^~~~~~~~~~~~~~
                          |      | |
                          |      | (30) entry to ‘process_regexp’
                          |......
                          | 4853 |   if (!ignore)
                          |      |      ~
                          |      |      |
                          |      |      (31) following ‘true’ branch...
                          | 4854 |     create_output_file ();
                          |      |     ~~~~~~~~~~~~~~~~~~~~~
                          |      |     |
                          |      |     (32) ...to here
                          |      |     (33) calling ‘create_output_file’ from
‘process_regexp’
                          |
                          +--> ‘create_output_file’: events 34-38
                                 |
                                 | 4986 | create_output_file (void)
                                 |      | ^~~~~~~~~~~~~~~~~~
                                 |      | |
                                 |      | (34) entry to ‘create_output_file’
                                 |......
                                 | 4993 |   if (nfiles == 0x7fffffff
                                 |      |      ~
                                 |      |      |
                                 |      |      (35) following ‘false’ branch
(when ‘nfiles != 2147483647’)...
                                 |......
                                 | 5006 |       sigprocmask (
                                 |      |       ~~~~~~~~~~~~~
                                 |      |       |
                                 |      |       (36) ...to here
                                 | 5007 |                   0
                                 |      |                   ~
                                 | 5008 |                            ,
&caught_signals, &oldset);
                                 |      |                           
~~~~~~~~~~~~~~~~~~~~~~~~~~~
                                 |......
                                 | 5023 |   if (! fopen_ok)
                                 |      |      ~
                                 |      |      |
                                 |      |      (37) following ‘false’ branch...
                                 |......
                                 | 5028 |   bytes_written = 0;
                                 |      |   ~~~~~~~~~~~~~~~~~
                                 |      |                 |
                                 |      |                 (38) ...to here
                                 |
                          <------+
                          |
                        ‘process_regexp’: events 39-42
                          |
                          | 4854 |     create_output_file ();
                          |      |     ^~~~~~~~~~~~~~~~~~~~~
                          |      |     |
                          |      |     (39) returning to ‘process_regexp’ from
‘create_output_file’
                          | 4855 |   if (p->offset >= 0)
                          |      |      ~
                          |      |      |
                          |      |      (40) following ‘true’ branch...
                          |......
                          | 4861 |           line = find_line (++current_line);
                          |      |                  ~~~~~~~~~~~~~~~~~~~~~~~~~~
                          |      |                  |
                          |      |                  (41) ...to here
                          |      |                  (42) calling ‘find_line’
from ‘process_regexp’
                          |
                          +--> ‘find_line’: events 43-46
                                 |
                                 | 4654 | find_line (intmax_t linenum)
                                 |      | ^~~~~~~~~
                                 |      | |
                                 |      | (43) entry to ‘find_line’
                                 |......
                                 | 4657 |   if (head ==
                                 |      |      ~
                                 |      |      |
                                 |      |      (44) following ‘true’ branch...
                                 | 4658 |              ((void *)0)
                                 | 4659 |                   && !load_buffer ())
                                 |      |                       ~~~~~~~~~~~~~~
                                 |      |                       |
                                 |      |                       (45) ...to here
                                 |      |                       (46) calling
‘load_buffer’ from ‘find_line’
                                 |
                                 +--> ‘load_buffer’: events 47-51
                                        |
                                        | 4542 | load_buffer (void)
                                        |      | ^~~~~~~~~~~
                                        |      | |
                                        |      | (47) entry to ‘load_buffer’
                                        | 4543 | {
                                        | 4544 |   if (have_read_eof)
                                        |      |      ~
                                        |      |      |
                                        |      |      (48) following ‘false’
branch...
                                        |......
                                        | 4549 |                       (((
                                        |      |                       ~~~
                                        | 4550 |                       8191
                                        |      |                       ~~~~
                                        | 4551 |                       )>(
                                        |      |                       ~~~
                                        | 4552 |                      
hold_count + 1
                                        |      |                      
~~~~~~~~~~~~~~
                                        | 4553 |                       ))?(
                                        |      |                       ~~~~
                                        | 4554 |                       8191
                                        |      |                       ~~~~
                                        | 4555 |                       ):(
                                        |      |                       ~~~
                                        |      |                        |
                                        |      |                        (49)
...to here
                                        | 4556 |                      
hold_count + 1
                                        |      |                      
~~~~~~~~~~~~~~
                                        | 4557 |                       ))
                                        |      |                       ~~
                                        |......
                                        | 4563 |       struct buffer_record *b
= get_new_buffer (bytes_wanted);
                                        |      |                               
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
                                        |      |                               
 |
                                        |      |                               
 (50) allocated here
                                        |      |                               
 (51) calling ‘get_new_buffer’ from ‘load_buffer’
                                        |
                                        +--> ‘get_new_buffer’: events 52-53
                                               |
                                               | 4502 | get_new_buffer (idx_t
min_size)
                                               |      | ^~~~~~~~~~~~~~
                                               |      | |
                                               |      | (52) entry to
‘get_new_buffer’
                                               |......
                                               | 4519 |   return new_buffer;
                                               |      |          ~~~~~~~~~~
                                               |      |          |
                                               |      |          (53) ‘b’ leaks
here; was allocated at (50)
                                               |
        a.i: In function ‘load_buffer’:
        a.i:4582:7: warning: ‘b’ should have been deallocated with ‘free’ but
was deallocated with ‘free_buffer’ [CWE-762]
[-Wanalyzer-mismatching-deallocation]
         4582 |       free_buffer (b);
              |       ^~~~~~~~~~~~~~~
          ‘main’: events 1-6
            |
            | 5509 | main (int argc, char **argv)
            |      | ^~~~
            |      | |
            |      | (1) entry to ‘main’
            |......
            | 5588 |   if (argc - optind < 2)
            |      |      ~
            |      |      |
            |      |      (2) following ‘false’ branch...
            |......
            | 5598 |   idx_t prefix_len = strlen (prefix);
            |      |                      ~~~~~~~~~~~~~~~
            |      |                      |
            |      |                      (3) ...to here
            |......
            | 5616 |   if (__builtin_add_overflow (prefix_len,
max_digit_string_len + 1, &filename_size))
            |      |      ~
            |      |      |
            |      |      (4) following ‘false’ branch...
            | 5617 |     xalloc_die ();
            | 5618 |   filename_space = ximalloc (filename_size);
            |      |                    ~~~~~~~~~~~~~~~~~~~~~~~~
            |      |                    |
            |      |                    (5) ...to here
            | 5619 |   set_input_file (argv[optind++]);
            |      |   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
            |      |   |
            |      |   (6) calling ‘set_input_file’ from ‘main’
            |
            +--> ‘set_input_file’: events 7-11
                   |
                   | 4708 | set_input_file (char const *name)
                   |      | ^~~~~~~~~~~~~~
                   |      | |
                   |      | (7) entry to ‘set_input_file’
                   | 4709 | {
                   | 4710 |   if (! (strcmp (name, "-") == 0) && fd_reopen (
                   |      |      ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
                   |      |      |                            |  |
                   |      |      |                            |  (9) ...to here
                   |      |      |                            (10) following
‘false’ branch...
                   |      |      (8) following ‘true’ branch (when the strings
are non-equal)...
                   | 4711 |                                        0
                   |      |                                        ~
                   | 4712 |                                                   
, name,
                   |      |                                                   
~~~~~~~
                   | 4713 |                                                    
       00
                   |      |                                                    
       ~~
                   | 4714 |                                                    
               , 0) < 0)
                   |      |                                                    
               ~~~~~~~~
                   |......
                   | 4731 | }
                   |      | ~
                   |      | |
                   |      | (11) ...to here
                   |
            <------+
            |
          ‘main’: events 12-21
            |
            | 5619 |   set_input_file (argv[optind++]);
            |      |   ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
            |      |   |
            |      |   (12) returning to ‘main’ from ‘set_input_file’
            |......
            | 5651 |     for (i = 0; i < nsigs; i++)
            |      |                 ~~~~~~~~~
            |      |                   |
            |      |                   (13) following ‘true’ branch (when ‘i <=
10’)...
            |      |                   (15) following ‘true’ branch (when ‘i <=
10’)...
            | 5652 |       {
            | 5653 |         sigaction (sig[i],
            |      |                    ~~~~~~
            |      |                       |
            |      |                       (14) ...to here
            |      |                       (16) ...to here
            |......
            | 5668 |     for (i = 0; i < nsigs; i++)
            |      |                 ~~~~~~~~~
            |      |                   |
            |      |                   (17) following ‘true’ branch (when ‘i <=
10’)...
            |      |                   (19) following ‘true’ branch (when ‘i <=
10’)...
            | 5669 |       if (sigismember (&caught_signals, sig[i]))
            |      |                                         ~~~~~~
            |      |                                            |
            |      |                                            (18) ...to here
            |      |                                            (20) ...to here
            |......
            | 5674 |   split_file ();
            |      |   ~~~~~~~~~~~~~
            |      |   |
            |      |   (21) calling ‘split_file’ from ‘main’
            |
            +--> ‘split_file’: events 22-29
                   |
                   | 4953 | split_file (void)
                   |      | ^~~~~~~~~~
                   |      | |
                   |      | (22) entry to ‘split_file’
                   | 4954 | {
                   | 4955 |   for (idx_t i = 0; i < control_used; i++)
                   |      |                     ~~~~~~~~~~~~~~~~
                   |      |                       |
                   |      |                       (23) following ‘true’
branch...
                   |......
                   | 4958 |       if (controls[i].regexpr)
                   |      |          ~        ~
                   |      |          |        |
                   |      |          |        (24) ...to here
                   |      |          (25) following ‘true’ branch...
                   | 4959 |         {
                   | 4960 |           for (j = 0; (controls[i].repeat_forever
                   |      |                ~~~~~  ~~~~~~~~~~~~~~~~~~~~~~~~~~~
                   |      |                  |
                   |      |                  (26) ...to here
                   | 4961 |                        || j <= controls[i].repeat);
j++)
                   |      |                        ~~~~~~~~~~~~~~~~~~~~~~~~~~~
                   |      |                        |
                   |      |                        (27) following ‘true’
branch...
                   | 4962 |             process_regexp (&controls[i], j);
                   |      |             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
                   |      |             |
                   |      |             (28) ...to here
                   |      |             (29) calling ‘process_regexp’ from
‘split_file’
                   |
                   +--> ‘process_regexp’: events 30-33
                          |
                          | 4845 | process_regexp (struct control *p, intmax_t
repetition)
                          |      | ^~~~~~~~~~~~~~
                          |      | |
                          |      | (30) entry to ‘process_regexp’
                          |......
                          | 4853 |   if (!ignore)
                          |      |      ~
                          |      |      |
                          |      |      (31) following ‘true’ branch...
                          | 4854 |     create_output_file ();
                          |      |     ~~~~~~~~~~~~~~~~~~~~~
                          |      |     |
                          |      |     (32) ...to here
                          |      |     (33) calling ‘create_output_file’ from
‘process_regexp’
                          |
                          +--> ‘create_output_file’: events 34-38
                                 |
                                 | 4986 | create_output_file (void)
                                 |      | ^~~~~~~~~~~~~~~~~~
                                 |      | |
                                 |      | (34) entry to ‘create_output_file’
                                 |......
                                 | 4993 |   if (nfiles == 0x7fffffff
                                 |      |      ~
                                 |      |      |
                                 |      |      (35) following ‘false’ branch
(when ‘nfiles != 2147483647’)...
                                 |......
                                 | 5006 |       sigprocmask (
                                 |      |       ~~~~~~~~~~~~~
                                 |      |       |
                                 |      |       (36) ...to here
                                 | 5007 |                   0
                                 |      |                   ~
                                 | 5008 |                            ,
&caught_signals, &oldset);
                                 |      |                           
~~~~~~~~~~~~~~~~~~~~~~~~~~~
                                 |......
                                 | 5023 |   if (! fopen_ok)
                                 |      |      ~
                                 |      |      |
                                 |      |      (37) following ‘false’ branch...
                                 |......
                                 | 5028 |   bytes_written = 0;
                                 |      |   ~~~~~~~~~~~~~~~~~
                                 |      |                 |
                                 |      |                 (38) ...to here
                                 |
                          <------+
                          |
                        ‘process_regexp’: events 39-42
                          |
                          | 4854 |     create_output_file ();
                          |      |     ^~~~~~~~~~~~~~~~~~~~~
                          |      |     |
                          |      |     (39) returning to ‘process_regexp’ from
‘create_output_file’
                          | 4855 |   if (p->offset >= 0)
                          |      |      ~
                          |      |      |
                          |      |      (40) following ‘true’ branch...
                          |......
                          | 4861 |           line = find_line (++current_line);
                          |      |                  ~~~~~~~~~~~~~~~~~~~~~~~~~~
                          |      |                  |
                          |      |                  (41) ...to here
                          |      |                  (42) calling ‘find_line’
from ‘process_regexp’
                          |
                          +--> ‘find_line’: events 43-46
                                 |
                                 | 4654 | find_line (intmax_t linenum)
                                 |      | ^~~~~~~~~
                                 |      | |
                                 |      | (43) entry to ‘find_line’
                                 |......
                                 | 4657 |   if (head ==
                                 |      |      ~
                                 |      |      |
                                 |      |      (44) following ‘true’ branch...
                                 | 4658 |              ((void *)0)
                                 | 4659 |                   && !load_buffer ())
                                 |      |                       ~~~~~~~~~~~~~~
                                 |      |                       |
                                 |      |                       (45) ...to here
                                 |      |                       (46) calling
‘load_buffer’ from ‘find_line’
                                 |
                                 +--> ‘load_buffer’: events 47-50
                                        |
                                        | 4542 | load_buffer (void)
                                        |      | ^~~~~~~~~~~
                                        |      | |
                                        |      | (47) entry to ‘load_buffer’
                                        | 4543 | {
                                        | 4544 |   if (have_read_eof)
                                        |      |      ~
                                        |      |      |
                                        |      |      (48) following ‘false’
branch...
                                        |......
                                        | 4549 |                       (((
                                        |      |                       ~~~
                                        | 4550 |                       8191
                                        |      |                       ~~~~
                                        | 4551 |                       )>(
                                        |      |                       ~~~
                                        | 4552 |                      
hold_count + 1
                                        |      |                      
~~~~~~~~~~~~~~
                                        | 4553 |                       ))?(
                                        |      |                       ~~~~
                                        | 4554 |                       8191
                                        |      |                       ~~~~
                                        | 4555 |                       ):(
                                        |      |                       ~~~
                                        |      |                        |
                                        |      |                        (49)
...to here
                                        | 4556 |                      
hold_count + 1
                                        |      |                      
~~~~~~~~~~~~~~
                                        | 4557 |                       ))
                                        |      |                       ~~
                                        |......
                                        | 4563 |       struct buffer_record *b
= get_new_buffer (bytes_wanted);
                                        |      |                               
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
                                        |      |                               
 |
                                        |      |                               
 (50) calling ‘get_new_buffer’ from ‘load_buffer’
                                        |
                                        +--> ‘get_new_buffer’: events 51-52
                                               |
                                               | 4502 | get_new_buffer (idx_t
min_size)
                                               |      | ^~~~~~~~~~~~~~
                                               |      | |
                                               |      | (51) entry to
‘get_new_buffer’
                                               | 4503 | {
                                               | 4504 |   struct buffer_record
*new_buffer = xmalloc (sizeof *new_buffer);
                                               |      |                        
             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
                                               |      |                        
             |
                                               |      |                        
             (52) state of ‘&HEAP_ALLOCATED_REGION(1452)’: ‘start’ -> ‘nonnull’
(NULL origin)
                                               |
                                        <------+
                                        |
                                      ‘load_buffer’: events 53-56
                                        |
                                        | 4563 |       struct buffer_record *b
= get_new_buffer (bytes_wanted);
                                        |      |                               
 ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
                                        |      |                               
 |
                                        |      |                               
 (53) returning to ‘load_buffer’ from ‘get_new_buffer’
                                        |......
                                        | 4567 |       if (hold_count)
                                        |      |          ~
                                        |      |          |
                                        |      |          (54) following
‘false’ branch...
                                        |......
                                        | 4574 |       b->bytes_used +=
read_input (p, bytes_avail - 1);
                                        |      |                       
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
                                        |      |                        |
                                        |      |                        (55)
...to here
                                        |      |                        (56)
calling ‘read_input’ from ‘load_buffer’
                                        |
                                        +--> ‘read_input’: events 57-59
                                               |
                                               | 4391 | read_input (char *dest,
idx_t max_n_bytes)
                                               |      | ^~~~~~~~~~
                                               |      | |
                                               |      | (57) entry to
‘read_input’
                                               |......
                                               | 4394 |   if (max_n_bytes == 0)
                                               |      |      ~
                                               |      |      |
                                               |      |      (58) following
‘true’ branch (when ‘max_n_bytes == 0’)...
                                               | 4395 |     return 0;
                                               |      |            ~
                                               |      |            |
                                               |      |            (59) ...to
here
                                               |
                                        <------+
                                        |
                                      ‘load_buffer’: events 60-61
                                        |
                                        | 4574 |       b->bytes_used +=
read_input (p, bytes_avail - 1);
                                        |      |                       
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
                                        |      |                        |
                                        |      |                        (60)
returning to ‘load_buffer’ from ‘read_input’
                                        | 4575 |       if (record_line_starts
(b) != 0)
                                        |      |          
~~~~~~~~~~~~~~~~~~~~~~
                                        |      |           |
                                        |      |           (61) calling
‘record_line_starts’ from ‘load_buffer’
                                        |
                                        +--> ‘record_line_starts’: events 62-64
                                               |
                                               | 4449 | record_line_starts
(struct buffer_record *b)
                                               |      | ^~~~~~~~~~~~~~~~~~
                                               |      | |
                                               |      | (62) entry to
‘record_line_starts’
                                               |......
                                               | 4454 |   if (b->bytes_used ==
0)
                                               |      |      ~
                                               |      |      |
                                               |      |      (63) following
‘true’ branch...
                                               | 4455 |     return 0;
                                               |      |            ~
                                               |      |            |
                                               |      |            (64) ...to
here
                                               |
                                        <------+
                                        |
                                      ‘load_buffer’: events 65-68
                                        |
                                        | 4575 |       if (record_line_starts
(b) != 0)
                                        |      |         
~^~~~~~~~~~~~~~~~~~~~~~
                                        |      |          ||
                                        |      |          |(65) returning to
‘load_buffer’ from ‘record_line_starts’
                                        |      |          (66) following
‘false’ branch...
                                        |......
                                        | 4582 |       free_buffer (b);
                                        |      |       ~~~~~~~~~~~~~~~
                                        |      |       |
                                        |      |       (67) ...to here
                                        |      |       (68) deallocated with
‘free_buffer’ here
                                        |
        a.i:4582:7: warning: leak of ‘<unknown>’ [CWE-401]
[-Wanalyzer-malloc-leak]
         4582 |       free_buffer (b);
              |       ^~~~~~~~~~~~~~~
          ‘main’: events 1-6
            |
            | 5509 | main (int argc, char **argv)
            |      | ^~~~
            |      | |
            |      | (1) entry to ‘main’
            |......
            | 5588 |   if (argc - optind < 2)
            |      |      ~
            |      |      |
            |      |      (2) following ‘false’ branch...
            |......
            | 5598 |   idx_t prefix_len = strlen (prefix);
            |      |                      ~~~~~~~~~~~~~~~
            |      |                      |
            |      |                      (3) ...to here
            |......
            | 5616 |   if (__builtin_add_overflow (prefix_len,
max_digit_string_len + 1, &filename_size))
            |      |      ~
            |      |      |
            |      |      (4) following ‘false’ branch...
            | 5617 |     xalloc_die ();
            | 5618 |   filename_space = ximalloc (filename_size);
            |      |                    ~~~~~~~~~~~~~~~~~~~~~~~~
            |      |                    |
            |      |                    (5) ...to here
            | 5619 |   set_input_file (argv[optind++]);
            |      |   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
            |      |   |
            |      |   (6) calling ‘set_input_file’ from ‘main’
            |
            +--> ‘set_input_file’: events 7-11
                   |
                   | 4708 | set_input_file (char const *name)
                   |      | ^~~~~~~~~~~~~~
                   |      | |
                   |      | (7) entry to ‘set_input_file’
                   | 4709 | {
                   | 4710 |   if (! (strcmp (name, "-") == 0) && fd_reopen (
                   |      |      ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
                   |      |      |                            |  |
                   |      |      |                            |  (9) ...to here
                   |      |      |                            (10) following
‘false’ branch...
                   |      |      (8) following ‘true’ branch (when the strings
are non-equal)...
                   | 4711 |                                        0
                   |      |                                        ~
                   | 4712 |                                                   
, name,
                   |      |                                                   
~~~~~~~
                   | 4713 |                                                    
       00
                   |      |                                                    
       ~~
                   | 4714 |                                                    
               , 0) < 0)
                   |      |                                                    
               ~~~~~~~~
                   |......
                   | 4731 | }
                   |      | ~
                   |      | |
                   |      | (11) ...to here
                   |
            <------+
            |
          ‘main’: events 12-21
            |
            | 5619 |   set_input_file (argv[optind++]);
            |      |   ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
            |      |   |
            |      |   (12) returning to ‘main’ from ‘set_input_file’
            |......
            | 5651 |     for (i = 0; i < nsigs; i++)
            |      |                 ~~~~~~~~~
            |      |                   |
            |      |                   (13) following ‘true’ branch (when ‘i <=
10’)...
            |      |                   (15) following ‘true’ branch (when ‘i <=
10’)...
            | 5652 |       {
            | 5653 |         sigaction (sig[i],
            |      |                    ~~~~~~
            |      |                       |
            |      |                       (14) ...to here
            |      |                       (16) ...to here
            |......
            | 5668 |     for (i = 0; i < nsigs; i++)
            |      |                 ~~~~~~~~~
            |      |                   |
            |      |                   (17) following ‘true’ branch (when ‘i <=
10’)...
            |      |                   (19) following ‘true’ branch (when ‘i <=
10’)...
            | 5669 |       if (sigismember (&caught_signals, sig[i]))
            |      |                                         ~~~~~~
            |      |                                            |
            |      |                                            (18) ...to here
            |      |                                            (20) ...to here
            |......
            | 5674 |   split_file ();
            |      |   ~~~~~~~~~~~~~
            |      |   |
            |      |   (21) calling ‘split_file’ from ‘main’
            |
            +--> ‘split_file’: events 22-29
                   |
                   | 4953 | split_file (void)
                   |      | ^~~~~~~~~~
                   |      | |
                   |      | (22) entry to ‘split_file’
                   | 4954 | {
                   | 4955 |   for (idx_t i = 0; i < control_used; i++)
                   |      |                     ~~~~~~~~~~~~~~~~
                   |      |                       |
                   |      |                       (23) following ‘true’
branch...
                   |......
                   | 4958 |       if (controls[i].regexpr)
                   |      |          ~        ~
                   |      |          |        |
                   |      |          |        (24) ...to here
                   |      |          (25) following ‘true’ branch...
                   | 4959 |         {
                   | 4960 |           for (j = 0; (controls[i].repeat_forever
                   |      |                ~~~~~  ~~~~~~~~~~~~~~~~~~~~~~~~~~~
                   |      |                  |
                   |      |                  (26) ...to here
                   | 4961 |                        || j <= controls[i].repeat);
j++)
                   |      |                        ~~~~~~~~~~~~~~~~~~~~~~~~~~~
                   |      |                        |
                   |      |                        (27) following ‘true’
branch...
                   | 4962 |             process_regexp (&controls[i], j);
                   |      |             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
                   |      |             |
                   |      |             (28) ...to here
                   |      |             (29) calling ‘process_regexp’ from
‘split_file’
                   |
                   +--> ‘process_regexp’: events 30-33
                          |
                          | 4845 | process_regexp (struct control *p, intmax_t
repetition)
                          |      | ^~~~~~~~~~~~~~
                          |      | |
                          |      | (30) entry to ‘process_regexp’
                          |......
                          | 4853 |   if (!ignore)
                          |      |      ~
                          |      |      |
                          |      |      (31) following ‘true’ branch...
                          | 4854 |     create_output_file ();
                          |      |     ~~~~~~~~~~~~~~~~~~~~~
                          |      |     |
                          |      |     (32) ...to here
                          |      |     (33) calling ‘create_output_file’ from
‘process_regexp’
                          |
                          +--> ‘create_output_file’: events 34-38
                                 |
                                 | 4986 | create_output_file (void)
                                 |      | ^~~~~~~~~~~~~~~~~~
                                 |      | |
                                 |      | (34) entry to ‘create_output_file’
                                 |......
                                 | 4993 |   if (nfiles == 0x7fffffff
                                 |      |      ~
                                 |      |      |
                                 |      |      (35) following ‘false’ branch
(when ‘nfiles != 2147483647’)...
                                 |......
                                 | 5006 |       sigprocmask (
                                 |      |       ~~~~~~~~~~~~~
                                 |      |       |
                                 |      |       (36) ...to here
                                 | 5007 |                   0
                                 |      |                   ~
                                 | 5008 |                            ,
&caught_signals, &oldset);
                                 |      |                           
~~~~~~~~~~~~~~~~~~~~~~~~~~~
                                 |......
                                 | 5023 |   if (! fopen_ok)
                                 |      |      ~
                                 |      |      |
                                 |      |      (37) following ‘false’ branch...
                                 |......
                                 | 5028 |   bytes_written = 0;
                                 |      |   ~~~~~~~~~~~~~~~~~
                                 |      |                 |
                                 |      |                 (38) ...to here
                                 |
                          <------+
                          |
                        ‘process_regexp’: events 39-42
                          |
                          | 4854 |     create_output_file ();
                          |      |     ^~~~~~~~~~~~~~~~~~~~~
                          |      |     |
                          |      |     (39) returning to ‘process_regexp’ from
‘create_output_file’
                          | 4855 |   if (p->offset >= 0)
                          |      |      ~
                          |      |      |
                          |      |      (40) following ‘true’ branch...
                          |......
                          | 4861 |           line = find_line (++current_line);
                          |      |                  ~~~~~~~~~~~~~~~~~~~~~~~~~~
                          |      |                  |
                          |      |                  (41) ...to here
                          |      |                  (42) calling ‘find_line’
from ‘process_regexp’
                          |
                          +--> ‘find_line’: events 43-46
                                 |
                                 | 4654 | find_line (intmax_t linenum)
                                 |      | ^~~~~~~~~
                                 |      | |
                                 |      | (43) entry to ‘find_line’
                                 |......
                                 | 4657 |   if (head ==
                                 |      |      ~
                                 |      |      |
                                 |      |      (44) following ‘true’ branch...
                                 | 4658 |              ((void *)0)
                                 | 4659 |                   && !load_buffer ())
                                 |      |                       ~~~~~~~~~~~~~~
                                 |      |                       |
                                 |      |                       (45) ...to here
                                 |      |                       (46) calling
‘load_buffer’ from ‘find_line’
                                 |
                                 +--> ‘load_buffer’: events 47-52
                                        |
                                        | 4542 | load_buffer (void)
                                        |      | ^~~~~~~~~~~
                                        |      | |
                                        |      | (47) entry to ‘load_buffer’
                                        | 4543 | {
                                        | 4544 |   if (have_read_eof)
                                        |      |      ~
                                        |      |      |
                                        |      |      (48) following ‘false’
branch...
                                        |......
                                        | 4549 |                       (((
                                        |      |                       ~~~
                                        | 4550 |                       8191
                                        |      |                       ~~~~
                                        | 4551 |                       )>(
                                        |      |                       ~~~
                                        | 4552 |                      
hold_count + 1
                                        |      |                      
~~~~~~~~~~~~~~
                                        | 4553 |                       ))?(
                                        |      |                       ~~~~
                                        | 4554 |                       8191
                                        |      |                       ~~~~
                                        | 4555 |                       ):(
                                        |      |                       ~~~
                                        |      |                        |
                                        |      |                        (49)
...to here
                                        | 4556 |                      
hold_count + 1
                                        |      |                      
~~~~~~~~~~~~~~
                                        | 4557 |                       ))
                                        |      |                       ~~
                                        |......
                                        | 4567 |       if (hold_count)
                                        |      |          ~
                                        |      |          |
                                        |      |          (50) following
‘false’ branch...
                                        |......
                                        | 4574 |       b->bytes_used +=
read_input (p, bytes_avail - 1);
                                        |      |                       
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
                                        |      |                        |
                                        |      |                        (51)
...to here
                                        |      |                        (52)
calling ‘read_input’ from ‘load_buffer’
                                        |
                                        +--> ‘read_input’: events 53-57
                                               |
                                               | 4391 | read_input (char *dest,
idx_t max_n_bytes)
                                               |      | ^~~~~~~~~~
                                               |      | |
                                               |      | (53) entry to
‘read_input’
                                               |......
                                               | 4394 |   if (max_n_bytes == 0)
                                               |      |      ~
                                               |      |      |
                                               |      |      (54) following
‘false’ branch (when ‘max_n_bytes != 0’)...
                                               | 4395 |     return 0;
                                               | 4396 |   bytes_read =
safe_read (
                                               |      |               
~~~~~~~~~~~
                                               |      |                |
                                               |      |                (55)
...to here
                                               | 4397 |                        
 0
                                               |      |                        
 ~
                                               | 4398 |                        
             , dest, max_n_bytes);
                                               |      |                        
             ~~~~~~~~~~~~~~~~~~~~
                                               |......
                                               | 4403 |   if (bytes_read ==
((size_t) -1))
                                               |      |      ~
                                               |      |      |
                                               |      |      (56) following
‘false’ branch (when ‘bytes_read != -1’)...
                                               |......
                                               | 4410 |   return bytes_read;
                                               |      |          ~~~~~~~~~~
                                               |      |          |
                                               |      |          (57) ...to
here
                                               |
                                        <------+
                                        |
                                      ‘load_buffer’: events 58-59
                                        |
                                        | 4574 |       b->bytes_used +=
read_input (p, bytes_avail - 1);
                                        |      |                       
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
                                        |      |                        |
                                        |      |                        (58)
returning to ‘load_buffer’ from ‘read_input’
                                        | 4575 |       if (record_line_starts
(b) != 0)
                                        |      |          
~~~~~~~~~~~~~~~~~~~~~~
                                        |      |           |
                                        |      |           (59) calling
‘record_line_starts’ from ‘load_buffer’
                                        |
                                        +--> ‘record_line_starts’: events 60-65
                                               |
                                               | 4449 | record_line_starts
(struct buffer_record *b)
                                               |      | ^~~~~~~~~~~~~~~~~~
                                               |      | |
                                               |      | (60) entry to
‘record_line_starts’
                                               |......
                                               | 4454 |   if (b->bytes_used ==
0)
                                               |      |      ~
                                               |      |      |
                                               |      |      (61) following
‘false’ branch...
                                               | 4455 |     return 0;
                                               | 4456 |   lines = 0;
                                               |      |   ~~~~~~~~~
                                               |      |         |
                                               |      |         (62) ...to here
                                               |......
                                               | 4465 |       if (line_end ==
buffer_end)
                                               |      |          ~
                                               |      |          |
                                               |      |          (63) following
‘false’ branch (when ‘line_end != buffer_end’)...
                                               | 4466 |         break;
                                               | 4467 |       line_length =
line_end - line_start + 1;
                                               |      |                    
~~~~~~~~~~~~~~~~~~~~~
                                               |      |                        
     |
                                               |      |                        
     (64) ...to here
                                               | 4468 |       keep_new_line (b,
line_start, line_length);
                                               |      |      
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
                                               |      |       |
                                               |      |       (65) calling
‘keep_new_line’ from ‘record_line_starts’
                                               |
                                               +--> ‘keep_new_line’: events
66-68
                                                      |
                                                      | 4430 | keep_new_line
(struct buffer_record *b, char *line_start, idx_t line_len)
                                                      |      | ^~~~~~~~~~~~~
                                                      |      | |
                                                      |      | (66) entry to
‘keep_new_line’
                                                      |......
                                                      | 4433 |   if
(b->line_start ==
                                                      |      |      ~
                                                      |      |      |
                                                      |      |      (67)
following ‘false’ branch...
                                                      |......
                                                      | 4437 |   if
(b->curr_line->used == 80)
                                                      |      |      
~~~~~~~~~~~~
                                                      |      |        |
                                                      |      |        (68)
...to here
                                                      |
                                               <------+
                                               |
                                             ‘record_line_starts’: events 69-72
                                               |
                                               | 4465 |       if (line_end ==
buffer_end)
                                               |      |          ~
                                               |      |          |
                                               |      |          (70) following
‘false’ branch (when ‘line_end != buffer_end’)...
                                               | 4466 |         break;
                                               | 4467 |       line_length =
line_end - line_start + 1;
                                               |      |                    
~~~~~~~~~~~~~~~~~~~~~
                                               |      |                        
     |
                                               |      |                        
     (71) ...to here
                                               | 4468 |       keep_new_line (b,
line_start, line_length);
                                               |      |      
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
                                               |      |       |
                                               |      |       (69) returning to
‘record_line_starts’ from ‘keep_new_line’
                                               |      |       (72) calling
‘keep_new_line’ from ‘record_line_starts’
                                               |
                                               +--> ‘keep_new_line’: events
73-76
                                                      |
                                                      | 4430 | keep_new_line
(struct buffer_record *b, char *line_start, idx_t line_len)
                                                      |      | ^~~~~~~~~~~~~
                                                      |      | |
                                                      |      | (73) entry to
‘keep_new_line’
                                                      |......
                                                      | 4433 |   if
(b->line_start ==
                                                      |      |      ~
                                                      |      |      |
                                                      |      |      (74)
following ‘true’ branch...
                                                      |......
                                                      | 4436 |    
b->line_start = b->curr_line = new_line_control ();
                                                      |      |                 
                  ~~~~~~~~~~~~~~~~~~~
                                                      |      |                 
                  |
                                                      |      |                 
                  (75) ...to here
                                                      |      |                 
                  (76) calling ‘new_line_control’ from ‘keep_new_line’
                                                      |
                                                      +--> ‘new_line_control’:
events 77-78
                                                             |
                                                             | 4420 |
new_line_control (void)
                                                             |      |
^~~~~~~~~~~~~~~~
                                                             |      | |
                                                             |      | (77)
entry to ‘new_line_control’
                                                             | 4421 | {
                                                             | 4422 |   struct
line *p = xmalloc (sizeof *p);
                                                             |      |          
         ~~~~~~~~~~~~~~~~~~~
                                                             |      |          
         |
                                                             |      |          
         (78) allocated here
                                                             |
                                                      <------+
                                                      |
                                                    ‘keep_new_line’: events
79-81
                                                      |
                                                      | 4436 |    
b->line_start = b->curr_line = new_line_control ();
                                                      |      |                 
                  ^~~~~~~~~~~~~~~~~~~
                                                      |      |                 
                  |
                                                      |      |                 
                  (79) returning to ‘keep_new_line’ from ‘new_line_control’
                                                      | 4437 |   if
(b->curr_line->used == 80)
                                                      |      |      ~
                                                      |      |      |
                                                      |      |      (80)
following ‘false’ branch...
                                                      |......
                                                      | 4442 |   l =
b->curr_line;
                                                      |      |  
~~~~~~~~~~~~~~~~
                                                      |      |     |
                                                      |      |     (81) ...to
here
                                                      |
                                               <------+
                                               |
                                             ‘record_line_starts’: events 82-83
                                               |
                                               | 4465 |       if (line_end ==
buffer_end)
                                               |      |          ~
                                               |      |          |
                                               |      |          (83) following
‘true’ branch (when ‘line_end == buffer_end’)...
                                               |......
                                               | 4468 |       keep_new_line (b,
line_start, line_length);
                                               |      |      
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
                                               |      |       |
                                               |      |       (82) returning to
‘record_line_starts’ from ‘keep_new_line’
                                               |
                                             ‘record_line_starts’: event 84
                                               |
                                               |cc1:
                                               | (84): ...to here
                                               |
                                        <------+
                                        |
                                      ‘load_buffer’: events 85-88
                                        |
                                        | 4575 |       if (record_line_starts
(b) != 0)
                                        |      |         
~^~~~~~~~~~~~~~~~~~~~~~
                                        |      |          ||
                                        |      |          |(85) returning to
‘load_buffer’ from ‘record_line_starts’
                                        |      |          (86) following
‘false’ branch...
                                        |......
                                        | 4582 |       free_buffer (b);
                                        |      |       ~~~~~~~~~~~~~~~
                                        |      |       |
                                        |      |       (87) ...to here
                                        |      |       (88) ‘<unknown>’ leaks
here; was allocated at (78)
                                        |

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2023-04-25  0:17 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-04-25  0:17 [Bug analyzer/109614] New: -Wanalyzer-use-after-free gets confused about a free function in Coreutils eggert at cs dot ucla.edu

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).