public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH]: Track uninitialized variables
@ 2007-05-02  0:03 Caroline Tice
  2007-05-08 16:25 ` Ping! " Caroline Tice
                   ` (2 more replies)
  0 siblings, 3 replies; 25+ messages in thread
From: Caroline Tice @ 2007-05-02  0:03 UTC (permalink / raw)
  To: gcc-patches@gcc.gnu.org Patches; +Cc: Caroline Tice

[-- Attachment #1: Type: text/plain, Size: 7469 bytes --]


As part of some work I've been doing on improving debugging of  
optimized code, I
have developed the following patch which, while tracking the locations  
of variables,
also keeps track of whether the variables are initialized or not (it  
makes conservative
assumptions where it can't be sure).  For those places where it is  
sure the variables
are unintialized, it adds an annotation to the var_location_note,  
which the dwarf
writer later translates to a new DW_OP (an extension) that indicates a  
variable is uninitialized
(DW_OP_GNU_uninit).

Since this work requires that GDB be able to read and do something  
reasonable with
the new DW_OP, I have also created a GDB patch to deal with the new  
op, and to
inform the user that a particular value is unintialized when the user  
asks to see it.
As the two patches really go together, I am attaching both of them to  
this message.
(I will also be sending the GDB patch to the gdb patches list).

Because using the new DW_OP is sensitive to whether or not the user  
has a version of GDB
that can handle it, I have added a macro, TARGET_DWARF_UNINIT_VARS,  
which defaults
to 0, and which controls whether the uninitialized variable tracking  
is done.

I have bootstrapped and run the dejagnu testsuite on this patch, with  
no regressions, on
a ppc running apple-darwin, an x86 running apple-darwin, and an x86 64  
running 64-bit linux.

Is this patch okay to commit to mainline?

-- Caroline Tice
ctice@apple.com

2007-05-01  Caroline Tice  <ctice@apple.com>

         * defaults.h (TARGET_DWARF_UNINIT_VARS): New macro, to control
         tracking uninitialized variables.
         * rtl.def (VAR_LOCATION): Add a new integer subfield to  
VAR_LOCATION
         note definitions, to allow recording of initialization status  
in the
         notes.
         * dwarf2out.c (dwarf_stack_op_name): Add case for  
DW_OP_GNU_uninit.
         (add_var_loc_to_decl): Add comparison of  
NOTE_VAR_LOCATION_STATUS to
         determine if two note locations are equal.
         (output_loc_list): Don't output list entries whose start &  
end labels
         are the same.
         (reg_loc_descriptor): Add parameter for initialization  
status; pass it
         to other loc descriptor functions.
         (one_reg_loc_descriptor): Add parameter for initialization  
status;
         check its value and add DW_OP_GNU_uninit to returned loc  
descr if
         appropriate.
         (multiple_reg_loc_descriptor): Add parameter for  
initialization status;
         pass init status argument to other loc descriptor functions;  
check
         value of intialization parameter and add DW_OP_GNU_uninit to  
returned
         loc descr if appropriate.
         (based_loc_descr): Add parameter for initialization status;  
add new
         variable for return value; check value of initialization  
parameter and
         add DW_OP_GNU_uninit to returned loc descr if appropriate.
         (concatn_mem_loc_descriptor): Add parameter for  
initialization status;
         pass init status argument to other loc descriptor functions;  
check
         value of intialization parameter and add DW_OP_GNU_uninit to  
returned
         loc descr if appropriate.
         (mem_loc_descriptor): Likewise.
         (concat_loc_descriptor): Likewise.
         (concatn_loc_descriptor): Likewise.
         (loc_descriptor): Add parameter for initialization status;  
pass it as
         argument to other loc descriptor function calls.
         (loc_descriptor_from_tree_1): Add appropriate initialization  
status
         to loc descriptor function calls.
         (add_location_or_const_value_attribute): Get initialization  
status
         from VAR_LOCATION note; add initialization status to loc  
descriptor
         function calls.
         * dwarf2.h (enum dwarf_location_atom): New op,  
DW_OP_GNU_uninit.
         * print-rtl.c (print_rtx): When printing a VAR_LOCATION note,  
if status
         is uninitialized, add "[uninint]" to output.
         * rtl.h (NOTE_VAR_LOCATION_STATUS): New macro for accessing  
new field.
         (enum var_init_status): New type, for var initialization  
status field.
         * var-tracking.c (struct location_chain_def): Two new fields,  
init,
         for initialization status, and set_src for the assignment  
value expr.
         (unshare_variable): New parameter for initialization status;  
initialize
         new init and set_src fields.
         (var_reg_set): New parameters for initialization status and  
value;
         pass them to set_variable_part.
         (var_mem_set): Likewise.
         (get_init_value): New function.
         (var_reg_delete_and_set): New initialization status & value  
parameters;
         add call to get_init_value if status is unknown; pass new  
parameters
         to clobber_variable_part and var_reg_set.
         (var_mem_delete_and_set): Likewise.
         (var_reg_delete): Pass null set_src value to  
clobber_variable_part.
         (var_mem_delete): Likewise.
         (variable_union): Pass status to unshare_variable; initialize  
new init
         and set_src fields.  If target doesn't have correct gdb  
(tested by
         macro TARGET_DWARF_UNINIT_VARS), force status to initialized.
         (add_stores): Store insn, rather than NEXT_INSN(insn), so it  
can be
         used later to get the set_src value.
         (find_src_status): New function.
         (find_src_set_src): New function.
         (compute_bb_dataflow): Pass init status to calls to  
var_reg_set,
         var_mem_set, var_reg_delete_and_set and  
var_mem_delete_and_set; for
         MO_SET, get set_src value and pass it to   
var_reg_delete_and_set
         and var_mem_delete_and_set.
         (dump_variable):  Print out "[uninit]" if appropriate.
         (set_variable_part): Add new initialization and set_src  
parameters;
         pass status to unshare_variable; set node->init and node- 
 >set_src
         fields and modify slot in hash table appropriately; save the  
init and
         set_src values if appropriate and assign to the new node.
         (clobber_variable_part): New set_src parameter; if two nodes  
have
         same variable and same location but different set_src  
(assignment)
         values, clobber old node.
         (delete_variable_part): Pass init status to unshare_variable.
         (emit_note_insn_var_location): Add initialized var; assign  
var's init
         status to new 'initialized'; pass new init status field to  
calls to
         gen_rtx_VAR_LOCATION.  If target doesn't have correct gdb  
(tested by
         macro TARGET_DWARF_UNINIT_VARS), force status to initialized.
         (emit_notes_in_bb): Pass initialization status to calls to  
var_reg_set,
         var_mem_set, var_reg_delete_and_set and  
var_mem_delete_and_set; for
         MO_SET, get set_src value and pass it to  
var_reg_delete_and_set and
         var_mem_delete_and_set; call emit_notes_for_changes on  
NEXT_INSN(insn)
         rather than on insn, to make up for change in add_stores.
         (vt_add_function_parameters): Add status to calls to  
set_variable_part.
         * config/i386/linux.h (TARGET_DWARF_UNINIT_VARS): New macro  
definition
         to control tracking uninitialized variables.  Redefined from  
defaults.h
         * config/darwin.h (TARGET_DWARF_UNINIT_VARS): New macro  
definition to
         control tracking uninitialized variables.  Redefined from  
defaults.h.




[-- Attachment #2: fsf-gcc-patch.txt --]
[-- Type: text/plain, Size: 43215 bytes --]

Index: gcc/defaults.h
===================================================================
--- gcc/defaults.h	(revision 124192)
+++ gcc/defaults.h	(working copy)
@@ -796,6 +796,12 @@
 #define TARGET_C99_FUNCTIONS 0
 #endif
 
+/* Determine whether gcc should output DWARF information about
+   uninitialized variables or not.  */
+#ifndef TARGET_DWARF_UNINIT_VARS
+#define TARGET_DWARF_UNINIT_VARS 0
+#endif
+
 /* Determine whether the target runtime library has
    a sincos implementation following the GNU extension.  */
 #ifndef TARGET_HAS_SINCOS
Index: gcc/rtl.def
===================================================================
--- gcc/rtl.def	(revision 124192)
+++ gcc/rtl.def	(working copy)
@@ -670,7 +670,7 @@
 DEF_RTL_EXPR(US_TRUNCATE, "us_truncate", "e", RTX_UNARY)
 
 /* Information about the variable and its location.  */
-DEF_RTL_EXPR(VAR_LOCATION, "var_location", "te", RTX_EXTRA)
+DEF_RTL_EXPR(VAR_LOCATION, "var_location", "tei", RTX_EXTRA)
 
 /* All expressions from this point forward appear only in machine
    descriptions.  */
Index: gcc/dwarf2out.c
===================================================================
--- gcc/dwarf2out.c	(revision 124192)
+++ gcc/dwarf2out.c	(working copy)
@@ -3116,6 +3116,8 @@
       return "DW_OP_call_ref";
     case DW_OP_GNU_push_tls_address:
       return "DW_OP_GNU_push_tls_address";
+    case DW_OP_GNU_uninit:
+      return "DW_OP_GNU_uninit";
     default:
       return "OP_<unknown>";
     }
@@ -4163,15 +4165,20 @@
 static int type_is_enum (tree);
 static unsigned int dbx_reg_number (rtx);
 static void add_loc_descr_op_piece (dw_loc_descr_ref *, int);
-static dw_loc_descr_ref reg_loc_descriptor (rtx);
-static dw_loc_descr_ref one_reg_loc_descriptor (unsigned int);
-static dw_loc_descr_ref multiple_reg_loc_descriptor (rtx, rtx);
+static dw_loc_descr_ref reg_loc_descriptor (rtx, enum var_init_status);
+static dw_loc_descr_ref one_reg_loc_descriptor (unsigned int, 
+						enum var_init_status);
+static dw_loc_descr_ref multiple_reg_loc_descriptor (rtx, rtx,
+						     enum var_init_status);
 static dw_loc_descr_ref int_loc_descriptor (HOST_WIDE_INT);
-static dw_loc_descr_ref based_loc_descr (rtx, HOST_WIDE_INT);
+static dw_loc_descr_ref based_loc_descr (rtx, HOST_WIDE_INT,
+					 enum var_init_status);
 static int is_based_loc (rtx);
-static dw_loc_descr_ref mem_loc_descriptor (rtx, enum machine_mode mode);
-static dw_loc_descr_ref concat_loc_descriptor (rtx, rtx);
-static dw_loc_descr_ref loc_descriptor (rtx);
+static dw_loc_descr_ref mem_loc_descriptor (rtx, enum machine_mode mode,
+					    enum var_init_status);
+static dw_loc_descr_ref concat_loc_descriptor (rtx, rtx,
+					       enum var_init_status);
+static dw_loc_descr_ref loc_descriptor (rtx, enum var_init_status);
 static dw_loc_descr_ref loc_descriptor_from_tree_1 (tree, int);
 static dw_loc_descr_ref loc_descriptor_from_tree (tree);
 static HOST_WIDE_INT ceiling (HOST_WIDE_INT, unsigned int);
@@ -5727,9 +5734,16 @@
   if (temp->last)
     {
       /* If the current location is the same as the end of the list,
+	 and either both or neither of the locations is uninitialized,
 	 we have nothing to do.  */
-      if (!rtx_equal_p (NOTE_VAR_LOCATION_LOC (temp->last->var_loc_note),
-			NOTE_VAR_LOCATION_LOC (loc->var_loc_note)))
+      if ((!rtx_equal_p (NOTE_VAR_LOCATION_LOC (temp->last->var_loc_note),
+			 NOTE_VAR_LOCATION_LOC (loc->var_loc_note)))
+	  || ((NOTE_VAR_LOCATION_STATUS (temp->last->var_loc_note)
+	       != NOTE_VAR_LOCATION_STATUS (loc->var_loc_note))
+	      && ((NOTE_VAR_LOCATION_STATUS (temp->last->var_loc_note)
+		   == STATUS_UNINITIALIZED)
+		  || (NOTE_VAR_LOCATION_STATUS (loc->var_loc_note)
+		      == STATUS_UNINITIALIZED))))
 	{
 	  /* Add LOC to the end of list and update LAST.  */
 	  temp->last->next = loc;
@@ -7039,6 +7053,9 @@
   for (curr = list_head; curr != NULL; curr = curr->dw_loc_next)
     {
       unsigned long size;
+      /* Don't output an entry that starts and ends at the same address.  */
+      if (strcmp (curr->begin, curr->end) == 0)
+	continue;
       if (!have_multiple_function_sections)
 	{
 	  dw2_asm_output_delta (DWARF2_ADDR_SIZE, curr->begin, curr->section,
@@ -8648,7 +8665,7 @@
    zero if there is none.  */
 
 static dw_loc_descr_ref
-reg_loc_descriptor (rtx rtl)
+reg_loc_descriptor (rtx rtl, enum var_init_status initialized)
 {
   rtx regs;
 
@@ -8658,28 +8675,35 @@
   regs = targetm.dwarf_register_span (rtl);
 
   if (hard_regno_nregs[REGNO (rtl)][GET_MODE (rtl)] > 1 || regs)
-    return multiple_reg_loc_descriptor (rtl, regs);
+    return multiple_reg_loc_descriptor (rtl, regs, initialized);
   else
-    return one_reg_loc_descriptor (dbx_reg_number (rtl));
+    return one_reg_loc_descriptor (dbx_reg_number (rtl), initialized);
 }
 
 /* Return a location descriptor that designates a machine register for
    a given hard register number.  */
 
 static dw_loc_descr_ref
-one_reg_loc_descriptor (unsigned int regno)
+one_reg_loc_descriptor (unsigned int regno, enum var_init_status initialized)
 {
+  dw_loc_descr_ref reg_loc_descr;
   if (regno <= 31)
-    return new_loc_descr (DW_OP_reg0 + regno, 0, 0);
+    reg_loc_descr = new_loc_descr (DW_OP_reg0 + regno, 0, 0);
   else
-    return new_loc_descr (DW_OP_regx, regno, 0);
+    reg_loc_descr =  new_loc_descr (DW_OP_regx, regno, 0);
+
+  if (initialized == STATUS_UNINITIALIZED)
+    add_loc_descr (&reg_loc_descr, new_loc_descr (DW_OP_GNU_uninit, 0, 0));
+
+  return reg_loc_descr;
 }
 
 /* Given an RTL of a register, return a location descriptor that
    designates a value that spans more than one register.  */
 
 static dw_loc_descr_ref
-multiple_reg_loc_descriptor (rtx rtl, rtx regs)
+multiple_reg_loc_descriptor (rtx rtl, rtx regs, 
+			     enum var_init_status initialized)
 {
   int nregs, size, i;
   unsigned reg;
@@ -8707,7 +8731,8 @@
 	{
 	  dw_loc_descr_ref t;
 
-	  t = one_reg_loc_descriptor (DBX_REGISTER_NUMBER (reg));
+	  t = one_reg_loc_descriptor (DBX_REGISTER_NUMBER (reg),
+				      STATUS_UNINITIALIZED);
 	  add_loc_descr (&loc_result, t);
 	  add_loc_descr_op_piece (&loc_result, size);
 	  ++reg;
@@ -8726,11 +8751,15 @@
     {
       dw_loc_descr_ref t;
 
-      t = one_reg_loc_descriptor (REGNO (XVECEXP (regs, 0, i)));
+      t = one_reg_loc_descriptor (REGNO (XVECEXP (regs, 0, i)),
+				  STATUS_INITIALIZED);
       add_loc_descr (&loc_result, t);
       size = GET_MODE_SIZE (GET_MODE (XVECEXP (regs, 0, 0)));
       add_loc_descr_op_piece (&loc_result, size);
     }
+
+  if (loc_result && initialized == STATUS_UNINITIALIZED)
+    add_loc_descr (&loc_result, new_loc_descr (DW_OP_GNU_uninit, 0, 0));
   return loc_result;
 }
 
@@ -8776,9 +8805,11 @@
 /* Return a location descriptor that designates a base+offset location.  */
 
 static dw_loc_descr_ref
-based_loc_descr (rtx reg, HOST_WIDE_INT offset)
+based_loc_descr (rtx reg, HOST_WIDE_INT offset,
+		 enum var_init_status initialized)
 {
   unsigned int regno;
+  dw_loc_descr_ref result;
 
   /* We only use "frame base" when we're sure we're talking about the
      post-prologue local stack frame.  We do this by *not* running
@@ -8805,9 +8836,14 @@
 
   regno = dbx_reg_number (reg);
   if (regno <= 31)
-    return new_loc_descr (DW_OP_breg0 + regno, offset, 0);
+    result = new_loc_descr (DW_OP_breg0 + regno, offset, 0);
   else
-    return new_loc_descr (DW_OP_bregx, regno, offset);
+    result = new_loc_descr (DW_OP_bregx, regno, offset);
+
+  if (initialized == STATUS_UNINITIALIZED)
+    add_loc_descr (&result, new_loc_descr (DW_OP_GNU_uninit, 0, 0));
+
+  return result;
 }
 
 /* Return true if this RTL expression describes a base+offset calculation.  */
@@ -8825,7 +8861,8 @@
    used to form the address of a memory location.  */
 
 static dw_loc_descr_ref
-concatn_mem_loc_descriptor (rtx concatn, enum machine_mode mode)
+concatn_mem_loc_descriptor (rtx concatn, enum machine_mode mode,
+			    enum var_init_status initialized)
 {
   unsigned int i;
   dw_loc_descr_ref cc_loc_result = NULL;
@@ -8836,7 +8873,7 @@
       dw_loc_descr_ref ref;
       rtx x = XVECEXP (concatn, 0, i);
 
-      ref = mem_loc_descriptor (x, mode);
+      ref = mem_loc_descriptor (x, mode, STATUS_INITIALIZED);
       if (ref == NULL)
 	return NULL;
 
@@ -8844,6 +8881,9 @@
       add_loc_descr_op_piece (&cc_loc_result, GET_MODE_SIZE (GET_MODE (x)));
     }
 
+  if (cc_loc_result && initialized == STATUS_UNINITIALIZED)
+    add_loc_descr (&cc_loc_result, new_loc_descr (DW_OP_GNU_uninit, 0, 0));
+
   return cc_loc_result;
 }
 
@@ -8866,7 +8906,8 @@
    Return 0 if we can't represent the location.  */
 
 static dw_loc_descr_ref
-mem_loc_descriptor (rtx rtl, enum machine_mode mode)
+mem_loc_descriptor (rtx rtl, enum machine_mode mode,
+		    enum var_init_status initialized)
 {
   dw_loc_descr_ref mem_loc_result = NULL;
   enum dwarf_location_atom op;
@@ -8913,11 +8954,12 @@
 	 memory) so DWARF consumers need to be aware of the subtle
 	 distinction between OP_REG and OP_BASEREG.  */
       if (REGNO (rtl) < FIRST_PSEUDO_REGISTER)
-	mem_loc_result = based_loc_descr (rtl, 0);
+	mem_loc_result = based_loc_descr (rtl, 0, STATUS_INITIALIZED);
       break;
 
     case MEM:
-      mem_loc_result = mem_loc_descriptor (XEXP (rtl, 0), GET_MODE (rtl));
+      mem_loc_result = mem_loc_descriptor (XEXP (rtl, 0), GET_MODE (rtl),
+					   STATUS_INITIALIZED);
       if (mem_loc_result != 0)
 	add_loc_descr (&mem_loc_result, new_loc_descr (DW_OP_deref, 0, 0));
       break;
@@ -8984,10 +9026,12 @@
     plus:
       if (is_based_loc (rtl))
 	mem_loc_result = based_loc_descr (XEXP (rtl, 0),
-					  INTVAL (XEXP (rtl, 1)));
+					  INTVAL (XEXP (rtl, 1)),
+					  STATUS_INITIALIZED);
       else
 	{
-	  mem_loc_result = mem_loc_descriptor (XEXP (rtl, 0), mode);
+	  mem_loc_result = mem_loc_descriptor (XEXP (rtl, 0), mode,
+					       STATUS_INITIALIZED);
 	  if (mem_loc_result == 0)
 	    break;
 
@@ -8999,7 +9043,8 @@
 	  else
 	    {
 	      add_loc_descr (&mem_loc_result,
-			     mem_loc_descriptor (XEXP (rtl, 1), mode));
+			     mem_loc_descriptor (XEXP (rtl, 1), mode,
+						 STATUS_INITIALIZED));
 	      add_loc_descr (&mem_loc_result,
 			     new_loc_descr (DW_OP_plus, 0, 0));
 	    }
@@ -9026,8 +9071,10 @@
 
     do_binop:
       {
-	dw_loc_descr_ref op0 = mem_loc_descriptor (XEXP (rtl, 0), mode);
-	dw_loc_descr_ref op1 = mem_loc_descriptor (XEXP (rtl, 1), mode);
+	dw_loc_descr_ref op0 = mem_loc_descriptor (XEXP (rtl, 0), mode,
+						   STATUS_INITIALIZED);
+	dw_loc_descr_ref op1 = mem_loc_descriptor (XEXP (rtl, 1), mode,
+						   STATUS_INITIALIZED);
 
 	if (op0 == 0 || op1 == 0)
 	  break;
@@ -9043,13 +9090,17 @@
       break;
 
     case CONCATN:
-      mem_loc_result = concatn_mem_loc_descriptor (rtl, mode);
+      mem_loc_result = concatn_mem_loc_descriptor (rtl, mode, 
+						   STATUS_INITIALIZED);
       break;
 
     default:
       gcc_unreachable ();
     }
 
+  if (mem_loc_result && initialized == STATUS_UNINITIALIZED)
+    add_loc_descr (&mem_loc_result, new_loc_descr (DW_OP_GNU_uninit, 0, 0));
+
   return mem_loc_result;
 }
 
@@ -9057,11 +9108,11 @@
    This is typically a complex variable.  */
 
 static dw_loc_descr_ref
-concat_loc_descriptor (rtx x0, rtx x1)
+concat_loc_descriptor (rtx x0, rtx x1, enum var_init_status initialized)
 {
   dw_loc_descr_ref cc_loc_result = NULL;
-  dw_loc_descr_ref x0_ref = loc_descriptor (x0);
-  dw_loc_descr_ref x1_ref = loc_descriptor (x1);
+  dw_loc_descr_ref x0_ref = loc_descriptor (x0, STATUS_INITIALIZED);
+  dw_loc_descr_ref x1_ref = loc_descriptor (x1, STATUS_INITIALIZED);
 
   if (x0_ref == 0 || x1_ref == 0)
     return 0;
@@ -9072,6 +9123,9 @@
   add_loc_descr (&cc_loc_result, x1_ref);
   add_loc_descr_op_piece (&cc_loc_result, GET_MODE_SIZE (GET_MODE (x1)));
 
+  if (initialized == STATUS_UNINITIALIZED)
+    add_loc_descr (&cc_loc_result, new_loc_descr (DW_OP_GNU_uninit, 0, 0));
+
   return cc_loc_result;
 }
 
@@ -9079,7 +9133,7 @@
    locations.  */
 
 static dw_loc_descr_ref
-concatn_loc_descriptor (rtx concatn)
+concatn_loc_descriptor (rtx concatn, enum var_init_status initialized)
 {
   unsigned int i;
   dw_loc_descr_ref cc_loc_result = NULL;
@@ -9090,7 +9144,7 @@
       dw_loc_descr_ref ref;
       rtx x = XVECEXP (concatn, 0, i);
 
-      ref = loc_descriptor (x);
+      ref = loc_descriptor (x, STATUS_INITIALIZED);
       if (ref == NULL)
 	return NULL;
 
@@ -9098,6 +9152,9 @@
       add_loc_descr_op_piece (&cc_loc_result, GET_MODE_SIZE (GET_MODE (x)));
     }
 
+  if (cc_loc_result && initialized == STATUS_UNINITIALIZED)
+    add_loc_descr (&cc_loc_result, new_loc_descr (DW_OP_GNU_uninit, 0, 0));
+
   return cc_loc_result;
 }
 
@@ -9110,7 +9167,7 @@
    If we don't know how to describe it, return 0.  */
 
 static dw_loc_descr_ref
-loc_descriptor (rtx rtl)
+loc_descriptor (rtx rtl, enum var_init_status initialized)
 {
   dw_loc_descr_ref loc_result = NULL;
 
@@ -9127,26 +9184,28 @@
       /* ... fall through ...  */
 
     case REG:
-      loc_result = reg_loc_descriptor (rtl);
+      loc_result = reg_loc_descriptor (rtl, initialized);
       break;
 
     case MEM:
-      loc_result = mem_loc_descriptor (XEXP (rtl, 0), GET_MODE (rtl));
+      loc_result = mem_loc_descriptor (XEXP (rtl, 0), GET_MODE (rtl),
+				       initialized);
       break;
 
     case CONCAT:
-      loc_result = concat_loc_descriptor (XEXP (rtl, 0), XEXP (rtl, 1));
+      loc_result = concat_loc_descriptor (XEXP (rtl, 0), XEXP (rtl, 1),
+					  initialized);
       break;
 
     case CONCATN:
-      loc_result = concatn_loc_descriptor (rtl);
+      loc_result = concatn_loc_descriptor (rtl, initialized);
       break;
 
     case VAR_LOCATION:
       /* Single part.  */
       if (GET_CODE (XEXP (rtl, 1)) != PARALLEL)
 	{
-	  loc_result = loc_descriptor (XEXP (XEXP (rtl, 1), 0));
+	  loc_result = loc_descriptor (XEXP (XEXP (rtl, 1), 0), initialized);
 	  break;
 	}
 
@@ -9161,14 +9220,16 @@
 	int i;
 
 	/* Create the first one, so we have something to add to.  */
-	loc_result = loc_descriptor (XEXP (RTVEC_ELT (par_elems, 0), 0));
+	loc_result = loc_descriptor (XEXP (RTVEC_ELT (par_elems, 0), 0),
+				     initialized);
 	mode = GET_MODE (XEXP (RTVEC_ELT (par_elems, 0), 0));
 	add_loc_descr_op_piece (&loc_result, GET_MODE_SIZE (mode));
 	for (i = 1; i < num_elem; i++)
 	  {
 	    dw_loc_descr_ref temp;
 
-	    temp = loc_descriptor (XEXP (RTVEC_ELT (par_elems, i), 0));
+	    temp = loc_descriptor (XEXP (RTVEC_ELT (par_elems, i), 0),
+				   initialized);
 	    add_loc_descr (&loc_result, temp);
 	    mode = GET_MODE (XEXP (RTVEC_ELT (par_elems, i), 0));
 	    add_loc_descr_op_piece (&loc_result, GET_MODE_SIZE (mode));
@@ -9300,7 +9361,7 @@
 
 	    /* Certain constructs can only be represented at top-level.  */
 	    if (want_address == 2)
-	      return loc_descriptor (rtl);
+	      return loc_descriptor (rtl, STATUS_INITIALIZED);
 
 	    mode = GET_MODE (rtl);
 	    if (MEM_P (rtl))
@@ -9308,7 +9369,7 @@
 		rtl = XEXP (rtl, 0);
 		have_address = 1;
 	      }
-	    ret = mem_loc_descriptor (rtl, mode);
+	    ret = mem_loc_descriptor (rtl, mode, STATUS_INITIALIZED);
 	  }
       }
       break;
@@ -9389,7 +9450,7 @@
 	  return 0;
 	mode = GET_MODE (rtl);
 	rtl = XEXP (rtl, 0);
-	ret = mem_loc_descriptor (rtl, mode);
+	ret = mem_loc_descriptor (rtl, mode, STATUS_INITIALIZED);
 	have_address = 1;
 	break;
       }
@@ -10475,6 +10536,7 @@
       const char *endname, *secname;
       dw_loc_list_ref list;
       rtx varloc;
+      enum var_init_status initialized;
 
       /* Now that we know what section we are using for a base,
 	 actually construct the list of locations.
@@ -10491,7 +10553,12 @@
       varloc = NOTE_VAR_LOCATION (node->var_loc_note);
       secname = secname_for_decl (decl);
 
-      list = new_loc_list (loc_descriptor (varloc),
+      if (NOTE_VAR_LOCATION_LOC (node->var_loc_note))
+	initialized = NOTE_VAR_LOCATION_STATUS (node->var_loc_note);
+      else
+	initialized = STATUS_INITIALIZED;
+
+      list = new_loc_list (loc_descriptor (varloc, initialized),
 			   node->label, node->next->label, secname, 1);
       node = node->next;
 
@@ -10500,8 +10567,11 @@
 	  {
 	    /* The variable has a location between NODE->LABEL and
 	       NODE->NEXT->LABEL.  */
+	    enum var_init_status initialized =
+	      NOTE_VAR_LOCATION_STATUS (node->var_loc_note);
 	    varloc = NOTE_VAR_LOCATION (node->var_loc_note);
-	    add_loc_descr_to_loc_list (&list, loc_descriptor (varloc),
+	    add_loc_descr_to_loc_list (&list, 
+				       loc_descriptor (varloc, initialized),
 				       node->label, node->next->label, secname);
 	  }
 
@@ -10510,6 +10580,8 @@
       if (NOTE_VAR_LOCATION_LOC (node->var_loc_note) != NULL_RTX)
 	{
 	  char label_id[MAX_ARTIFICIAL_LABEL_BYTES];
+	  enum var_init_status initialized =
+	    NOTE_VAR_LOCATION_STATUS (node->var_loc_note);
 
 	  varloc = NOTE_VAR_LOCATION (node->var_loc_note);
 	  if (!current_function_decl)
@@ -10520,7 +10592,8 @@
 					   current_function_funcdef_no);
 	      endname = ggc_strdup (label_id);
 	    }
-	  add_loc_descr_to_loc_list (&list, loc_descriptor (varloc),
+	  add_loc_descr_to_loc_list (&list, 
+				     loc_descriptor (varloc, initialized),
 				     node->label, endname, secname);
 	}
 
@@ -10544,8 +10617,10 @@
      location list, try generating a location from that.  */
   if (loc_list && loc_list->first)
     {
+      enum var_init_status status;
       node = loc_list->first;
-      descr = loc_descriptor (NOTE_VAR_LOCATION (node->var_loc_note));
+      status = NOTE_VAR_LOCATION_STATUS (node->var_loc_note);
+      descr = loc_descriptor (NOTE_VAR_LOCATION (node->var_loc_note), status);
       if (descr)
 	{
 	  add_AT_location_description (die, attr, descr);
Index: gcc/dwarf2.h
===================================================================
--- gcc/dwarf2.h	(revision 124192)
+++ gcc/dwarf2.h	(working copy)
@@ -540,6 +540,7 @@
     DW_OP_bit_piece = 0x9d,
     /* GNU extensions.  */
     DW_OP_GNU_push_tls_address = 0xe0,
+    DW_OP_GNU_uninit     = 0xf0,
     /* HP extensions.  */
     DW_OP_HP_unknown     = 0xe0, /* Ouch, the same as GNU_push_tls_address.  */
     DW_OP_HP_is_value    = 0xe1,
Index: gcc/print-rtl.c
===================================================================
--- gcc/print-rtl.c	(revision 124192)
+++ gcc/print-rtl.c	(working copy)
@@ -325,6 +325,8 @@
 		print_mem_expr (outfile, NOTE_VAR_LOCATION_DECL (in_rtx));
 		fprintf (outfile, " ");
 		print_rtx (NOTE_VAR_LOCATION_LOC (in_rtx));
+		if (NOTE_VAR_LOCATION_STATUS (in_rtx) == STATUS_UNINITIALIZED)
+		  fprintf (outfile, " [uninit]");
 		fprintf (outfile, ")");
 #endif
 		break;
Index: gcc/rtl.h
===================================================================
--- gcc/rtl.h	(revision 124192)
+++ gcc/rtl.h	(working copy)
@@ -868,6 +868,16 @@
 #define NOTE_VAR_LOCATION_LOC(INSN)	(XCEXP (XCEXP (INSN, 4, NOTE),  \
 						1, VAR_LOCATION))
 
+#define NOTE_VAR_LOCATION_STATUS(INSN)  (XCINT (XCEXP (INSN, 4, NOTE), \
+						2, VAR_LOCATION))
+
+enum var_init_status
+{
+  STATUS_UNKNOWN,
+  STATUS_UNINITIALIZED,
+  STATUS_INITIALIZED
+};
+
 /* Codes that appear in the NOTE_LINE_NUMBER field for kinds of notes
    that are not line numbers.  These codes are all negative.
    
Index: gcc/var-tracking.c
===================================================================
--- gcc/var-tracking.c	(revision 124192)
+++ gcc/var-tracking.c	(working copy)
@@ -219,6 +219,12 @@
 
   /* The location (REG or MEM).  */
   rtx loc;
