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

--- Comment #7 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
Now, determine_min_objsize has been introduced for the strcmp_eq optimization
and maybe doing something conservative for the strcmp -> ~[0, 0] or [0, 0]
optimization there like get_base_address on the ADDR_EXPR argument would not be
appropriate for that use case, if the original use case is "is there a
guarantee at least that many bytes will be actually accessible".  So maybe the
bug is actually in the caller, that assumes that if determine_min_objsize
returns something small and we need to strcmp that with some larger string that
it can't be equal.  That is wrong though.  Say if determine_min_objsize
successfully uses compute_builtin_object_size with kind 2, on
  _3 = PHI <_1, _2>
where _1 = __builtin_malloc (2); and _2 = __builtin_malloc (16);
Here, __builtin_object_size (_3, 2) is 2 and __builtin_object_size (_3, 0) is
16.
If there is __builtin_strcmp (_3, "abcd"), we can't assume it is not equal
simply because determine_min_objsize returned 2 for _3, we would need to use
(non-existent) determine_max_objsize for that.
Perhaps to determine if it should warn determine_min_objsize is acceptable,
though it likely should use both determine_min_objsize and
determine_max_objsize and differentiate between is vs. may be in the warning
(perhaps have two levels of the warning).  But for code generation,
determine_min_objsize is wrong.

__attribute__((noipa)) int
bar (char *x, int y)
{
  asm volatile ("" : : "g" (x), "g" (y) : "memory");
  if (y == 0)
    __builtin_strcpy (x, "abcd");
  return y;
}

__attribute__((noipa)) char *
foo (int x)
{
  char *p;
  if (x)
    p = __builtin_malloc (2);
  else
    p = __builtin_calloc (16, 1);
  if (bar (p, x))
    return p;
  if (__builtin_strcmp (p, "abcd") != 0)
    __builtin_abort ();
  return p;
}

int
main ()
{
  __builtin_free (foo (0));
  __builtin_free (foo (1));
  return 0;
}

Reply via email to