Commit cced5e7f by Jakub Jelinek Committed by Jakub Jelinek

re PR debug/41048 (bad DW_AT_data_member_location from g++)

	PR debug/41048
	* dwarf2out.c (double_int_type_size_in_bits): New function.
	(round_up_to_align): Change first argument and return value to
	double_int.
	(field_byte_offset): Work internally on double_ints.

From-SVN: r159975
parent aa6d7c81
2010-05-28 Jakub Jelinek <jakub@redhat.com>
PR debug/41048
* dwarf2out.c (double_int_type_size_in_bits): New function.
(round_up_to_align): Change first argument and return value to
double_int.
(field_byte_offset): Work internally on double_ints.
PR target/43636
* builtins.c (expand_movstr): Use a temporary pseudo instead
of target even when target is not NULL and not const0_rtx, but
......
......@@ -12361,6 +12361,21 @@ simple_type_size_in_bits (const_tree type)
return TYPE_ALIGN (type);
}
/* Similarly, but return a double_int instead of UHWI. */
static inline double_int
double_int_type_size_in_bits (const_tree type)
{
if (TREE_CODE (type) == ERROR_MARK)
return uhwi_to_double_int (BITS_PER_WORD);
else if (TYPE_SIZE (type) == NULL_TREE)
return double_int_zero;
else if (TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST)
return tree_to_double_int (TYPE_SIZE (type));
else
return uhwi_to_double_int (TYPE_ALIGN (type));
}
/* Given a pointer to a tree node for a subrange type, return a pointer
to a DIE that describes the given type. */
......@@ -15410,20 +15425,15 @@ simple_decl_align_in_bits (const_tree decl)
/* Return the result of rounding T up to ALIGN. */
static inline HOST_WIDE_INT
round_up_to_align (HOST_WIDE_INT t, unsigned int align)
static inline double_int
round_up_to_align (double_int t, unsigned int align)
{
/* We must be careful if T is negative because HOST_WIDE_INT can be
either "above" or "below" unsigned int as per the C promotion
rules, depending on the host, thus making the signedness of the
direct multiplication and division unpredictable. */
unsigned HOST_WIDE_INT u = (unsigned HOST_WIDE_INT) t;
u += align - 1;
u /= align;
u *= align;
return (HOST_WIDE_INT) u;
double_int alignd = uhwi_to_double_int (align);
t = double_int_add (t, alignd);
t = double_int_add (t, double_int_minus_one);
t = double_int_div (t, alignd, true, TRUNC_DIV_EXPR);
t = double_int_mul (t, alignd);
return t;
}
/* Given a pointer to a FIELD_DECL, compute and return the byte offset of the
......@@ -15436,8 +15446,9 @@ round_up_to_align (HOST_WIDE_INT t, unsigned int align)
static HOST_WIDE_INT
field_byte_offset (const_tree decl)
{
HOST_WIDE_INT object_offset_in_bits;
HOST_WIDE_INT bitpos_int;
double_int object_offset_in_bits;
double_int object_offset_in_bytes;
double_int bitpos_int;
if (TREE_CODE (decl) == ERROR_MARK)
return 0;
......@@ -15447,24 +15458,24 @@ field_byte_offset (const_tree decl)
/* We cannot yet cope with fields whose positions are variable, so
for now, when we see such things, we simply return 0. Someday, we may
be able to handle such cases, but it will be damn difficult. */
if (! host_integerp (bit_position (decl), 0))
if (TREE_CODE (bit_position (decl)) != INTEGER_CST)
return 0;
bitpos_int = int_bit_position (decl);
bitpos_int = tree_to_double_int (bit_position (decl));
#ifdef PCC_BITFIELD_TYPE_MATTERS
if (PCC_BITFIELD_TYPE_MATTERS)
{
tree type;
tree field_size_tree;
HOST_WIDE_INT deepest_bitpos;
unsigned HOST_WIDE_INT field_size_in_bits;
double_int deepest_bitpos;
double_int field_size_in_bits;
unsigned int type_align_in_bits;
unsigned int decl_align_in_bits;
unsigned HOST_WIDE_INT type_size_in_bits;
double_int type_size_in_bits;
type = field_type (decl);
type_size_in_bits = simple_type_size_in_bits (type);
type_size_in_bits = double_int_type_size_in_bits (type);
type_align_in_bits = simple_type_align_in_bits (type);
field_size_tree = DECL_SIZE (decl);
......@@ -15475,8 +15486,8 @@ field_byte_offset (const_tree decl)
field_size_tree = bitsize_zero_node;
/* If the size of the field is not constant, use the type size. */
if (host_integerp (field_size_tree, 1))
field_size_in_bits = tree_low_cst (field_size_tree, 1);
if (TREE_CODE (field_size_tree) == INTEGER_CST)
field_size_in_bits = tree_to_double_int (field_size_tree);
else
field_size_in_bits = type_size_in_bits;
......@@ -15528,21 +15539,24 @@ field_byte_offset (const_tree decl)
/* Figure out the bit-distance from the start of the structure to
the "deepest" bit of the bit-field. */
deepest_bitpos = bitpos_int + field_size_in_bits;
deepest_bitpos = double_int_add (bitpos_int, field_size_in_bits);
/* This is the tricky part. Use some fancy footwork to deduce
where the lowest addressed bit of the containing object must
be. */
object_offset_in_bits = deepest_bitpos - type_size_in_bits;
object_offset_in_bits
= double_int_add (deepest_bitpos, double_int_neg (type_size_in_bits));
/* Round up to type_align by default. This works best for
bitfields. */
object_offset_in_bits
= round_up_to_align (object_offset_in_bits, type_align_in_bits);
if (object_offset_in_bits > bitpos_int)
if (double_int_ucmp (object_offset_in_bits, bitpos_int) > 0)
{
object_offset_in_bits = deepest_bitpos - type_size_in_bits;
object_offset_in_bits
= double_int_add (deepest_bitpos,
double_int_neg (type_size_in_bits));
/* Round up to decl_align instead. */
object_offset_in_bits
......@@ -15553,7 +15567,11 @@ field_byte_offset (const_tree decl)
#endif
object_offset_in_bits = bitpos_int;
return object_offset_in_bits / BITS_PER_UNIT;
object_offset_in_bytes
= double_int_div (object_offset_in_bits,
uhwi_to_double_int (BITS_PER_UNIT), true,
TRUNC_DIV_EXPR);
return double_int_to_shwi (object_offset_in_bytes);
}
/* The following routines define various Dwarf attributes and any data
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment