Add ability to report when a variable's value is uninitialized,
based on information provided by the compiler. Also add new DWARF OP, DW_OP_GNU_uninit, for this purpose.
This commit is contained in:
parent
a7c569c8f0
commit
42be36b328
@ -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.
|
||||
|
@ -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 */
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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.
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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));
|
||||
|
20
gdb/value.c
20
gdb/value.c
@ -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)
|
||||
{
|
||||
|
@ -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,
|
||||
|
Loading…
Reference in New Issue
Block a user