re PR debug/49871 (-gdwarf-3 creates invalid DWARF3 with DW_AT_data_member_location...
authorJakub Jelinek <jakub@redhat.com>
Thu, 28 Jul 2011 16:21:08 +0000 (18:21 +0200)
committerJakub Jelinek <jakub@gcc.gnu.org>
Thu, 28 Jul 2011 16:21:08 +0000 (18:21 +0200)
PR debug/49871
* dwarf2out.c (size_of_die, value_format, output_die): Use
DW_FORM_udata instead of DW_FORM_data[48] for
dw_val_class_unsigned_const DW_AT_data_member_location for DWARF 3.

* gcc.dg/debug/dwarf2/pr49871.c: New test.

From-SVN: r176876

gcc/ChangeLog
gcc/dwarf2out.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/debug/dwarf2/pr49871.c [new file with mode: 0644]

index a19ed37d0276303f5e3056466b8ee9ce61134696..4336abd717c11d2b46ffc4115592e72008ff5575 100644 (file)
@@ -1,3 +1,10 @@
+2011-07-28  Jakub Jelinek  <jakub@redhat.com>
+
+       PR debug/49871
+       * dwarf2out.c (size_of_die, value_format, output_die): Use
+       DW_FORM_udata instead of DW_FORM_data[48] for
+       dw_val_class_unsigned_const DW_AT_data_member_location for DWARF 3.
+
 2011-07-28  H.J. Lu  <hongjiu.lu@intel.com>
 
        * config/i386/i386.md (*tls_global_dynamic_64): Update
index 7109c9dbfb360b1f0eac1fa2392b37f4365ea7df..806c0d75c40e22245e2871cdbf057f54bba09052 100644 (file)
@@ -7652,7 +7652,15 @@ size_of_die (dw_die_ref die)
          size += size_of_sleb128 (AT_int (a));
          break;
        case dw_val_class_unsigned_const:
-         size += constant_size (AT_unsigned (a));
+         {
+           int csize = constant_size (AT_unsigned (a));
+           if (dwarf_version == 3
+               && a->dw_attr == DW_AT_data_member_location
+               && csize >= 4)
+             size += size_of_uleb128 (AT_unsigned (a));
+           else
+             size += csize;
+         }
          break;
        case dw_val_class_const_double:
          size += 2 * HOST_BITS_PER_WIDE_INT / HOST_BITS_PER_CHAR;
@@ -7953,8 +7961,16 @@ value_format (dw_attr_ref a)
        case 2:
          return DW_FORM_data2;
        case 4:
+         /* In DWARF3 DW_AT_data_member_location with
+            DW_FORM_data4 or DW_FORM_data8 is a loclistptr, not
+            constant, so we need to use DW_FORM_udata if we need
+            a large constant.  */
+         if (dwarf_version == 3 && a->dw_attr == DW_AT_data_member_location)
+           return DW_FORM_udata;
          return DW_FORM_data4;
        case 8:
+         if (dwarf_version == 3 && a->dw_attr == DW_AT_data_member_location)
+           return DW_FORM_udata;
          return DW_FORM_data8;
        default:
          gcc_unreachable ();
@@ -8261,8 +8277,15 @@ output_die (dw_die_ref die)
          break;
 
        case dw_val_class_unsigned_const:
-         dw2_asm_output_data (constant_size (AT_unsigned (a)),
-                              AT_unsigned (a), "%s", name);
+         {
+           int csize = constant_size (AT_unsigned (a));
+           if (dwarf_version == 3
+               && a->dw_attr == DW_AT_data_member_location
+               && csize >= 4)
+             dw2_asm_output_data_uleb128 (AT_unsigned (a), "%s", name);
+           else
+             dw2_asm_output_data (csize, AT_unsigned (a), "%s", name);
+         }
          break;
 
        case dw_val_class_const_double:
index 73e75bc2cc358b0f951ee9468f97a04b6d4b6249..e5837139646dda68007d389be3a97258b317bee7 100644 (file)
@@ -1,3 +1,8 @@
+2011-07-28  Jakub Jelinek  <jakub@redhat.com>
+
+       PR debug/49871
+       * gcc.dg/debug/dwarf2/pr49871.c: New test.
+
 2011-07-28  Jakub Jelinek  <jakub@redhat.com>
 
        * gcc.target/i386/i386.exp (check_effective_target_bmi): Make sure
diff --git a/gcc/testsuite/gcc.dg/debug/dwarf2/pr49871.c b/gcc/testsuite/gcc.dg/debug/dwarf2/pr49871.c
new file mode 100644 (file)
index 0000000..c1a58c4
--- /dev/null
@@ -0,0 +1,12 @@
+/* PR debug/49871 */
+/* { dg-do compile } */
+/* { dg-options "-gdwarf-3 -dA -fno-merge-debug-strings" } */
+
+struct S
+{
+  char a[1 << 16];
+  int b;
+} s;
+
+/* { dg-final { scan-assembler "\\(DW_AT_data_member_location\\)\[^\\r\\n\]*\[\\r\\n\]+\[^\\r\\n\]*\\(DW_FORM_udata\\)" } } */
+/* { dg-final { scan-assembler-not "\\(DW_AT_data_member_location\\)\[^\\r\\n\]*\[\\r\\n\]+\[^\\r\\n\]*\\(DW_FORM_data\[48\]\\)" } } */