This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
C++ patch for class.c, fix debug info problem found by gdb testsuite
- To: gcc-patches at gcc dot gnu dot org
- Subject: C++ patch for class.c, fix debug info problem found by gdb testsuite
- From: Jim Wilson <wilson at cygnus dot com>
- Date: Mon, 31 Jan 2000 15:41:03 -0800
This patch fixes a case where the C++ front end emits incorrect debug info
for vtables. This was broken by the C++ front end rewrite.
The testcase comes from the gdb testsuite, gdb.c++/inherit.exp. A pared down
testcase is this:
class vA {
public:
int va;
int vx;
};
class vB : public virtual vA {
public:
int vb;
int vx;
};
main()
{
}
Compile this with -g for a stabs target (like x86-linux), load it into gdb,
type the command "ptype vB" and notice that the vtable line is wrong:
vA *_vb.FOO;
The problem is that the type for the vtable is itself instead of the inherited
type. This confuses gdb into printing "FOO", which is what it prints when it
sees incorrect C++ debug info.
With the following patch, I get the correct result
vA *_vb.vA;
The problem happened when the vtable support was rewritten. Older versions of
the compiler have in class.c:
DECL_ASSEMBLER_NAME (vfield) = get_identifier (VFIELD_BASE);
...
DECL_FIELD_CONTEXT (vfield) = t;
DECL_CLASS_CONTEXT (vfield) = t;
DECL_FCONTEXT (vfield) = t;
and in tree.c:
DECL_ASSEMBLER_NAME (decl) = get_identifier (VTABLE_BASE);
...
DECL_FIELD_CONTEXT (decl) = rec;
DECL_CLASS_CONTEXT (decl) = rec;
DECL_FCONTEXT (decl) = basetype;
But the current compiler uses common code
DECL_FIELD_CONTEXT (field) = class_type;
DECL_CLASS_CONTEXT (field) = class_type;
DECL_FCONTEXT (field) = class_type;
and thus DECL_FCONTEXT is set wrong for VTABLE_BASE. This is trivial to fix
by adding another parameter to build_vtbl_or_vbase_field.
Mon Jan 31 15:35:29 2000 Jim Wilson <wilson@cygnus.com>
* class.c (build_vtbl_or_vbase_field): New parameter fcontext.
Store it in DECL_FCONTEXT.
(build_vbase_pointer_fields, create_vtable_ptr): Fix callers.
Index: class.c
===================================================================
RCS file: /cvs/cvsfiles/devo/gcc/cp/class.c,v
retrieving revision 1.364
diff -p -r1.364 class.c
*** class.c 2000/01/11 15:00:44 1.364
--- class.c 2000/01/31 23:35:13
*************** static void check_field_decls PROTO((tre
*** 126,132 ****
static int avoid_overlap PROTO((tree, tree, int *));
static tree build_base_fields PROTO((tree, int *));
static tree build_vbase_pointer_fields PROTO((tree, int *));
! static tree build_vtbl_or_vbase_field PROTO((tree, tree, tree, tree, int *));
static void check_methods PROTO((tree));
static void remove_zero_width_bit_fields PROTO((tree));
static void check_bases PROTO((tree, int *, int *, int *));
--- 127,134 ----
static int avoid_overlap PROTO((tree, tree, int *));
static tree build_base_fields PROTO((tree, int *));
static tree build_vbase_pointer_fields PROTO((tree, int *));
! static tree build_vtbl_or_vbase_field PROTO((tree, tree, tree, tree, tree,
! int *));
static void check_methods PROTO((tree));
static void remove_zero_width_bit_fields PROTO((tree));
static void check_bases PROTO((tree, int *, int *, int *));
*************** check_field_decls (t, access_decls, empt
*** 3610,3626 ****
/* Return a FIELD_DECL for a pointer-to-virtual-table or
pointer-to-virtual-base. The NAME, ASSEMBLER_NAME, and TYPE of the
field are as indicated. The CLASS_TYPE in which this field occurs
! is also indicated. *EMPTY_P is set to a non-zero value by this
function to indicate that a class containing this field is
non-empty. */
static tree
! build_vtbl_or_vbase_field (name, assembler_name, type, class_type,
empty_p)
tree name;
tree assembler_name;
tree type;
tree class_type;
int *empty_p;
{
tree field;
--- 3613,3631 ----
/* Return a FIELD_DECL for a pointer-to-virtual-table or
pointer-to-virtual-base. The NAME, ASSEMBLER_NAME, and TYPE of the
field are as indicated. The CLASS_TYPE in which this field occurs
! is also indicated. FCONTEXT is the type that is needed for the debug
! info output routines. *EMPTY_P is set to a non-zero value by this
function to indicate that a class containing this field is
non-empty. */
static tree
! build_vtbl_or_vbase_field (name, assembler_name, type, class_type, fcontext,
empty_p)
tree name;
tree assembler_name;
tree type;
tree class_type;
+ tree fcontext;
int *empty_p;
{
tree field;
*************** build_vtbl_or_vbase_field (name, assembl
*** 3635,3641 ****
DECL_ARTIFICIAL (field) = 1;
DECL_FIELD_CONTEXT (field) = class_type;
DECL_CLASS_CONTEXT (field) = class_type;
! DECL_FCONTEXT (field) = class_type;
DECL_SAVED_INSNS (field) = 0;
DECL_FIELD_SIZE (field) = 0;
DECL_ALIGN (field) = TYPE_ALIGN (type);
--- 3640,3646 ----
DECL_ARTIFICIAL (field) = 1;
DECL_FIELD_CONTEXT (field) = class_type;
DECL_CLASS_CONTEXT (field) = class_type;
! DECL_FCONTEXT (field) = fcontext;
DECL_SAVED_INSNS (field) = 0;
DECL_FIELD_SIZE (field) = 0;
DECL_ALIGN (field) = TYPE_ALIGN (type);
*************** build_vbase_pointer_fields (rec, empty_p
*** 3700,3705 ****
--- 3705,3711 ----
get_identifier (VTABLE_BASE),
build_pointer_type (basetype),
rec,
+ basetype,
empty_p);
BINFO_VPTR_FIELD (base_binfo) = decl;
TREE_CHAIN (decl) = vbase_decls;
*************** create_vtable_ptr (t, empty_p, has_virtu
*** 4041,4046 ****
--- 4047,4053 ----
get_identifier (VFIELD_BASE),
vtbl_ptr_type_node,
t,
+ t,
empty_p);
/* Add the new field to the list of fields in this class. */