aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@gcc.gnu.org>2002-02-20 23:54:35 +0100
committerJakub Jelinek <jakub@gcc.gnu.org>2002-02-20 23:54:35 +0100
commit4636c87e232d7df60478859d9a15556d5bc3c0c8 (patch)
tree92091a1ae9884506ec5a5bd1f121978289726ebf /gcc
parentc98b201bd9e49891ff049835c3ae79897a885071 (diff)
downloadgcc-4636c87e232d7df60478859d9a15556d5bc3c0c8.zip
gcc-4636c87e232d7df60478859d9a15556d5bc3c0c8.tar.gz
gcc-4636c87e232d7df60478859d9a15556d5bc3c0c8.tar.bz2
re PR c/4389 (Improper constant folding)
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. From-SVN: r49914
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog11
-rw-r--r--gcc/c-format.c9
-rw-r--r--gcc/testsuite/ChangeLog2
-rw-r--r--gcc/testsuite/gcc.dg/20020219-1.c28
-rw-r--r--gcc/tree.c12
5 files changed, 52 insertions, 10 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index bbcf0f1..235f625 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,14 @@
+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.
+
2002-02-20 Richard Henderson <rth@redhat.com>
* config/i386/i386.c (ix86_expand_vector_move): Use the mode
diff --git a/gcc/c-format.c b/gcc/c-format.c
index b15b630..d52cfba 100644
--- a/gcc/c-format.c
+++ b/gcc/c-format.c
@@ -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, info, format_tree, params, arg_num)
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)
{
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index fb55f89..90b39b2 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -2,6 +2,8 @@
* gcc.c-torture/execute/20020219-1.c: New test.
+ * gcc.dg/20020219-1.c: New test.
+
2002-02-17 Jakub Jelinek <jakub@redhat.com>
* gcc.c-torture/execute/20020216-1.c: New test.
diff --git a/gcc/testsuite/gcc.dg/20020219-1.c b/gcc/testsuite/gcc.dg/20020219-1.c
new file mode 100644
index 0000000..c879f23
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/20020219-1.c
@@ -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);
+}
diff --git a/gcc/tree.c b/gcc/tree.c
index 764aa79..5e0210b 100644
--- a/gcc/tree.c
+++ b/gcc/tree.c
@@ -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