From 4636c87e232d7df60478859d9a15556d5bc3c0c8 Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Wed, 20 Feb 2002 23:54:35 +0100 Subject: [PATCH] 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 --- gcc/ChangeLog | 11 +++++++++++ gcc/c-format.c | 9 ++++----- gcc/testsuite/ChangeLog | 2 ++ gcc/testsuite/gcc.dg/20020219-1.c | 28 ++++++++++++++++++++++++++++ gcc/tree.c | 12 +++++++----- 5 files changed, 52 insertions(+), 10 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/20020219-1.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index bbcf0f12e27..235f625222d 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,14 @@ +2002-02-20 Roger Sayle + Jakub Jelinek + + 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 * config/i386/i386.c (ix86_expand_vector_move): Use the mode diff --git a/gcc/c-format.c b/gcc/c-format.c index b15b6300563..d52cfba7c70 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 fb55f893310..90b39b227f1 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 * 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 00000000000..c879f230db6 --- /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 764aa798ed8..5e0210b7676 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 -- 2.30.2