+
+  /* The "value" stored in this location.  */
+  rtx set_src;
+
+  /* Initialized? */
+  enum var_init_status init;
 } *location_chain;
 
 /* Structure describing one part of variable.  */
@@ -294,16 +300,19 @@
 static void attrs_list_union (attrs *, attrs);
 
 static void vars_clear (htab_t);
-static variable unshare_variable (dataflow_set *set, variable var);
+static variable unshare_variable (dataflow_set *set, variable var, 
+				  enum var_init_status);
 static int vars_copy_1 (void **, void *);
 static void vars_copy (htab_t, htab_t);
 static tree var_debug_decl (tree);
-static void var_reg_set (dataflow_set *, rtx);
-static void var_reg_delete_and_set (dataflow_set *, rtx, bool);
+static void var_reg_set (dataflow_set *, rtx, enum var_init_status, rtx);
+static void var_reg_delete_and_set (dataflow_set *, rtx, bool, 
+				    enum var_init_status, rtx);
 static void var_reg_delete (dataflow_set *, rtx, bool);
 static void var_regno_delete (dataflow_set *, int);
-static void var_mem_set (dataflow_set *, rtx);
-static void var_mem_delete_and_set (dataflow_set *, rtx, bool);
+static void var_mem_set (dataflow_set *, rtx, enum var_init_status, rtx);
+static void var_mem_delete_and_set (dataflow_set *, rtx, bool, 
+				    enum var_init_status, rtx);
 static void var_mem_delete (dataflow_set *, rtx, bool);
 
 static void dataflow_set_init (dataflow_set *, int);
