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;