public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc(refs/vendors/redhat/heads/gcc-8-branch)] c-family: Use TYPE_OVERFLOW_UNDEFINED instead of !TYPE_UNSIGNED in pointer_sum [PR95903]
@ 2020-09-17 17:23 Jakub Jelinek
  0 siblings, 0 replies; only message in thread
From: Jakub Jelinek @ 2020-09-17 17:23 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:4480fd55df08f95fdf045228cd4aaaa5ccd3e49f

commit 4480fd55df08f95fdf045228cd4aaaa5ccd3e49f
Author: Jakub Jelinek <jakub@redhat.com>
Date:   Sat Jun 27 12:38:23 2020 +0200

    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.
    
    (cherry picked from commit 37995960984ea2222346dd9d168d332cd6f7adf0)

Diff:
---
 gcc/c-family/c-common.c              |  2 +-
 gcc/testsuite/c-c++-common/pr95903.c | 19 +++++++++++++++++++
 2 files changed, 20 insertions(+), 1 deletion(-)

diff --git a/gcc/c-family/c-common.c b/gcc/c-family/c-common.c
index 655c3bf10a7..c890299996b 100644
--- a/gcc/c-family/c-common.c
+++ b/gcc/c-family/c-common.c
@@ -3120,7 +3120,7 @@ pointer_int_sum (location_t loc, enum tree_code resultcode,
       /* If the constant is unsigned, and smaller than the pointer size,
 	 then we must skip this optimization.  This is because it could cause
 	 an overflow error if the constant is negative but INTOP is not.  */
-      && (!TYPE_UNSIGNED (TREE_TYPE (intop))
+      && (TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (intop))
 	  || (TYPE_PRECISION (TREE_TYPE (intop))
 	      == TYPE_PRECISION (TREE_TYPE (ptrop)))))
     {
diff --git a/gcc/testsuite/c-c++-common/pr95903.c b/gcc/testsuite/c-c++-common/pr95903.c
new file mode 100644
index 00000000000..6e9f68e200f
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/pr95903.c
@@ -0,0 +1,19 @@
+/* PR middle-end/95903 */
+/* { dg-do compile { target lp64 } } */
+/* { dg-options "-O2 -fwrapv -fdump-tree-optimized" } */
+/* Verify that for -fwrapv the + 1 addition is performed in the parameter's
+   type before sign extending it.  */
+/* { dg-final { scan-tree-dump-times "off_\[0-9]+\\\(D\\\) \\+ 1" 2 "optimized" } } */
+
+char
+foo (const char *ptr, int off)
+{
+  off += 1;
+  return ptr[off];
+}
+
+char
+bar (const char *ptr, int off)
+{
+  return ptr[off + 1];
+}


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

only message in thread, other threads:[~2020-09-17 17:23 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-09-17 17:23 [gcc(refs/vendors/redhat/heads/gcc-8-branch)] c-family: Use TYPE_OVERFLOW_UNDEFINED instead of !TYPE_UNSIGNED in pointer_sum [PR95903] Jakub Jelinek

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).