This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Fix to compare_tree_int
- From: kenner at vlsi1 dot ultra dot nyu dot edu (Richard Kenner)
- To: gcc-patches at gcc dot gnu dot org
- Date: Fri, 25 Jan 02 15:56:05 EST
- Subject: Fix to compare_tree_int
There are two places in expand_expr where it is called with an unsigned
HOST_WIDE_INT as an operand, but it actually takes an unsigned int, so the
operand gets truncated and the test doesn't do what it's supposed to.
The test case where I saw this was in Ada, compiling the library file
s-secsta.adb with Pragma Normalize_Scalars.
I looked at all the compare_tree_int calls to make sure this was OK and
saw a few things about them (unrelated to this change) that should be fixed
and did.
Tested on alphaev56-dec-osf4.0c.
Fri Jan 25 08:26:19 2002 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
* builtins.c (expand_builtin_strncpy): Use integer_zerop instead
of compare_tree_int.
(expand_builtin_strncat): Likewise.
* c-decl.c (finish_struct): Use tree_low_cst.
* tree.h (compare_tree_int): Arg is unsigned HOST_WIDE_INT.
* tree.c (compare_tree_int): Likewise.
*** builtins.c 2002/01/25 04:32:46 1.140
--- builtins.c 2002/01/25 20:40:27
*************** expand_builtin_strncpy (arglist, target,
*** 2063,2067 ****
/* If the len parameter is zero, return the dst parameter. */
! if (compare_tree_int (len, 0) == 0)
{
/* Evaluate and ignore the src argument in case it has
--- 2063,2067 ----
/* If the len parameter is zero, return the dst parameter. */
! if (integer_zerop (len))
{
/* Evaluate and ignore the src argument in case it has
*************** expand_builtin_memcmp (exp, arglist, tar
*** 2280,2287 ****
than the lengths of arg1 and arg2, evaluate at compile-time. */
if (host_integerp (len, 1) && p1 && p2
! && compare_tree_int (len, strlen (p1)+1) <= 0
! && compare_tree_int (len, strlen (p2)+1) <= 0)
{
const int r = memcmp (p1, p2, tree_low_cst (len, 1));
return (r < 0 ? constm1_rtx : (r > 0 ? const1_rtx : const0_rtx));
}
--- 2280,2288 ----
than the lengths of arg1 and arg2, evaluate at compile-time. */
if (host_integerp (len, 1) && p1 && p2
! && compare_tree_int (len, strlen (p1) + 1) <= 0
! && compare_tree_int (len, strlen (p2) + 1) <= 0)
{
const int r = memcmp (p1, p2, tree_low_cst (len, 1));
+
return (r < 0 ? constm1_rtx : (r > 0 ? const1_rtx : const0_rtx));
}
*************** expand_builtin_strncat (arglist, target,
*** 2608,2612 ****
/* If the requested length is zero, or the src parameter string
length is zero, return the dst parameter. */
! if ((TREE_CODE (len) == INTEGER_CST && compare_tree_int (len, 0) == 0)
|| (p && *p == '\0'))
{
--- 2609,2613 ----
/* If the requested length is zero, or the src parameter string
length is zero, return the dst parameter. */
! if ((TREE_CODE (len) == INTEGER_CST && integer_zerop (len))
|| (p && *p == '\0'))
{
*************** expand_builtin_strncat (arglist, target,
*** 2623,2629 ****
&& compare_tree_int (len, strlen (p)) >= 0)
{
! tree newarglist =
! tree_cons (NULL_TREE, dst, build_tree_list (NULL_TREE, src)),
! fn = built_in_decls[BUILT_IN_STRCAT];
/* If the replacement _DECL isn't initialized, don't do the
--- 2624,2630 ----
&& compare_tree_int (len, strlen (p)) >= 0)
{
! tree newarglist
! = tree_cons (NULL_TREE, dst, build_tree_list (NULL_TREE, src));
! tree fn = built_in_decls[BUILT_IN_STRCAT];
/* If the replacement _DECL isn't initialized, don't do the
*** c-decl.c 2002/01/10 18:51:13 1.288
--- c-decl.c 2002/01/25 20:40:47
*************** finish_struct (t, fieldlist, attributes)
*** 5694,5702 ****
if (DECL_INITIAL (x))
{
! int max_width;
! if (TYPE_MAIN_VARIANT (TREE_TYPE (x)) == c_bool_type_node)
! max_width = CHAR_TYPE_SIZE;
! else
! max_width = TYPE_PRECISION (TREE_TYPE (x));
if (tree_int_cst_sgn (DECL_INITIAL (x)) < 0)
error_with_decl (x, "negative width in bit-field `%s'");
--- 5694,5701 ----
if (DECL_INITIAL (x))
{
! int max_width
! = (TYPE_MAIN_VARIANT (TREE_TYPE (x)) == c_bool_type_node
! ? CHAR_TYPE_SIZE : TYPE_PRECISION (TREE_TYPE (x)));
!
if (tree_int_cst_sgn (DECL_INITIAL (x)) < 0)
error_with_decl (x, "negative width in bit-field `%s'");
*************** finish_struct (t, fieldlist, attributes)
*** 5709,5713 ****
/* The test above has assured us that TREE_INT_CST_HIGH is 0. */
unsigned HOST_WIDE_INT width
! = TREE_INT_CST_LOW (DECL_INITIAL (x));
if (TREE_CODE (TREE_TYPE (x)) == ENUMERAL_TYPE
--- 5708,5712 ----
/* The test above has assured us that TREE_INT_CST_HIGH is 0. */
unsigned HOST_WIDE_INT width
! = tree_low_cst (DECL_INITIAL (x), 1);
if (TREE_CODE (TREE_TYPE (x)) == ENUMERAL_TYPE
*** tree.c 2002/01/23 12:44:34 1.232
--- tree.c 2002/01/25 20:40:57
*************** int
*** 3634,3638 ****
compare_tree_int (t, u)
tree t;
! unsigned int u;
{
if (tree_int_cst_sgn (t) < 0)
--- 3634,3638 ----
compare_tree_int (t, u)
tree t;
! unsigned HOST_WIDE_INT u;
{
if (tree_int_cst_sgn (t) < 0)
*** tree.h 2002/01/10 18:51:15 1.299
--- tree.h 2002/01/25 20:41:08
*************** extern int object_permanent_p PARAMS ((
*** 2889,2893 ****
extern int type_precision PARAMS ((tree));
extern int simple_cst_equal PARAMS ((tree, tree));
! extern int compare_tree_int PARAMS ((tree, unsigned int));
extern int type_list_equal PARAMS ((tree, tree));
extern int chain_member PARAMS ((tree, tree));
--- 2889,2894 ----
extern int type_precision PARAMS ((tree));
extern int simple_cst_equal PARAMS ((tree, tree));
! extern int compare_tree_int PARAMS ((tree,
! unsigned HOST_WIDE_INT));
extern int type_list_equal PARAMS ((tree, tree));
extern int chain_member PARAMS ((tree, tree));