expr.c (get_bit_range): Add OFFSET parameter and adjust BITPOS.
* expr.c (get_bit_range): Add OFFSET parameter and adjust BITPOS. Change type of BITOFFSET to signed. Make sure the lower bound of the computed range is non-negative by adjusting OFFSET and BITPOS. (expand_assignment): Adjust call to get_bit_range. From-SVN: r186110
This commit is contained in:
parent
f4ea81123d
commit
1d0bafd9b0
5 changed files with 73 additions and 7 deletions
|
@ -1,3 +1,10 @@
|
|||
2012-04-03 Eric Botcazou <ebotcazou@adacore.com>
|
||||
|
||||
* expr.c (get_bit_range): Add OFFSET parameter and adjust BITPOS.
|
||||
Change type of BITOFFSET to signed. Make sure the lower bound of
|
||||
the computed range is non-negative by adjusting OFFSET and BITPOS.
|
||||
(expand_assignment): Adjust call to get_bit_range.
|
||||
|
||||
2012-04-03 Sandeep Kumar Singh <Sandeep.Singh2@kpitcummins.com>
|
||||
|
||||
* h8300/h8300.c (h8300_current_function_monitor_function_p):
|
||||
|
|
35
gcc/expr.c
35
gcc/expr.c
|
@ -4431,19 +4431,22 @@ optimize_bitfield_assignment_op (unsigned HOST_WIDE_INT bitsize,
|
|||
/* In the C++ memory model, consecutive bit fields in a structure are
|
||||
considered one memory location.
|
||||
|
||||
Given a COMPONENT_REF EXP at bit position BITPOS, this function
|
||||
Given a COMPONENT_REF EXP at position (BITPOS, OFFSET), this function
|
||||
returns the bit range of consecutive bits in which this COMPONENT_REF
|
||||
belongs in. The values are returned in *BITSTART and *BITEND.
|
||||
If the access does not need to be restricted 0 is returned in
|
||||
belongs. The values are returned in *BITSTART and *BITEND. *BITPOS
|
||||
and *OFFSET may be adjusted in the process.
|
||||
|
||||
If the access does not need to be restricted, 0 is returned in both
|
||||
*BITSTART and *BITEND. */
|
||||
|
||||
static void
|
||||
get_bit_range (unsigned HOST_WIDE_INT *bitstart,
|
||||
unsigned HOST_WIDE_INT *bitend,
|
||||
tree exp,
|
||||
HOST_WIDE_INT bitpos)
|
||||
HOST_WIDE_INT *bitpos,
|
||||
tree *offset)
|
||||
{
|
||||
unsigned HOST_WIDE_INT bitoffset;
|
||||
HOST_WIDE_INT bitoffset;
|
||||
tree field, repr;
|
||||
|
||||
gcc_assert (TREE_CODE (exp) == COMPONENT_REF);
|
||||
|
@ -4490,7 +4493,25 @@ get_bit_range (unsigned HOST_WIDE_INT *bitstart,
|
|||
bitoffset += (tree_low_cst (DECL_FIELD_BIT_OFFSET (field), 1)
|
||||
- tree_low_cst (DECL_FIELD_BIT_OFFSET (repr), 1));
|
||||
|
||||
*bitstart = bitpos - bitoffset;
|
||||
/* If the adjustment is larger than bitpos, we would have a negative bit
|
||||
position for the lower bound and this may wreak havoc later. This can
|
||||
occur only if we have a non-null offset, so adjust offset and bitpos
|
||||
to make the lower bound non-negative. */
|
||||
if (bitoffset > *bitpos)
|
||||
{
|
||||
HOST_WIDE_INT adjust = bitoffset - *bitpos;
|
||||
|
||||
gcc_assert ((adjust % BITS_PER_UNIT) == 0);
|
||||
gcc_assert (*offset != NULL_TREE);
|
||||
|
||||
*bitpos += adjust;
|
||||
*offset
|
||||
= size_binop (MINUS_EXPR, *offset, size_int (adjust / BITS_PER_UNIT));
|
||||
*bitstart = 0;
|
||||
}
|
||||
else
|
||||
*bitstart = *bitpos - bitoffset;
|
||||
|
||||
*bitend = *bitstart + tree_low_cst (DECL_SIZE (repr), 1) - 1;
|
||||
}
|
||||
|
||||
|
@ -4595,7 +4616,7 @@ expand_assignment (tree to, tree from, bool nontemporal)
|
|||
|
||||
if (TREE_CODE (to) == COMPONENT_REF
|
||||
&& DECL_BIT_FIELD_TYPE (TREE_OPERAND (to, 1)))
|
||||
get_bit_range (&bitregion_start, &bitregion_end, to, bitpos);
|
||||
get_bit_range (&bitregion_start, &bitregion_end, to, &bitpos, &offset);
|
||||
|
||||
/* If we are going to use store_bit_field and extract_bit_field,
|
||||
make sure to_rtx will be safe for multiple use. */
|
||||
|
|
|
@ -1,3 +1,8 @@
|
|||
2012-04-03 Eric Botcazou <ebotcazou@adacore.com>
|
||||
|
||||
* gnat.dg/pack18.adb: New test.
|
||||
* gnat.dg/pack18_pkg.ads: New helper.
|
||||
|
||||
2012-04-03 Richard Guenther <rguenther@suse.de>
|
||||
|
||||
PR tree-optimization/52808
|
||||
|
|
12
gcc/testsuite/gnat.dg/pack18.adb
Normal file
12
gcc/testsuite/gnat.dg/pack18.adb
Normal file
|
@ -0,0 +1,12 @@
|
|||
-- { dg-do run }
|
||||
|
||||
with Pack18_Pkg; use Pack18_Pkg;
|
||||
|
||||
procedure Pack18 is
|
||||
use Pack18_Pkg.Attributes_Tables;
|
||||
Table : Instance;
|
||||
begin
|
||||
Init (Table);
|
||||
Set_Last (Table, 1);
|
||||
Table.Table (Last (Table)).N := 0;
|
||||
end;
|
21
gcc/testsuite/gnat.dg/pack18_pkg.ads
Normal file
21
gcc/testsuite/gnat.dg/pack18_pkg.ads
Normal file
|
@ -0,0 +1,21 @@
|
|||
with GNAT.Dynamic_Tables;
|
||||
|
||||
package Pack18_Pkg is
|
||||
|
||||
type String_Access is access String;
|
||||
|
||||
type Rec is record
|
||||
S : String_Access;
|
||||
B : Boolean;
|
||||
N : Natural;
|
||||
end record;
|
||||
pragma Pack (Rec);
|
||||
|
||||
package Attributes_Tables is new GNAT.Dynamic_Tables
|
||||
(Table_Component_Type => Rec,
|
||||
Table_Index_Type => Natural,
|
||||
Table_Low_Bound => 1,
|
||||
Table_Initial => 200,
|
||||
Table_Increment => 200);
|
||||
|
||||
end Pack18_Pkg;
|
Loading…
Add table
Reference in a new issue