From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 2126) id 678313858406; Mon, 18 Apr 2022 15:45:54 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 678313858406 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable From: Tom Tromey To: gdb-cvs@sourceware.org Subject: [binutils-gdb] Fix C++ cast of derived class to base class X-Act-Checkin: binutils-gdb X-Git-Author: Tom Tromey X-Git-Refname: refs/heads/master X-Git-Oldrev: c67f4e53895da91ce7f2eff3544e9de02280f740 X-Git-Newrev: 2390419d1cb72882110538e01e5586372df19657 Message-Id: <20220418154554.678313858406@sourceware.org> Date: Mon, 18 Apr 2022 15:45:54 +0000 (GMT) X-BeenThere: gdb-cvs@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gdb-cvs mailing list List-Unsubscribe: , List-Archive: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 18 Apr 2022 15:45:54 -0000 https://sourceware.org/git/gitweb.cgi?p=3Dbinutils-gdb.git;h=3D2390419d1cb7= 2882110538e01e5586372df19657 commit 2390419d1cb72882110538e01e5586372df19657 Author: Tom Tromey Date: Sat Apr 2 09:54:40 2022 -0600 Fix C++ cast of derived class to base class =20 PR c++/28907 points out that casting from a derived class to a base class fails in some situations. The problem turned out to be a missing use of value_embedded_offset. One peculiarity here is that, if you managed to construct a pointer-to-derived with an embedded offset of 0, the cast would work -- for example, one of the two new tests here passes without the patch. =20 This embedded offset stuff is an endless source of bugs. I wonder if it's possible to get rid of it somehow. =20 Regression tested on x86-64 Fedora 34. =20 Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=3D28907 Diff: --- gdb/testsuite/gdb.cp/casts.cc | 20 ++++++++++++++++++++ gdb/testsuite/gdb.cp/casts.exp | 6 ++++++ gdb/valops.c | 2 +- 3 files changed, 27 insertions(+), 1 deletion(-) diff --git a/gdb/testsuite/gdb.cp/casts.cc b/gdb/testsuite/gdb.cp/casts.cc index 543db896d3d..ea4dc961793 100644 --- a/gdb/testsuite/gdb.cp/casts.cc +++ b/gdb/testsuite/gdb.cp/casts.cc @@ -34,6 +34,20 @@ struct DoublyDerived : public VirtuallyDerived, { }; =20 +struct Left +{ + int left; +}; + +struct Right +{ + int right; +}; + +struct LeftRight : public Left, public Right +{ +}; + int main (int argc, char **argv) { @@ -48,5 +62,11 @@ main (int argc, char **argv) Alpha *ad =3D &derived; Alpha *add =3D &doublyderived; =20 + LeftRight gd; + gd.left =3D 23; + gd.right =3D 27; + unsigned long long gd_value =3D (unsigned long long) &gd; + unsigned long long r_value =3D (unsigned long long) (Right *) &gd; + return 0; /* breakpoint spot: casts.exp: 1 */ } diff --git a/gdb/testsuite/gdb.cp/casts.exp b/gdb/testsuite/gdb.cp/casts.exp index cda870f77a4..5d0a52401a8 100644 --- a/gdb/testsuite/gdb.cp/casts.exp +++ b/gdb/testsuite/gdb.cp/casts.exp @@ -174,6 +174,12 @@ gdb_test "print dynamic_cast (add)" \ " =3D \\(Gamma \\*\\) $nonzero_hex" \ "dynamic_cast to sibling" =20 +gdb_test "print (unsigned long long) &gd =3D=3D gd_value" " =3D true" +gdb_test "print (unsigned long long) (LeftRight *) (Right *) &gd =3D=3D gd= _value" \ + " =3D true" +gdb_test "print (unsigned long long) (LeftRight *) (Right *) r_value =3D= =3D gd_value" \ + " =3D true" + if {[prepare_for_testing "failed to prepare" ${testfile}03 $srcfile2 \ {debug c++ additional_flags=3D-std=3Dc++03}]} { return -1 diff --git a/gdb/valops.c b/gdb/valops.c index 42a1213b0c5..e84cabf8f14 100644 --- a/gdb/valops.c +++ b/gdb/valops.c @@ -274,7 +274,7 @@ value_cast_structs (struct type *type, struct value *v2) if (v) { /* Downcasting is possible (t1 is superclass of v2). */ - CORE_ADDR addr2 =3D value_address (v2); + CORE_ADDR addr2 =3D value_address (v2) + value_embedded_offset (v2); =20 addr2 -=3D value_address (v) + value_embedded_offset (v); return value_at (type, addr2);