This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] Fix PR target/6522 (dwarf-2 regression from 2.95.x)


Hi!

In
struct T
{
  int a;
  long long b;
  int c;
  long long d;
  long long e;
  long long f;
};

on IA-32, b is at offset 4 and c at offset 12, but we were emitting:
        .uleb128 0x3    # (DIE (0x2f) DW_TAG_member)
        .ascii "a\0"    # DW_AT_name
        .byte   0x1     # DW_AT_decl_file
        .byte   0x3     # DW_AT_decl_line
        .long   0x78    # DW_AT_type
        .byte   0x2     # DW_AT_data_member_location
        .byte   0x23    # DW_OP_plus_uconst
        .uleb128 0x0
        .uleb128 0x3    # (DIE (0x3b) DW_TAG_member)
        .ascii "b\0"    # DW_AT_name
        .byte   0x1     # DW_AT_decl_file
        .byte   0x4     # DW_AT_decl_line
        .long   0x7f    # DW_AT_type
        .byte   0x2     # DW_AT_data_member_location
        .byte   0x23    # DW_OP_plus_uconst
        .uleb128 0x8
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
here is the bug, should be 0x4
        .uleb128 0x3    # (DIE (0x47) DW_TAG_member)
        .ascii "c\0"    # DW_AT_name
        .byte   0x1     # DW_AT_decl_file
        .byte   0x5     # DW_AT_decl_line
        .long   0x78    # DW_AT_type
        .byte   0x2     # DW_AT_data_member_location
        .byte   0x23    # DW_OP_plus_uconst
        .uleb128 0xc
        .uleb128 0x3    # (DIE (0x53) DW_TAG_member)
        .ascii "d\0"    # DW_AT_name
        .byte   0x1     # DW_AT_decl_file
        .byte   0x6     # DW_AT_decl_line
        .long   0x7f    # DW_AT_type
        .byte   0x2     # DW_AT_data_member_location
        .byte   0x23    # DW_OP_plus_uconst
        .uleb128 0x10

The problem is that field_byte_offset sees b with DECL_ALIGN () == 64
and aligns the bit offset to that.
The following patch fixes this by doing the same adjustements
on DECL_ALIGN as stor-layout.c does.
IMHO it is quite severe problem, since now dwarf-2 is the default
and debugger will show e.g. bogus value for st_size in struct stat64
(= struct stat if -D_FILE_OFFSET_BITS=64) on IA-32 linux.
I've checked the testcase attached in
http://gcc.gnu.org/ml/gcc-patches/2000-12/msg01038.html
and the output before and after this patch is unchanged, so there shouldn't
be regressions in that area.
I wonder what testcase should be for this, something like:
/* { dg-final { scan-assembler "\"b(|\\0)"(\n|\r\n|\r)[^\n\r]*(\n|\r\n|\r)[^\n\r]*(\n|\r\n|\r)[^\n\r]*(\n|\r\n|\r)[^\n\r]*0x2(\n|\r\n|\r)[^\n\r]*0x23(\n|\r\n|\r)[^\n\r]*(uleb128|byte)[^\n\r]*0x4(\n|\r\n|\r)" } } */
would look too error-prone to me. Probably just gdb should have it in its
testsuite.
Ok to commit?
Mark, ok for branch?

2002-05-03  Jakub Jelinek  <jakub@redhat.com>

	PR target/6522
	* dwarf2out.c (simple_decl_align_in_bits): Renamed to...
	(simple_field_decl_align_in_bits): this.  Apply
	BIGGEST_FIELD_ALIGNMENT and ADJUST_FIELD_ALIGN if defined.

--- gcc/dwarf2out.c.jj	Fri Apr 26 13:39:32 2002
+++ gcc/dwarf2out.c	Fri May  3 13:02:27 2002
@@ -3592,7 +3592,7 @@ static dw_loc_descr_ref loc_descriptor_f
 static HOST_WIDE_INT ceiling		PARAMS ((HOST_WIDE_INT, unsigned int));
 static tree field_type			PARAMS ((tree));
 static unsigned int simple_type_align_in_bits PARAMS ((tree));
-static unsigned int simple_decl_align_in_bits PARAMS ((tree));
+static unsigned int simple_field_decl_align_in_bits PARAMS ((tree));
 static unsigned HOST_WIDE_INT simple_type_size_in_bits PARAMS ((tree));
 static HOST_WIDE_INT field_byte_offset	PARAMS ((tree));
 static void add_AT_location_description	PARAMS ((dw_die_ref,
@@ -8355,10 +8355,28 @@ simple_type_align_in_bits (type)
 }
 
 static inline unsigned
-simple_decl_align_in_bits (decl)
-     tree decl;
+simple_field_decl_align_in_bits (field)
+     tree field;
 {
-  return (TREE_CODE (decl) != ERROR_MARK) ? DECL_ALIGN (decl) : BITS_PER_WORD;
+  unsigned align;
+
+  if (TREE_CODE (field) == ERROR_MARK)
+    return BITS_PER_WORD;
+
+  align = DECL_ALIGN (field);
+
+#ifdef BIGGEST_FIELD_ALIGNMENT
+  /* Some targets (i.e. i386) limit union field alignment
+     to a lower boundary than alignment of variables unless
+     it was overridden by attribute aligned.  */
+  if (! DECL_USER_ALIGN (field))
+    align = MIN (align, (unsigned) BIGGEST_FIELD_ALIGNMENT);
+#endif
+
+#ifdef ADJUST_FIELD_ALIGN
+  align = ADJUST_FIELD_ALIGN (field, align);
+#endif
+  return align;                          
 }
 
 /* Given a pointer to a tree node, assumed to be some kind of a ..._TYPE
@@ -8432,7 +8450,7 @@ field_byte_offset (decl)
 
   type_size_in_bits = simple_type_size_in_bits (type);
   type_align_in_bits = simple_type_align_in_bits (type);
-  decl_align_in_bits = simple_decl_align_in_bits (decl);
+  decl_align_in_bits = simple_field_decl_align_in_bits (decl);
 
   /* The GCC front-end doesn't make any attempt to keep track of the starting
      bit offset (relative to the start of the containing structure type) of the

	Jakub


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]