Never change BINFO_INHERITANCE_CHAIN.

* init.c (emit_base_init): Change modification of
	BINFO_INHERITANCE_CHAIN to an assert.
	* search.c (get_base_distance_recursive): Likewise.
	(get_base_distance): Likewise.
	(lookup_member): Likewise.
	(convert_pointer_to_single_level): Likewise.
	(lookup_field): Likewise.  Lose setting TREE_VIA_* on TREE_LISTs.
	(lookup_fnfields): Likewise.
	* tree.c (propagate_binfo_offsets): Don't call unshare_base_binfos.
	(unshare_base_binfos): Don't call propagate_binfo_offsets.
	(layout_basetypes): Call propagate_binfo_offsets instead of
	unshare_base_binfos.
	* decl.c (xref_basetypes): Call unshare_base_binfos.
	* pt.c (instantiate_class_template): Likewise.
	* tree.c (reverse_path): Remove 'copy' parm; always make a
	temporary copy.
	* class.c (build_vbase_path): Just call it.
	* search.c (compute_access): Likewise.  Don't re-reverse.

From-SVN: r22024
This commit is contained in:
Jason Merrill 1998-08-27 15:30:49 +00:00 committed by Jason Merrill
parent 3e2a2957a0
commit dfbcd65a01
8 changed files with 111 additions and 102 deletions

View File

@ -1,3 +1,25 @@
1998-08-27 Jason Merrill <jason@yorick.cygnus.com>
Never change BINFO_INHERITANCE_CHAIN.
* init.c (emit_base_init): Change modification of
BINFO_INHERITANCE_CHAIN to an assert.
* search.c (get_base_distance_recursive): Likewise.
(get_base_distance): Likewise.
(lookup_member): Likewise.
(convert_pointer_to_single_level): Likewise.
(lookup_field): Likewise. Lose setting TREE_VIA_* on TREE_LISTs.
(lookup_fnfields): Likewise.
* tree.c (propagate_binfo_offsets): Don't call unshare_base_binfos.
(unshare_base_binfos): Don't call propagate_binfo_offsets.
(layout_basetypes): Call propagate_binfo_offsets instead of
unshare_base_binfos.
* decl.c (xref_basetypes): Call unshare_base_binfos.
* pt.c (instantiate_class_template): Likewise.
* tree.c (reverse_path): Remove 'copy' parm; always make a
temporary copy.
* class.c (build_vbase_path): Just call it.
* search.c (compute_access): Likewise. Don't re-reverse.
1998-08-27 Mark Mitchell <mark@markmitchell.com> 1998-08-27 Mark Mitchell <mark@markmitchell.com>
* class.c (build_vbase_path): Use reverse_path. * class.c (build_vbase_path): Use reverse_path.

View File

@ -265,11 +265,7 @@ build_vbase_path (code, type, expr, path, nonnull)
nonnull_expr = expr; nonnull_expr = expr;
if (BINFO_INHERITANCE_CHAIN (path)) if (BINFO_INHERITANCE_CHAIN (path))
{ path = reverse_path (path);
push_expression_obstack ();
path = reverse_path (path, /*copy=*/1);
pop_obstacks ();
}
basetype = BINFO_TYPE (path); basetype = BINFO_TYPE (path);

View File

@ -3017,7 +3017,7 @@ extern tree hash_chainon PROTO((tree, tree));
extern tree get_decl_list PROTO((tree)); extern tree get_decl_list PROTO((tree));
extern tree make_binfo PROTO((tree, tree, tree, tree)); extern tree make_binfo PROTO((tree, tree, tree, tree));
extern tree binfo_value PROTO((tree, tree)); extern tree binfo_value PROTO((tree, tree));
extern tree reverse_path PROTO((tree, int)); extern tree reverse_path PROTO((tree));
extern int count_functions PROTO((tree)); extern int count_functions PROTO((tree));
extern int is_overloaded_fn PROTO((tree)); extern int is_overloaded_fn PROTO((tree));
extern tree get_first_fn PROTO((tree)); extern tree get_first_fn PROTO((tree));

View File

