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;