@@ -338,8 +347,10 @@
 static void dump_dataflow_sets (void);
 
 static void variable_was_changed (variable, htab_t);
-static void set_variable_part (dataflow_set *, rtx, tree, HOST_WIDE_INT);
-static void clobber_variable_part (dataflow_set *, rtx, tree, HOST_WIDE_INT);
+static void set_variable_part (dataflow_set *, rtx, tree, HOST_WIDE_INT, 
+			       enum var_init_status, rtx);
+static void clobber_variable_part (dataflow_set *, rtx, tree, HOST_WIDE_INT, 
+				   rtx);
 static void delete_variable_part (dataflow_set *, rtx, tree, HOST_WIDE_INT);
 static int emit_note_insn_var_location (void **, void *);
 static void emit_notes_for_changes (rtx, enum emit_note_where);
@@ -727,7 +738,8 @@
 /* Return a copy of a variable VAR and insert it to dataflow set SET.  */
 
 static variable
-unshare_variable (dataflow_set *set, variable var)
+unshare_variable (dataflow_set *set, variable var, 
+		  enum var_init_status initialized)
 {
   void **slot;
   variable new_var;
@@ -752,6 +764,14 @@
 
 	  new_lc = pool_alloc (loc_chain_pool);
 	  new_lc->next = NULL;
+	  if (node->init > initialized)
+	    new_lc->init = node->init;
+	  else
+	    new_lc->init = initialized;
+	  if (node->set_src && !(MEM_P (node->set_src)))
+	    new_lc->set_src = node->set_src;
+	  else
+	    new_lc->set_src = NULL;
 	  new_lc->loc = node->loc;
 
 	  *nextp = new_lc;
@@ -819,7 +839,8 @@
 /* Set the register to contain REG_EXPR (LOC), REG_OFFSET (LOC).  */
 
 static void
-var_reg_set (dataflow_set *set, rtx loc)
+var_reg_set (dataflow_set *set, rtx loc, enum var_init_status initialized, 
+	     rtx set_src)
 {
   tree decl = REG_EXPR (loc);
   HOST_WIDE_INT offset = REG_OFFSET (loc);
@@ -832,9 +853,44 @@
       break;
   if (!node)
     attrs_list_insert (&set->regs[REGNO (loc)], decl, offset, loc);
-  set_variable_part (set, loc, decl, offset);
+  set_variable_part (set, loc, decl, offset, initialized, set_src);
 }
 
+
+/* Lookup the variable described by DECL in SET, and return its initialization
+   status for location LOC.  */
+
+static int
+get_init_value (dataflow_set *set, rtx loc, tree decl)
+{
+  void **slot;
+  variable var;
+  int i;
+  int ret_val = STATUS_UNKNOWN;
+
+  if (! TARGET_DWARF_UNINIT_VARS)
+    return STATUS_INITIALIZED;
+
+  slot = htab_find_slot_with_hash (set->vars, decl, VARIABLE_HASH_VAL (decl),
+				   NO_INSERT);
+  if (slot)
+    {
+      var = * (variable *) slot;
+      for (i = 0; i < var->n_var_parts && ret_val == STATUS_UNKNOWN; i++)
+	{
+	  location_chain nextp;
+	  for (nextp = var->var_part[i].loc_chain; nextp; nextp = nextp->next)
+	    if (rtx_equal_p (nextp->loc, loc))
+	      {
+		ret_val = nextp->init;
+		break;
+	      }
+	}
+    }
+
+  return ret_val;
+}
+
 /* Delete current content of register LOC in dataflow set SET and set
    the register to contain REG_EXPR (LOC), REG_OFFSET (LOC).  If
    MODIFY is true, any other live copies of the same variable part are
@@ -843,7 +899,8 @@
    part.  */
 
 static void
-var_reg_delete_and_set (dataflow_set *set, rtx loc, bool modify)
+var_reg_delete_and_set (dataflow_set *set, rtx loc, bool modify, 
+			enum var_init_status initialized, rtx set_src)
 {
   tree decl = REG_EXPR (loc);
   HOST_WIDE_INT offset = REG_OFFSET (loc);
@@ -852,6 +909,9 @@
 
   decl = var_debug_decl (decl);
 
+  if (initialized == STATUS_UNKNOWN)
+    initialized = get_init_value (set, loc, decl);
+
   nextp = &set->regs[REGNO (loc)];
   for (node = *nextp; node; node = next)
     {
@@ -869,8 +929,8 @@
 	}
     }
   if (modify)
-    clobber_variable_part (set, loc, decl, offset);
-  var_reg_set (set, loc);
+    clobber_variable_part (set, loc, decl, offset, set_src);
+  var_reg_set (set, loc, initialized, set_src);
 }
 
 /* Delete current content of register LOC in dataflow set SET.  If
@@ -890,7 +950,7 @@
 
       decl = var_debug_decl (decl);
 
-      clobber_variable_part (set, NULL, decl, offset);
+      clobber_variable_part (set, NULL, decl, offset, NULL);
     }
 
   for (node = *reg; node; node = next)
@@ -924,14 +984,15 @@
    Adjust the address first if it is stack pointer based.  */
 
 static void