@ -11764,6 +11764,10 @@ xref_basetypes (code_type_node, name, ref, binfo)
TREE_VIA_VIRTUAL (base_binfo) = via_virtual; TREE_VIA_VIRTUAL (base_binfo) = via_virtual;
BINFO_INHERITANCE_CHAIN (base_binfo) = TYPE_BINFO (ref); BINFO_INHERITANCE_CHAIN (base_binfo) = TYPE_BINFO (ref);
/* We need to unshare the binfos now so that lookups during class
definition work. */
unshare_base_binfos (base_binfo);
SET_CLASSTYPE_MARKED (basetype); SET_CLASSTYPE_MARKED (basetype);
/* We are free to modify these bits because they are meaningless /* We are free to modify these bits because they are meaningless

View File

@ -569,11 +569,8 @@ emit_base_init (t, immediately)
if (TREE_VIA_VIRTUAL (base_binfo)) if (TREE_VIA_VIRTUAL (base_binfo))
continue; continue;
#if 0 /* Once unsharing happens soon enough. */ my_friendly_assert (BINFO_INHERITANCE_CHAIN (base_binfo) == t_binfo,
my_friendly_assert (BINFO_INHERITANCE_CHAIN (base_binfo) == t_binfo, 999); 999);
#else
BINFO_INHERITANCE_CHAIN (base_binfo) = t_binfo;
#endif
if (TREE_PURPOSE (rbase_init_list)) if (TREE_PURPOSE (rbase_init_list))
init = TREE_VALUE (rbase_init_list); init = TREE_VALUE (rbase_init_list);

View File

