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

--- Comment #5 from Sergei Trofimovich <slyfox at gcc dot gnu.org> ---
(In reply to Martin Sebor from comment #4)
> Actually, this is already supposed to be handled but the code is not
> effective due to a typo.  This fixes it:
> 
> diff --git a/gcc/gimple-ssa-warn-access.cc b/gcc/gimple-ssa-warn-access.cc
> index f639807a78a..f9508a1d211 100644
> --- a/gcc/gimple-ssa-warn-access.cc
> +++ b/gcc/gimple-ssa-warn-access.cc
> @@ -4082,7 +4082,9 @@ pointers_related_p (gimple *stmt, tree p, tree q,
> pointer_query &qry)
>    access_ref pref, qref;
>    if (!qry.get_ref (p, stmt, &pref, 0)
>        || !qry.get_ref (q, stmt, &qref, 0))
> -    return true;
> +    /* GET_REF() only rarely fails.  When it does, it's likely because
> +       it involves a self-referential PHI.  Return a conservative result. 
> */
> +    return false;
>  
>    return pref.ref == qref.ref;
>  }

Thank you! This helped elfutils-0.186.

But linux's objtool still fails to build. Here is extracted false positive (I
think it's false positive):

typedef long unsigned int size_t;

extern void *malloc(size_t __size) __attribute__((__nothrow__, __leaf__))
__attribute__((__malloc__)) __attribute__((__alloc_size__(1)));
extern void *realloc(void *__ptr, size_t __size)
    __attribute__((__nothrow__, __leaf__))
    __attribute__((__warn_unused_result__)) __attribute__((__alloc_size__(2)));
extern void die(const char *err, ...);

struct cmdnames {
  size_t alloc;
  size_t cnt;
  struct cmdname {
    size_t len;
    char name[];
  } * *names;
};

static inline void *xrealloc(void *ptr, size_t size) {
  void *ret = realloc(ptr, size);
  if (!ret && !size)
    ret = realloc(ptr, 1);
  if (!ret) {
    ret = realloc(ptr, size);
    if (!ret && !size)
      ret = realloc(ptr, 1);
    if (!ret)
      die("Out of memory, realloc failed");
  }
  return ret;
}

void add_cmdname(struct cmdnames *cmds, const char *name, size_t len) {
  struct cmdname *ent = malloc(sizeof(*ent) + len + 1);
  ent->len = len;
  // memcpy(ent->name, name, len);
  ent->name[len] = 0;
  do {
    if ((cmds->cnt + 1) > cmds->alloc) {
      if ((((cmds->alloc) + 16) * 3 / 2) < (cmds->cnt + 1))
        cmds->alloc = (cmds->cnt + 1);
      else
        cmds->alloc = (((cmds->alloc) + 16) * 3 / 2);
      cmds->names =
          xrealloc((cmds->names), cmds->alloc * sizeof(*(cmds->names)));
    }
  } while (0);
  cmds->names[cmds->cnt++] = ent;
}

$ gcc-12.0.0 -Wall -Werror -c help.c.c
help.c.c: In function 'xrealloc':
help.c.c:26:13: error: pointer 'ptr' may be used after 'realloc'
[-Werror=use-after-free]
   26 |       ret = realloc(ptr, 1);
      |             ^~~~~~~~~~~~~~~
help.c.c:20:15: note: call to 'realloc' here
   20 |   void *ret = realloc(ptr, size);
      |               ^~~~~~~~~~~~~~~~~~
help.c.c:24:11: error: pointer 'ptr' may be used after 'realloc'
[-Werror=use-after-free]
   24 |     ret = realloc(ptr, size);
      |           ^~~~~~~~~~~~~~~~~~
help.c.c:20:15: note: call to 'realloc' here
   20 |   void *ret = realloc(ptr, size);
      |               ^~~~~~~~~~~~~~~~~~
cc1: all warnings being treated as errors

Reply via email to