c-family: Use TYPE_OVERFLOW_UNDEFINED instead of !TYPE_UNSIGNED in pointer_sum [PR95903]
authorJakub Jelinek <jakub@redhat.com>
Sat, 27 Jun 2020 10:38:23 +0000 (12:38 +0200)
committerJakub Jelinek <jakub@redhat.com>
Sat, 27 Jun 2020 10:42:13 +0000 (12:42 +0200)
commit37995960984ea2222346dd9d168d332cd6f7adf0
treea4fa692125fde0f40042723e52372c67f8911b77
parentdaaed0199ee57013ae011421a7e90b7bdd295373
c-family: Use TYPE_OVERFLOW_UNDEFINED instead of !TYPE_UNSIGNED in pointer_sum [PR95903]

For lp64 targets and int off ... ptr[off + 1]
is lowered in pointer_sum to *(ptr + ((sizetype) off + (sizetype) 1)).
That is fine when signed integer wrapping is undefined (and is not done
already if off has unsigned type), but changes behavior for -fwrapv, where
overflow is well defined.  Runtime test could be:
int
main ()
{
  char *p = __builtin_malloc (0x100000000UL);
  if (!p) return 0;
  char *q = p + 0x80000000UL;
  int o = __INT_MAX__;
  q[o + 1] = 1;
  if (q[-__INT_MAX__ - 1] != 1) __builtin_abort ();
  return 0;
}
with -fwrapv or so, not included in the testsuite because it requires 4GB
allocation (with some other test it would be enough to have something
slightly above 2GB, but still...).

2020-06-27  Jakub Jelinek  <jakub@redhat.com>

PR middle-end/95903
gcc/c-family/
* c-common.c (pointer_int_sum): Use TYPE_OVERFLOW_UNDEFINED instead of
!TYPE_UNSIGNED check to see if we can apply distributive law and handle
smaller precision intop operands separately.
gcc/testsuite/
* c-c++-common/pr95903.c: New test.
gcc/c-family/c-common.c
gcc/testsuite/c-c++-common/pr95903.c [new file with mode: 0644]