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
This commit is contained in:
Jakub Jelinek 2002-02-20 23:54:35 +01:00
parent c98b201bd9
commit 4636c87e23
5 changed files with 52 additions and 10 deletions

View file

@ -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

View file

@ -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)
{

View file

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

View file

@ -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);
}

View file

@ -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