forked from Imagelibrary/binutils-gdb
[PR gdb/19893] Fix handling of synthetic C++ references
https://sourceware.org/bugzilla/show_bug.cgi?id=19893 I've traced the main source of the problem to pieced_value_funcs.coerce_ref not being implemented. Since gdb always assumes references are implemented as pointers, this causes it to think that it's dealing with a NULL pointer, thus breaking any operations involving synthetic references. What I did here was implementing pieced_value_funcs.coerce_ref using some of the synthetic pointer handling code from indirect_pieced_value, as Pedro suggested. I also made a few adjustments to the reference printing code so that it correctly shows either the address of the referenced value or (if it's non-addressable) the "<synthetic pointer>" string. I also wrote some unit tests based on Dwarf::assemble; these took a while to make because in most cases I needed a synthetic reference to a physical variable. Additionally, I started working on a unit test for classes that have a vtable, but ran into a few issues so that'll probably go in a future patch. One thing that should definitely be fixed is that proc function_range (called for MACRO_AT_func) will always try to compile/link using gcc with the default options instead of g++, thus breaking C++ compilations that require e.g. libstdc++. gdb/ChangeLog: * dwarf2loc.c (coerce_pieced_ref, indirect_synthetic_pointer, fetch_const_value_from_synthetic_pointer): New functions. (indirect_pieced_value): Move lower half to indirect_synthetic_pointer. (pieced_value_funcs): Implement coerce_ref. * valops.c (value_addr): Call coerce_ref for synthetic references. * valprint.c (valprint_check_validity): Return true for synthetic references. Also, don't show "<synthetic pointer>" if they reference addressable values. (generic_val_print_ref): Handle synthetic references. Also move some code to print_ref_address. (print_ref_address, get_value_addr_contents): New functions. gdb/testsuite/ChangeLog: * gdb.dwarf2/implref.exp: Rename to... * gdb.dwarf2/implref-const.exp: ...this. Also add more test statements. * gdb.dwarf2/implref-array.c: New file. * gdb.dwarf2/implref-array.exp: Likewise. * gdb.dwarf2/implref-global.c: Likewise. * gdb.dwarf2/implref-global.exp: Likewise. * gdb.dwarf2/implref-struct.c: Likewise. * gdb.dwarf2/implref-struct.exp: Likewise.
This commit is contained in:
34
gdb/valops.c
34
gdb/valops.c
@@ -1465,22 +1465,28 @@ value_addr (struct value *arg1)
|
||||
|
||||
if (TYPE_CODE (type) == TYPE_CODE_REF)
|
||||
{
|
||||
/* Copy the value, but change the type from (T&) to (T*). We
|
||||
keep the same location information, which is efficient, and
|
||||
allows &(&X) to get the location containing the reference.
|
||||
Do the same to its enclosing type for consistency. */
|
||||
struct type *type_ptr
|
||||
= lookup_pointer_type (TYPE_TARGET_TYPE (type));
|
||||
struct type *enclosing_type
|
||||
= check_typedef (value_enclosing_type (arg1));
|
||||
struct type *enclosing_type_ptr
|
||||
= lookup_pointer_type (TYPE_TARGET_TYPE (enclosing_type));
|
||||
if (value_bits_synthetic_pointer (arg1, value_embedded_offset (arg1),
|
||||
TARGET_CHAR_BIT * TYPE_LENGTH (type)))
|
||||
arg1 = coerce_ref (arg1);
|
||||
else
|
||||
{
|
||||
/* Copy the value, but change the type from (T&) to (T*). We
|
||||
keep the same location information, which is efficient, and
|
||||
allows &(&X) to get the location containing the reference.
|
||||
Do the same to its enclosing type for consistency. */
|
||||
struct type *type_ptr
|
||||
= lookup_pointer_type (TYPE_TARGET_TYPE (type));
|
||||
struct type *enclosing_type
|
||||
= check_typedef (value_enclosing_type (arg1));
|
||||
struct type *enclosing_type_ptr
|
||||
= lookup_pointer_type (TYPE_TARGET_TYPE (enclosing_type));
|
||||
|
||||
arg2 = value_copy (arg1);
|
||||
deprecated_set_value_type (arg2, type_ptr);
|
||||
set_value_enclosing_type (arg2, enclosing_type_ptr);
|
||||
arg2 = value_copy (arg1);
|
||||
deprecated_set_value_type (arg2, type_ptr);
|
||||
set_value_enclosing_type (arg2, enclosing_type_ptr);
|
||||
|
||||
return arg2;
|
||||
return arg2;
|
||||
}
|
||||
}
|
||||
if (TYPE_CODE (type) == TYPE_CODE_FUNC)
|
||||
return value_coerce_function (arg1);
|
||||
|
||||
Reference in New Issue
Block a user