This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

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


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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]