This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] dwarf2 bug with negative enum values
- To: gcc-patches at gcc dot gnu dot org
- Subject: [PATCH] dwarf2 bug with negative enum values
- From: Jakub Jelinek <jakub at redhat dot com>
- Date: Wed, 29 Mar 2000 19:18:58 +0200
Hi!
enum { foo = -1, bar, baz };
causes very weird output in the dwarf2 debugging info with compiler which
has sizeof(long) > 4, like:
...
.uaword 0xffffffffffffffff
.uaword 0x30100000303
...
The reason is that gen_enumeration_type_die does not care about negative
enum values and outputs them as unsigned (the patch below should take care
of it). The other issue is that in output_die's dw_val_class_unsigned_const
case the code does:
switch (constant_size (AT_unsigned (a)))
{
case 1:
ASM_OUTPUT_DWARF_DATA1 (asm_out_file, AT_unsigned (a));
break;
case 2:
ASM_OUTPUT_DWARF_DATA2 (asm_out_file, AT_unsigned (a));
break;
case 4:
ASM_OUTPUT_DWARF_DATA4 (asm_out_file, AT_unsigned (a));
break;
case 8:
ASM_OUTPUT_DWARF_DATA8 (asm_out_file,
a->dw_attr_val.v.val_long_long.hi,
a->dw_attr_val.v.val_long_long.low);
break;
which seems very suspicious to me. It is checking AT_unsigned (ie.
v.val_unsigned) and if it is larger than 32 bits, it outputs the 64bit value
v.val_long_long.hi (which happens to be at the same memory location as
v.val_unsigned) - but using a 32bit asm type and then outputs total garbage
from v.val_long_long.low which is not initialized.
IMHO that code should read instead as something like:
case 8:
ASM_OUTPUT_DWARF_DATA8 (asm_out_file,
(AT_unsigned (a) >> 32) & 0xffffffff,
AT_unsigned (a) & 0xffffffff);
if constant_size returns 8, we are sure AT_unsigned is a 64bit type...
2000-03-29 Jakub Jelinek <jakub@redhat.com>
* dwarf2out.c (gen_enumeration_type_die): If enum has a negative
value, don't output it as unsigned.
--- gcc/dwarf2out.c.jj Tue Mar 28 13:32:56 2000
+++ gcc/dwarf2out.c Wed Mar 29 18:48:15 2000
@@ -7905,8 +7905,15 @@ gen_enumeration_type_die (type, context_
IDENTIFIER_POINTER (TREE_PURPOSE (link)));
if (host_integerp (TREE_VALUE (link), 0))
- add_AT_unsigned (enum_die, DW_AT_const_value,
- tree_low_cst (TREE_VALUE (link), 0));
+ {
+ if (TREE_INT_CST_HIGH (TREE_VALUE (link)) == -1
+ && (HOST_WIDE_INT) TREE_INT_CST_LOW (TREE_VALUE (link)) < 0)
+ add_AT_int (enum_die, DW_AT_const_value,
+ tree_low_cst (TREE_VALUE (link), 0));
+ else
+ add_AT_unsigned (enum_die, DW_AT_const_value,
+ tree_low_cst (TREE_VALUE (link), 0));
+ }
}
}
else
Cheers,
Jakub
___________________________________________________________________
Jakub Jelinek | jakub@redhat.com | http://sunsite.mff.cuni.cz/~jj
Linux version 2.3.99-pre2 on a sparc64 machine (1343.49 BogoMips)
___________________________________________________________________