-var_mem_set (dataflow_set *set, rtx loc)
+var_mem_set (dataflow_set *set, rtx loc, enum var_init_status initialized, 
+	     rtx set_src)
 {
   tree decl = MEM_EXPR (loc);
   HOST_WIDE_INT offset = MEM_OFFSET (loc) ? INTVAL (MEM_OFFSET (loc)) : 0;
 
   decl = var_debug_decl (decl);
 
-  set_variable_part (set, loc, decl, offset);
+  set_variable_part (set, loc, decl, offset, initialized, set_src);
 }
 
 /* Delete and set the location part of variable MEM_EXPR (LOC) in
@@ -942,16 +1003,20 @@
    Adjust the address first if it is stack pointer based.  */
 
 static void
-var_mem_delete_and_set (dataflow_set *set, rtx loc, bool modify)
+var_mem_delete_and_set (dataflow_set *set, rtx loc, bool modify, 
+			enum var_init_status initialized, rtx set_src)
 {
   tree decl = MEM_EXPR (loc);
   HOST_WIDE_INT offset = MEM_OFFSET (loc) ? INTVAL (MEM_OFFSET (loc)) : 0;
 
   decl = var_debug_decl (decl);
 
+  if (initialized == STATUS_UNKNOWN)
+    initialized = get_init_value (set, loc, decl);
+
   if (modify)
-    clobber_variable_part (set, NULL, decl, offset);
-  var_mem_set (set, loc);
+    clobber_variable_part (set, NULL, decl, offset, set_src);
+  var_mem_set (set, loc, initialized, set_src);
 }
 
 /* Delete the location part LOC from dataflow set SET.  If CLOBBER is
@@ -966,7 +1031,7 @@
 
   decl = var_debug_decl (decl);
   if (clobber)
-    clobber_variable_part (set, NULL, decl, offset);
+    clobber_variable_part (set, NULL, decl, offset, NULL);
   delete_variable_part (set, loc, decl, offset);
 }
 
@@ -1078,7 +1143,14 @@
 	    }
 	}
       if (k < src->n_var_parts)
-	unshare_variable (set, src);
+	{
+	  enum var_init_status status = STATUS_UNKNOWN;
+	  
+	  if (! TARGET_DWARF_UNINIT_VARS)
+	    status = STATUS_INITIALIZED;
+
+	  unshare_variable (set, src, status);
+	}
       else
 	*dstp = src;
 
@@ -1112,7 +1184,13 @@
   gcc_assert (k <= MAX_VAR_PARTS);
 
   if (dst->refcount > 1 && dst->n_var_parts != k)
-    dst = unshare_variable (set, dst);
+    {
+      enum var_init_status status = STATUS_UNKNOWN;
+      
+      if (! TARGET_DWARF_UNINIT_VARS)
+	status = STATUS_INITIALIZED;
+      dst = unshare_variable (set, dst, status);
+    }
 
   i = src->n_var_parts - 1;
   j = dst->n_var_parts - 1;
@@ -1145,10 +1223,12 @@
 			 && REG_P (node->loc)
 			 && REGNO (node2->loc) == REGNO (node->loc))
 			|| rtx_equal_p (node2->loc, node->loc)))
+		    if (node2->init < node->init)
+		      node2->init = node->init;
 		    break;
 		}
 	      if (node || node2)
-		dst = unshare_variable (set, dst);
+		dst = unshare_variable (set, dst, STATUS_UNKNOWN);
 	    }
 
 	  src_l = 0;
@@ -1194,6 +1274,11 @@
 		  /* Copy the location from SRC.  */
 		  new_node = pool_alloc (loc_chain_pool);
 		  new_node->loc = node->loc;
