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

eggert at cs dot ucla.edu changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |eggert at cs dot ucla.edu

--- Comment #2 from eggert at cs dot ucla.edu ---
I ran into what appear to be several instances of this bug when compiling GNU
coreutils. My instances didn't necessarily involve two allocations; one
sufficed. Here is a stripped-down version of the first instance:

void *malloc (unsigned long);

struct hash_table;
void *hash_insert (struct hash_table *, const void *);

struct di_ent
{
  unsigned long dev;
  struct hash_table *ino_set;
};
struct di_set
{
  struct hash_table *dev_map;
  struct di_ent *probe;
};

void
map_device (struct di_set *dis, unsigned long dev)
{
  struct di_ent *probe = dis->probe;
  if (probe)
    {
      if (probe->dev == dev)
        return;
    }
  else
    {
      probe = malloc (sizeof *probe);
      if (!probe)
        return;
      dis->probe = probe;
    }
  probe->dev = dev;
  struct di_ent *ent = hash_insert (dis->dev_map, probe);
  if (ent == probe)
    dis->probe = 0;
}



in the file t3.i, and here is the incorrect output when I compiled with 'gcc
-fanalyzer -S t3.i':

In function 'map_device':
t3.i:36:16: warning: leak of 'probe' [CWE-401] [-Wanalyzer-malloc-leak]
   36 |     dis->probe = 0;
      |     ~~~~~~~~~~~^~~
  'map_device': events 1-9
    |
    |   21 |   if (probe)
    |      |      ^
    |      |      |
    |      |      (1) following 'false' branch (when 'probe' is NULL)...
    |......
    |   28 |       probe = malloc (sizeof *probe);
    |      |               ~~~~~~~~~~~~~~~~~~~~~~
    |      |               |
    |      |               (2) ...to here
    |      |               (3) allocated here
    |   29 |       if (!probe)
    |      |          ~
    |      |          |
    |      |          (4) assuming 'probe' is non-NULL
    |      |          (5) following 'false' branch (when 'probe' is
non-NULL)...
    |   30 |  return;
    |   31 |       dis->probe = probe;
    |      |       ~~~~~~~~~~~~~~~~~~
    |      |                  |
    |      |                  (6) ...to here
    |......
    |   35 |   if (ent == probe)
    |      |      ~
    |      |      |
    |      |      (7) following 'true' branch (when 'ent == probe')...
    |   36 |     dis->probe = 0;
    |      |     ~~~~~~~~~~~~~~
    |      |                |
    |      |                (8) ...to here
    |      |                (9) 'probe' leaks here; was allocated at (3)
    |

Reply via email to