Never change BINFO_INHERITANCE_CHAIN.
authorJason Merrill <jason@yorick.cygnus.com>
Thu, 27 Aug 1998 15:30:49 +0000 (15:30 +0000)
committerJason Merrill <jason@gcc.gnu.org>
Thu, 27 Aug 1998 15:30:49 +0000 (11:30 -0400)
* 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

gcc/cp/ChangeLog
gcc/cp/class.c
gcc/cp/cp-tree.h
gcc/cp/decl.c
gcc/cp/init.c
gcc/cp/pt.c
gcc/cp/search.c
gcc/cp/tree.c

index 7044d92c5378d6895fc78a3c4f7806ac28a6deec..a5b99482fd33e6e95bf9dfdb8d1b203c798be85f 100644 (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>
 
        * class.c (build_vbase_path): Use reverse_path.
index 66b91436521cd884112f78b7a367b415b0627182..a836a095ee1297a606c14ad05efd7dcedde8fd70 100644 (file)
@@ -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);
 
index 532a5147c754ade62e7b1a823bfdcce68a55f34a..1ac399a977ed598b68e714820adee28d6b9fef4c 100644 (file)
@@ -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));
index 8e3b0722b86abd89cb84b93c68dacc7716a7393d..e3b67acc383be864a039b057660c02435f827334 100644 (file)
@@ -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
index f50483d235bf910c05fe203e7064d191644e936c..29408630e1cd6e7d8288ca1de874d4b2a1797009 100644 (file)
@@ -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);
index ddaf5fecb7a4a396cedb585fd395b7fc989312e2..b0b89c4c3d337d11f5ae63b78e36326723a14bc8 100644 (file)
@@ -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;
index 8e29bc1a2c576d216b4c4df36390b17eb8c0d7e5..33fd19bf6126fcfe7e903430ab6fca92e70e3c74 100644 (file)
@@ -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.
index feb1a44180f3590cbf2e6f563b8978253b134522..41475b5f46782f29b6c1c8f56fb5c434a64128c8 100644 (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,
                                    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 base_binfos = BINFO_BASETYPES (base_binfo);
-      tree chain = NULL_TREE;
-      int j;
+  tree binfos = BINFO_BASETYPES (binfo);
+  tree new_binfo;
+  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;
-       }
+  if (binfos == NULL_TREE)
+    return;
 
-      /* Completely unshare potentially shared data, and
-        update what is ours.  */
-      propagate_binfo_offsets (base_binfo, BINFO_OFFSET (base_binfo));
+  /* Now unshare the structure beneath BINFO.  */
+  for (j = TREE_VEC_LENGTH (binfos)-1;
+       j >= 0; j--)
+    {
+      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;
 }