+		  new_node->init = node->init;
+		  if (!node->set_src || MEM_P (node->set_src))
+		    new_node->set_src = NULL;
+		  else
+		    new_node->set_src = node->set_src;
 		  vui[n].lc = new_node;
 		  vui[n].pos_src = ii;
 		  vui[n].pos_dst = src_l + dst_l;
@@ -1240,6 +1325,11 @@
 
 	      new_lc = pool_alloc (loc_chain_pool);
 	      new_lc->next = NULL;
+	      new_lc->init = node->init;
+	      if (!node->set_src || MEM_P (node->set_src))
+		new_lc->set_src = NULL;
+	      else
+		new_lc->set_src = node->set_src;
 	      new_lc->loc = node->loc;
 
 	      *nextp = new_lc;
@@ -1258,6 +1348,18 @@
 	dst->var_part[k].cur_loc = NULL;
     }
 
+  for (i = 0; i < src->n_var_parts && i < dst->n_var_parts; i++)
+    {
+      location_chain node, node2;
+      for (node = src->var_part[i].loc_chain; node; node = node->next)
+	for (node2 = dst->var_part[i].loc_chain; node2; node2 = node2->next)
+	  if (rtx_equal_p (node->loc, node2->loc))
+	    {
+	      if (node->init > node2->init)
+		node2->init = node->init;
+	    }
+    }
+
   /* Continue traversing the hash table.  */
   return 1;
 }
@@ -1679,7 +1781,7 @@
       else
 	mo->type = MO_SET;
       mo->u.loc = loc;
-      mo->insn = NEXT_INSN ((rtx) insn);
+      mo->insn = (rtx) insn;
     }
   else if (MEM_P (loc)
 	   && MEM_EXPR (loc)
@@ -1700,10 +1802,109 @@
       else
 	mo->type = MO_SET;
       mo->u.loc = loc;
-      mo->insn = NEXT_INSN ((rtx) insn);
+      mo->insn = (rtx) insn;
     }
 }
 
+/* Given a dataflow_set IN, a location LOC, and an instruction INSN that
+   supposedly assigns a value to loc, find the piece of the instruction
+   that is being assigned to LOC, check to see if it's a variable (decl),
+   and if so, look up and return its initialization status.*/
+
+static enum var_init_status
+find_src_status (dataflow_set *in, rtx loc, rtx insn)
+{
+  rtx src = NULL_RTX;
+  tree decl = NULL_TREE;
+  enum var_init_status status = STATUS_UNINITIALIZED;
+
+  if (! TARGET_DWARF_UNINIT_VARS)
+    status = STATUS_INITIALIZED;
+
+  if (GET_CODE (PATTERN (insn)) == SET)
+    src = SET_SRC (PATTERN (insn));
+  else if (GET_CODE (PATTERN (insn)) == PARALLEL
+	   || GET_CODE (PATTERN (insn)) == SEQUENCE)
+    {
+      int i;
+      for (i = XVECLEN (PATTERN (insn), 0) - 1; i >= 0; i--)
+	if (GET_CODE (XVECEXP (PATTERN (insn), 0, i)) == SET
+	    && SET_DEST (XVECEXP (PATTERN (insn), 0, i)) == loc)
+	  src = SET_SRC (XVECEXP (PATTERN (insn), 0, i));
+    }
+
+  if (REG_P (src))
+    decl = var_debug_decl (REG_EXPR (src));
+  else if (MEM_P (src))
+    decl = var_debug_decl (MEM_EXPR (src));
+
+  if (src && decl)
+    status = get_init_value (in, src, decl);
+
+  return status;
+}
+
+/* Given an assignment instruction (INSN) and an assignment destination
+   (LOC), find the piece of INSN that is being assigned to LOC.  If it
+   corresponds to a variable (decl), look up the variable in SET and
+   return *its* set_src. 
+
+   In other words, (using 'set_src' as short hand for 'the value assigned
+   to'), look up and return the set_src of the variable being assigned 
+   to LOC. */
+
+static rtx
+find_src_set_src (dataflow_set *set, rtx loc, rtx insn)
+{
+  tree decl = NULL_TREE;   /* The variable being copied around.          */
+  rtx src = NULL_RTX;      /* The location "decl" is being copied from.  */
+  rtx set_src = NULL_RTX;  /* The value for "decl" stored in "src".      */
+  void **slot;
+  variable var;
+  location_chain nextp;
+  int i;
+  bool found;
+
+  if (GET_CODE (PATTERN (insn)) == SET)
+    src = SET_SRC (PATTERN (insn));
+  else if (GET_CODE (PATTERN (insn)) == PARALLEL
+	   || GET_CODE (PATTERN (insn)) == SEQUENCE)
+    {
+      for (i = XVECLEN (PATTERN (insn), 0) - 1; i >= 0; i--)
+	if (GET_CODE (XVECEXP (PATTERN (insn), 0, i)) == SET
+	    && SET_DEST (XVECEXP (PATTERN (insn), 0, i)) == loc)
+	  src = SET_SRC (XVECEXP (PATTERN (insn), 0, i));
+    }
+
+  if (REG_P (src))
+    decl = var_debug_decl (REG_EXPR (src));
+  else if (MEM_P (src))
+    decl = var_debug_decl (MEM_EXPR (src));
+
+  if (src && decl)
+    {
+      slot = htab_find_slot_with_hash (set->vars, decl, 
+				       VARIABLE_HASH_VAL (decl), NO_INSERT);
+
+      if (slot)
+	{
+	  var = *(variable *) slot;
+	  found = false;
+	  for (i = 0; i < var->n_var_parts && !found; i++)
+	    for (nextp = var->var_part[i].loc_chain; nextp && !found; 
+		 nextp = nextp->next)
+	      if (rtx_equal_p (nextp->loc, src))
+		{
+		  set_src = nextp->set_src;
+		  found = true;
+		}
+	      
+	}
+    }
+
+  return set_src;
+}
+
 /* Compute the changes of variable locations in the basic block BB.  */
 
 static bool
