aboutsummaryrefslogtreecommitdiff
path: root/gdb/testsuite
diff options
context:
space:
mode:
authorHannes Domani <ssbssa@yahoo.de>2022-03-29 20:05:06 +0200
committerHannes Domani <ssbssa@yahoo.de>2023-12-11 15:50:00 +0100
commit0238b543f3c294fc8512021a40b708e8ddc72bb2 (patch)
tree794db4b3b773c6de97035ffbd7b6c2fcfa9d47af /gdb/testsuite
parent22b78fad28d54bad1d0aee2fe0acf5f3f40648f6 (diff)
downloadgdb-0238b543f3c294fc8512021a40b708e8ddc72bb2.zip
gdb-0238b543f3c294fc8512021a40b708e8ddc72bb2.tar.gz
gdb-0238b543f3c294fc8512021a40b708e8ddc72bb2.tar.bz2
Fix dynamic_cast
PR29011 notes that dynamic_cast does not work correctly if classes with virtual methods are involved, some of the results wrongly point into the vtable of the derived class: ``` (gdb) p vlr $1 = (VirtualLeftRight *) 0x162240 (gdb) p vl $2 = (VirtualLeft *) 0x162240 (gdb) p vr $3 = (VirtualRight *) 0x162250 (gdb) p dynamic_cast<VirtualLeftRight*>(vlr) $4 = (VirtualLeftRight *) 0x13fab89b0 <vtable for VirtualLeftRight+16> (gdb) p dynamic_cast<VirtualLeftRight*>(vl) $5 = (VirtualLeftRight *) 0x13fab89b0 <vtable for VirtualLeftRight+16> (gdb) p dynamic_cast<VirtualLeftRight*>(vr) $6 = (VirtualLeftRight *) 0x13fab89b0 <vtable for VirtualLeftRight+16> (gdb) p dynamic_cast<VirtualLeft*>(vlr) $7 = (VirtualLeft *) 0x162240 (gdb) p dynamic_cast<VirtualLeft*>(vl) $8 = (VirtualLeft *) 0x13fab89b0 <vtable for VirtualLeftRight+16> (gdb) p dynamic_cast<VirtualLeft*>(vr) $9 = (VirtualLeft *) 0x162240 (gdb) p dynamic_cast<VirtualRight*>(vlr) $10 = (VirtualRight *) 0x162250 (gdb) p dynamic_cast<VirtualRight*>(vl) $11 = (VirtualRight *) 0x162250 (gdb) p dynamic_cast<VirtualRight*>(vr) $12 = (VirtualRight *) 0x13fab89b0 <vtable for VirtualLeftRight+16> ``` For the cases where the dynamic_cast type is the same as the original type, it used the ARG value for the result, which in case of pointer types was already the dereferenced value. And the TEM value at the value address was created with the pointer/reference type, not the actual class type. With these fixed, the dynamic_cast results make more sense: ``` (gdb) p vlr $1 = (VirtualLeftRight *) 0x692240 (gdb) p vl $2 = (VirtualLeft *) 0x692240 (gdb) p vr $3 = (VirtualRight *) 0x692250 (gdb) p dynamic_cast<VirtualLeftRight*>(vlr) $4 = (VirtualLeftRight *) 0x692240 (gdb) p dynamic_cast<VirtualLeftRight*>(vl) $5 = (VirtualLeftRight *) 0x692240 (gdb) p dynamic_cast<VirtualLeftRight*>(vr) $6 = (VirtualLeftRight *) 0x692240 (gdb) p dynamic_cast<VirtualLeft*>(vlr) $7 = (VirtualLeft *) 0x692240 (gdb) p dynamic_cast<VirtualLeft*>(vl) $8 = (VirtualLeft *) 0x692240 (gdb) p dynamic_cast<VirtualLeft*>(vr) $9 = (VirtualLeft *) 0x692240 (gdb) p dynamic_cast<VirtualRight*>(vlr) $10 = (VirtualRight *) 0x692250 (gdb) p dynamic_cast<VirtualRight*>(vl) $11 = (VirtualRight *) 0x692250 (gdb) p dynamic_cast<VirtualRight*>(vr) $12 = (VirtualRight *) 0x692250 ``` Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=29011 Approved-By: Tom Tromey <tom@tromey.com>
Diffstat (limited to 'gdb/testsuite')
-rw-r--r--gdb/testsuite/gdb.cp/casts.cc22
-rw-r--r--gdb/testsuite/gdb.cp/casts.exp20
2 files changed, 42 insertions, 0 deletions
diff --git a/gdb/testsuite/gdb.cp/casts.cc b/gdb/testsuite/gdb.cp/casts.cc
index f64d13c..5c7f9dc 100644
--- a/gdb/testsuite/gdb.cp/casts.cc
+++ b/gdb/testsuite/gdb.cp/casts.cc
@@ -50,6 +50,24 @@ struct LeftRight : public Left, public Right
{
};
+struct VirtualLeft
+{
+ virtual ~VirtualLeft () {}
+
+ int left;
+};
+
+struct VirtualRight
+{
+ virtual ~VirtualRight () {}
+
+ int right;
+};
+
+struct VirtualLeftRight : public VirtualLeft, public VirtualRight
+{
+};
+
int
main (int argc, char **argv)
{
@@ -70,5 +88,9 @@ main (int argc, char **argv)
unsigned long long gd_value = (unsigned long long) (std::uintptr_t)&gd;
unsigned long long r_value = (unsigned long long) (Right *) &gd;
+ VirtualLeftRight *vlr = new VirtualLeftRight ();
+ VirtualLeft *vl = vlr;
+ VirtualRight *vr = vlr;
+
return 0; /* breakpoint spot: casts.exp: 1 */
}
diff --git a/gdb/testsuite/gdb.cp/casts.exp b/gdb/testsuite/gdb.cp/casts.exp
index 41bb125..a0c7382 100644
--- a/gdb/testsuite/gdb.cp/casts.exp
+++ b/gdb/testsuite/gdb.cp/casts.exp
@@ -180,6 +180,26 @@ gdb_test "print (unsigned long long) (LeftRight *) (Right *) &gd == gd_value" \
gdb_test "print (unsigned long long) (LeftRight *) (Right *) r_value == gd_value" \
" = true"
+gdb_test "print dynamic_cast<VirtualLeftRight *> (vlr) == vlr" " = true"
+gdb_test "print dynamic_cast<VirtualLeftRight *> (vl) == vlr" " = true"
+gdb_test "print dynamic_cast<VirtualLeftRight *> (vr) == vlr" " = true"
+gdb_test "print dynamic_cast<VirtualLeft *> (vlr) == vl" " = true"
+gdb_test "print dynamic_cast<VirtualLeft *> (vl) == vl" " = true"
+gdb_test "print dynamic_cast<VirtualLeft *> (vr) == vl" " = true"
+gdb_test "print dynamic_cast<VirtualRight *> (vlr) == vr" " = true"
+gdb_test "print dynamic_cast<VirtualRight *> (vl) == vr" " = true"
+gdb_test "print dynamic_cast<VirtualRight *> (vr) == vr" " = true"
+
+gdb_test "print &dynamic_cast<VirtualLeftRight &> (*vlr) == vlr" " = true"
+gdb_test "print &dynamic_cast<VirtualLeftRight &> (*vl) == vlr" " = true"
+gdb_test "print &dynamic_cast<VirtualLeftRight &> (*vr) == vlr" " = true"
+gdb_test "print &dynamic_cast<VirtualLeft &> (*vlr) == vl" " = true"
+gdb_test "print &dynamic_cast<VirtualLeft &> (*vl) == vl" " = true"
+gdb_test "print &dynamic_cast<VirtualLeft &> (*vr) == vl" " = true"
+gdb_test "print &dynamic_cast<VirtualRight &> (*vlr) == vr" " = true"
+gdb_test "print &dynamic_cast<VirtualRight &> (*vl) == vr" " = true"
+gdb_test "print &dynamic_cast<VirtualRight &> (*vr) == vr" " = true"
+
if {[prepare_for_testing "failed to prepare" ${testfile}03 $srcfile2 \
{debug c++ additional_flags=-std=c++03}]} {
return -1