This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] Fix PR c++/4401


Hi!

The following testcase segfaults on 64-bit platforms.
The problem is that pointer_int_sum attempts to do fold()s job, but doesn't do
it correctly (it doesn't care about intop precision and happily optimizes
(pointer + (unsigned_int + 1))
into
((pointer + 1) + unsigned_int)).
fold is called unconditionally on the result anyway, so for things like:
size_t i, j;
..
a[i - j + 1] = 0;
the folded result is always
((a + (size_t) (i - j)) + (size_t) 1)
anyway, no matter whether the special pointer_int_sum code below is in or
not.
Ok to commit?

2002-02-20  Jakub Jelinek  <jakub@redhat.com>

	* typeck.c (pointer_int_sum): Don't apply distributive law here.

	* g++.dg/other/ptrintsum1.C: New test.

--- gcc/cp/typeck.c.jj	Sat Feb 16 22:48:21 2002
+++ gcc/cp/typeck.c	Wed Feb 20 13:24:58 2002
@@ -4120,23 +4120,6 @@ pointer_int_sum (resultcode, ptrop, into
   if (integer_zerop (intop))
     return ptrop;
 
-  /* If what we are about to multiply by the size of the elements
-     contains a constant term, apply distributive law
-     and multiply that constant term separately.
-     This helps produce common subexpressions.  */
-
-  if ((TREE_CODE (intop) == PLUS_EXPR || TREE_CODE (intop) == MINUS_EXPR)
-      && ! TREE_CONSTANT (intop)
-      && TREE_CONSTANT (TREE_OPERAND (intop, 1))
-      && TREE_CONSTANT (size_exp))
-    {
-      enum tree_code subcode = resultcode;
-      if (TREE_CODE (intop) == MINUS_EXPR)
-	subcode = (subcode == PLUS_EXPR ? MINUS_EXPR : PLUS_EXPR);
-      ptrop = cp_build_binary_op (subcode, ptrop, TREE_OPERAND (intop, 1));
-      intop = TREE_OPERAND (intop, 0);
-    }
-
   /* Convert the integer argument to a type the same size as sizetype
      so the multiply won't overflow spuriously.  */
 
--- gcc/testsuite/g++.dg/other/ptrintsum1.C.jj	Wed Feb 20 13:32:15 2002
+++ gcc/testsuite/g++.dg/other/ptrintsum1.C	Wed Feb 20 13:32:12 2002
@@ -0,0 +1,29 @@
+// PR c++/4401
+// This testcase was miscompiled on 64-bit platforms, resulting to
+// operating on a[0x100000000] instead of a[0].
+// { dg-do run }
+// { dg-options "-O2" }
+
+char *a;
+char b[] = "AAAA";
+
+extern "C" void abort (void);
+extern "C" void exit (int);
+
+void foo (void)
+{
+  unsigned int i, j;
+
+  i = 2;
+  j = 3;
+  a[i + 1 - j] += i;
+}
+
+int main (void)
+{
+  a = b;
+  foo ();
+  if (b[0] != 'A' + 2)
+    abort ();
+  exit (0);
+}

	Jakub


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]