@@ -1733,33 +1934,65 @@
 	  case MO_USE:
 	    {
 	      rtx loc = VTI (bb)->mos[i].u.loc;
+	      enum var_init_status status = STATUS_UNINITIALIZED;
 
+	      if (! TARGET_DWARF_UNINIT_VARS)
+		status = STATUS_INITIALIZED;
+
 	      if (GET_CODE (loc) == REG)
-		var_reg_set (out, loc);
+		var_reg_set (out, loc, status, NULL);
 	      else if (GET_CODE (loc) == MEM)
-		var_mem_set (out, loc);
+		var_mem_set (out, loc, status, NULL);
 	    }
 	    break;
 
 	  case MO_SET:
 	    {
 	      rtx loc = VTI (bb)->mos[i].u.loc;
+	      rtx set_src =  NULL;
+	      rtx insn = VTI (bb)->mos[i].insn;
 
+	      if (GET_CODE (PATTERN (insn)) == SET)
+		set_src = SET_SRC (PATTERN (insn));
+	      else if (GET_CODE (PATTERN (insn)) == PARALLEL
+		       || GET_CODE (PATTERN (insn)) == SEQUENCE)
+		{
+		  int j;
+		  for (j = XVECLEN (PATTERN (insn), 0) - 1; j >= 0; j--)
+		    if (GET_CODE (XVECEXP (PATTERN (insn), 0, j)) == SET
+			&& SET_DEST (XVECEXP (PATTERN (insn), 0, j)) == loc)
+		      set_src = SET_SRC (XVECEXP (PATTERN (insn), 0, j));
+		}
+
 	      if (REG_P (loc))
-		var_reg_delete_and_set (out, loc, true);
+		var_reg_delete_and_set (out, loc, true, STATUS_INITIALIZED,
+					set_src);
 	      else if (MEM_P (loc))
-		var_mem_delete_and_set (out, loc, true);
+		var_mem_delete_and_set (out, loc, true, STATUS_INITIALIZED,
+					set_src);
 	    }
 	    break;
 
 	  case MO_COPY:
 	    {
 	      rtx loc = VTI (bb)->mos[i].u.loc;
+	      enum var_init_status src_status;
+	      rtx set_src;
 
+	      if (! TARGET_DWARF_UNINIT_VARS)
+		src_status = STATUS_INITIALIZED;
+	      else
+		src_status = find_src_status (in, loc, VTI (bb)->mos[i].insn);
+
+	      if (src_status == STATUS_UNKNOWN)
+		src_status = find_src_status (out, loc, VTI (bb)->mos[i].insn);
+
+	      set_src = find_src_set_src (in, loc, VTI (bb)->mos[i].insn);
+
 	      if (REG_P (loc))
-		var_reg_delete_and_set (out, loc, false);
+		var_reg_delete_and_set (out, loc, false, src_status, set_src);
 	      else if (MEM_P (loc))
-		var_mem_delete_and_set (out, loc, false);
+		var_mem_delete_and_set (out, loc, false, src_status, set_src);
 	    }
 	    break;
 
@@ -1932,6 +2165,8 @@
       for (node = var->var_part[i].loc_chain; node; node = node->next)
 	{
 	  fprintf (dump_file, "      ");
+	  if (node->init == STATUS_UNINITIALIZED)
+	    fprintf (dump_file, "[uninit]");
 	  print_rtl_single (dump_file, node->loc);
 	}
     }
@@ -2077,7 +2312,8 @@
    part's location by LOC.  */
 
 static void
-set_variable_part (dataflow_set *set, rtx loc, tree decl, HOST_WIDE_INT offset)
+set_variable_part (dataflow_set *set, rtx loc, tree decl, HOST_WIDE_INT offset,
+		   enum var_init_status initialized, rtx set_src)
 {
   int pos;
   location_chain node, next;
@@ -2119,13 +2355,19 @@
 	    {
 	      /* LOC is in the beginning of the chain so we have nothing
 		 to do.  */
+	      if (node->init < initialized)
+		node->init = initialized;
+	      if (set_src != NULL)
+		node->set_src = set_src;
+
+	      *slot = var;
 	      return;
 	    }
 	  else
 	    {
 	      /* We have to make a copy of a shared variable.  */
 	      if (var->refcount > 1)
-		var = unshare_variable (set, var);
+		var = unshare_variable (set, var, initialized);
 	    }
 	}
       else
@@ -2134,7 +2376,7 @@
 
 	  /* We have to make a copy of the shared variable.  */
 	  if (var->refcount > 1)
-	    var = unshare_variable (set, var);
+	    var = unshare_variable (set, var, initialized);
 
 	  /* We track only variables whose size is <= MAX_VAR_PARTS bytes
 	     thus there are at most MAX_VAR_PARTS different offsets.  */
@@ -2161,6 +2403,12 @@
 	   && REGNO (node->loc) == REGNO (loc))
 	  || rtx_equal_p (node->loc, loc))
 	{
+	  /* Save these values, to assign to the new node, before
+	     deleting this one.  */
+	  if (node->init > initialized)
+	    initialized = node->init;
+	  if (node->set_src != NULL && set_src == NULL)
+	    set_src = node->set_src;
 	  pool_free (loc_chain_pool, node);
 	  *nextp = next;
 	  break;
@@ -2172,6 +2420,8 @@
   /* Add the location to the beginning.  */
   node = pool_alloc (loc_chain_pool);
   node->loc = loc;
+  node->init = initialized;
+  node->set_src = set_src;
   node->next = var->var_part[pos].loc_chain;
   var->var_part[pos].loc_chain = node;
 
@@ -2190,7 +2440,7 @@
 
 static void
 clobber_variable_part (dataflow_set *set, rtx loc, tree decl,
-		      HOST_WIDE_INT offset)
+		       HOST_WIDE_INT offset, rtx set_src)
 {
   void **slot;
 
@@ -2213,7 +2463,11 @@
 	  for (node = next; node; node = next)
 	    {
 	      next = node->next;
-	      if (node->loc != loc)
+	      if (node->loc != loc 
+		  && (!(TARGET_DWARF_UNINIT_VARS)
+		      || !set_src 
+		      || MEM_P (set_src)
+		      || !rtx_equal_p (set_src, node->set_src)))
 		{
 		  if (REG_P (node->loc))
 		    {
@@ -2278,7 +2532,10 @@
 		       && REGNO (node->loc) == REGNO (loc))
 		      || rtx_equal_p (node->loc, loc))
 		    {
-		      var = unshare_variable (set, var);
+		      enum var_init_status status = STATUS_UNKNOWN;
+		      if (! TARGET_DWARF_UNINIT_VARS)
+			status = STATUS_INITIALIZED;
+		      var = unshare_variable (set, var, status);
 		      break;
 		    }
 		}
@@ -2345,6 +2602,7 @@
   rtx note;
   int i, j, n_var_parts;
   bool complete;
+  enum var_init_status initialized = STATUS_UNINITIALIZED;
   HOST_WIDE_INT last_limit;
   tree type_size_unit;
   HOST_WIDE_INT offsets[MAX_VAR_PARTS];
@@ -2352,6 +2610,9 @@
 
   gcc_assert (var->decl);
 
+  if (! TARGET_DWARF_UNINIT_VARS)
+    initialized = STATUS_INITIALIZED;
+
   complete = true;
   last_limit = 0;
   n_var_parts = 0;
@@ -2369,6 +2630,7 @@
       offsets[n_var_parts] = var->var_part[i].offset;
       loc[n_var_parts] = var->var_part[i].loc_chain->loc;
       mode = GET_MODE (loc[n_var_parts]);
+      initialized = var->var_part[i].loc_chain->init;
       last_limit = offsets[n_var_parts] + GET_MODE_SIZE (mode);
 
       /* Attempt to merge adjacent registers or memory.  */
@@ -2448,10 +2710,13 @@
   else
     note = emit_note_before (NOTE_INSN_VAR_LOCATION, insn);
 
+  if (!(TARGET_DWARF_UNINIT_VARS))
+    initialized = STATUS_INITIALIZED;
+
   if (!complete)
     {
       NOTE_VAR_LOCATION (note) = gen_rtx_VAR_LOCATION (VOIDmode, var->decl,
-						       NULL_RTX);
+						       NULL_RTX, 0);
     }
   else if (n_var_parts == 1)
     {
@@ -2459,7 +2724,8 @@
 	= gen_rtx_EXPR_LIST (VOIDmode, loc[0], GEN_INT (offsets[0]));
 
       NOTE_VAR_LOCATION (note) = gen_rtx_VAR_LOCATION (VOIDmode, var->decl,
-						       expr_list);
+						       expr_list, 
+						       (int) initialized);
     }
   else if (n_var_parts)
     {
@@ -2472,9 +2738,12 @@
       parallel = gen_rtx_PARALLEL (VOIDmode,
 				   gen_rtvec_v (n_var_parts, loc));
       NOTE_VAR_LOCATION (note) = gen_rtx_VAR_LOCATION (VOIDmode, var->decl,
-						       parallel);
+						       parallel, 
+						       (int) initialized);
     }
 
