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> 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 PR target/43636
* builtins.c (expand_movstr): Use a temporary pseudo instead * builtins.c (expand_movstr): Use a temporary pseudo instead
of target even when target is not NULL and not const0_rtx, but 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) ...@@ -12361,6 +12361,21 @@ simple_type_size_in_bits (const_tree type)
return TYPE_ALIGN (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 /* Given a pointer to a tree node for a subrange type, return a pointer
to a DIE that describes the given type. */ to a DIE that describes the given type. */
...@@ -15410,20 +15425,15 @@ simple_decl_align_in_bits (const_tree decl) ...@@ -15410,20 +15425,15 @@ simple_decl_align_in_bits (const_tree decl)
/* Return the result of rounding T up to ALIGN. */ /* Return the result of rounding T up to ALIGN. */
static inline HOST_WIDE_INT static inline double_int
round_up_to_align (HOST_WIDE_INT t, unsigned int align) round_up_to_align (double_int t, unsigned int align)
{ {
/* We must be careful if T is negative because HOST_WIDE_INT can be double_int alignd = uhwi_to_double_int (align);
either "above" or "below" unsigned int as per the C promotion t = double_int_add (t, alignd);
rules, depending on the host, thus making the signedness of the t = double_int_add (t, double_int_minus_one);
direct multiplication and division unpredictable. */ t = double_int_div (t, alignd, true, TRUNC_DIV_EXPR);
unsigned HOST_WIDE_INT u = (unsigned HOST_WIDE_INT) t; t = double_int_mul (t, alignd);
return t;
u += align - 1;
u /= align;
u *= align;
return (HOST_WIDE_INT) u;
} }
/* Given a pointer to a FIELD_DECL, compute and return the byte offset of the /* 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) ...@@ -15436,8 +15446,9 @@ round_up_to_align (HOST_WIDE_INT t, unsigned int align)
static HOST_WIDE_INT static HOST_WIDE_INT
field_byte_offset (const_tree decl) field_byte_offset (const_tree decl)
{ {
HOST_WIDE_INT object_offset_in_bits; double_int object_offset_in_bits;
HOST_WIDE_INT bitpos_int; double_int object_offset_in_bytes;
double_int bitpos_int;
if (TREE_CODE (decl) == ERROR_MARK) if (TREE_CODE (decl) == ERROR_MARK)
return 0; return 0;
...@@ -15447,24 +15458,24 @@ field_byte_offset (const_tree decl) ...@@ -15447,24 +15458,24 @@ field_byte_offset (const_tree decl)
/* We cannot yet cope with fields whose positions are variable, so /* 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 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. */ 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; return 0;
bitpos_int = int_bit_position (decl); bitpos_int = tree_to_double_int (bit_position (decl));
#ifdef PCC_BITFIELD_TYPE_MATTERS #ifdef PCC_BITFIELD_TYPE_MATTERS
if (PCC_BITFIELD_TYPE_MATTERS) if (PCC_BITFIELD_TYPE_MATTERS)
{ {
tree type; tree type;
tree field_size_tree; tree field_size_tree;
HOST_WIDE_INT deepest_bitpos; double_int deepest_bitpos;
unsigned HOST_WIDE_INT field_size_in_bits; double_int field_size_in_bits;
unsigned int type_align_in_bits; unsigned int type_align_in_bits;
unsigned int decl_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 = 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); type_align_in_bits = simple_type_align_in_bits (type);
field_size_tree = DECL_SIZE (decl); field_size_tree = DECL_SIZE (decl);
...@@ -15475,8 +15486,8 @@ field_byte_offset (const_tree decl) ...@@ -15475,8 +15486,8 @@ field_byte_offset (const_tree decl)
field_size_tree = bitsize_zero_node; field_size_tree = bitsize_zero_node;
/* If the size of the field is not constant, use the type size. */ /* If the size of the field is not constant, use the type size. */
if (host_integerp (field_size_tree, 1)) if (TREE_CODE (field_size_tree) == INTEGER_CST)
field_size_in_bits = tree_low_cst (field_size_tree, 1); field_size_in_bits = tree_to_double_int (field_size_tree);
else else
field_size_in_bits = type_size_in_bits; field_size_in_bits = type_size_in_bits;
...@@ -15528,21 +15539,24 @@ field_byte_offset (const_tree decl) ...@@ -15528,21 +15539,24 @@ field_byte_offset (const_tree decl)
/* Figure out the bit-distance from the start of the structure to /* Figure out the bit-distance from the start of the structure to
the "deepest" bit of the bit-field. */ 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 /* This is the tricky part. Use some fancy footwork to deduce
where the lowest addressed bit of the containing object must where the lowest addressed bit of the containing object must
be. */ 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 /* Round up to type_align by default. This works best for
bitfields. */ bitfields. */
object_offset_in_bits object_offset_in_bits
= round_up_to_align (object_offset_in_bits, type_align_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. */ /* Round up to decl_align instead. */
object_offset_in_bits object_offset_in_bits
...@@ -15553,7 +15567,11 @@ field_byte_offset (const_tree decl) ...@@ -15553,7 +15567,11 @@ field_byte_offset (const_tree decl)
#endif #endif
object_offset_in_bits = bitpos_int; 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 /* 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