From cda41f694fa280413c7ac9c6522d149e20ea2b23 Mon Sep 17 00:00:00 2001 From: tromey Date: Tue, 2 Feb 2010 23:40:26 +0000 Subject: [PATCH] gdb * valops.c (value_cast_structs): Try downcasting using the RTTI type. gdb/testsuite * gdb.cp/virtbase.exp: Add regression tests. * gdb.cp/virtbase.cc (RHA, RHB, RHC): New classes. (main): Instantiate RHC. --- gdb/ChangeLog | 5 +++++ gdb/testsuite/ChangeLog | 6 ++++++ gdb/testsuite/gdb.cp/virtbase.cc | 32 ++++++++++++++++++++++++++++++++ gdb/testsuite/gdb.cp/virtbase.exp | 5 +++++ gdb/valops.c | 27 +++++++++++++++++++++++++-- 5 files changed, 73 insertions(+), 2 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index f743cd2cf2..c81a7c6cdf 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,5 +1,10 @@ 2010-02-02 Tom Tromey + * valops.c (value_cast_structs): Try downcasting using the RTTI + type. + +2010-02-02 Tom Tromey + * gnu-v2-abi.c: Don't include gnu-v2-abi.h. (gnuv2_baseclass_offset): Now static. * Makefile.in (HFILES_NO_SRCDIR): Remove gnu-v2-abi.h. diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog index 1a78e549bf..4e0ba4ccea 100644 --- a/gdb/testsuite/ChangeLog +++ b/gdb/testsuite/ChangeLog @@ -1,5 +1,11 @@ 2010-02-02 Tom Tromey + * gdb.cp/virtbase.exp: Add regression tests. + * gdb.cp/virtbase.cc (RHA, RHB, RHC): New classes. + (main): Instantiate RHC. + +2010-02-02 Tom Tromey + * gdb.dwarf2/member-ptr-forwardref.exp: Update expected result for type-printing change. diff --git a/gdb/testsuite/gdb.cp/virtbase.cc b/gdb/testsuite/gdb.cp/virtbase.cc index ae0a2c719a..fed5927db5 100644 --- a/gdb/testsuite/gdb.cp/virtbase.cc +++ b/gdb/testsuite/gdb.cp/virtbase.cc @@ -46,12 +46,44 @@ struct D:virtual C{}; class E:B,D{}; +// These classes are for another regression test, from +// https://bugzilla.redhat.com/show_bug.cgi?id=560741 + +class RHA +{ +public: + RHA() : mA(0xaaaaaaaa) {} + virtual void a() = 0; + int mA; +}; + +class RHB +{ +public: + RHB() : mB(0xbbbbbbbb) {} + virtual void b() = 0; + int mB; +}; + +class RHC : public RHA, + public RHB +{ +public: + RHC() : RHA(), RHB() {} + virtual void a() {} + virtual void b() {} +}; + + + + int main() { ph::Derived tst; tst.get_y(); tst.get_z(); E *e = new E; + RHB *b = new RHC(); return 0; // breakpoint 3 } diff --git a/gdb/testsuite/gdb.cp/virtbase.exp b/gdb/testsuite/gdb.cp/virtbase.exp index 6a37626bc0..5a0de97337 100644 --- a/gdb/testsuite/gdb.cp/virtbase.exp +++ b/gdb/testsuite/gdb.cp/virtbase.exp @@ -55,3 +55,8 @@ gdb_continue_to_breakpoint "third breakpoint" # In PR 9629, we failed to print v correctly here. gdb_test "print *(D *) e" " = { = {v = 11}, _vptr.D = $hex}" + +# A regression test reported to Red Hat bugzilla, see: +# https://bugzilla.redhat.com/show_bug.cgi?id=560741 +gdb_test "set print object on" "" +gdb_test "print/x b->mA" " = 0xaaaaaaaa" diff --git a/gdb/valops.c b/gdb/valops.c index 4c5927d7c5..cee10fb922 100644 --- a/gdb/valops.c +++ b/gdb/valops.c @@ -250,10 +250,33 @@ value_cast_structs (struct type *type, struct value *v2) /* Downcasting: look in the type of the target to see if it contains the type of the source as a superclass. If so, we'll need to - offset the pointer rather than just change its type. - FIXME: This fails silently with virtual inheritance. */ + offset the pointer rather than just change its type. */ if (TYPE_NAME (t2) != NULL) { + /* Try downcasting using the run-time type of the value. */ + int full, top, using_enc; + struct type *real_type; + + real_type = value_rtti_type (v2, &full, &top, &using_enc); + if (real_type) + { + v = value_full_object (v2, real_type, full, top, using_enc); + v = value_at_lazy (real_type, value_address (v)); + + /* We might be trying to cast to the outermost enclosing + type, in which case search_struct_field won't work. */ + if (TYPE_NAME (real_type) != NULL + && !strcmp (TYPE_NAME (real_type), TYPE_NAME (t1))) + return v; + + v = search_struct_field (type_name_no_tag (t2), v, 0, real_type, 1); + if (v) + return v; + } + + /* Try downcasting using information from the destination type + T2. This wouldn't work properly for classes with virtual + bases, but those were handled above. */ v = search_struct_field (type_name_no_tag (t2), value_zero (t1, not_lval), 0, t1, 1); if (v) -- 2.11.0