mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2025-01-12 12:16:04 +08:00
8776cfe971
Given the following variable... BT : Bounded := New_Bounded (Low => 1, High => 3); ... where type Bounded is defined as a simple unconstrained array: type Bounded is array (Integer range <>) of Integer; Creating a varobj for that variable, and immediately asking for varobj updates, GDB says that our varobj changed types! (gdb) -var-create bt * bt ^done,name="bt",numchild="3",value="[3]",type="<ref> array (1 .. 3) of integer",has_more="0" (gdb) -var-update 1 * ^done,changelist=[{name="bt",value="[3]",in_scope="true",type_changed="true",new_type="<ref> array (1 .. 3) of integer",new_num_children="3",has_more="0"}] The expected output for the -var-update command is, in this case: (gdb) -var-update 1 * ^done,changelist=[] The problem occurs because the ada-varobj module does not handle references, and while the references gets stripped when the varobj gets created, it doesn't when computing varobj updates. More specifically, when creating the varobj, varobj_create creates a new value which is a reference to a TYPE_CODE_ARRAY. It then calls install_new_value which calls coerce_ref with the following comment: /* We are not interested in the address of references, and given that in C++ a reference is not rebindable, it cannot meaningfully change. So, get hold of the real value. */ if (value) value = coerce_ref (value); This leaves the varobj's type component still a ref, while the varobj's value is now our array, without the ref. This explains why the "value" field in the varobj indicates an array with 3 elements "[3]" while the "type" field shows a ref to an array. Generally speaking, most users have said that showing the ref was a useful piece of information, so this patch is not touching this part. Next, when the user issues the -var-update request, varobj_update calls value_of_root to compute the varobj's new value as well as determine whether the value's type has changed or not. What happens in a nutshell is that it calls value_of_root_1 (which re-evaluates the expression and returns the corresponding new value), finds that the new value is not NULL, and thus asks whether it has mutated: else if (varobj_value_has_mutated (var, value, value_type (value))) This then indirectly delegates the determination to the language-specific callback, which fails, because it does not handle references. This patch fixes the issue by adjusting varobj_value_has_mutated to expect references, and strip them when seen. This allows the various language-specific implementations to remain unaware of references. gdb/ChangeLog: * varobj.c (varobj_value_has_mutated): If NEW_VALUE is a reference, strip the reference layer before calling the lang_ops value_has_mutated callback. gdb/testsuite/ChangeLog: * gdb.ada/mi_dyn_arr: New testcase. |
||
---|---|---|
.. | ||
aliased_array | ||
array_bounds | ||
array_char_idx | ||
array_return | ||
array_subscript_addr | ||
arraydim | ||
arrayidx | ||
arrayparam | ||
arrayptr | ||
atomic_enum | ||
bad-task-bp-keyword | ||
bp_enum_homonym | ||
bp_on_var | ||
bp_range_type | ||
bp_reset | ||
call_pn | ||
catch_ex | ||
char_enum | ||
char_param | ||
complete | ||
cond_lang | ||
dot_all | ||
dyn_loc | ||
enum_idx_packed | ||
exec_changed | ||
expr_delims | ||
exprs | ||
fixed_cmp | ||
fixed_points | ||
float_param | ||
formatted_ref | ||
frame_args | ||
fullname_bp | ||
fun_addr | ||
fun_in_declare | ||
funcall_param | ||
homonym | ||
info_exc | ||
info_locals_renaming | ||
int_deref | ||
interface | ||
iwide | ||
lang_switch | ||
mi_catch_ex | ||
mi_dyn_arr | ||
mi_ex_cond | ||
mi_exc_info | ||
mi_interface | ||
mi_task_arg | ||
mi_task_info | ||
mod_from_name | ||
nested | ||
null_array | ||
null_record | ||
O2_float_param | ||
operator_bp | ||
optim_drec | ||
packed_array | ||
packed_tagged | ||
pckd_arr_ren | ||
pp-rec-component | ||
print_chars | ||
ptr_typedef | ||
ptype_field | ||
ptype_tagged_param | ||
py_range | ||
rdv_wait | ||
rec_return | ||
ref_param | ||
ref_tick_size | ||
same_enum | ||
set_pckd_arr_elt | ||
set_wstr | ||
small_reg_param | ||
start | ||
str_ref_cmp | ||
sym_print_name | ||
taft_type | ||
tagged | ||
tagged_access | ||
tagged_not_init | ||
task_bp | ||
tasks | ||
tick_last_segv | ||
tick_length_array_enum_idx | ||
type_coercion | ||
unc_arr_ptr_in_var_rec | ||
uninitialized_vars | ||
variant_record_packed_array | ||
watch_arg | ||
whatis_array_val | ||
widewide | ||
win_fu_syms | ||
aliased_array.exp | ||
array_bounds.exp | ||
array_char_idx.exp | ||
array_return.exp | ||
array_subscript_addr.exp | ||
arraydim.exp | ||
arrayidx.exp | ||
arrayparam.exp | ||
arrayptr.exp | ||
assign_1.exp | ||
atomic_enum.exp | ||
bad-task-bp-keyword.exp | ||
boolean_expr.exp | ||
bp_enum_homonym.exp | ||
bp_on_var.exp | ||
bp_range_type.exp | ||
bp_reset.exp | ||
call_pn.exp | ||
catch_ex.exp | ||
char_enum.exp | ||
char_param.exp | ||
complete.exp | ||
cond_lang.exp | ||
dot_all.exp | ||
dyn_loc.exp | ||
enum_idx_packed.exp | ||
exec_changed.exp | ||
expr_delims.exp | ||
exprs.exp | ||
fixed_cmp.exp | ||
fixed_points.exp | ||
float_param.exp | ||
formatted_ref.exp | ||
frame_args.exp | ||
fullname_bp.exp | ||
fun_addr.exp | ||
fun_in_declare.exp | ||
funcall_param.exp | ||
gnat_ada.gpr | ||
homonym.exp | ||
info_exc.exp | ||
info_locals_renaming.exp | ||
info_types.c | ||
info_types.exp | ||
int_deref.exp | ||
interface.exp | ||
iwide.exp | ||
lang_switch.exp | ||
Makefile.in | ||
mi_catch_ex.exp | ||
mi_dyn_arr.exp | ||
mi_ex_cond.exp | ||
mi_exc_info.exp | ||
mi_interface.exp | ||
mi_task_arg.exp | ||
mi_task_info.exp | ||
mod_from_name.exp | ||
nested.exp | ||
null_array.exp | ||
null_record.exp | ||
O2_float_param.exp | ||
operator_bp.exp | ||
optim_drec.exp | ||
packed_array.exp | ||
packed_tagged.exp | ||
pckd_arr_ren.exp | ||
pp-rec-component.exp | ||
pp-rec-component.py | ||
print_chars.exp | ||
print_pc.exp | ||
ptr_typedef.exp | ||
ptype_arith_binop.exp | ||
ptype_field.exp | ||
ptype_tagged_param.exp | ||
py_range.exp | ||
rdv_wait.exp | ||
rec_return.exp | ||
ref_param.exp | ||
ref_tick_size.exp | ||
same_enum.exp | ||
set_pckd_arr_elt.exp | ||
set_wstr.exp | ||
small_reg_param.exp | ||
start.exp | ||
str_ref_cmp.exp | ||
sym_print_name.exp | ||
taft_type.exp | ||
tagged_access.exp | ||
tagged_not_init.exp | ||
tagged.exp | ||
task_bp.exp | ||
tasks.exp | ||
tick_last_segv.exp | ||
tick_length_array_enum_idx.exp | ||
type_coercion.exp | ||
unc_arr_ptr_in_var_rec.exp | ||
uninitialized_vars.exp | ||
variant_record_packed_array.exp | ||
watch_arg.exp | ||
whatis_array_val.exp | ||
widewide.exp | ||
win_fu_syms.exp |