aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog7
-rw-r--r--gcc/dwarf2out.c29
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.dg/debug/dwarf2/pr49871.c12
4 files changed, 50 insertions, 3 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index a19ed37..4336abd 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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
diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c
index 7109c9d..806c0d75c 100644
--- a/gcc/dwarf2out.c
+++ b/gcc/dwarf2out.c
@@ -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:
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 73e75bc..e583713 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,5 +1,10 @@
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
the builtin isn't optimized away.
diff --git a/gcc/testsuite/gcc.dg/debug/dwarf2/pr49871.c b/gcc/testsuite/gcc.dg/debug/dwarf2/pr49871.c
new file mode 100644
index 0000000..c1a58c4
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/debug/dwarf2/pr49871.c
@@ -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\]\\)" } } */