This is the mail archive of the
gdb-patches@sourceware.org
mailing list for the GDB project.
FYI: fix casting bug
- From: Tom Tromey <tromey at redhat dot com>
- To: gdb-patches at sourceware dot org
- Date: Tue, 02 Feb 2010 16:40:09 -0700
- Subject: FYI: fix casting bug
- Reply-to: tromey at redhat dot com
I'm checking this in.
This fixes a bug reported in Red Hat bugzilla:
https://bugzilla.redhat.com/show_bug.cgi?id=560741
The bug is that downcasting gives the wrong result in some cases. Not
only were the pointers offset incorrectly, but this also manifested as
an inability to find a field in one case.
I traced this down to some code in value_cast_structs that was commented
as not working in the presence of virtual base classes.
This patch fixes the bug by first trying to use the RTTI type when
downcasting.
Built and regtested on x86-64 (compile farm).
New test case included.
Tom
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>
* gdb.cp/virtbase.exp: Add regression tests.
* gdb.cp/virtbase.cc (RHA, RHB, RHC): New classes.
(main): Instantiate RHC.
Index: valops.c
===================================================================
RCS file: /cvs/src/src/gdb/valops.c,v
retrieving revision 1.234
diff -u -r1.234 valops.c
--- valops.c 2 Feb 2010 16:45:16 -0000 1.234
+++ valops.c 2 Feb 2010 23:31:33 -0000
@@ -250,10 +250,33 @@
/* 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)
Index: testsuite/gdb.cp/virtbase.cc
===================================================================
RCS file: /cvs/src/src/gdb/testsuite/gdb.cp/virtbase.cc,v
retrieving revision 1.1
diff -u -r1.1 virtbase.cc
--- testsuite/gdb.cp/virtbase.cc 2 Feb 2010 16:45:17 -0000 1.1
+++ testsuite/gdb.cp/virtbase.cc 2 Feb 2010 23:31:34 -0000
@@ -46,12 +46,44 @@
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
}
Index: testsuite/gdb.cp/virtbase.exp
===================================================================
RCS file: /cvs/src/src/gdb/testsuite/gdb.cp/virtbase.exp,v
retrieving revision 1.1
diff -u -r1.1 virtbase.exp
--- testsuite/gdb.cp/virtbase.exp 2 Feb 2010 16:45:17 -0000 1.1
+++ testsuite/gdb.cp/virtbase.exp 2 Feb 2010 23:31:34 -0000
@@ -55,3 +55,8 @@
# 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"