+  NOTE_VAR_LOCATION_STATUS (note) = (int) initialized;
+
   htab_clear_slot (changed_variables, varp);
 
   /* When there are no location parts the variable has been already
@@ -2603,11 +2872,14 @@
 	  case MO_USE:
 	    {
 	      rtx loc = VTI (bb)->mos[i].u.loc;
-
+      
+	      enum var_init_status status = STATUS_UNINITIALIZED;
+	      if (! TARGET_DWARF_UNINIT_VARS)
+		status = STATUS_INITIALIZED;
 	      if (GET_CODE (loc) == REG)
-		var_reg_set (&set, loc);
+		var_reg_set (&set, loc, status, NULL);
 	      else
-		var_mem_set (&set, loc);
+		var_mem_set (&set, loc, status, NULL);
 
 	      emit_notes_for_changes (insn, EMIT_NOTE_AFTER_INSN);
 	    }
@@ -2616,26 +2888,46 @@
 	  case MO_SET:
 	    {
 	      rtx loc = VTI (bb)->mos[i].u.loc;
+	      rtx set_src =  NULL;
 
+	      if (GET_CODE (PATTERN (insn)) == SET)
+		set_src = SET_SRC (PATTERN (insn));
+	      else if (GET_CODE (PATTERN (insn)) == PARALLEL
+		       || GET_CODE (PATTERN (insn)) == SEQUENCE)
+		{
+		  int j;
+		  for (j = XVECLEN (PATTERN (insn), 0) - 1; j >= 0; j--)
+		    if (GET_CODE (XVECEXP (PATTERN (insn), 0, j)) == SET
+			&& SET_DEST (XVECEXP (PATTERN (insn), 0, j)) == loc)
+		      set_src = SET_SRC (XVECEXP (PATTERN (insn), 0, j));
+		}
+
 	      if (REG_P (loc))
-		var_reg_delete_and_set (&set, loc, true);
+		var_reg_delete_and_set (&set, loc, true, STATUS_INITIALIZED, 
+					set_src);
 	      else
-		var_mem_delete_and_set (&set, loc, true);
+		var_mem_delete_and_set (&set, loc, true, STATUS_INITIALIZED, 
+					set_src);
 
-	      emit_notes_for_changes (insn, EMIT_NOTE_BEFORE_INSN);
+	      emit_notes_for_changes (NEXT_INSN (insn), EMIT_NOTE_BEFORE_INSN);
 	    }
 	    break;
 
 	  case MO_COPY:
 	    {
 	      rtx loc = VTI (bb)->mos[i].u.loc;
+	      enum var_init_status src_status;
+	      rtx set_src;
 
+	      src_status = find_src_status (&set, loc, VTI (bb)->mos[i].insn);
+	      set_src = find_src_set_src (&set, loc, VTI (bb)->mos[i].insn);
+
 	      if (REG_P (loc))
-		var_reg_delete_and_set (&set, loc, false);
+		var_reg_delete_and_set (&set, loc, false, src_status, set_src);
 	      else
-		var_mem_delete_and_set (&set, loc, false);
+		var_mem_delete_and_set (&set, loc, false, src_status, set_src);
 
-	      emit_notes_for_changes (insn, EMIT_NOTE_BEFORE_INSN);
+	      emit_notes_for_changes (NEXT_INSN (insn), EMIT_NOTE_BEFORE_INSN);
 	    }
 	    break;
 
@@ -2661,7 +2953,7 @@
 	      else
 		var_mem_delete (&set, loc, true);
 
-	      emit_notes_for_changes (insn, EMIT_NOTE_BEFORE_INSN);
+	      emit_notes_for_changes (NEXT_INSN (insn), EMIT_NOTE_BEFORE_INSN);
 	    }
 	    break;
 
@@ -2777,10 +3069,12 @@
 	  gcc_assert (REGNO (incoming) < FIRST_PSEUDO_REGISTER);
 	  attrs_list_insert (&out->regs[REGNO (incoming)],
 			     parm, offset, incoming);
-	  set_variable_part (out, incoming, parm, offset);
+	  set_variable_part (out, incoming, parm, offset, STATUS_INITIALIZED, 
+			     NULL);
 	}
       else if (MEM_P (incoming))
-	set_variable_part (out, incoming, parm, offset);
+	set_variable_part (out, incoming, parm, offset, STATUS_INITIALIZED, 
+			   NULL);
     }
 }
 
Index: gcc/config/i386/linux.h
===================================================================
--- gcc/config/i386/linux.h	(revision 124192)
+++ gcc/config/i386/linux.h	(working copy)
@@ -195,3 +195,6 @@
 /* i386 glibc provides __stack_chk_guard in %gs:0x14.  */
 #define TARGET_THREAD_SSP_OFFSET	0x14
 #endif
+
+#undef  TARGET_DWARF_UNINIT_VARS
+#define TARGET_DWARF_UNINIT_VARS   1
Index: gcc/config/darwin.h
===================================================================
--- gcc/config/darwin.h	(revision 124192)
+++ gcc/config/darwin.h	(working copy)
@@ -984,4 +984,8 @@
 
 #define TARGET_HAS_TARGETCM 1
 
+#undef  TARGET_DWARF_UNINIT_VARS
+#define TARGET_DWARF_UNINIT_VARS   \
+  (strverscmp (darwin_macosx_version_min, "10.5") >= 0)
+
 #endif /* CONFIG_DARWIN_H */

