Add ability to report when a variable's value is uninitialized,
authorCaroline Tice <cmtice@google.com>
Fri, 18 May 2007 19:42:42 +0000 (19:42 +0000)
committerCaroline Tice <cmtice@google.com>
Fri, 18 May 2007 19:42:42 +0000 (19:42 +0000)
based on information provided by the compiler.  Also add new
DWARF OP, DW_OP_GNU_uninit, for this purpose.

gdb/ChangeLog
gdb/c-valprint.c
gdb/dwarf2expr.c
gdb/dwarf2expr.h
gdb/dwarf2loc.c
gdb/dwarf2read.c
gdb/value.c
include/elf/dwarf2.h

index 1f6a1e048a68cc5c3837c8e32878c25c14b8afe7..4852d1f09d6443eb7bc3301bc14ff74cf89c51c0 100644 (file)
@@ -1,3 +1,26 @@
+2007-05-18  Caroline Tice  <ctice@apple.com>
+
+       * c-valprint.c (c_value_print):  If the initialized field of the
+       value struct is 0, print out "[uninitialized]" before the value.
+       * dwarf2expr.c (execute_stack_op): Initialize ctx->initialized 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->initialized appropriately. Verify no location op follows
+       DW_OP_GNU_uninit.
+       * dwarf2expr.h (struct dwarf_expr_context): New field, initialized.
+       * dwarf2loc.c (dwarf2_evaluate_loc_desc): Add call to 
+       set_value_initialized.
+       * 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, initialized.
+       (allocate_value): Initialize new field.
+       (set_value_initialized): New function.
+       (value_initialized): New function.
+       * value.h (value_initialized): New extern declaration.
+       (set_value_initialized): Likewise.
+       * include/elf/dwarf2.h: (enum dwarf_location_atom): Add new DW_OP, 
+       DW_OP_GNU_uninit.
+       
 2007-05-18  Caroline Tice  <ctice@apple.com>
 
        * MAINTAINERS (Write After Approval): Add self.
index 2ec90585b85a853c1fec00cf5fc46807ceb71eba..ad5e4d16edac22a5ac577d2ddcb3d94c0baa281b 100644 (file)
@@ -556,6 +556,9 @@ c_value_print (struct value *val, struct ui_file *stream, int format,
        }
     }
 
+  if (!value_initialized (val))
+    fprintf_filtered (stream, " [uninitialized] ");
+
   if (objectprint && (TYPE_CODE (type) == TYPE_CODE_CLASS))
     {
       /* Attempt to determine real type of object */
index ad259f4a40d836887c277751105c5bf121913d97..92d9e16e359d337fcafee0d38ca1c703722a1ee9 100644 (file)
@@ -284,6 +284,7 @@ execute_stack_op (struct dwarf_expr_context *ctx,
                  gdb_byte *op_ptr, gdb_byte *op_end)
 {
   ctx->in_reg = 0;
+  ctx->initialized = 1;  /* Default is initialized.  */
 
   while (op_ptr < op_end)
     {
@@ -410,7 +411,9 @@ execute_stack_op (struct dwarf_expr_context *ctx,
        case DW_OP_reg29:
        case DW_OP_reg30:
        case DW_OP_reg31:
-         if (op_ptr != op_end && *op_ptr != DW_OP_piece)
+         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."));
 
@@ -731,6 +734,14 @@ execute_stack_op (struct dwarf_expr_context *ctx,
           }
           goto no_push;
 
+       case DW_OP_GNU_uninit:
+         if (op_ptr != op_end)
+           error (_("DWARF-2 expression error: DW_OP_GNU_unint must always "
+                  "be the very last op."));
+
+         ctx->initialized = 0;
+         goto no_push;
+
        default:
          error (_("Unhandled dwarf expression opcode 0x%x"), op);
        }
index ef85275e3c9c995ef9c05d139d737d98fdec3064..c1adf9ad687b3e3e880cd1e7abb8478e1ac128da 100644 (file)
@@ -76,6 +76,10 @@ struct dwarf_expr_context
      will be on the expression stack.  */
   int in_reg;
 
+  /* Initialization status of variable: Non-zero if variable has been
+     initialized; zero otherwise.  */
+  int initialized;
+
   /* An array of pieces.  PIECES points to its first element;
      NUM_PIECES is its length.
 
index a179566cfa58d232950d3a294e77cede1b4c21bc..1e6ff67b5ba2f351c86ea98c915efde94bbc1950 100644 (file)
@@ -256,6 +256,8 @@ dwarf2_evaluate_loc_desc (struct symbol *var, struct frame_info *frame,
       VALUE_ADDRESS (retval) = address;
     }
 
+  set_value_initialized (retval, ctx->initialized);
+
   free_dwarf_expr_context (ctx);
 
   return retval;
index 3b3f263ffd3107240f7e26969d9e6a06c8654968..2cb455e03dd39124dceebf335d0fdfa6bb710b3f 100644 (file)
@@ -8656,6 +8656,8 @@ dwarf_stack_op_name (unsigned op)
       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";
@@ -9231,6 +9233,9 @@ decode_locdesc (struct dwarf_block *blk, struct dwarf2_cu *cu)
            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 d31a5f45560cdc04647a8a88e2efc89f022d1dd4..26ba2a44898b7bc54d4166543ac390ee077030b8 100644 (file)
@@ -157,6 +157,9 @@ struct value
      actually exist in the program.  */
   char optimized_out;
 
+  /* If value is a variable, is it initialized or not.  */
+  int initialized;
+
   /* 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
@@ -232,6 +235,7 @@ allocate_value (struct type *type)
   val->embedded_offset = 0;
   val->pointed_to_offset = 0;
   val->modifiable = 1;
+  val->initialized = 1;  /* Default to initialized.  */
   return val;
 }
 
@@ -1699,6 +1703,22 @@ using_struct_return (struct type *value_type, int gcc_p)
          != RETURN_VALUE_REGISTER_CONVENTION);
 }
 
+/* Set the initialized field in a value struct.  */
+
+void
+set_value_initialized (struct value *val, int status)
+{
+  val->initialized = status;
+}
+
+/* Return the initialized field in a value struct.  */
+
+int
+value_initialized (struct value *val)
+{
+  return val->initialized;
+}
+
 void
 _initialize_values (void)
 {
index 264952af1394e50fb9fd8db54a921837a4813796..2683f5131c740bcb0acf4f3e80bcbc5bebef71c1 100644 (file)
@@ -540,6 +540,7 @@ enum dwarf_location_atom
     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,