This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
Re: g++ bug on Alpha Linux
- To: green at redhat dot com, green at cygnus dot com
- Subject: Re: g++ bug on Alpha Linux
- From: Mark Mitchell <mark at codesourcery dot com>
- Date: Sun, 30 Jan 2000 20:04:34 -0800
- Cc: gcc-bugs at gcc dot gnu dot org
- Organization: CodeSourcery, LLC
- References: <200001302338.PAA01414@decepticon.cygnus.com>
>>>>> "Anthony" == Anthony Green <green@cygnus.com> writes:
Anthony> I just bootstrapped a g++ from the latest cvs sources on
Anthony> an Alpha Linux box. When I compile the following code
Anthony> derived from libgcj with `-c -fno-rtti' I get:
Oops -- my fault. Fixed thusly.
--
Mark Mitchell mark@codesourcery.com
CodeSourcery, LLC http://www.codesourcery.com
2000-01-30 Mark Mitchell <mark@codesourcery.com>
* cp/class.c (build_vtable): Rename to build_primary_vtable.
(prepare_fresh_vtable): Rename to build_secondary_vtable.
(make_new_vtable): New function.
(modify_vtable_entry): Handle generation of new vtables correctly.
(modify_one_vtable): Remove unused parameter.
(dfs_fixup_vtable_deltas): Likewise.
(override_one_vtable): Use build_secondary_vtable.
(finish_struct_1): Use build_primary_vtable and
build_secondary_vtable.
Index: testsuite/g++.old-deja/g++.other/virtual7.C
===================================================================
RCS file: virtual7.C
diff -N virtual7.C
*** /dev/null Tue May 5 13:32:27 1998
--- virtual7.C Sun Jan 30 20:00:14 2000
***************
*** 0 ****
--- 1,17 ----
+ // Build don't link:
+ // Special g++ Options: -fno-rtti
+ // Origin: Anthony Green <green@cygnus.com>
+
+ class _JvObjectPrefix
+ {
+ protected:
+ virtual void finalize (void) = 0;
+ };
+
+ class Object : public _JvObjectPrefix
+ {
+ protected:
+ virtual void finalize (void);
+ };
+
+ Object x;
Index: cp/class.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/class.c,v
retrieving revision 1.249
diff -c -p -r1.249 class.c
*** class.c 2000/01/29 15:47:14 1.249
--- class.c 2000/01/31 04:00:18
*************** static tree get_vtable_name PARAMS ((tre
*** 80,91 ****
static tree get_derived_offset PARAMS ((tree, tree));
static tree get_basefndecls PARAMS ((tree, tree));
static void set_rtti_entry PARAMS ((tree, tree, tree));
! static void build_vtable PARAMS ((tree, tree));
! static void prepare_fresh_vtable PARAMS ((tree, tree));
static tree dfs_fixup_vtable_deltas PARAMS ((tree, void *));
static tree dfs_finish_vtbls PARAMS ((tree, void *));
static void finish_vtbls PARAMS ((tree));
! static void modify_vtable_entry PARAMS ((tree, tree, tree, tree));
static void add_virtual_function PARAMS ((tree *, tree *, int *, tree, tree));
static tree delete_duplicate_fields_1 PARAMS ((tree, tree));
static void delete_duplicate_fields PARAMS ((tree));
--- 80,91 ----
static tree get_derived_offset PARAMS ((tree, tree));
static tree get_basefndecls PARAMS ((tree, tree));
static void set_rtti_entry PARAMS ((tree, tree, tree));
! static int build_primary_vtable PARAMS ((tree, tree));
! static int build_secondary_vtable PARAMS ((tree, tree));
static tree dfs_fixup_vtable_deltas PARAMS ((tree, void *));
static tree dfs_finish_vtbls PARAMS ((tree, void *));
static void finish_vtbls PARAMS ((tree));
! static void modify_vtable_entry PARAMS ((tree, tree, tree, tree *));
static void add_virtual_function PARAMS ((tree *, tree *, int *, tree, tree));
static tree delete_duplicate_fields_1 PARAMS ((tree, tree));
static void delete_duplicate_fields PARAMS ((tree));
*************** static tree dfs_count_virtuals PARAMS ((
*** 151,156 ****
--- 151,157 ----
static void start_vtable PARAMS ((tree, int *));
static void layout_vtable_decl PARAMS ((tree, int));
static int num_vfun_entries PARAMS ((tree));
+ static int make_new_vtable PARAMS ((tree, tree));
/* Variables shared between class.c and call.c. */
*************** get_vtable_name (type)
*** 903,909 ****
int i;
for (i = 0; ptr[i] == OPERATOR_TYPENAME_FORMAT[i]; i++) ;
#if 0
! /* We don't take off the numbers; prepare_fresh_vtable uses the
DECL_ASSEMBLER_NAME for the type, which includes the number
in `3foo'. If we were to pull them off here, we'd end up with
something like `_vt.foo.3bar', instead of a uniform definition. */
--- 904,910 ----
int i;
for (i = 0; ptr[i] == OPERATOR_TYPENAME_FORMAT[i]; i++) ;
#if 0
! /* We don't take off the numbers; build_secondary_vtable uses the
DECL_ASSEMBLER_NAME for the type, which includes the number
in `3foo'. If we were to pull them off here, we'd end up with
something like `_vt.foo.3bar', instead of a uniform definition. */
*************** tree get_vtable_decl (type, complete)
*** 1042,1054 ****
return decl;
}
! /* Build a virtual function for type TYPE.
! If BINFO is non-NULL, build the vtable starting with the initial
! approximation that it is the same as the one which is the head of
! the association list. */
! static void
! build_vtable (binfo, type)
tree binfo, type;
{
tree virtuals, decl;
--- 1043,1056 ----
return decl;
}
! /* Build the primary virtual function table for TYPE. If BINFO is
! non-NULL, build the vtable starting with the initial approximation
! that it is the same as the one which is the head of the association
! list. Returns a non-zero value if a new vtable is actually
! created. */
! static int
! build_primary_vtable (binfo, type)
tree binfo, type;
{
tree virtuals, decl;
*************** build_vtable (binfo, type)
*** 1062,1069 ****
if (BINFO_NEW_VTABLE_MARKED (binfo))
/* We have already created a vtable for this base, so there's
no need to do it again. */
! return;
!
virtuals = copy_list (BINFO_VIRTUALS (binfo));
TREE_TYPE (decl) = TREE_TYPE (BINFO_VTABLE (binfo));
DECL_SIZE (decl) = TYPE_SIZE (TREE_TYPE (BINFO_VTABLE (binfo)));
--- 1064,1071 ----
if (BINFO_NEW_VTABLE_MARKED (binfo))
/* We have already created a vtable for this base, so there's
no need to do it again. */
! return 0;
!
virtuals = copy_list (BINFO_VIRTUALS (binfo));
TREE_TYPE (decl) = TREE_TYPE (BINFO_VTABLE (binfo));
DECL_SIZE (decl) = TYPE_SIZE (TREE_TYPE (BINFO_VTABLE (binfo)));
*************** build_vtable (binfo, type)
*** 1092,1097 ****
--- 1094,1100 ----
binfo = TYPE_BINFO (type);
SET_BINFO_NEW_VTABLE_MARKED (binfo);
+ return 1;
}
/* Give TYPE a new virtual function table which is initialized
*************** build_vtable (binfo, type)
*** 1108,1115 ****
an object must remain the same, otherwise a binary incompatibility
can result. */
! static void
! prepare_fresh_vtable (binfo, for_type)
tree binfo, for_type;
{
tree basetype;
--- 1111,1118 ----
an object must remain the same, otherwise a binary incompatibility
can result. */
! static int
! build_secondary_vtable (binfo, for_type)
tree binfo, for_type;
{
tree basetype;
*************** prepare_fresh_vtable (binfo, for_type)
*** 1129,1135 ****
if (BINFO_NEW_VTABLE_MARKED (binfo))
/* We already created a vtable for this base. There's no need to
do it again. */
! return;
basetype = TYPE_MAIN_VARIANT (BINFO_TYPE (binfo));
--- 1132,1138 ----
if (BINFO_NEW_VTABLE_MARKED (binfo))
/* We already created a vtable for this base. There's no need to
do it again. */
! return 0;
basetype = TYPE_MAIN_VARIANT (BINFO_TYPE (binfo));
*************** prepare_fresh_vtable (binfo, for_type)
*** 1259,1282 ****
current_class_type),
170);
SET_BINFO_NEW_VTABLE_MARKED (binfo);
}
! /* Make V, an entry on the BINFO_VIRTUALS list for BINFO (which is in
! the hierarchy dominated by T) list FNDECL as its BF_FN. */
static void
! modify_vtable_entry (t, binfo, fndecl, v)
tree t;
tree binfo;
tree fndecl;
! tree v;
{
! tree base_offset, offset;
! tree context = DECL_CLASS_CONTEXT (fndecl);
! tree vfield = TYPE_VFIELD (t);
tree this_offset;
tree vcall_index;
offset = get_class_offset (context, t, binfo, fndecl);
/* Find the right offset for ythe this pointer based on the
--- 1262,1312 ----
current_class_type),
170);
SET_BINFO_NEW_VTABLE_MARKED (binfo);
+ return 1;
}
! /* Create a new vtable for BINFO which is the hierarchy dominated by
! T. */
+ static int
+ make_new_vtable (t, binfo)
+ tree t;
+ tree binfo;
+ {
+ if (binfo == TYPE_BINFO (t))
+ /* In this case, it is *type*'s vtable we are modifying. We start
+ with the approximation that it's vtable is that of the
+ immediate base class. */
+ return build_primary_vtable (TYPE_BINFO (DECL_CONTEXT (TYPE_VFIELD (t))),
+ t);
+ else
+ /* This is our very own copy of `basetype' to play with. Later,
+ we will fill in all the virtual functions that override the
+ virtual functions in these base classes which are not defined
+ by the current type. */
+ return build_secondary_vtable (binfo, t);
+ }
+
+ /* Make *VIRTUALS, an entry on the BINFO_VIRTUALS list for BINFO
+ (which is in the hierarchy dominated by T) list FNDECL as its
+ BF_FN. */
+
static void
! modify_vtable_entry (t, binfo, fndecl, virtuals)
tree t;
tree binfo;
tree fndecl;
! tree *virtuals;
{
! tree base_offset;
! tree offset;
! tree context;
tree this_offset;
tree vcall_index;
+ tree v;
+ v = *virtuals;
+ context = DECL_CLASS_CONTEXT (fndecl);
offset = get_class_offset (context, t, binfo, fndecl);
/* Find the right offset for ythe this pointer based on the
*************** modify_vtable_entry (t, binfo, fndecl, v
*** 1300,1317 ****
{
tree base_fndecl;
! /* Make sure we can modify the derived association with immunity. */
! if (binfo == TYPE_BINFO (t))
! /* In this case, it is *type*'s vtable we are modifying. We
! start with the approximation that it's vtable is that of
! the immediate base class. */
! build_vtable (TYPE_BINFO (DECL_CONTEXT (vfield)), t);
! else
! /* This is our very own copy of `basetype' to play with.
! Later, we will fill in all the virtual functions that
! override the virtual functions in these base classes which
! are not defined by the current type. */
! prepare_fresh_vtable (binfo, t);
base_fndecl = BF_FN (v);
BF_DELTA (v) = this_offset;
--- 1330,1346 ----
{
tree base_fndecl;
! /* We need a new vtable for BINFO. */
! if (make_new_vtable (t, binfo))
! {
! /* If we really did make a new vtable, we also made a copy
! of the BINFO_VIRTUALS list. Now, we have to find the
! corresponding entry in that list. */
! *virtuals = BINFO_VIRTUALS (binfo);
! while (BF_FN (*virtuals) != BF_FN (v))
! *virtuals = TREE_CHAIN (*virtuals);
! v = *virtuals;
! }
base_fndecl = BF_FN (v);
BF_DELTA (v) = this_offset;
*************** modify_one_vtable (binfo, t, fndecl)
*** 2948,2971 ****
tree binfo, t, fndecl;
{
tree virtuals;
- unsigned HOST_WIDE_INT n;
/* If we're support RTTI then we always need a new vtable to point
to the RTTI information. Under the new ABI we may need a new
vtable to contain vcall and vbase offsets. */
if (flag_rtti || flag_new_abi)
! {
! if (binfo == TYPE_BINFO (t))
! build_vtable (TYPE_BINFO (DECL_CONTEXT (TYPE_VFIELD (t))), t);
! else
! prepare_fresh_vtable (binfo, t);
! }
if (fndecl == NULL_TREE)
return;
! for (virtuals = skip_rtti_stuff (binfo, BINFO_TYPE (binfo), &n);
virtuals;
! virtuals = TREE_CHAIN (virtuals), ++n)
{
tree current_fndecl = BF_FN (virtuals);
--- 2977,2995 ----
tree binfo, t, fndecl;
{
tree virtuals;
/* If we're support RTTI then we always need a new vtable to point
to the RTTI information. Under the new ABI we may need a new
vtable to contain vcall and vbase offsets. */
if (flag_rtti || flag_new_abi)
! make_new_vtable (t, binfo);
!
if (fndecl == NULL_TREE)
return;
! for (virtuals = skip_rtti_stuff (binfo, BINFO_TYPE (binfo), NULL);
virtuals;
! virtuals = TREE_CHAIN (virtuals))
{
tree current_fndecl = BF_FN (virtuals);
*************** modify_one_vtable (binfo, t, fndecl)
*** 2977,2983 ****
19990727);
if (current_fndecl && overrides (fndecl, current_fndecl))
! modify_vtable_entry (t, binfo, fndecl, virtuals);
}
}
--- 3001,3007 ----
19990727);
if (current_fndecl && overrides (fndecl, current_fndecl))
! modify_vtable_entry (t, binfo, fndecl, &virtuals);
}
}
*************** dfs_fixup_vtable_deltas (binfo, data)
*** 3088,3094 ****
void *data;
{
tree virtuals;
- unsigned HOST_WIDE_INT n;
tree t = (tree) data;
while (BINFO_PRIMARY_MARKED_P (binfo))
--- 3112,3117 ----
*************** dfs_fixup_vtable_deltas (binfo, data)
*** 3099,3112 ****
return NULL_TREE;
}
! for (virtuals = skip_rtti_stuff (binfo, BINFO_TYPE (binfo), &n);
virtuals;
! virtuals = TREE_CHAIN (virtuals), ++n)
{
tree fndecl = BF_FN (virtuals);
if (fndecl)
! modify_vtable_entry (t, binfo, fndecl, virtuals);
}
return NULL_TREE;
--- 3122,3135 ----
return NULL_TREE;
}
! for (virtuals = skip_rtti_stuff (binfo, BINFO_TYPE (binfo), NULL);
virtuals;
! virtuals = TREE_CHAIN (virtuals))
{
tree fndecl = BF_FN (virtuals);
if (fndecl)
! modify_vtable_entry (t, binfo, fndecl, &virtuals);
}
return NULL_TREE;
*************** override_one_vtable (binfo, old, t)
*** 3194,3200 ****
choose = NEITHER;
if (! BINFO_NEW_VTABLE_MARKED (binfo))
{
! prepare_fresh_vtable (binfo, t);
override_one_vtable (binfo, old, t);
return;
}
--- 3217,3223 ----
choose = NEITHER;
if (! BINFO_NEW_VTABLE_MARKED (binfo))
{
! build_secondary_vtable (binfo, t);
override_one_vtable (binfo, old, t);
return;
}
*************** override_one_vtable (binfo, old, t)
*** 3209,3215 ****
choose = NEITHER;
if (! BINFO_NEW_VTABLE_MARKED (binfo))
{
! prepare_fresh_vtable (binfo, t);
override_one_vtable (binfo, old, t);
return;
}
--- 3232,3238 ----
choose = NEITHER;
if (! BINFO_NEW_VTABLE_MARKED (binfo))
{
! build_secondary_vtable (binfo, t);
override_one_vtable (binfo, old, t);
return;
}
*************** override_one_vtable (binfo, old, t)
*** 3225,3231 ****
choose = NEITHER;
if (! BINFO_NEW_VTABLE_MARKED (binfo))
{
! prepare_fresh_vtable (binfo, t);
override_one_vtable (binfo, old, t);
return;
}
--- 3248,3254 ----
choose = NEITHER;
if (! BINFO_NEW_VTABLE_MARKED (binfo))
{
! build_secondary_vtable (binfo, t);
override_one_vtable (binfo, old, t);
return;
}
*************** finish_struct_1 (t)
*** 5146,5157 ****
set_rtti_entry (new_virtuals,
convert (ssizetype, integer_zero_node), t);
}
! build_vtable (NULL_TREE, t);
}
else if (! BINFO_NEW_VTABLE_MARKED (TYPE_BINFO (t)))
/* Here we know enough to change the type of our virtual
function table, but we will wait until later this function. */
! build_vtable (CLASSTYPE_PRIMARY_BINFO (t), t);
/* If this type has basetypes with constructors, then those
constructors might clobber the virtual function table. But
--- 5169,5180 ----
set_rtti_entry (new_virtuals,
convert (ssizetype, integer_zero_node), t);
}
! build_primary_vtable (NULL_TREE, t);
}
else if (! BINFO_NEW_VTABLE_MARKED (TYPE_BINFO (t)))
/* Here we know enough to change the type of our virtual
function table, but we will wait until later this function. */
! build_primary_vtable (CLASSTYPE_PRIMARY_BINFO (t), t);
/* If this type has basetypes with constructors, then those
constructors might clobber the virtual function table. But