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]

[PATCH] dwarf2 bug with negative enum values


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)
___________________________________________________________________

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