[-- Attachment #3: Type: text/plain, Size: 1435 bytes --]



GDB PATCH:

2007-05-01  Caroline Tice  <ctice@apple.com>

         * c-valprint.c (c_value_print):  If the var_status field of the
         value struct is 0, print out "[uninitialized]" before the  
value.
         * dwarf2expr.c (add_piece): Make function non-static.
         (unsigned_address_type): Likewise.
         (signed_address_type): Likewise.
         (execute_stack_op): Initialize ctx->var_status field; allow
         DW_OP_GNU_uninit as legal op following a DW_OP_reg op or a
         DW_OP_regx op; add case for DW_OP_GNU_uninit and update
         ctx->var_status appropriately.
         * dwarf2expr.h (struct dwarf_expr_context): New field,  
var_status.
         (unsigned_address_type): Add extern declaration.
         (signed_address_type): Likewise.
         (add_piece): Likewise.
         * dwarf2loc.c (dwarf2_evaluate_loc_desc): Add call to
         set_var_status.
         * dwarf2read.c (dwarf_stack_op_name): Add case for  
DW_OP_GNU_uninit.
         (decode_locdesc): Add case for DW_OP_GNU_uninit.
         * value.c (struct value):  New field, var_status.
         (allocate_value): Initialize new field.
         (set_var_status): New function.
         (value_var_status): New function.
         * value.h (value_var_status): New extern declaration.
         (set_var_status): Likewise.
         * include/elf/dwarf2.h: (enum dwarf_location_atom): Add new  
DW_OP,
         DW_OP_GNU_uninit.



[-- Attachment #4: fsf-gdb-patch.txt --]
[-- Type: text/plain, Size: 9486 bytes --]

Index: gdb/c-valprint.c
===================================================================
RCS file: /cvs/src/src/gdb/c-valprint.c,v
retrieving revision 1.42
diff -c -3 -p -r1.42 c-valprint.c
*** gdb/c-valprint.c	26 Jan 2007 20:54:16 -0000	1.42
--- gdb/c-valprint.c	1 May 2007 22:10:43 -0000
*************** c_value_print (struct value *val, struct
*** 556,561 ****
--- 556,564 ----
  	}
      }
  
+   if (value_var_status (val) == 0)
+     fprintf_filtered (stream, " [uninitialized] ");
+ 
    if (objectprint && (TYPE_CODE (type) == TYPE_CODE_CLASS))
      {
        /* Attempt to determine real type of object */
Index: gdb/dwarf2expr.c
===================================================================
RCS file: /cvs/src/src/gdb/dwarf2expr.c,v
retrieving revision 1.19
diff -c -3 -p -r1.19 dwarf2expr.c
*** gdb/dwarf2expr.c	9 Jan 2007 17:58:50 -0000	1.19
--- gdb/dwarf2expr.c	1 May 2007 22:10:43 -0000
*************** dwarf_expr_fetch (struct dwarf_expr_cont
*** 106,112 ****
  }
  
  /* Add a new piece to CTX's piece list.  */
! static void
  add_piece (struct dwarf_expr_context *ctx,
             int in_reg, CORE_ADDR value, ULONGEST size)
  {
--- 106,112 ----
  }
  
  /* Add a new piece to CTX's piece list.  */
! void
  add_piece (struct dwarf_expr_context *ctx,
             int in_reg, CORE_ADDR value, ULONGEST size)
  {
*************** dwarf2_read_address (gdb_byte *buf, gdb_
*** 213,219 ****
  
  /* Return the type of an address, for unsigned arithmetic.  */
  
! static struct type *
  unsigned_address_type (void)
  {
    switch (TARGET_ADDR_BIT / TARGET_CHAR_BIT)
--- 213,219 ----
  
  /* Return the type of an address, for unsigned arithmetic.  */
  
! struct type *
  unsigned_address_type (void)
  {
    switch (TARGET_ADDR_BIT / TARGET_CHAR_BIT)
*************** unsigned_address_type (void)
*** 232,238 ****
  
  /* Return the type of an address, for signed arithmetic.  */
  
! static struct type *
  signed_address_type (void)
  {
    switch (TARGET_ADDR_BIT / TARGET_CHAR_BIT)
--- 232,238 ----
  
  /* Return the type of an address, for signed arithmetic.  */
  
! struct type *
  signed_address_type (void)
  {
    switch (TARGET_ADDR_BIT / TARGET_CHAR_BIT)
*************** execute_stack_op (struct dwarf_expr_cont
*** 257,262 ****
--- 257,263 ----
  		  gdb_byte *op_ptr, gdb_byte *op_end)
  {
    ctx->in_reg = 0;
+   ctx->var_status = 1;  /* Default is initialized.  */
  
    while (op_ptr < op_end)
      {
*************** execute_stack_op (struct dwarf_expr_cont
*** 383,389 ****
  	case DW_OP_reg29:
  	case DW_OP_reg30:
  	case DW_OP_reg31:
! 	  if (op_ptr != op_end && *op_ptr != DW_OP_piece)
  	    error (_("DWARF-2 expression error: DW_OP_reg operations must be "
  		   "used either alone or in conjuction with DW_OP_piece."));
  
--- 384,392 ----
  	case DW_OP_reg29:
  	case DW_OP_reg30:
  	case DW_OP_reg31:
! 	  if (op_ptr != op_end 
! 	      && *op_ptr != DW_OP_piece
! 	      && *op_ptr != DW_OP_GNU_uninit)
  	    error (_("DWARF-2 expression error: DW_OP_reg operations must be "
  		   "used either alone or in conjuction with DW_OP_piece."));
  
*************** execute_stack_op (struct dwarf_expr_cont
*** 394,400 ****
  
  	case DW_OP_regx:
  	  op_ptr = read_uleb128 (op_ptr, op_end, &reg);
! 	  if (op_ptr != op_end && *op_ptr != DW_OP_piece)
  	    error (_("DWARF-2 expression error: DW_OP_reg operations must be "
  		   "used either alone or in conjuction with DW_OP_piece."));
  
--- 397,405 ----
  
  	case DW_OP_regx:
  	  op_ptr = read_uleb128 (op_ptr, op_end, &reg);
! 	  if (op_ptr != op_end 
! 	      && *op_ptr != DW_OP_piece
! 	      && *op_ptr != DW_OP_GNU_uninit)
  	    error (_("DWARF-2 expression error: DW_OP_reg operations must be "
  		   "used either alone or in conjuction with DW_OP_piece."));
  
*************** execute_stack_op (struct dwarf_expr_cont
*** 704,709 ****
--- 709,718 ----
            }
            goto no_push;
  
+ 	case DW_OP_GNU_uninit:
+ 	  ctx->var_status = 0;
+ 	  goto no_push;
+ 
  	default:
  	  error (_("Unhandled dwarf expression opcode 0x%x"), op);
  	}
Index: gdb/dwarf2expr.h
===================================================================
RCS file: /cvs/src/src/gdb/dwarf2expr.h,v
retrieving revision 1.9
diff -c -3 -p -r1.9 dwarf2expr.h
*** gdb/dwarf2expr.h	9 Jan 2007 17:58:50 -0000	1.9
--- gdb/dwarf2expr.h	1 May 2007 22:10:43 -0000
*************** struct dwarf_expr_context
*** 76,81 ****
--- 76,84 ----
       will be on the expression stack.  */
    int in_reg;
  
+   /* Initialization status of variable.  */
+   int var_status;
+ 
    /* An array of pieces.  PIECES points to its first element;
       NUM_PIECES is its length.
  
*************** gdb_byte *read_sleb128 (gdb_byte *buf, g
*** 135,138 ****
--- 138,144 ----
  CORE_ADDR dwarf2_read_address (gdb_byte *buf, gdb_byte *buf_end,
  			       int *bytes_read);
  
+ extern struct type *unsigned_address_type (void);
+ extern struct type *signed_address_type (void);
+ extern void add_piece (struct dwarf_expr_context *, int, CORE_ADDR, ULONGEST);
  #endif /* dwarf2expr.h */
Index: gdb/dwarf2loc.c
===================================================================
RCS file: /cvs/src/src/gdb/dwarf2loc.c,v
retrieving revision 1.39
diff -c -3 -p -r1.39 dwarf2loc.c
*** gdb/dwarf2loc.c	24 Jan 2007 22:04:48 -0000	1.39
--- gdb/dwarf2loc.c	1 May 2007 22:10:43 -0000
*************** dwarf2_evaluate_loc_desc (struct symbol 
*** 256,261 ****
--- 256,263 ----
        VALUE_ADDRESS (retval) = address;
      }
  
+   set_var_status (retval, ctx->var_status);
+ 
    free_dwarf_expr_context (ctx);
  
    return retval;
Index: gdb/dwarf2read.c
===================================================================
RCS file: /cvs/src/src/gdb/dwarf2read.c,v
retrieving revision 1.218
diff -c -3 -p -r1.218 dwarf2read.c
*** gdb/dwarf2read.c	18 Apr 2007 13:25:04 -0000	1.218
--- gdb/dwarf2read.c	1 May 2007 22:10:44 -0000
*************** dwarf_stack_op_name (unsigned op)
*** 8629,8634 ****
--- 8629,8636 ----
        return "DW_OP_bit_piece";
      case DW_OP_GNU_push_tls_address:
        return "DW_OP_GNU_push_tls_address";
+     case DW_OP_GNU_uninit:
+       return "DW_OP_GNU_uninit";
      /* HP extensions. */ 
      case DW_OP_HP_is_value:
        return "DW_OP_HP_is_value";
*************** decode_locdesc (struct dwarf_block *blk,
*** 9204,9209 ****
--- 9206,9214 ----
  	    dwarf2_complex_location_expr_complaint ();
            break;
  
+ 	case DW_OP_GNU_uninit:
+ 	  break;
+ 
  	default:
  	  complaint (&symfile_complaints, _("unsupported stack op: '%s'"),
  		     dwarf_stack_op_name (op));
Index: gdb/value.c
===================================================================
RCS file: /cvs/src/src/gdb/value.c,v
retrieving revision 1.41
diff -c -3 -p -r1.41 value.c
*** gdb/value.c	13 Apr 2007 14:17:46 -0000	1.41
--- gdb/value.c	1 May 2007 22:10:44 -0000
*************** struct value
*** 157,162 ****
--- 157,165 ----
       actually exist in the program.  */
    char optimized_out;
  
+   /* If value is a variable, is it initialized or not.  */
+   int var_status;
+ 
    /* Actual contents of the value.  For use of this value; setting it
       uses the stuff above.  Not valid if lazy is nonzero.  Target
       byte-order.  We force it to be aligned properly for any possible
*************** allocate_value (struct type *type)
*** 232,237 ****
--- 235,241 ----
    val->embedded_offset = 0;
    val->pointed_to_offset = 0;
    val->modifiable = 1;
+   val->var_status = 1;  /* Default to initialized.  */
    return val;
  }
  
*************** using_struct_return (struct type *value_
*** 1691,1696 ****
--- 1695,1717 ----
  	  != RETURN_VALUE_REGISTER_CONVENTION);
  }
  
+ /* Set the var_status field in a value struct.  */
+ 
+ void
+ set_var_status (struct value *val, int status)
+ {
+   val->var_status = status;
+ }
+ 
+ 
+ /* Return the var_status field in a value struct.  */
+ 
+ int
+ value_var_status (struct value *val)
+ {
+   return val->var_status;
+ }
+ 
  void
  _initialize_values (void)
  {
Index: gdb/value.h
===================================================================
RCS file: /cvs/src/src/gdb/value.h,v
retrieving revision 1.96
diff -c -3 -p -r1.96 value.h
*** gdb/value.h	9 Jan 2007 17:58:59 -0000	1.96
--- gdb/value.h	1 May 2007 22:10:44 -0000
*************** extern int value_contents_equal (struct 
*** 193,198 ****
--- 193,202 ----
  extern int value_optimized_out (struct value *value);
  extern void set_value_optimized_out (struct value *value, int val);
  
+ /* */
+ extern int value_var_status (struct value *);
+ extern void set_var_status (struct value *, int);
+ 
  /* While the following fields are per- VALUE .CONTENT .PIECE (i.e., a
     single value might have multiple LVALs), this hacked interface is
     limited to just the first PIECE.  Expect further change.  */
Index: include/elf/dwarf2.h
===================================================================
RCS file: /cvs/src/src/include/elf/dwarf2.h,v
retrieving revision 1.19
diff -c -3 -p -r1.19 dwarf2.h
*** include/elf/dwarf2.h	2 Mar 2006 00:54:27 -0000	1.19
--- include/elf/dwarf2.h	1 May 2007 22:10:44 -0000
*************** enum dwarf_location_atom
*** 540,545 ****
--- 540,546 ----
      DW_OP_bit_piece = 0x9d,
      /* GNU extensions.  */
      DW_OP_GNU_push_tls_address = 0xe0,
+     DW_OP_GNU_uninit     = 0xf0,
      /* HP extensions.  */
      DW_OP_HP_unknown     = 0xe0, /* Ouch, the same as GNU_push_tls_address.  */
      DW_OP_HP_is_value    = 0xe1,

^ permalink raw reply	[flat|nested] 25+ messages in thread

end of thread, other threads:[~2007-07-16 17:26 UTC | newest]

Thread overview: 25+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2007-05-02  0:03 [PATCH]: Track uninitialized variables Caroline Tice
2007-05-08 16:25 ` Ping! " Caroline Tice
2007-05-09  0:28 ` Ian Lance Taylor
2007-05-09 16:48   ` Caroline Tice
2007-05-09 17:40     ` Caroline Tice
2007-05-09 18:08     ` Ian Lance Taylor
2007-05-09 18:16       ` Daniel Jacobowitz
2007-05-10  3:29         ` Mark Mitchell
2007-05-11 19:13 ` [PATCH, revised]: " Caroline Tice
2007-05-18 19:48   ` Ping! " Caroline Tice
2007-05-25 21:26     ` Ping2! " Caroline Tice
2007-06-01 16:59       ` Ping3! " Caroline Tice
2007-06-01 17:13         ` Manuel López-Ibáñez
2007-06-01 17:24           ` Caroline Tice
2007-06-08 17:52             ` Ping 4! " Caroline Tice
2007-06-21 17:02               ` Ping 5! " Caroline Tice
2007-06-23 18:54                 ` Mark Mitchell
2007-07-12 17:24                 ` Ping 6! " Caroline Tice
2007-07-12 20:11                   ` Eric Christopher
2007-07-12 21:04                     ` Caroline Tice
2007-07-11 14:45   ` Ian Lance Taylor
2007-07-16 13:37     ` Richard Guenther
2007-07-16 16:40       ` Caroline Tice
2007-07-16 17:19         ` Caroline Tice
2007-07-16 17:33           ` H.J. Lu

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).