Hi,

PR 49343 showed that build_ref_for_model in tree-sra.c used a more
primitive technique to determine an offset of a field than
get_ref_base_and_extent, cannot crunch fields with "placeholders" in
their offsets and ICEs on them (while  get_ref_base_and_extent
processed them fine before).

Fixed thusly, code closely follows what is in get_ref_base_and_extent
but is simpler because we know that function has once already accepted
this input.

Bootstrapped and tested on x86_64-linux.  OK for trunk?

Thanks,

Martin



2011-06-10  Martin Jambor  <mjam...@suse.cz>

        PR tree-optimization/49343
        * tree-sra.c (build_ref_for_model): Use component_ref_field_offset to
        calculate offset, provide 2nd operand for the new COMPONENT_REF.

        * testsuite/gnat.dg/discr31.adb: New test.
        * testsuite/gnat.dg/discr31.ads: Likewise.


Index: src/gcc/tree-sra.c
===================================================================
--- src.orig/gcc/tree-sra.c
+++ src/gcc/tree-sra.c
@@ -1421,12 +1421,16 @@ build_ref_for_model (location_t loc, tre
 {
   if (TREE_CODE (model->expr) == COMPONENT_REF)
     {
-      tree t, exp_type;
-      offset -= int_bit_position (TREE_OPERAND (model->expr, 1));
+      tree t, exp_type, fld = TREE_OPERAND (model->expr, 1);
+      tree cr_offset = component_ref_field_offset (model->expr);
+
+      gcc_assert (cr_offset && host_integerp (cr_offset, 1));
+      offset -= TREE_INT_CST_LOW (cr_offset) * BITS_PER_UNIT;
+      offset -= TREE_INT_CST_LOW (DECL_FIELD_BIT_OFFSET (fld));
       exp_type = TREE_TYPE (TREE_OPERAND (model->expr, 0));
       t = build_ref_for_offset (loc, base, offset, exp_type, gsi, 
insert_after);
-      return fold_build3_loc (loc, COMPONENT_REF, model->type, t,
-                             TREE_OPERAND (model->expr, 1), NULL_TREE);
+      return fold_build3_loc (loc, COMPONENT_REF, model->type, t, fld,
+                             TREE_OPERAND (model->expr, 2));
     }
   else
     return build_ref_for_offset (loc, base, offset, model->type,
Index: src/gcc/testsuite/gnat.dg/discr31.adb
===================================================================
--- /dev/null
+++ src/gcc/testsuite/gnat.dg/discr31.adb
@@ -0,0 +1,12 @@
+-- { dg-do compile }
+-- { dg-options "-O" }
+
+package body Discr31 is
+
+   function Log_Item(Packet : in Packet_Data_Type) return Log_Item_Type is
+      None : Log_Item_Type(0);
+   begin
+      return None;
+   end;
+
+end Discr31;
Index: src/gcc/testsuite/gnat.dg/discr31.ads
===================================================================
--- /dev/null
+++ src/gcc/testsuite/gnat.dg/discr31.ads
@@ -0,0 +1,14 @@
+package Discr31 is
+
+   type Byte_List_Type is array(Positive range <>) of Integer;
+
+   type Log_Item_Type(Last : Natural) is record
+      Data : Byte_List_Type(1 .. Last) := (others => 0);
+      Link : Natural := 0;
+   end record;
+
+   type Packet_Data_Type is access Log_Item_Type;
+
+   function Log_Item(Packet : in Packet_Data_Type) return Log_Item_Type;
+
+end Discr31;

Reply via email to