From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 2111) id 103AA385828C; Wed, 20 Mar 2024 17:02:53 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 103AA385828C DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1710954173; bh=ErNO05cITvgP7v+IctKT8wPKbvPbLoxJQy26I6BpTYE=; h=From:To:Subject:Date:From; b=wz57vCv976mKEXYcO7kHJ+h5rd65rouUSltAIEMYNStipXq6kyzdIkVXbo9BITYGG JlsTHQ6GjNtyCre6joY0eud0hBPkRJOdrF4CDCi9ptv3umYcItkAMbSYHsnx7HCjQk s0oGG15F0jpbZfhkedscClP/S8Afl9p1VayJ4OEk= Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable From: Hannes Domani To: gdb-cvs@sourceware.org Subject: [binutils-gdb] Fix reinterpret_cast for classes with multiple inheritance X-Act-Checkin: binutils-gdb X-Git-Author: Hannes Domani X-Git-Refname: refs/heads/master X-Git-Oldrev: e8f6050cfb990452fcfc685bc9ccbae79113fa36 X-Git-Newrev: 23cdd9431ad424b092c65419d47ef4601168a1c9 Message-Id: <20240320170253.103AA385828C@sourceware.org> Date: Wed, 20 Mar 2024 17:02:53 +0000 (GMT) List-Id: https://sourceware.org/git/gitweb.cgi?p=3Dbinutils-gdb.git;h=3D23cdd9431ad4= 24b092c65419d47ef4601168a1c9 commit 23cdd9431ad424b092c65419d47ef4601168a1c9 Author: Hannes Domani Date: Wed Mar 20 18:02:06 2024 +0100 Fix reinterpret_cast for classes with multiple inheritance =20 Currently a reinterpret_cast may change the pointer value if multiple inheritance is involved: ``` (gdb) p r $1 =3D (Right *) 0x22f75c (gdb) p reinterpret_cast(r) $2 =3D (LeftRight *) 0x22f758 ``` =20 It's because value_cast is called in this case, which automatically does up- and downcasting. =20 Fixed by simply using the target pointer type in a copy of the original value: ``` (gdb) p r $1 =3D (Right *) 0x3bf87c (gdb) p reinterpret_cast(r) $2 =3D (LeftRight *) 0x3bf87c ``` =20 Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=3D18861 Approved-By: Tom Tromey Diff: --- gdb/testsuite/gdb.cp/casts.cc | 8 ++++++++ gdb/testsuite/gdb.cp/casts.exp | 10 ++++++++++ gdb/valops.c | 11 +++++++++-- 3 files changed, 27 insertions(+), 2 deletions(-) diff --git a/gdb/testsuite/gdb.cp/casts.cc b/gdb/testsuite/gdb.cp/casts.cc index 5c7f9dc8a1c..eacd8bc0a44 100644 --- a/gdb/testsuite/gdb.cp/casts.cc +++ b/gdb/testsuite/gdb.cp/casts.cc @@ -88,6 +88,14 @@ main (int argc, char **argv) unsigned long long gd_value =3D (unsigned long long) (std::uintptr_t)&gd; unsigned long long r_value =3D (unsigned long long) (Right *) &gd; =20 + LeftRight *lr =3D &gd; + Left *l =3D lr; + Right *r =3D lr; + LeftRight *lr_l =3D reinterpret_cast(l); + LeftRight *lr_r =3D reinterpret_cast(r); + Left *l_lr =3D reinterpret_cast(lr); + Right *r_lr =3D reinterpret_cast(lr); + VirtualLeftRight *vlr =3D new VirtualLeftRight (); VirtualLeft *vl =3D vlr; VirtualRight *vr =3D vlr; diff --git a/gdb/testsuite/gdb.cp/casts.exp b/gdb/testsuite/gdb.cp/casts.exp index 7bfc93b1a02..ca82ab084b9 100644 --- a/gdb/testsuite/gdb.cp/casts.exp +++ b/gdb/testsuite/gdb.cp/casts.exp @@ -180,6 +180,16 @@ gdb_test "print (unsigned long long) (LeftRight *) (Ri= ght *) &gd =3D=3D gd_value" \ gdb_test "print (unsigned long long) (LeftRight *) (Right *) r_value =3D= =3D gd_value" \ " =3D true" =20 +gdb_test "print reinterpret_cast(l) =3D=3D lr_l" " =3D true" +gdb_test "print reinterpret_cast(r) =3D=3D lr_r" " =3D true" +gdb_test "print reinterpret_cast(lr) =3D=3D l_lr" " =3D true" +gdb_test "print reinterpret_cast(lr) =3D=3D r_lr" " =3D true" + +gdb_test "print &reinterpret_cast(*l) =3D=3D lr_l" " =3D true" +gdb_test "print &reinterpret_cast(*r) =3D=3D lr_r" " =3D true" +gdb_test "print &reinterpret_cast(*lr) =3D=3D l_lr" " =3D true" +gdb_test "print &reinterpret_cast(*lr) =3D=3D r_lr" " =3D true" + gdb_test "print dynamic_cast (vlr) =3D=3D vlr" " =3D t= rue" gdb_test "print dynamic_cast (vl) =3D=3D vlr" " =3D tr= ue" gdb_test "print dynamic_cast (vr) =3D=3D vlr" " =3D tr= ue" diff --git a/gdb/valops.c b/gdb/valops.c index be907440a59..1a943f0fc78 100644 --- a/gdb/valops.c +++ b/gdb/valops.c @@ -694,10 +694,17 @@ value_reinterpret_cast (struct type *type, struct val= ue *arg) || (dest_code =3D=3D TYPE_CODE_MEMBERPTR && arg_code =3D=3D TYPE_COD= E_INT) || (dest_code =3D=3D TYPE_CODE_INT && arg_code =3D=3D TYPE_CODE_MEMB= ERPTR) || (dest_code =3D=3D arg_code - && (dest_code =3D=3D TYPE_CODE_PTR - || dest_code =3D=3D TYPE_CODE_METHODPTR + && (dest_code =3D=3D TYPE_CODE_METHODPTR || dest_code =3D=3D TYPE_CODE_MEMBERPTR))) result =3D value_cast (dest_type, arg); + else if (dest_code =3D=3D TYPE_CODE_PTR && arg_code =3D=3D TYPE_CODE_PTR) + { + /* Don't do any up- or downcasting. */ + result =3D arg->copy (); + result->deprecated_set_type (dest_type); + result->set_enclosing_type (dest_type); + result->set_pointed_to_offset (0); + } else error (_("Invalid reinterpret_cast"));