This is another tiny step towards making TYPE_IS_SIZETYPE not special
wrt sign-extension.  In output_constructor_regular_field we call
tree_low_cst without first assuring it won't ICE.  Instead of
doing that simply compute the zero-based index in double-ints
and assert that that result is representable in a HWI.  Being there
I noticed that strange comment and thought it is a good idea
to ICE instead of creating silently wrong code.  The cgraph code
compares a sign-extended tree to a unsigned (but atm still
sign-extended) size_int - that's bogus.  And we can avoid
creating a tree node by simply using double-int functions.

Bootstrapped and tested on x86_64-unknown-linux-gnu, installed on trunk.

Richard.

2011-05-02  Richard Guenther  <rguent...@suse.de>

        * varasm.c (output_constructor_regular_field): Compute zero-based
        index with double-ints.  Make sure to ICE instead of producing
        wrong code.
        * cgraph.c (cgraph_add_thunk): Do not create new tree nodes
        in asserts.  Properly use a signed type.

Index: trunk/gcc/varasm.c
===================================================================
*** trunk.orig/gcc/varasm.c     2011-05-02 14:50:36.000000000 +0200
--- trunk/gcc/varasm.c  2011-05-02 15:15:59.000000000 +0200
*************** output_constructor_regular_field (oc_loc
*** 4711,4719 ****
    unsigned int align2;
  
    if (local->index != NULL_TREE)
!     fieldpos = (tree_low_cst (TYPE_SIZE_UNIT (TREE_TYPE (local->val)), 1)
!               * ((tree_low_cst (local->index, 0)
!                   - tree_low_cst (local->min_index, 0))));
    else if (local->field != NULL_TREE)
      fieldpos = int_byte_position (local->field);
    else
--- 4711,4723 ----
    unsigned int align2;
  
    if (local->index != NULL_TREE)
!     {
!       double_int idx = double_int_sub (tree_to_double_int (local->index),
!                                      tree_to_double_int (local->min_index));
!       gcc_assert (double_int_fits_in_shwi_p (idx));
!       fieldpos = (tree_low_cst (TYPE_SIZE_UNIT (TREE_TYPE (local->val)), 1)
!                 * idx.low);
!     }
    else if (local->field != NULL_TREE)
      fieldpos = int_byte_position (local->field);
    else
*************** output_constructor_regular_field (oc_loc
*** 4760,4772 ****
             better be last.  */
          gcc_assert (!fieldsize || !DECL_CHAIN (local->field));
        }
!       else if (DECL_SIZE_UNIT (local->field))
!       {
!         /* ??? This can't be right.  If the decl size overflows
!            a host integer we will silently emit no data.  */
!         if (host_integerp (DECL_SIZE_UNIT (local->field), 1))
!           fieldsize = tree_low_cst (DECL_SIZE_UNIT (local->field), 1);
!       }
      }
    else
      fieldsize = int_size_in_bytes (TREE_TYPE (local->type));
--- 4764,4771 ----
             better be last.  */
          gcc_assert (!fieldsize || !DECL_CHAIN (local->field));
        }
!       else
!       fieldsize = tree_low_cst (DECL_SIZE_UNIT (local->field), 1);
      }
    else
      fieldsize = int_size_in_bytes (TREE_TYPE (local->type));
Index: trunk/gcc/cgraph.c
===================================================================
*** trunk.orig/gcc/cgraph.c     2011-05-02 12:20:22.000000000 +0200
--- trunk/gcc/cgraph.c  2011-05-02 15:42:19.000000000 +0200
*************** cgraph_add_thunk (struct cgraph_node *de
*** 613,620 ****
    node = cgraph_same_body_alias_1 (decl_node, alias, decl);
    gcc_assert (node);
    gcc_checking_assert (!virtual_offset
!                      || tree_int_cst_equal (virtual_offset,
!                                             size_int (virtual_value)));
    node->thunk.fixed_offset = fixed_offset;
    node->thunk.this_adjusting = this_adjusting;
    node->thunk.virtual_value = virtual_value;
--- 613,621 ----
    node = cgraph_same_body_alias_1 (decl_node, alias, decl);
    gcc_assert (node);
    gcc_checking_assert (!virtual_offset
!                      || double_int_equal_p
!                           (tree_to_double_int (virtual_offset),
!                            shwi_to_double_int (virtual_value)));
    node->thunk.fixed_offset = fixed_offset;
    node->thunk.this_adjusting = this_adjusting;
    node->thunk.virtual_value = virtual_value;

Reply via email to