Patchwork RFA; Fix DW_AT_bit_offset generation for types with size > alignment

login
register
mail settings
Submitter Nick Clifton
Date July 21, 2010, 7:48 a.m.
Message ID <m3wrspz35k.fsf@redhat.com>
Download mbox | patch
Permalink /patch/59408/
State New
Headers show

Comments

Nick Clifton - July 21, 2010, 7:48 a.m.
Hi Guys,

  A customer recently uncovered a problem with the XStormy16 port
  whereby the DWARF debug information being generated for bitfields was
  incorrect.  The issue was bogus DW_AT_bit_offset fields, and it turns
  out to happen when the size of the type of the bitfield is larger than
  the alignment of the type of the bitfield.  Eg:

    unsigned long a : 8;

  For the XStormy16 this bitfield has an alignment of 16-bits (the
  maximum for this target), but a type size of 32-bits.  The problem is
  the code in dwarf2out.c:field_byte_offset() which assumes that the
  alignment will always be at least as big as the size.

  Fixed with the patch below.  Tested with no regressions on an
  i686-pc-linux-gnu target as well as an xstormy16-elf target.

  OK to apply ?

Cheers
  Nick

gcc/ChangeLog
2010-07-21  Nick Clifton  <nickc@redhat.com>

	* dwarf2out.c (field_byte_offset): Handle the situation where a
	bit field's type alignment is less than the size of the type.

Patch

Index: gcc/dwarf2out.c
===================================================================
--- gcc/dwarf2out.c	(revision 162327)
+++ gcc/dwarf2out.c	(working copy)
@@ -15704,6 +15704,12 @@ 
       type_size_in_bits = double_int_type_size_in_bits (type);
       type_align_in_bits = simple_type_align_in_bits (type);
 
+      /* If the type is bigger than its alignment, the computation to round
+	 up object_offset_in_bits will in fact *reduce* the object offset.
+	 Catch this here by setting the alignment to the size.  */
+      if (((unsigned HOST_WIDE_INT) type_align_in_bits) < double_int_to_uhwi (type_size_in_bits))
+	type_align_in_bits = (unsigned int) double_int_to_uhwi (type_size_in_bits);
+
       field_size_tree = DECL_SIZE (decl);
 
       /* The size could be unspecified if there was an error, or for