2002-07-05 Daniel Jacobowitz <drow@mvista.com>
authorDaniel Jacobowitz <drow@false.org>
Fri, 5 Jul 2002 16:23:13 +0000 (16:23 +0000)
committerDaniel Jacobowitz <drow@false.org>
Fri, 5 Jul 2002 16:23:13 +0000 (16:23 +0000)
        Fix PR gdb/595, gdb/602
        * gnu-v3-abi.c (gnuv3_baseclass_offset): Remove unused variables.
        Don't call value_cast, just read the vtable pointer; update comments
        to match.

gdb/ChangeLog
gdb/gnu-v3-abi.c

index cddf6595be9198b7bcc97e4930d8d26c753c2355..f1b366bb28fb71969d110896195a1ddd35133704 100644 (file)
@@ -1,3 +1,10 @@
+2002-07-05  Daniel Jacobowitz  <drow@mvista.com>
+
+       Fix PR gdb/595, gdb/602
+       * gnu-v3-abi.c (gnuv3_baseclass_offset): Remove unused variables.
+       Don't call value_cast, just read the vtable pointer; update comments
+       to match.
+
 2002-07-05  Grace Sainsbury  <graces@redhat.com>
 
        * config/mcore/tm-mcore.h: Remove file.
index e86af89d55727a56cceee944d61cf7956fb02698..a9ab4941cfdd59bf42c70484ebb845547b0e7e79 100644 (file)
@@ -374,15 +374,11 @@ gnuv3_baseclass_offset (struct type *type, int index, char *valaddr,
 {
   struct type *vtable_type = gdbarch_data (current_gdbarch,
                                           vtable_type_gdbarch_data);
-  struct type *basetype = TYPE_BASECLASS (type, index);
-  struct value *full_object, *vbase_object, *orig_object;
-  struct value *vtable, *orig_typeinfo, *orig_base_info;
-  struct type *orig_type, *vbasetype;
+  struct value *vtable;
+  struct type *vbasetype;
   struct value *offset_val, *vbase_array;
   CORE_ADDR vtable_address;
   long int cur_base_offset, base_offset;
-  int to_top;
-  int baseclasses, i;
 
   /* If it isn't a virtual base, this is easy.  The offset is in the
      type definition.  */
@@ -405,15 +401,22 @@ gnuv3_baseclass_offset (struct type *type, int index, char *valaddr,
     / ((int) TYPE_LENGTH (builtin_type_void_data_ptr));
 
   /* We're now looking for the cur_base_offset'th entry (negative index)
-     in the vcall_and_vbase_offsets array.  */
-
-  orig_object = value_at_lazy (type, address, NULL);
-  vbasetype = TYPE_VPTR_BASETYPE (VALUE_TYPE (orig_object));
-  vbase_object = value_cast (vbasetype, orig_object);
-
-  vtable_address
-    = value_as_address (value_field (vbase_object,
-                                    TYPE_VPTR_FIELDNO (vbasetype)));
+     in the vcall_and_vbase_offsets array.  We used to cast the object to
+     its TYPE_VPTR_BASETYPE, and reference the vtable as TYPE_VPTR_FIELDNO;
+     however, that cast can not be done without calling baseclass_offset again
+     if the TYPE_VPTR_BASETYPE is a virtual base class, as described in the
+     v3 C++ ABI Section 2.4.I.2.b.  Fortunately the ABI guarantees that the
+     vtable pointer will be located at the beginning of the object, so we can
+     bypass the casting.  Verify that the TYPE_VPTR_FIELDNO is in fact at the
+     start of whichever baseclass it resides in, as a sanity measure.  */
+
+  vbasetype = TYPE_VPTR_BASETYPE (type);
+  if (TYPE_FIELD_BITPOS (vbasetype, TYPE_VPTR_FIELDNO (vbasetype)) != 0)
+    error ("Illegal vptr offset in class %s",
+          TYPE_NAME (vbasetype) ? TYPE_NAME (vbasetype) : "<unknown>");
+
+  vtable_address = value_as_address (value_at_lazy (builtin_type_void_data_ptr,
+                                                   address, NULL));
   vtable = value_at_lazy (vtable_type,
                           vtable_address - vtable_address_point_offset (),
                           NULL);