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,85 +15486,92 @@ field_byte_offset (const_tree decl) ...@@ -15475,85 +15486,92 @@ 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;
decl_align_in_bits = simple_decl_align_in_bits (decl); decl_align_in_bits = simple_decl_align_in_bits (decl);
/* The GCC front-end doesn't make any attempt to keep track of the /* The GCC front-end doesn't make any attempt to keep track of the
starting bit offset (relative to the start of the containing starting bit offset (relative to the start of the containing
structure type) of the hypothetical "containing object" for a structure type) of the hypothetical "containing object" for a
bit-field. Thus, when computing the byte offset value for the bit-field. Thus, when computing the byte offset value for the
start of the "containing object" of a bit-field, we must deduce start of the "containing object" of a bit-field, we must deduce
this information on our own. This can be rather tricky to do in this information on our own. This can be rather tricky to do in
some cases. For example, handling the following structure type some cases. For example, handling the following structure type
definition when compiling for an i386/i486 target (which only definition when compiling for an i386/i486 target (which only
aligns long long's to 32-bit boundaries) can be very tricky: aligns long long's to 32-bit boundaries) can be very tricky:
struct S { int field1; long long field2:31; }; struct S { int field1; long long field2:31; };
Fortunately, there is a simple rule-of-thumb which can be used Fortunately, there is a simple rule-of-thumb which can be used
in such cases. When compiling for an i386/i486, GCC will in such cases. When compiling for an i386/i486, GCC will
allocate 8 bytes for the structure shown above. It decides to allocate 8 bytes for the structure shown above. It decides to
do this based upon one simple rule for bit-field allocation. do this based upon one simple rule for bit-field allocation.
GCC allocates each "containing object" for each bit-field at GCC allocates each "containing object" for each bit-field at
the first (i.e. lowest addressed) legitimate alignment boundary the first (i.e. lowest addressed) legitimate alignment boundary
(based upon the required minimum alignment for the declared (based upon the required minimum alignment for the declared
type of the field) which it can possibly use, subject to the type of the field) which it can possibly use, subject to the
condition that there is still enough available space remaining condition that there is still enough available space remaining
in the containing object (when allocated at the selected point) in the containing object (when allocated at the selected point)
to fully accommodate all of the bits of the bit-field itself. to fully accommodate all of the bits of the bit-field itself.
This simple rule makes it obvious why GCC allocates 8 bytes for This simple rule makes it obvious why GCC allocates 8 bytes for
each object of the structure type shown above. When looking each object of the structure type shown above. When looking
for a place to allocate the "containing object" for `field2', for a place to allocate the "containing object" for `field2',
the compiler simply tries to allocate a 64-bit "containing the compiler simply tries to allocate a 64-bit "containing
object" at each successive 32-bit boundary (starting at zero) object" at each successive 32-bit boundary (starting at zero)
until it finds a place to allocate that 64- bit field such that until it finds a place to allocate that 64- bit field such that
at least 31 contiguous (and previously unallocated) bits remain at least 31 contiguous (and previously unallocated) bits remain
within that selected 64 bit field. (As it turns out, for the within that selected 64 bit field. (As it turns out, for the
example above, the compiler finds it is OK to allocate the example above, the compiler finds it is OK to allocate the
"containing object" 64-bit field at bit-offset zero within the "containing object" 64-bit field at bit-offset zero within the
structure type.) structure type.)
Here we attempt to work backwards from the limited set of facts Here we attempt to work backwards from the limited set of facts
we're given, and we try to deduce from those facts, where GCC we're given, and we try to deduce from those facts, where GCC
must have believed that the containing object started (within must have believed that the containing object started (within
the structure type). The value we deduce is then used (by the the structure type). The value we deduce is then used (by the
callers of this routine) to generate DW_AT_location and callers of this routine) to generate DW_AT_location and
DW_AT_bit_offset attributes for fields (both bit-fields and, in DW_AT_bit_offset attributes for fields (both bit-fields and, in
the case of DW_AT_location, regular fields as well). */ the case of DW_AT_location, regular fields as well). */
/* 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
= round_up_to_align (object_offset_in_bits, decl_align_in_bits); = round_up_to_align (object_offset_in_bits, decl_align_in_bits);
} }
} }
else else
#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