[PATCH v3 PR gdb/16841] virtual inheritance via typedef cannot find base

Weimin Pan weimin.pan@oracle.com
Fri Sep 14 21:49:00 GMT 2018



On 9/14/2018 11:26 AM, Simon Marchi wrote:
> On 2018-09-12 09:01 PM, Weimin Pan wrote:
>> 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, add function get_baseclass_offset() which searches
>> recursively for the base class along the class hierarchy. If the base
>> is virtual, it uses "vptr" in virtual class object, which indexes to
>> its derived class's vtable, to get and returns the baseclass offset.
>> If the base is non-virtual, it returns the accumulated offset of its
>> parent classes. The offset is then added to the address of the class
>> object to access its member in value_struct_elt_for_reference().
>>
>> Tested on amd64-linux-gnu. No regressions.
> I have some last nits about the test, but I'd like Tom to give the final approval,
> since he clearly knows this stuff better than I do.  If everything is fine with him,
> then there is no need to post a new version, just fix it up and push.
>
>> ---
>>   gdb/ChangeLog                      |    7 +++
>>   gdb/testsuite/ChangeLog            |    6 +++
>>   gdb/testsuite/gdb.cp/virtbase2.cc  |   46 +++++++++++++++++++++
>>   gdb/testsuite/gdb.cp/virtbase2.exp |   78 ++++++++++++++++++++++++++++++++++++
>>   gdb/valops.c                       |   63 ++++++++++++++++++++++++++++-
>>   5 files changed, 199 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..9cbd8ca 100644
>> --- a/gdb/ChangeLog
>> +++ b/gdb/ChangeLog
>> @@ -1,3 +1,10 @@
>> +2018-09-12  Weimin Pan  <weimin.pan@oracle.com>
>> +
>> +	PR gdb/16841
>> +	* valops.c (get_virtual_base_offset): New function.
>> +	(value_struct_elt_for_reference): Use it to get virtual base offset
>> +	and add it in calculating class member address.
>> +
>>   2018-06-29  Pedro Alves  <palves@redhat.com>
>>   
>>   	* gdb/amd64-tdep.h (amd64_create_target_description): Add
>> diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog
>> index 93c849c..46f16d7 100644
>> --- a/gdb/testsuite/ChangeLog
>> +++ b/gdb/testsuite/ChangeLog
>> @@ -1,3 +1,9 @@
>> +2018-09-12  Weimin Pan  <weimin.pan@oracle.com>
>> +
>> +	PR gdb/16841
>> +	* gdb.cp/virtbase2.cc: New file.
>> +	* gdb.cp/virtbase2.exp: New file.
>> +
>>   2018-06-29  Pedro Alves  <palves@redhat.com>
>>   
>>   	* 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..60c95c4
>> --- /dev/null
>> +++ b/gdb/testsuite/gdb.cp/virtbase2.cc
>> @@ -0,0 +1,46 @@
>> +/* This testcase 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 <http://www.gnu.org/licenses/>.  */
>> +
>> +struct superbase {
>> +  int x;
>> +  superbase () : x(22) {}
>> +};
>> +
>> +struct base : superbase {
>> +  int i;
>> +  double d;
>> +  base() : i(55), d(6.6) {}
>> +};
>> +
>> +typedef base tbase;
>> +struct derived: virtual tbase
>> +{
>> +  void func_d() { }
>> +};
>> +
>> +struct foo: virtual derived
>> +{
>> +  void func_f() { }
>> +};
>> +
>> +int main()
>> +{
>> +  derived().func_d();
>> +  foo().func_f();
>> +}
>> +
>> +
> Remove the trailing empty lines here, git shows a warning when applying the patch:
>
> Applying: virtual inheritance via typedef cannot find base
> Using index info to reconstruct a base tree...
> M       gdb/ChangeLog
> M       gdb/testsuite/ChangeLog
> M       gdb/valops.c
> .git/rebase-apply/patch:90: new blank line at EOF.
> +
> warning: 1 line adds whitespace errors.
>
>> diff --git a/gdb/testsuite/gdb.cp/virtbase2.exp b/gdb/testsuite/gdb.cp/virtbase2.exp
>> new file mode 100644
>> index 0000000..4c14419
>> --- /dev/null
>> +++ b/gdb/testsuite/gdb.cp/virtbase2.exp
>> @@ -0,0 +1,78 @@
>> +# 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 <http://www.gnu.org/licenses/>.
>> +
>> +# Make sure printing virtual base class data member works 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
>> +}
>> +> +proc make_scope_list { scopes } {
> Please add a comment for this proc, since it's not very intuitive.  Here's
> a suggestion:
>
> # From a list of nested scopes, generate all possible ways of accessing something
> # in those scopes.  For example, with the argument {foo bar baz}, this proc will
> # return:
> #  - {} (empty string)
> #  - baz::
> #  - bar::
> #  - bar::baz::
> #  - foo::
> #  - foo::baz::
> #  - foo::bar::
> #  - foo::bar::baz::
>
> Thanks!
>
> Simon

Hi Simon,

OK, Thanks for your comments. I've incorporated them into the patch.

Weimin



More information about the Gdb-patches mailing list