varasm.c (output_constructor_regular_field): Compute zero-based index with double...
authorRichard Guenther <rguenther@suse.de>
Mon, 2 May 2011 15:22:54 +0000 (15:22 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Mon, 2 May 2011 15:22:54 +0000 (15:22 +0000)
2011-05-02  Richard Guenther  <rguenther@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.

From-SVN: r173255

gcc/ChangeLog
gcc/cgraph.c
gcc/varasm.c

index 3279294..26b40ac 100644 (file)
@@ -1,3 +1,11 @@
+2011-05-02  Richard Guenther  <rguenther@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.
+
 2011-05-02  Uros Bizjak  <ubizjak@gmail.com>
 
        * config/i386/sse.md (V): New mode iterator.
index 2086bfe..91805e3 100644 (file)
@@ -613,8 +613,9 @@ cgraph_add_thunk (struct cgraph_node *decl_node, tree alias, tree decl,
   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)));
+                      || 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;
index 8755dde..b4f3805 100644 (file)
@@ -4711,9 +4711,13 @@ output_constructor_regular_field (oc_local_state *local)
   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))));
+    {
+      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
@@ -4760,13 +4764,8 @@ output_constructor_regular_field (oc_local_state *local)
             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 = tree_low_cst (DECL_SIZE_UNIT (local->field), 1);
     }
   else
     fieldsize = int_size_in_bytes (TREE_TYPE (local->type));