@ -4297,6 +4297,9 @@ instantiate_class_template (type)
/* These are set up in xref_basetypes for normal classes, so /* These are set up in xref_basetypes for normal classes, so
we have to handle them here for template bases. */ we have to handle them here for template bases. */
unshare_base_binfos (elt);
if (TYPE_USES_VIRTUAL_BASECLASSES (basetype)) if (TYPE_USES_VIRTUAL_BASECLASSES (basetype))
{ {
TYPE_USES_VIRTUAL_BASECLASSES (type) = 1; TYPE_USES_VIRTUAL_BASECLASSES (type) = 1;

View File

@ -683,7 +683,8 @@ get_base_distance_recursive (binfo, depth, is_private, rval,
current_scope_in_chain); current_scope_in_chain);
/* watch for updates; only update if path is good. */ /* watch for updates; only update if path is good. */
if (path_ptr && WATCH_VALUES (rval, *via_virtual_ptr) != was) if (path_ptr && WATCH_VALUES (rval, *via_virtual_ptr) != was)
BINFO_INHERITANCE_CHAIN (base_binfo) = binfo; my_friendly_assert (BINFO_INHERITANCE_CHAIN (base_binfo) == binfo,
980827);
if (rval == -2 && *via_virtual_ptr == 0) if (rval == -2 && *via_virtual_ptr == 0)
return rval; return rval;
@ -741,7 +742,8 @@ get_base_distance (parent, binfo, protect, path_ptr)
binfo = TYPE_BINFO (type); binfo = TYPE_BINFO (type);
if (path_ptr) if (path_ptr)
BINFO_INHERITANCE_CHAIN (binfo) = NULL_TREE; my_friendly_assert (BINFO_INHERITANCE_CHAIN (binfo) == NULL_TREE,
980827);
} }
else else
my_friendly_abort (92); my_friendly_abort (92);
@ -777,7 +779,7 @@ get_base_distance (parent, binfo, protect, path_ptr)
&& parent == binfo_member (BINFO_TYPE (parent), && parent == binfo_member (BINFO_TYPE (parent),
CLASSTYPE_VBASECLASSES (type))) CLASSTYPE_VBASECLASSES (type)))
{ {
BINFO_INHERITANCE_CHAIN (parent) = binfo; my_friendly_assert (BINFO_INHERITANCE_CHAIN (parent) == binfo, 980827);
new_binfo = parent; new_binfo = parent;
rval = 1; rval = 1;
} }
@ -1003,7 +1005,7 @@ compute_access (basetype_path, field)
} }
/* must reverse more than one element */ /* must reverse more than one element */
basetype_path = reverse_path (basetype_path, /*copy=*/0); basetype_path = reverse_path (basetype_path);
types = basetype_path; types = basetype_path;
via_protected = 0; via_protected = 0;
access = access_default_node; access = access_default_node;
@ -1049,7 +1051,6 @@ compute_access (basetype_path, field)
else else
break; break;
} }
reverse_path (basetype_path, /*copy=*/0);
/* No special visibilities apply. Use normal rules. */ /* No special visibilities apply. Use normal rules. */
@ -1223,7 +1224,8 @@ lookup_field (xbasetype, name, protect, want_type)
{ {
type = xbasetype; type = xbasetype;
basetype_path = TYPE_BINFO (type); basetype_path = TYPE_BINFO (type);
BINFO_INHERITANCE_CHAIN (basetype_path) = NULL_TREE; my_friendly_assert (BINFO_INHERITANCE_CHAIN (basetype_path) == NULL_TREE,
980827);
} }
else else
my_friendly_abort (97); my_friendly_abort (97);
@ -1315,9 +1317,6 @@ lookup_field (xbasetype, name, protect, want_type)
} }
basetype_chain = build_expr_list (NULL_TREE, basetype_path); basetype_chain = build_expr_list (NULL_TREE, basetype_path);
TREE_VIA_PUBLIC (basetype_chain) = TREE_VIA_PUBLIC (basetype_path);
TREE_VIA_PROTECTED (basetype_chain) = TREE_VIA_PROTECTED (basetype_path);
TREE_VIA_VIRTUAL (basetype_chain) = TREE_VIA_VIRTUAL (basetype_path);
/* The ambiguity check relies upon breadth first searching. */ /* The ambiguity check relies upon breadth first searching. */
@ -1341,9 +1340,6 @@ lookup_field (xbasetype, name, protect, want_type)
SET_BINFO_FIELDS_MARKED (base_binfo); SET_BINFO_FIELDS_MARKED (base_binfo);
btypes = my_tree_cons (NULL_TREE, base_binfo, basetype_chain); btypes = my_tree_cons (NULL_TREE, base_binfo, basetype_chain);
TREE_VIA_PUBLIC (btypes) = TREE_VIA_PUBLIC (base_binfo);
TREE_VIA_PROTECTED (btypes) = TREE_VIA_PROTECTED (base_binfo);
TREE_VIA_VIRTUAL (btypes) = TREE_VIA_VIRTUAL (base_binfo);
if (TREE_VIA_VIRTUAL (base_binfo)) if (TREE_VIA_VIRTUAL (base_binfo))
btypes = my_tree_cons (NULL_TREE, btypes = my_tree_cons (NULL_TREE,
TYPE_BINFO (BINFO_TYPE (TREE_VEC_ELT (BINFO_BASETYPES (binfo_h), i))), TYPE_BINFO (BINFO_TYPE (TREE_VEC_ELT (BINFO_BASETYPES (binfo_h), i))),
@ -1368,9 +1364,12 @@ lookup_field (xbasetype, name, protect, want_type)
basetype_chain = TREE_CHAIN (basetype_chain); basetype_chain = TREE_CHAIN (basetype_chain);
basetype_path = TREE_VALUE (basetype_chain); basetype_path = TREE_VALUE (basetype_chain);
if (TREE_CHAIN (basetype_chain)) if (TREE_CHAIN (basetype_chain))
BINFO_INHERITANCE_CHAIN (basetype_path) = TREE_VALUE (TREE_CHAIN (basetype_chain)); my_friendly_assert (BINFO_INHERITANCE_CHAIN (basetype_path)
== TREE_VALUE (TREE_CHAIN (basetype_chain)),
980827);
else else
BINFO_INHERITANCE_CHAIN (basetype_path) = NULL_TREE; my_friendly_assert (BINFO_INHERITANCE_CHAIN (basetype_path)
== NULL_TREE, 980827);
binfo = basetype_path; binfo = basetype_path;
type = BINFO_TYPE (binfo); type = BINFO_TYPE (binfo);
@ -1850,16 +1849,11 @@ lookup_fnfields (basetype_path, name, complain)
if (basetype_path == TYPE_BINFO (type)) if (basetype_path == TYPE_BINFO (type))
{ {
basetype_chain = CLASSTYPE_BINFO_AS_LIST (type); basetype_chain = CLASSTYPE_BINFO_AS_LIST (type);
TREE_VIA_PUBLIC (basetype_chain) = 1; my_friendly_assert (BINFO_INHERITANCE_CHAIN (basetype_path) == NULL_TREE,
BINFO_INHERITANCE_CHAIN (basetype_path) = NULL_TREE; 980827);
} }
else else
{
basetype_chain = build_expr_list (NULL_TREE, basetype_path); basetype_chain = build_expr_list (NULL_TREE, basetype_path);
TREE_VIA_PUBLIC (basetype_chain) = TREE_VIA_PUBLIC (basetype_path);
TREE_VIA_PROTECTED (basetype_chain) = TREE_VIA_PROTECTED (basetype_path);
TREE_VIA_VIRTUAL (basetype_chain) = TREE_VIA_VIRTUAL (basetype_path);
}
/* The ambiguity check relies upon breadth first searching. */ /* The ambiguity check relies upon breadth first searching. */
@ -1883,9 +1877,6 @@ lookup_fnfields (basetype_path, name, complain)
SET_BINFO_FIELDS_MARKED (base_binfo); SET_BINFO_FIELDS_MARKED (base_binfo);
btypes = my_tree_cons (NULL_TREE, base_binfo, basetype_chain); btypes = my_tree_cons (NULL_TREE, base_binfo, basetype_chain);
TREE_VIA_PUBLIC (btypes) = TREE_VIA_PUBLIC (base_binfo);
TREE_VIA_PROTECTED (btypes) = TREE_VIA_PROTECTED (base_binfo);
TREE_VIA_VIRTUAL (btypes) = TREE_VIA_VIRTUAL (base_binfo);
if (TREE_VIA_VIRTUAL (base_binfo)) if (TREE_VIA_VIRTUAL (base_binfo))
btypes = my_tree_cons (NULL_TREE, btypes = my_tree_cons (NULL_TREE,
TYPE_BINFO (BINFO_TYPE (TREE_VEC_ELT (BINFO_BASETYPES (binfo_h), i))), TYPE_BINFO (BINFO_TYPE (TREE_VEC_ELT (BINFO_BASETYPES (binfo_h), i))),
@ -1910,9 +1901,12 @@ lookup_fnfields (basetype_path, name, complain)
basetype_chain = TREE_CHAIN (basetype_chain); basetype_chain = TREE_CHAIN (basetype_chain);
basetype_path = TREE_VALUE (basetype_chain); basetype_path = TREE_VALUE (basetype_chain);
if (TREE_CHAIN (basetype_chain)) if (TREE_CHAIN (basetype_chain))
BINFO_INHERITANCE_CHAIN (basetype_path) = TREE_VALUE (TREE_CHAIN (basetype_chain)); my_friendly_assert (BINFO_INHERITANCE_CHAIN (basetype_path)
== TREE_VALUE (TREE_CHAIN (basetype_chain)),
980827);
else else
BINFO_INHERITANCE_CHAIN (basetype_path) = NULL_TREE; my_friendly_assert (BINFO_INHERITANCE_CHAIN (basetype_path)
== NULL_TREE, 980827);
binfo = basetype_path; binfo = basetype_path;
type = BINFO_TYPE (binfo); type = BINFO_TYPE (binfo);
@ -2016,7 +2010,8 @@ lookup_member (xbasetype, name, protect, want_type)
else if (IS_AGGR_TYPE_CODE (TREE_CODE (xbasetype))) else if (IS_AGGR_TYPE_CODE (TREE_CODE (xbasetype)))
{ {
basetype_path = TYPE_BINFO (xbasetype); basetype_path = TYPE_BINFO (xbasetype);
BINFO_INHERITANCE_CHAIN (basetype_path) = NULL_TREE; my_friendly_assert (BINFO_INHERITANCE_CHAIN (basetype_path)
== NULL_TREE, 980827);
} }
else else
my_friendly_abort (97); my_friendly_abort (97);
@ -2538,9 +2533,12 @@ convert_pointer_to_single_level (to_type, expr)
binfo_of_derived = TYPE_BINFO (TREE_TYPE (TREE_TYPE (expr))); binfo_of_derived = TYPE_BINFO (TREE_TYPE (TREE_TYPE (expr)));
last = get_binfo (to_type, TREE_TYPE (TREE_TYPE (expr)), 0); last = get_binfo (to_type, TREE_TYPE (TREE_TYPE (expr)), 0);
BINFO_INHERITANCE_CHAIN (last) = binfo_of_derived; my_friendly_assert (BINFO_INHERITANCE_CHAIN (last) == binfo_of_derived,
BINFO_INHERITANCE_CHAIN (binfo_of_derived) = NULL_TREE; 980827);
return build_vbase_path (PLUS_EXPR, build_pointer_type (to_type), expr, last, 1); my_friendly_assert (BINFO_INHERITANCE_CHAIN (binfo_of_derived) == NULL_TREE,
980827);
return build_vbase_path (PLUS_EXPR, build_pointer_type (to_type), expr,
last, 1);
} }
/* The main function which implements depth first search. /* The main function which implements depth first search.

View File

@ -39,7 +39,6 @@ static int list_hash PROTO((tree, tree, tree));
static tree list_hash_lookup PROTO((int, int, int, int, tree, tree, static tree list_hash_lookup PROTO((int, int, int, int, tree, tree,
tree)); tree));
static void propagate_binfo_offsets PROTO((tree, tree)); static void propagate_binfo_offsets PROTO((tree, tree));
static void unshare_base_binfos PROTO((tree));
static int avoid_overlap PROTO((tree, tree)); static int avoid_overlap PROTO((tree, tree));
#define CEIL(x,y) (((x) + (y) - 1) / (y)) #define CEIL(x,y) (((x) + (y) - 1) / (y))
@ -584,10 +583,7 @@ propagate_binfo_offsets (binfo, offset)
tree base_binfo = TREE_VEC_ELT (binfos, i); tree base_binfo = TREE_VEC_ELT (binfos, i);
if (TREE_VIA_VIRTUAL (base_binfo)) if (TREE_VIA_VIRTUAL (base_binfo))
{
i += 1; i += 1;
unshare_base_binfos (base_binfo);
}
else else
{ {
int j; int j;
@ -614,7 +610,7 @@ propagate_binfo_offsets (binfo, offset)
BINFO_OFFSET (base_binfo) = offset; BINFO_OFFSET (base_binfo) = offset;
#endif #endif
unshare_base_binfos (base_binfo); propagate_binfo_offsets (base_binfo, offset);
/* Go to our next class that counts for offset propagation. */ /* Go to our next class that counts for offset propagation. */
i = j; i = j;
@ -624,39 +620,35 @@ propagate_binfo_offsets (binfo, offset)
} }
} }
/* Makes new binfos for the indirect bases under BASE_BINFO, and updates /* Makes new binfos for the indirect bases under BINFO, and updates
BINFO_OFFSET for them and their bases. */ BINFO_OFFSET for them and their bases. */
static void void
unshare_base_binfos (base_binfo) unshare_base_binfos (binfo)
tree base_binfo; tree binfo;
{ {
if (BINFO_BASETYPES (base_binfo)) tree binfos = BINFO_BASETYPES (binfo);
{ tree new_binfo;
tree base_binfos = BINFO_BASETYPES (base_binfo);
tree chain = NULL_TREE;
int j; int j;
/* Now unshare the structure beneath BASE_BINFO. */ if (binfos == NULL_TREE)
for (j = TREE_VEC_LENGTH (base_binfos)-1; return;
/* Now unshare the structure beneath BINFO. */
for (j = TREE_VEC_LENGTH (binfos)-1;
j >= 0; j--) j >= 0; j--)
{ {
tree base_base_binfo = TREE_VEC_ELT (base_binfos, j); tree base_binfo = TREE_VEC_ELT (binfos, j);
TREE_VEC_ELT (base_binfos, j) new_binfo = TREE_VEC_ELT (binfos, j)
= make_binfo (BINFO_OFFSET (base_base_binfo), = make_binfo (BINFO_OFFSET (base_binfo),
base_base_binfo, base_binfo,
BINFO_VTABLE (base_base_binfo), BINFO_VTABLE (base_binfo),
BINFO_VIRTUALS (base_base_binfo)); BINFO_VIRTUALS (base_binfo));
chain = TREE_VEC_ELT (base_binfos, j); TREE_VIA_PUBLIC (new_binfo) = TREE_VIA_PUBLIC (base_binfo);
TREE_VIA_PUBLIC (chain) = TREE_VIA_PUBLIC (base_base_binfo); TREE_VIA_PROTECTED (new_binfo) = TREE_VIA_PROTECTED (base_binfo);
TREE_VIA_PROTECTED (chain) = TREE_VIA_PROTECTED (base_base_binfo); TREE_VIA_VIRTUAL (new_binfo) = TREE_VIA_VIRTUAL (base_binfo);
TREE_VIA_VIRTUAL (chain) = TREE_VIA_VIRTUAL (base_base_binfo); BINFO_INHERITANCE_CHAIN (new_binfo) = binfo;
BINFO_INHERITANCE_CHAIN (chain) = base_binfo; unshare_base_binfos (new_binfo);
}
/* Completely unshare potentially shared data, and
update what is ours. */
propagate_binfo_offsets (base_binfo, BINFO_OFFSET (base_binfo));
} }
} }
@ -758,9 +750,8 @@ layout_basetypes (rec, max)
tree field = TYPE_FIELDS (rec); tree field = TYPE_FIELDS (rec);
if (TREE_VIA_VIRTUAL (base_binfo)) if (TREE_VIA_VIRTUAL (base_binfo))
unshare_base_binfos (base_binfo); continue;
else
{
my_friendly_assert (TREE_TYPE (field) == basetype, 23897); my_friendly_assert (TREE_TYPE (field) == basetype, 23897);
if (get_base_distance (basetype, rec, 0, (tree*)0) == -2) if (get_base_distance (basetype, rec, 0, (tree*)0) == -2)
@ -770,16 +761,16 @@ layout_basetypes (rec, max)
BINFO_OFFSET (base_binfo) BINFO_OFFSET (base_binfo)
= size_int (CEIL (TREE_INT_CST_LOW (DECL_FIELD_BITPOS (field)), = size_int (CEIL (TREE_INT_CST_LOW (DECL_FIELD_BITPOS (field)),
BITS_PER_UNIT)); BITS_PER_UNIT));
unshare_base_binfos (base_binfo); propagate_binfo_offsets (base_binfo, BINFO_OFFSET (base_binfo));
TYPE_FIELDS (rec) = TREE_CHAIN (field); TYPE_FIELDS (rec) = TREE_CHAIN (field);
} }
}
for (vbase_types = CLASSTYPE_VBASECLASSES (rec); vbase_types; for (vbase_types = CLASSTYPE_VBASECLASSES (rec); vbase_types;
vbase_types = TREE_CHAIN (vbase_types)) vbase_types = TREE_CHAIN (vbase_types))
{ {
BINFO_INHERITANCE_CHAIN (vbase_types) = TYPE_BINFO (rec); BINFO_INHERITANCE_CHAIN (vbase_types) = TYPE_BINFO (rec);
unshare_base_binfos (vbase_types); unshare_base_binfos (vbase_types);
propagate_binfo_offsets (vbase_types, BINFO_OFFSET (vbase_types));
if (extra_warnings) if (extra_warnings)
{ {
@ -1258,26 +1249,24 @@ binfo_value (elem, type)
return get_binfo (elem, type, 0); return get_binfo (elem, type, 0);
} }
/* Reverse the BINFO-chain given by PATH. (If the /* Return a reversed copy of the BINFO-chain given by PATH. (If the
BINFO_INHERITANCE_CHAIN points from base classes to derived BINFO_INHERITANCE_CHAIN points from base classes to derived
classes, it will instead point from derived classes to base classes, it will instead point from derived classes to base
classes.) Returns the first node in the reversed chain. If COPY classes.) Returns the first node in the reversed chain. */
is non-zero, the nodes are copied as the chain is traversed. */
tree tree
reverse_path (path, copy) reverse_path (path)
tree path; tree path;
int copy;
{ {
register tree prev = 0, tmp, next; register tree prev = NULL_TREE, cur;
for (tmp = path; tmp; tmp = next) push_expression_obstack ();
for (cur = path; cur; cur = BINFO_INHERITANCE_CHAIN (cur))
{ {
if (copy) tree r = copy_node (cur);
tmp = copy_node (tmp); BINFO_INHERITANCE_CHAIN (r) = prev;
next = BINFO_INHERITANCE_CHAIN (tmp); prev = r;
BINFO_INHERITANCE_CHAIN (tmp) = prev;
prev = tmp;
} }
pop_obstacks ();
return prev; return prev;
} }