This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] Fix c/4389 (take 2)
- From: Jakub Jelinek <jakub at redhat dot com>
- To: Richard Kenner <kenner at vlsi1 dot ultra dot nyu dot edu>
- Cc: gcc-patches at gcc dot gnu dot org
- Date: Wed, 20 Feb 2002 20:06:45 +0100
- Subject: [PATCH] Fix c/4389 (take 2)
- References: <10202201239.AA15446@vlsi1.ultra.nyu.edu>
- Reply-to: Jakub Jelinek <jakub at redhat dot com>
On Wed, Feb 20, 2002 at 01:59:41PM -0500, Richard Kenner wrote:
> I believe there has to be an TREE_UNSIGNED (TREE_TYPE (t))
> check, though not where it used to be. IMHO it should look like:
>
> || (! pos && TREE_INT_CST_HIGH (t) == -1
> && (HOST_WIDE_INT) TREE_INT_CST_LOW (t) < 0
> && ! TREE_UNSIGNED (TREE_TYPE (t)))
>
> Yes, I think that's right.
Ok to commit Roger's patch plus the above fix then (bootstrapped and
regression tested on i386-redhat-linux, included below)?
>
> type of code will have to change to:
>
> HOST_WIDE_INT bitsize;
> ...
> if (host_integerp (bitsize, 0)
> && tree_int_cst_sgn (bitsize) >= 0)
> bitsize = tree_low_cst (bitsize, 0);
> else
> bitsize = -1;
>
> Well, we treat all negative bitsizes as the same, so I think the added test
> accomplishes nothing in precisely this case.
You're right, false alarm.
2002-02-20 Roger Sayle <roger@eyesopen.com>
Jakub Jelinek <jakub@redhat.com>
PR c/4389
* tree.c (host_integerp): Ensure that the constant integer is
representable in a HOST_WIDE_INT or an unsigned HOST_WIDE_INT
when pos is zero or non-zero respectively. Clarify comment.
* c-format.c (check_format_info_recurse): Fix host_integerp
usage; the pos argument should be zero when assigning to a
signed HOST_WIDE_INT.
* gcc.dg/20020219-1.c: New test.
--- gcc/testsuite/gcc.dg/20020219-1.c.jj Tue Feb 19 18:33:26 2002
+++ gcc/testsuite/gcc.dg/20020219-1.c Wed Feb 20 17:49:04 2002
@@ -0,0 +1,28 @@
+/* PR c/4389
+ This testcase failed because host_integerp (x, 0) was returning
+ 1 even for constants bigger than 2^31. */
+/* { dg-do run } */
+/* { dg-options "-O2" } */
+
+extern void abort (void);
+extern void exit (int);
+struct A {
+ int a[10000][10000];
+};
+int b[2] = { 213151, 0 };
+
+void foo (struct A *x, int y)
+{
+ if (x->a[9999][9999] != x->a[y][y])
+ abort ();
+ if (x->a[9999][9999] != 213151)
+ abort ();
+}
+
+int main (void)
+{
+ struct A *x;
+ asm ("" : "=r" (x) : "0" (&b[1]));
+ foo (x - 1, 9999);
+ exit (0);
+}
--- gcc/tree.c.jj Tue Feb 19 11:13:31 2002
+++ gcc/tree.c Wed Feb 20 17:44:40 2002
@@ -3436,8 +3436,10 @@ tree_int_cst_compare (t1, t2)
return 0;
}
-/* Return 1 if T is an INTEGER_CST that can be represented in a single
- HOST_WIDE_INT value. If POS is nonzero, the result must be positive. */
+/* Return 1 if T is an INTEGER_CST that can be manipulated efficiently on
+ the host. If POS is zero, the value can be represented in a single
+ HOST_WIDE_INT. If POS is nonzero, the value must be positive and can
+ be represented in a single unsigned HOST_WIDE_INT. */
int
host_integerp (t, pos)
@@ -3449,9 +3451,9 @@ host_integerp (t, pos)
&& ((TREE_INT_CST_HIGH (t) == 0
&& (HOST_WIDE_INT) TREE_INT_CST_LOW (t) >= 0)
|| (! pos && TREE_INT_CST_HIGH (t) == -1
- && (HOST_WIDE_INT) TREE_INT_CST_LOW (t) < 0)
- || (! pos && TREE_INT_CST_HIGH (t) == 0
- && TREE_UNSIGNED (TREE_TYPE (t)))));
+ && (HOST_WIDE_INT) TREE_INT_CST_LOW (t) < 0
+ && ! TREE_UNSIGNED (TREE_TYPE (t)))
+ || (pos && TREE_INT_CST_HIGH (t) == 0)));
}
/* Return the HOST_WIDE_INT least significant bits of T if it is an
--- gcc/c-format.c.jj Tue Nov 27 17:15:23 2001
+++ gcc/c-format.c Wed Feb 20 17:47:22 2002
@@ -1,6 +1,6 @@
/* Check calls to formatted I/O functions (-Wformat).
- Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001
- Free Software Foundation, Inc.
+ Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
+ 2001, 2002 Free Software Foundation, Inc.
This file is part of GCC.
@@ -1516,13 +1516,12 @@ check_format_info_recurse (status, res,
res->number_non_literal++;
return;
}
- if (!host_integerp (arg1, 1))
+ if (!host_integerp (arg1, 0)
+ || (offset = tree_low_cst (arg1, 0)) < 0)
{
res->number_non_literal++;
return;
}
-
- offset = TREE_INT_CST_LOW (arg1);
}
if (TREE_CODE (format_tree) != ADDR_EXPR)
{
Jakub