diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 7044d92c537..a5b99482fd3 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,25 @@ +1998-08-27 Jason Merrill + + 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 * class.c (build_vbase_path): Use reverse_path. diff --git a/gcc/cp/class.c b/gcc/cp/class.c index 66b91436521..a836a095ee1 100644 --- a/gcc/cp/class.c +++ b/gcc/cp/class.c @@ -265,11 +265,7 @@ build_vbase_path (code, type, expr, path, nonnull) nonnull_expr = expr; if (BINFO_INHERITANCE_CHAIN (path)) - { - push_expression_obstack (); - path = reverse_path (path, /*copy=*/1); - pop_obstacks (); - } + path = reverse_path (path); basetype = BINFO_TYPE (path); diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 532a5147c75..1ac399a977e 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -3017,7 +3017,7 @@ extern tree hash_chainon PROTO((tree, tree)); extern tree get_decl_list PROTO((tree)); extern tree make_binfo PROTO((tree, tree, 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 is_overloaded_fn PROTO((tree)); extern tree get_first_fn PROTO((tree)); diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 8e3b0722b86..e3b67acc383 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -11764,6 +11764,10 @@ xref_basetypes (code_type_node, name, ref, binfo) TREE_VIA_VIRTUAL (base_binfo) = via_virtual; 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); /* We are free to modify these bits because they are meaningless diff --git a/gcc/cp/init.c b/gcc/cp/init.c index f50483d235b..29408630e1c 100644 --- a/gcc/cp/init.c +++ b/gcc/cp/init.c @@ -569,11 +569,8 @@ emit_base_init (t, immediately) if (TREE_VIA_VIRTUAL (base_binfo)) continue; -#if 0 /* Once unsharing happens soon enough. */ - my_friendly_assert (BINFO_INHERITANCE_CHAIN (base_binfo) == t_binfo, 999); -#else - BINFO_INHERITANCE_CHAIN (base_binfo) = t_binfo; -#endif + my_friendly_assert (BINFO_INHERITANCE_CHAIN (base_binfo) == t_binfo, + 999); if (TREE_PURPOSE (rbase_init_list)) init = TREE_VALUE (rbase_init_list); diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index ddaf5fecb7a..b0b89c4c3d3 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -4297,6 +4297,9 @@ instantiate_class_template (type) /* These are set up in xref_basetypes for normal classes, so we have to handle them here for template bases. */ + + unshare_base_binfos (elt); + if (TYPE_USES_VIRTUAL_BASECLASSES (basetype)) { TYPE_USES_VIRTUAL_BASECLASSES (type) = 1; diff --git a/gcc/cp/search.c b/gcc/cp/search.c index 8e29bc1a2c5..33fd19bf612 100644 --- a/gcc/cp/search.c +++ b/gcc/cp/search.c @@ -683,7 +683,8 @@ get_base_distance_recursive (binfo, depth, is_private, rval, current_scope_in_chain); /* watch for updates; only update if path is good. */ 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) return rval; @@ -741,7 +742,8 @@ get_base_distance (parent, binfo, protect, path_ptr) binfo = TYPE_BINFO (type); if (path_ptr) - BINFO_INHERITANCE_CHAIN (binfo) = NULL_TREE; + my_friendly_assert (BINFO_INHERITANCE_CHAIN (binfo) == NULL_TREE, + 980827); } else my_friendly_abort (92); @@ -777,7 +779,7 @@ get_base_distance (parent, binfo, protect, path_ptr) && parent == binfo_member (BINFO_TYPE (parent), CLASSTYPE_VBASECLASSES (type))) { - BINFO_INHERITANCE_CHAIN (parent) = binfo; + my_friendly_assert (BINFO_INHERITANCE_CHAIN (parent) == binfo, 980827); new_binfo = parent; rval = 1; } @@ -1003,7 +1005,7 @@ compute_access (basetype_path, field) } /* must reverse more than one element */ - basetype_path = reverse_path (basetype_path, /*copy=*/0); + basetype_path = reverse_path (basetype_path); types = basetype_path; via_protected = 0; access = access_default_node; @@ -1049,7 +1051,6 @@ compute_access (basetype_path, field) else break; } - reverse_path (basetype_path, /*copy=*/0); /* No special visibilities apply. Use normal rules. */ @@ -1223,7 +1224,8 @@ lookup_field (xbasetype, name, protect, want_type) { type = xbasetype; basetype_path = TYPE_BINFO (type); - BINFO_INHERITANCE_CHAIN (basetype_path) = NULL_TREE; + my_friendly_assert (BINFO_INHERITANCE_CHAIN (basetype_path) == NULL_TREE, + 980827); } else my_friendly_abort (97); @@ -1315,9 +1317,6 @@ lookup_field (xbasetype, name, protect, want_type) } 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. */ @@ -1341,9 +1340,6 @@ lookup_field (xbasetype, name, protect, want_type) SET_BINFO_FIELDS_MARKED (base_binfo); 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)) btypes = my_tree_cons (NULL_TREE, 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_path = TREE_VALUE (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 - BINFO_INHERITANCE_CHAIN (basetype_path) = NULL_TREE; + my_friendly_assert (BINFO_INHERITANCE_CHAIN (basetype_path) + == NULL_TREE, 980827); binfo = basetype_path; type = BINFO_TYPE (binfo); @@ -1850,16 +1849,11 @@ lookup_fnfields (basetype_path, name, complain) if (basetype_path == TYPE_BINFO (type)) { basetype_chain = CLASSTYPE_BINFO_AS_LIST (type); - TREE_VIA_PUBLIC (basetype_chain) = 1; - BINFO_INHERITANCE_CHAIN (basetype_path) = NULL_TREE; + my_friendly_assert (BINFO_INHERITANCE_CHAIN (basetype_path) == NULL_TREE, + 980827); } else - { - 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); - } + basetype_chain = build_expr_list (NULL_TREE, basetype_path); /* The ambiguity check relies upon breadth first searching. */ @@ -1883,9 +1877,6 @@ lookup_fnfields (basetype_path, name, complain) SET_BINFO_FIELDS_MARKED (base_binfo); 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)) btypes = my_tree_cons (NULL_TREE, 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_path = TREE_VALUE (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 - BINFO_INHERITANCE_CHAIN (basetype_path) = NULL_TREE; + my_friendly_assert (BINFO_INHERITANCE_CHAIN (basetype_path) + == NULL_TREE, 980827); binfo = basetype_path; type = BINFO_TYPE (binfo); @@ -2016,7 +2010,8 @@ lookup_member (xbasetype, name, protect, want_type) else if (IS_AGGR_TYPE_CODE (TREE_CODE (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 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))); last = get_binfo (to_type, TREE_TYPE (TREE_TYPE (expr)), 0); - BINFO_INHERITANCE_CHAIN (last) = binfo_of_derived; - BINFO_INHERITANCE_CHAIN (binfo_of_derived) = NULL_TREE; - return build_vbase_path (PLUS_EXPR, build_pointer_type (to_type), expr, last, 1); + my_friendly_assert (BINFO_INHERITANCE_CHAIN (last) == binfo_of_derived, + 980827); + 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. diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c index feb1a44180f..41475b5f467 100644 --- a/gcc/cp/tree.c +++ b/gcc/cp/tree.c @@ -39,7 +39,6 @@ static int list_hash PROTO((tree, tree, tree)); static tree list_hash_lookup PROTO((int, int, int, int, tree, tree, tree)); static void propagate_binfo_offsets PROTO((tree, tree)); -static void unshare_base_binfos PROTO((tree)); static int avoid_overlap PROTO((tree, tree)); #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); if (TREE_VIA_VIRTUAL (base_binfo)) - { - i += 1; - unshare_base_binfos (base_binfo); - } + i += 1; else { int j; @@ -614,7 +610,7 @@ propagate_binfo_offsets (binfo, offset) BINFO_OFFSET (base_binfo) = offset; #endif - unshare_base_binfos (base_binfo); + propagate_binfo_offsets (base_binfo, offset); /* Go to our next class that counts for offset propagation. */ 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. */ -static void -unshare_base_binfos (base_binfo) - tree base_binfo; +void +unshare_base_binfos (binfo) + tree binfo; { - if (BINFO_BASETYPES (base_binfo)) + tree binfos = BINFO_BASETYPES (binfo); + tree new_binfo; + int j; + + if (binfos == NULL_TREE) + return; + + /* Now unshare the structure beneath BINFO. */ + for (j = TREE_VEC_LENGTH (binfos)-1; + j >= 0; j--) { - tree base_binfos = BINFO_BASETYPES (base_binfo); - tree chain = NULL_TREE; - int j; - - /* Now unshare the structure beneath BASE_BINFO. */ - for (j = TREE_VEC_LENGTH (base_binfos)-1; - j >= 0; j--) - { - tree base_base_binfo = TREE_VEC_ELT (base_binfos, j); - TREE_VEC_ELT (base_binfos, j) - = make_binfo (BINFO_OFFSET (base_base_binfo), - base_base_binfo, - BINFO_VTABLE (base_base_binfo), - BINFO_VIRTUALS (base_base_binfo)); - chain = TREE_VEC_ELT (base_binfos, j); - TREE_VIA_PUBLIC (chain) = TREE_VIA_PUBLIC (base_base_binfo); - TREE_VIA_PROTECTED (chain) = TREE_VIA_PROTECTED (base_base_binfo); - TREE_VIA_VIRTUAL (chain) = TREE_VIA_VIRTUAL (base_base_binfo); - BINFO_INHERITANCE_CHAIN (chain) = base_binfo; - } - - /* Completely unshare potentially shared data, and - update what is ours. */ - propagate_binfo_offsets (base_binfo, BINFO_OFFSET (base_binfo)); + tree base_binfo = TREE_VEC_ELT (binfos, j); + new_binfo = TREE_VEC_ELT (binfos, j) + = make_binfo (BINFO_OFFSET (base_binfo), + base_binfo, + BINFO_VTABLE (base_binfo), + BINFO_VIRTUALS (base_binfo)); + TREE_VIA_PUBLIC (new_binfo) = TREE_VIA_PUBLIC (base_binfo); + TREE_VIA_PROTECTED (new_binfo) = TREE_VIA_PROTECTED (base_binfo); + TREE_VIA_VIRTUAL (new_binfo) = TREE_VIA_VIRTUAL (base_binfo); + BINFO_INHERITANCE_CHAIN (new_binfo) = binfo; + unshare_base_binfos (new_binfo); } } @@ -758,21 +750,19 @@ layout_basetypes (rec, max) tree field = TYPE_FIELDS (rec); if (TREE_VIA_VIRTUAL (base_binfo)) - unshare_base_binfos (base_binfo); - else - { - my_friendly_assert (TREE_TYPE (field) == basetype, 23897); + continue; - if (get_base_distance (basetype, rec, 0, (tree*)0) == -2) - cp_warning ("direct base `%T' inaccessible in `%T' due to ambiguity", - basetype, rec); + my_friendly_assert (TREE_TYPE (field) == basetype, 23897); - BINFO_OFFSET (base_binfo) - = size_int (CEIL (TREE_INT_CST_LOW (DECL_FIELD_BITPOS (field)), - BITS_PER_UNIT)); - unshare_base_binfos (base_binfo); - TYPE_FIELDS (rec) = TREE_CHAIN (field); - } + if (get_base_distance (basetype, rec, 0, (tree*)0) == -2) + cp_warning ("direct base `%T' inaccessible in `%T' due to ambiguity", + basetype, rec); + + BINFO_OFFSET (base_binfo) + = size_int (CEIL (TREE_INT_CST_LOW (DECL_FIELD_BITPOS (field)), + BITS_PER_UNIT)); + propagate_binfo_offsets (base_binfo, BINFO_OFFSET (base_binfo)); + TYPE_FIELDS (rec) = TREE_CHAIN (field); } for (vbase_types = CLASSTYPE_VBASECLASSES (rec); vbase_types; @@ -780,6 +770,7 @@ layout_basetypes (rec, max) { BINFO_INHERITANCE_CHAIN (vbase_types) = TYPE_BINFO (rec); unshare_base_binfos (vbase_types); + propagate_binfo_offsets (vbase_types, BINFO_OFFSET (vbase_types)); if (extra_warnings) { @@ -1258,26 +1249,24 @@ binfo_value (elem, type) 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 classes, it will instead point from derived classes to base - classes.) Returns the first node in the reversed chain. If COPY - is non-zero, the nodes are copied as the chain is traversed. */ + classes.) Returns the first node in the reversed chain. */ tree -reverse_path (path, copy) +reverse_path (path) tree path; - int copy; { - register tree prev = 0, tmp, next; - for (tmp = path; tmp; tmp = next) + register tree prev = NULL_TREE, cur; + push_expression_obstack (); + for (cur = path; cur; cur = BINFO_INHERITANCE_CHAIN (cur)) { - if (copy) - tmp = copy_node (tmp); - next = BINFO_INHERITANCE_CHAIN (tmp); - BINFO_INHERITANCE_CHAIN (tmp) = prev; - prev = tmp; + tree r = copy_node (cur); + BINFO_INHERITANCE_CHAIN (r) = prev; + prev = r; } + pop_obstacks (); return prev; }