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]

FYI: fix PR c++/13342


I'm checking this in.

PR 13342 concerns printing "*this" in a derived class' destructor when
the base class has already rewritten the vtable to make it look like the
object is an instance of the base.  In this scenario, it seems
friendliest to continue to pretend that the object is an instance of the
derived class -- following the static type of *this, not the dynamic
type.

Built and regtested on x86-64 F15.  New test case included.

Tom

2011-11-09  Tom Tromey  <tromey@redhat.com>

	PR c++/13342:
	* valops.c (value_full_object): Return early if real type is
	smaller than the enclosing type.

2011-11-09  Tom Tromey  <tromey@redhat.com>

	* gdb.cp/destrprint.exp: New file.
	* gdb.cp/destrprint.cc: New file.

diff --git a/gdb/testsuite/gdb.cp/destrprint.cc b/gdb/testsuite/gdb.cp/destrprint.cc
new file mode 100644
index 0000000..0def8e4
--- /dev/null
+++ b/gdb/testsuite/gdb.cp/destrprint.cc
@@ -0,0 +1,36 @@
+
+class Base
+{
+public:
+  int x, y;
+
+  Base() : x(0), y(1)
+  {
+  }
+
+  virtual ~Base()
+  {
+    // Break here.
+  }
+};
+
+class Derived : public Base
+{
+public:
+  int z;
+
+  Derived() : Base(), z(23)
+  {
+  }
+
+  ~Derived()
+  {
+  }
+};
+
+int main()
+{
+  Derived d;
+
+  return 0;
+}
diff --git a/gdb/testsuite/gdb.cp/destrprint.exp b/gdb/testsuite/gdb.cp/destrprint.exp
new file mode 100644
index 0000000..e2dc437
--- /dev/null
+++ b/gdb/testsuite/gdb.cp/destrprint.exp
@@ -0,0 +1,42 @@
+# Copyright 2011 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/>.
+
+set testfile destrprint
+set srcfile ${testfile}.cc
+if [prepare_for_testing $testfile.exp $testfile $srcfile {debug c++}] {
+    return -1
+}
+
+if ![runto_main] {
+    untested destrprint
+    return -1
+}
+
+gdb_breakpoint [gdb_get_line_number "Break here"]
+gdb_continue_to_breakpoint "Break here"
+
+gdb_test "up" "#1 .*~Derived.*" "go up to ~Derived"
+
+foreach setting {on off} {
+    gdb_test_no_output "set print object $setting"
+
+    # Here we are in ~Derived.  At this point, Derived has been
+    # destroyed, so *this looks like a Base.  But, the static type of
+    # *this is still Derived, and printing it should show us all the
+    # fields, regardless of what "set print object" says.
+    gdb_test "print *this" \
+	" = .*, z = 23." \
+	"print *this with print object = $setting"
+}
diff --git a/gdb/valops.c b/gdb/valops.c
index cb39677..29d1fbd 100644
--- a/gdb/valops.c
+++ b/gdb/valops.c
@@ -3581,6 +3581,13 @@ value_full_object (struct value *argp,
   if (!real_type || real_type == value_enclosing_type (argp))
     return argp;
 
+  /* In a destructor we might see a real type that is a superclass of
+     the object's type.  In this case it is better to leave the object
+     as-is.  */
+  if (full
+      && TYPE_LENGTH (real_type) < TYPE_LENGTH (value_enclosing_type (argp)))
+    return argp;
+
   /* If we have the full object, but for some reason the enclosing
      type is wrong, set it.  */
   /* pai: FIXME -- sounds iffy */


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