From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 45988 invoked by alias); 20 Jul 2018 23:50:49 -0000 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org Received: (qmail 45571 invoked by uid 89); 20 Jul 2018 23:50:48 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-26.9 required=5.0 tests=BAYES_00,GIT_PATCH_0,GIT_PATCH_1,GIT_PATCH_2,GIT_PATCH_3,KAM_SHORT,SPF_HELO_PASS,SPF_PASS,UNPARSEABLE_RELAY autolearn=ham version=3.3.2 spammy=fetched, tcc, demonstrates X-HELO: aserp2120.oracle.com Received: from aserp2120.oracle.com (HELO aserp2120.oracle.com) (141.146.126.78) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Fri, 20 Jul 2018 23:50:47 +0000 Received: from pps.filterd (aserp2120.oracle.com [127.0.0.1]) by aserp2120.oracle.com (8.16.0.22/8.16.0.22) with SMTP id w6KNoYKA121693 for ; Fri, 20 Jul 2018 23:50:45 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oracle.com; h=from : to : subject : date : message-id; s=corp-2018-07-02; bh=ausuXTj8WU3NJJgc7/VGtMFcUzUAPVU0VQ5PF4j8d4A=; b=zW7sigZZ/dH76YeR6aRJIcMnivDl09BwBSrAOq6du+iYEhaqVGQxj9UijX4GBBsi4f7M leiL/HBtxHuqZQ2otbB4xA29EJAvdUbzSzxVWZrDMw1SAbkoA7C1/8J1qI+IyfzpZXPI biVEt2M7p2098fa3TDXuGirm/3ntYLAAdUWVoriZj7Rd0SLJRf6aFSdtEmv2h+w21UHA TTie1ha3ukUIMaM/uJklFFlbmIUyHzVRUeO5dSGJru/KTN/uiWVSyqQnHYXrat9NWAK1 FNLvfqZ2fxxGuBDAv3LojYmVgq12+PSEhjsSUTbfgXjq2r8qO9UGWjoALgMZLVNiU8yd tw== Received: from userv0022.oracle.com (userv0022.oracle.com [156.151.31.74]) by aserp2120.oracle.com with ESMTP id 2k9yjgvytw-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK) for ; Fri, 20 Jul 2018 23:50:44 +0000 Received: from userv0122.oracle.com (userv0122.oracle.com [156.151.31.75]) by userv0022.oracle.com (8.14.4/8.14.4) with ESMTP id w6KNoinE011556 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK) for ; Fri, 20 Jul 2018 23:50:44 GMT Received: from abhmp0019.oracle.com (abhmp0019.oracle.com [141.146.116.25]) by userv0122.oracle.com (8.14.4/8.14.4) with ESMTP id w6KNohIt024240 for ; Fri, 20 Jul 2018 23:50:43 GMT Received: from wmpan.us.oracle.com (/10.147.27.127) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Fri, 20 Jul 2018 16:50:43 -0700 From: Weimin Pan To: gdb-patches@sourceware.org Subject: [PATCH PR gdb/16841] virtual inheritance via typedef cannot find base Date: Fri, 20 Jul 2018 23:50:00 -0000 Message-Id: <1532128565-75923-1-git-send-email-weimin.pan@oracle.com> X-SW-Source: 2018-07/txt/msg00629.txt.bz2 Finding data member in virtual base class This patch fixes the original problem - printing member in a virtual base, using various expressions, do not yield the same value. Simple test case below demonstrates the problem: % cat t.cc struct base { int i; }; typedef base tbase; struct derived: virtual tbase { void func() { } }; int main() { derived().func(); } % g++ -g t.cc % gdb a.out (gdb) break derived::func (gdb) run (gdb) p i $1 = 0 (gdb) p base::i $2 = 0 (gdb) p derived::base::i $3 = 0 (gdb) p derived::i $4 = 4196392 To fix the problem, the virtual-base offset, relative to its derived class, needs to be fetched, via baseclass_offset(), and used in calculating the address of its data member in value_struct_elt_for_reference(). Tested on amd64-linux-gnu. No regressions. --- gdb/ChangeLog | 6 +++++ gdb/testsuite/ChangeLog | 6 +++++ gdb/testsuite/gdb.cp/virtbase2.cc | 28 ++++++++++++++++++++++++++ gdb/testsuite/gdb.cp/virtbase2.exp | 38 ++++++++++++++++++++++++++++++++++++ gdb/valops.c | 17 +++++++++++++++- 5 files changed, 94 insertions(+), 1 deletions(-) create mode 100644 gdb/testsuite/gdb.cp/virtbase2.cc create mode 100644 gdb/testsuite/gdb.cp/virtbase2.exp diff --git a/gdb/ChangeLog b/gdb/ChangeLog index c47c111..1531ff1 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,9 @@ +2018-07-20 Weimin Pan + + PR gdb/16841 + * valops.c (value_struct_elt_for_reference): Calculate virtual + baseclass offset, relative to its derived class. + 2018-06-29 Pedro Alves * gdb/amd64-tdep.h (amd64_create_target_description): Add diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog index 93c849c..1577a54 100644 --- a/gdb/testsuite/ChangeLog +++ b/gdb/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2018-07-20 Weimin Pan + + PR gdb/16841 + * gdb.cp/virtbase2.cc: New file. + * gdb.cp/virtbase2.exp: New file. + 2018-06-29 Pedro Alves * gdb.threads/names.exp: Adjust expected "info threads" output. diff --git a/gdb/testsuite/gdb.cp/virtbase2.cc b/gdb/testsuite/gdb.cp/virtbase2.cc new file mode 100644 index 0000000..33753b3 --- /dev/null +++ b/gdb/testsuite/gdb.cp/virtbase2.cc @@ -0,0 +1,28 @@ +/* This test script is part of GDB, the GNU debugger. + + Copyright 2018 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +struct left { int i; }; +struct right {int j;}; +struct derived: virtual left, virtual right +{ + void func() { } +}; + +int main() +{ + derived().func(); +} diff --git a/gdb/testsuite/gdb.cp/virtbase2.exp b/gdb/testsuite/gdb.cp/virtbase2.exp new file mode 100644 index 0000000..01dd298 --- /dev/null +++ b/gdb/testsuite/gdb.cp/virtbase2.exp @@ -0,0 +1,38 @@ +# Copyright 2018 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +# Make sure printing virtual base class data member correctly (PR16841) + +if { [skip_cplus_tests] } { continue } + +standard_testfile .cc + +if {[prepare_for_testing "failed to prepare" $testfile $srcfile {debug c++}]} { + return -1 +} + +if {![runto_main]} then { + perror "couldn't run to main" + continue +} + +gdb_breakpoint "derived::func" +gdb_continue_to_breakpoint "continue to derived::func" +gdb_test "print j" " = 0" "j in base class right" +gdb_test "print i" " = 0" "i in base class left" +gdb_test "print derived::j" " = 0" "j in base class right" +gdb_test "print derived::i" " = 0" "i in base class left" +gdb_test "print derived::right::j" " = 0" "j in base class right" +gdb_test "print derived::left::i" " = 0" "i in base class left" diff --git a/gdb/valops.c b/gdb/valops.c index 9bdbf22..f0a8118 100644 --- a/gdb/valops.c +++ b/gdb/valops.c @@ -3385,6 +3385,7 @@ value_struct_elt_for_reference (struct type *domain, int offset, struct value *ptr; long mem_offset; struct type *type, *tmp; + int index; ptr = value_aggregate_elt (domain, name, NULL, 1, noside); type = check_typedef (value_type (ptr)); @@ -3392,7 +3393,21 @@ value_struct_elt_for_reference (struct type *domain, int offset, && TYPE_CODE (type) == TYPE_CODE_MEMBERPTR); tmp = lookup_pointer_type (TYPE_SELF_TYPE (type)); v = value_cast_pointers (tmp, v, 1); - mem_offset = value_as_long (ptr); + for (index = 0; index < TYPE_NFIELDS (domain); index++) + { + if (TYPE_FIELDS (domain)[index].type == curtype) + break; + } + if (index != TYPE_NFIELDS (domain) + && BASETYPE_VIA_VIRTUAL (domain, index)) + { + const gdb_byte *adr = value_contents_for_printing (ptr); + mem_offset = baseclass_offset (domain, index, adr, + value_offset (ptr), + value_as_long (v), ptr); + } + else + mem_offset = value_as_long (ptr); tmp = lookup_pointer_type (TYPE_TARGET_TYPE (type)); result = value_from_pointer (tmp, value_as_long (v) + mem_offset); -- 1.7.1