aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Tromey <tromey@redhat.com>2010-02-02 23:40:28 +0000
committerTom Tromey <tromey@redhat.com>2010-02-02 23:40:28 +0000
commit9c3c02fd158a5a0f8d64ec1c36078b1c9df0e6fc (patch)
treec1cdfef1022c3f73c6eabc8d781791261efb1d86
parentf23f4c5973c3ad96ecf812036c6b0ee5a17d726f (diff)
downloadgdb-9c3c02fd158a5a0f8d64ec1c36078b1c9df0e6fc.zip
gdb-9c3c02fd158a5a0f8d64ec1c36078b1c9df0e6fc.tar.gz
gdb-9c3c02fd158a5a0f8d64ec1c36078b1c9df0e6fc.tar.bz2
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.
-rw-r--r--gdb/ChangeLog5
-rw-r--r--gdb/testsuite/ChangeLog6
-rw-r--r--gdb/testsuite/gdb.cp/virtbase.cc32
-rw-r--r--gdb/testsuite/gdb.cp/virtbase.exp5
-rw-r--r--gdb/valops.c27
5 files changed, 73 insertions, 2 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index f743cd2..c81a7c6 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,5 +1,10 @@
2010-02-02 Tom Tromey <tromey@redhat.com>
+ * valops.c (value_cast_structs): Try downcasting using the RTTI
+ type.
+
+2010-02-02 Tom Tromey <tromey@redhat.com>
+
* 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 1a78e54..4e0ba4c 100644
--- a/gdb/testsuite/ChangeLog
+++ b/gdb/testsuite/ChangeLog
@@ -1,5 +1,11 @@
2010-02-02 Tom Tromey <tromey@redhat.com>
+ * gdb.cp/virtbase.exp: Add regression tests.
+ * gdb.cp/virtbase.cc (RHA, RHB, RHC): New classes.
+ (main): Instantiate RHC.
+
+2010-02-02 Tom Tromey <tromey@redhat.com>
+
* 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 ae0a2c7..fed5927 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 6a37626..5a0de97 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" " = {<C> = {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 4c5927d..cee10fb 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)