class.c (build_vbase_path): Use reverse_path.
authorMark Mitchell <mark@markmitchell.com>
Thu, 27 Aug 1998 10:17:48 +0000 (10:17 +0000)
committerMark Mitchell <mmitchel@gcc.gnu.org>
Thu, 27 Aug 1998 10:17:48 +0000 (10:17 +0000)
* class.c (build_vbase_path): Use reverse_path.
(finish_base_struct): Move warnings for inaccessible bases to
layout_basetypes.
(modify_one_vtable): Remove check of TREE_USED (binfo).
(fixup_vtable_deltas1): Likewise.
* cp-tree.h (BINFO_INHERITANCE_CHAIN): Document here.
(xref_tag): Remove binfos parameter.
(make_binfo): Remove chain parameter.
(reverse_path): Add copy parameter.
* decl.c (init_decl_processing): Change calls to xref_tag.
(xref_tag): Remove binfos parameter.
(xref_basetypes): Change calls to make_binfo.
* decl2.c (grok_x_components): Change calls to xref_tag.
(handle_class_head): Likewise.
* friend.c (do_friend): Likewise.
* lex.c (make_lang_type): Change calls to make_binfo.
* parse.y (structsp): Change calls to xref_tag.
(named_complex_class_head_sans_basetype): Likewise.
(named_class_head): Likewise.
* rtti.c (init_rtti_processing): Likewise.
* search.c (compute_access): Change calls to reverse_path.
(dfs_get_vbase_types): Change calls to make_binfo.
(get_vbase_types): Remove dead code.
* tree.c (unshare_base_binfos): Change calls to make_binfo.
(layout_basetypes): Warn here about inaccessible bases.
(make_binfo): Remove chain parameter.
(reverse_path): Add copy parameter.

From-SVN: r22021

14 files changed:
gcc/cp/ChangeLog
gcc/cp/class.c
gcc/cp/cp-tree.h
gcc/cp/decl.c
gcc/cp/decl2.c
gcc/cp/friend.c
gcc/cp/lex.c
gcc/cp/parse.c
gcc/cp/parse.y
gcc/cp/rtti.c
gcc/cp/search.c
gcc/cp/tree.c
gcc/testsuite/g++.old-deja/g++.other/lookup2.C [new file with mode: 0644]
gcc/testsuite/g++.old-deja/g++.pt/lookup5.C [new file with mode: 0644]

index 446199364aa790ec32edfe71a056767fb5229d3b..7044d92c5378d6895fc78a3c4f7806ac28a6deec 100644 (file)
@@ -1,3 +1,33 @@
+1998-08-27  Mark Mitchell  <mark@markmitchell.com>
+
+       * class.c (build_vbase_path): Use reverse_path.
+       (finish_base_struct): Move warnings for inaccessible bases to
+       layout_basetypes.
+       (modify_one_vtable): Remove check of TREE_USED (binfo).
+       (fixup_vtable_deltas1): Likewise.
+       * cp-tree.h (BINFO_INHERITANCE_CHAIN): Document here.
+       (xref_tag): Remove binfos parameter.
+       (make_binfo): Remove chain parameter.
+       (reverse_path): Add copy parameter.
+       * decl.c (init_decl_processing): Change calls to xref_tag.
+       (xref_tag): Remove binfos parameter.
+       (xref_basetypes): Change calls to make_binfo.
+       * decl2.c (grok_x_components): Change calls to xref_tag.
+       (handle_class_head): Likewise.
+       * friend.c (do_friend): Likewise.
+       * lex.c (make_lang_type): Change calls to make_binfo.
+       * parse.y (structsp): Change calls to xref_tag.
+       (named_complex_class_head_sans_basetype): Likewise.
+       (named_class_head): Likewise.
+       * rtti.c (init_rtti_processing): Likewise.
+       * search.c (compute_access): Change calls to reverse_path.
+       (dfs_get_vbase_types): Change calls to make_binfo.
+       (get_vbase_types): Remove dead code.
+       * tree.c (unshare_base_binfos): Change calls to make_binfo.
+       (layout_basetypes): Warn here about inaccessible bases.
+       (make_binfo): Remove chain parameter.
+       (reverse_path): Add copy parameter.
+       
 1998-08-27  Jason Merrill  <jason@yorick.cygnus.com>
 
        * class.c: #if 0 complete_type_p.
index e86638eeda983bf27420426fdafa7fc9c3e4ef59..66b91436521cd884112f78b7a367b415b0627182 100644 (file)
@@ -266,17 +266,8 @@ build_vbase_path (code, type, expr, path, nonnull)
 
   if (BINFO_INHERITANCE_CHAIN (path))
     {
-      tree reverse_path = NULL_TREE;
-
       push_expression_obstack ();
-      while (path)
-       {
-         tree r = copy_node (path);
-         BINFO_INHERITANCE_CHAIN (r) = reverse_path;
-         reverse_path = r;
-         path = BINFO_INHERITANCE_CHAIN (path);
-       }
-      path = reverse_path;
+      path = reverse_path (path, /*copy=*/1);
       pop_obstacks ();
     }
 
@@ -1758,35 +1749,6 @@ finish_base_struct (t, b)
        }
     }
 
-  /* This comment said "Must come after offsets are fixed for all bases."
-     Well, now this happens before the offsets are fixed, but it seems to
-     work fine.  Guess we'll see...  */
-  for (i = 0; i < n_baseclasses; i++)
-    {
-      tree base_binfo = TREE_VEC_ELT (binfos, i);
-      tree basetype = BINFO_TYPE (base_binfo);
-
-      if (get_base_distance (basetype, t, 0, (tree*)0) == -2)
-       {
-         cp_warning ("direct base `%T' inaccessible in `%T' due to ambiguity",
-                     basetype, t);
-       }
-    }
-  {
-    tree v = get_vbase_types (t);
-
-    for (; v; v = TREE_CHAIN (v))
-      {
-       tree basetype = BINFO_TYPE (v);
-       if (get_base_distance (basetype, t, 0, (tree*)0) == -2)
-         {
-           if (extra_warnings)
-             cp_warning ("virtual base `%T' inaccessible in `%T' due to ambiguity",
-                         basetype, t);
-         }
-      }
-  }    
-
   {
     tree vfields;
     /* Find the base class with the largest number of virtual functions.  */
@@ -2413,10 +2375,6 @@ modify_one_vtable (binfo, t, fndecl, pfn)
                                    BINFO_OFFSET (binfo));
          this_offset = ssize_binop (MINUS_EXPR, offset, base_offset);
 
-         /* Make sure we can modify the derived association with immunity.  */
-         if (TREE_USED (binfo))
-           my_friendly_assert (0, 999);
-
          if (binfo == TYPE_BINFO (t))
            {
              /* In this case, it is *type*'s vtable we are modifying.
@@ -2516,9 +2474,6 @@ fixup_vtable_deltas1 (binfo, t)
          if (! tree_int_cst_equal (this_offset, delta))
            {
              /* Make sure we can modify the derived association with immunity.  */
-             if (TREE_USED (binfo))
-               my_friendly_assert (0, 999);
-
              if (binfo == TYPE_BINFO (t))
                {
                  /* In this case, it is *type*'s vtable we are modifying.
index 85d983cca3ae4e77cde7f3b812e0ab7036174f4e..532a5147c754ade62e7b1a823bfdcce68a55f34a 100644 (file)
@@ -966,6 +966,16 @@ struct lang_type
 \f
 /* Additional macros for inheritance information.  */
 
+/* The BINFO_INHERITANCE_CHAIN is used opposite to the description in
+   gcc/tree.h.  In particular if D is derived from B then the BINFO
+   for B (in D) will have a BINFO_INHERITANCE_CHAIN pointing to
+   D.  In tree.h, this pointer is described as pointing in other
+   direction.  
+
+   After a call to get_vbase_types, the vbases are chained together in
+   depth-first order via TREE_CHAIN.  Other than that, TREE_CHAIN is
+   unused.  */
+
 #ifdef MI_MATRIX
 /* When building a matrix to determine by a single lookup
    whether one class is derived from another or not,
@@ -2548,7 +2558,7 @@ extern int parmlist_is_exprlist                   PROTO((tree));
 extern int copy_args_p                         PROTO((tree));
 extern int grok_ctor_properties                        PROTO((tree, tree));
 extern void grok_op_properties                 PROTO((tree, int, int));
-extern tree xref_tag                           PROTO((tree, tree, tree, int));
+extern tree xref_tag                           PROTO((tree, tree, int));
 extern tree xref_tag_from_type                 PROTO((tree, tree, int));
 extern void xref_basetypes                     PROTO((tree, tree, tree, tree));
 extern tree start_enum                         PROTO((tree));
@@ -3005,9 +3015,9 @@ extern tree hash_tree_cons                        PROTO((int, int, int, tree, tree, tree));
 extern tree hash_tree_chain                    PROTO((tree, tree));
 extern tree hash_chainon                       PROTO((tree, tree));
 extern tree get_decl_list                      PROTO((tree));
-extern tree make_binfo                         PROTO((tree, tree, tree, tree, tree));
+extern tree make_binfo                         PROTO((tree, tree, tree, tree));
 extern tree binfo_value                                PROTO((tree, tree));
-extern tree reverse_path                       PROTO((tree));
+extern tree reverse_path                       PROTO((tree, int));
 extern int count_functions                     PROTO((tree));
 extern int is_overloaded_fn                    PROTO((tree));
 extern tree get_first_fn                       PROTO((tree));
index ad52979fb8e28e5beac5955410bb7e95c6f292ba..8e3b0722b86abd89cb84b93c68dacc7716a7393d 100644 (file)
@@ -6166,7 +6166,7 @@ init_decl_processing ()
     if (flag_honor_std)
       push_namespace (get_identifier ("std"));
     bad_alloc_type_node = xref_tag
-      (class_type_node, get_identifier ("bad_alloc"), NULL_TREE, 1);
+      (class_type_node, get_identifier ("bad_alloc"), 1);
     if (flag_honor_std)
       pop_namespace ();
     newtype = build_exception_variant
@@ -11415,9 +11415,9 @@ grok_op_properties (decl, virtualp, friendp)
    scope.)  */
 
 tree
-xref_tag (code_type_node, name, binfo, globalize)
+xref_tag (code_type_node, name, globalize)
      tree code_type_node;
-     tree name, binfo;
+     tree name;
      int globalize;
 {
   enum tag_types tag_code;
@@ -11623,9 +11623,6 @@ xref_tag (code_type_node, name, binfo, globalize)
        redeclare_class_template (ref, current_template_parms);
     }
 
-  if (binfo)
-    xref_basetypes (code_type_node, name, ref, binfo);
-
   /* Until the type is defined, tentatively accept whatever
      structure tag the user hands us.  */
   if (TYPE_SIZE (ref) == NULL_TREE
@@ -11662,7 +11659,7 @@ xref_tag_from_type (old, id, globalize)
   if (id == NULL_TREE)
     id = TYPE_IDENTIFIER (old);
 
-  return xref_tag (code_type_node, id, NULL_TREE, globalize);
+  return xref_tag (code_type_node, id, globalize);
 }
 
 void
@@ -11759,7 +11756,7 @@ xref_basetypes (code_type_node, name, ref, binfo)
   
          base_binfo = make_binfo (integer_zero_node, basetype,
                                   TYPE_BINFO_VTABLE (basetype),
-                                  TYPE_BINFO_VIRTUALS (basetype), NULL_TREE);
+                                  TYPE_BINFO_VIRTUALS (basetype));
  
          TREE_VEC_ELT (binfos, i) = base_binfo;
          TREE_VIA_PUBLIC (base_binfo) = via_public;
index b8c4370ceb901092a3d9cffea88993f611c3864a..098c8435c9df2acb9f44659b053c819ebd8e00d5 100644 (file)
@@ -945,7 +945,7 @@ grok_x_components (specs, components)
                x = DECL_NAME (CLASSTYPE_TI_TEMPLATE (t));
              else
                x = TYPE_IDENTIFIER (t);
-             t = xref_tag (tcode, x, NULL_TREE, 0);
+             t = xref_tag (tcode, x, 0);
            }
 
          if (ANON_UNION_TYPE_P (t))
@@ -989,7 +989,7 @@ grok_x_components (specs, components)
 
        case ENUMERAL_TYPE:
          tcode = enum_type_node;
-         t = xref_tag (tcode, TYPE_IDENTIFIER (t), NULL_TREE, 0);
+         t = xref_tag (tcode, TYPE_IDENTIFIER (t), 0);
          x = grok_enum_decls (NULL_TREE);
          return x;
          break;
@@ -4943,6 +4943,6 @@ handle_class_head (aggr, scope, id)
     cp_error ("no file-scope type named `%D'", id);
 
   id = xref_tag
-    (aggr, make_anon_name (), NULL_TREE, 1);
+    (aggr, make_anon_name (), 1);
   return TYPE_MAIN_DECL (id);
 }
index a566d0504f570747d213a37ddf92a9e4e3f75305..561c9d747b321beaaf2f1d86a6847d77c80dea9a 100644 (file)
@@ -476,7 +476,7 @@ do_friend (ctype, declarator, decl, parmdecls, flags, quals, funcdef_flag)
       if (decl == NULL_TREE)
        {
          cp_warning ("implicitly declaring `%T' as struct", declarator);
-         decl = xref_tag (record_type_node, declarator, NULL_TREE, 1);
+         decl = xref_tag (record_type_node, declarator, 1);
          decl = TYPE_MAIN_DECL (decl);
        }
 
index 8cd3eb54c6d4bf0fdd53e46640e1283022a00103..9d8f2d2ad06f207c9b382536e3454fa0d29383c6 100644 (file)
@@ -4623,8 +4623,7 @@ make_lang_type (code)
   CLASSTYPE_AS_LIST (t) = build_expr_list (NULL_TREE, t);
   SET_CLASSTYPE_INTERFACE_UNKNOWN_X (t, interface_unknown);
   CLASSTYPE_INTERFACE_ONLY (t) = interface_only;
-  TYPE_BINFO (t) = make_binfo (integer_zero_node, t, NULL_TREE, NULL_TREE,
-                              NULL_TREE);
+  TYPE_BINFO (t) = make_binfo (integer_zero_node, t, NULL_TREE, NULL_TREE);
   CLASSTYPE_BINFO_AS_LIST (t) = build_tree_list (NULL_TREE, TYPE_BINFO (t));
 
   /* Make sure this is laid out, for ease of use later.
index 5ae0a84275ee0506ef614b85c3b60e231edeb7ae..f64a24f8c80fe73a113d790e1438241f7f53798c 100644 (file)
@@ -3589,7 +3589,7 @@ static const short yycheck[] = {     4,
     77,    78,    79,    80,    81,    82,    83,    84
 };
 /* -*-C-*-  Note some compilers choke on comments on `#line' lines.  */
-#line 3 "/usr/cygnus/gnupro-98r1/share/bison.simple"
+#line 3 "/usr/lib/bison.simple"
 
 /* Skeleton output parser for bison,
    Copyright (C) 1984, 1989, 1990 Free Software Foundation, Inc.
@@ -3782,7 +3782,7 @@ __yy_memcpy (char *to, char *from, int count)
 #endif
 #endif
 \f
-#line 196 "/usr/cygnus/gnupro-98r1/share/bison.simple"
+#line 196 "/usr/lib/bison.simple"
 
 /* The user can define YYPARSE_PARAM as the name of an argument to be passed
    into yyparse.  The argument should have type void *.
@@ -6003,12 +6003,12 @@ case 470:
     break;}
 case 471:
 #line 2086 "parse.y"
-{ yyval.ftype.t = xref_tag (enum_type_node, yyvsp[0].ttype, NULL_TREE, 1); 
+{ yyval.ftype.t = xref_tag (enum_type_node, yyvsp[0].ttype, 1); 
                  yyval.ftype.new_type_flag = 0; ;
     break;}
 case 472:
 #line 2089 "parse.y"
-{ yyval.ftype.t = xref_tag (enum_type_node, yyvsp[0].ttype, NULL_TREE, 1); 
+{ yyval.ftype.t = xref_tag (enum_type_node, yyvsp[0].ttype, 1); 
                  yyval.ftype.new_type_flag = 0; ;
     break;}
 case 473:
@@ -6130,11 +6130,11 @@ case 496:
     break;}
 case 497:
 #line 2196 "parse.y"
-{ yyval.ttype = xref_tag (current_aggr, yyvsp[0].ttype, NULL_TREE, 0); ;
+{ yyval.ttype = xref_tag (current_aggr, yyvsp[0].ttype, 0); ;
     break;}
 case 498:
 #line 2201 "parse.y"
-{ yyval.ttype = xref_tag (current_aggr, yyvsp[0].ttype, NULL_TREE, 1); ;
+{ yyval.ttype = xref_tag (current_aggr, yyvsp[0].ttype, 1); ;
     break;}
 case 499:
 #line 2204 "parse.y"
@@ -6163,7 +6163,7 @@ case 500:
     break;}
 case 501:
 #line 2228 "parse.y"
-{ yyval.ttype = xref_tag (yyval.ttype, make_anon_name (), NULL_TREE, 0);
+{ yyval.ttype = xref_tag (yyval.ttype, make_anon_name (), 0);
                  yyungetc ('{', 1); ;
     break;}
 case 504:
@@ -7828,7 +7828,7 @@ case 870:
     break;}
 }
    /* the action file gets copied in in place of this dollarsign */
-#line 498 "/usr/cygnus/gnupro-98r1/share/bison.simple"
+#line 498 "/usr/lib/bison.simple"
 \f
   yyvsp -= yylen;
   yyssp -= yylen;
index c9842f9546fbae1febd90a61389c5745282c53d9..022e50b2854f6130df631ce643c416d6f71d3fcb 100644 (file)
@@ -2083,10 +2083,10 @@ structsp:
                  $$.new_type_flag = 1;
                  check_for_missing_semicolon ($$.t); }
        | ENUM identifier
-               { $$.t = xref_tag (enum_type_node, $2, NULL_TREE, 1); 
+               { $$.t = xref_tag (enum_type_node, $2, 1); 
                  $$.new_type_flag = 0; }
        | ENUM complex_type_name
-               { $$.t = xref_tag (enum_type_node, $2, NULL_TREE, 1); 
+               { $$.t = xref_tag (enum_type_node, $2, 1); 
                  $$.new_type_flag = 0; }
        | TYPENAME_KEYWORD typename_sub
                { $$.t = $2;
@@ -2193,12 +2193,12 @@ named_complex_class_head_sans_basetype:
 
 do_xref_defn:
          /* empty */  %prec EMPTY
-               { $<ttype>$ = xref_tag (current_aggr, $<ttype>0, NULL_TREE, 0); }
+               { $<ttype>$ = xref_tag (current_aggr, $<ttype>0, 0); }
        ;
 
 named_class_head:
          named_class_head_sans_basetype  %prec EMPTY
-               { $$ = xref_tag (current_aggr, $1, NULL_TREE, 1); }
+               { $$ = xref_tag (current_aggr, $1, 1); }
        | named_class_head_sans_basetype_defn do_xref_defn
           maybe_base_class_list  %prec EMPTY
                { 
@@ -2225,7 +2225,7 @@ named_class_head:
 
 unnamed_class_head:
          aggr '{'
-               { $$ = xref_tag ($$, make_anon_name (), NULL_TREE, 0);
+               { $$ = xref_tag ($$, make_anon_name (), 0);
                  yyungetc ('{', 1); }
        ;
 
index 0087bc394678a4399172d812e41468c1463b1d71..01c4a861ec25b0e1091c2369b0fdf013aea0382d 100644 (file)
@@ -60,7 +60,7 @@ init_rtti_processing ()
   if (flag_honor_std)
     push_namespace (get_identifier ("std"));
   type_info_type_node = xref_tag
-    (class_type_node, get_identifier ("type_info"), NULL_TREE, 1);
+    (class_type_node, get_identifier ("type_info"), 1);
   if (flag_honor_std)
     pop_namespace ();
   tinfo_fn_id = get_identifier ("__tf");
index 1d0f1c34920e986f24ca60fc7536c085e29a1967..8e29bc1a2c576d216b4c4df36390b17eb8c0d7e5 100644 (file)
@@ -1003,7 +1003,7 @@ compute_access (basetype_path, field)
     }
 
   /* must reverse more than one element */
-  basetype_path = reverse_path (basetype_path);
+  basetype_path = reverse_path (basetype_path, /*copy=*/0);
   types = basetype_path;
   via_protected = 0;
   access = access_default_node;
@@ -1049,7 +1049,7 @@ compute_access (basetype_path, field)
       else
        break;
     }
-  reverse_path (basetype_path);
+  reverse_path (basetype_path, /*copy=*/0);
 
   /* No special visibilities apply.  Use normal rules.  */
 
@@ -3196,10 +3196,12 @@ dfs_get_vbase_types (binfo)
 {
   if (TREE_VIA_VIRTUAL (binfo) && ! BINFO_VBASE_MARKED (binfo))
     {
-      vbase_types = make_binfo (integer_zero_node, binfo,
-                               BINFO_VTABLE (binfo),
-                               BINFO_VIRTUALS (binfo), vbase_types);
-      TREE_VIA_VIRTUAL (vbase_types) = 1;
+      tree new_vbase = make_binfo (integer_zero_node, binfo,
+                                  BINFO_VTABLE (binfo),
+                                  BINFO_VIRTUALS (binfo));
+      TREE_CHAIN (new_vbase) = vbase_types;
+      TREE_VIA_VIRTUAL (new_vbase) = 1;
+      vbase_types = new_vbase;
       SET_BINFO_VBASE_MARKED (binfo);
     }
   SET_BINFO_MARKED (binfo);
@@ -3214,11 +3216,7 @@ get_vbase_types (type)
   tree vbases;
   tree binfo;
 
-  if (TREE_CODE (type) == TREE_VEC)
-    binfo = type;
-  else
-    binfo = TYPE_BINFO (type);
-
+  binfo = TYPE_BINFO (type);
   vbase_types = NULL_TREE;
   dfs_walk (binfo, dfs_get_vbase_types, unmarkedp);
   dfs_walk (binfo, dfs_unmark, markedp);
@@ -4004,3 +4002,4 @@ types_overlap_p (empty_type, next_type)
   dfs_walk (TYPE_BINFO (empty_type), dfs_check_overlap, dfs_no_overlap_yet);
   return found_overlap;
 }
+
index 6f33ec86d10b029b1110d340e500da4890424490..feb1a44180f3590cbf2e6f563b8978253b134522 100644 (file)
@@ -646,8 +646,7 @@ unshare_base_binfos (base_binfo)
            = make_binfo (BINFO_OFFSET (base_base_binfo),
                          base_base_binfo,
                          BINFO_VTABLE (base_base_binfo),
-                         BINFO_VIRTUALS (base_base_binfo),
-                         chain);
+                         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);
@@ -677,9 +676,7 @@ layout_basetypes (rec, max)
   tree binfos = TYPE_BINFO_BASETYPES (rec);
   int i, n_baseclasses = binfos ? TREE_VEC_LENGTH (binfos) : 0;
 
-  /* Get all the virtual base types that this type uses.
-     The TREE_VALUE slot holds the virtual baseclass type.  */
-  tree vbase_types = get_vbase_types (rec);
+  tree vbase_types;
 
   unsigned int record_align = MAX (BITS_PER_UNIT, TYPE_ALIGN (rec));
   unsigned int desired_align;
@@ -694,7 +691,11 @@ layout_basetypes (rec, max)
     record_align = MAX (record_align, STRUCTURE_SIZE_BOUNDARY);
 #endif
 
-  CLASSTYPE_VBASECLASSES (rec) = vbase_types;
+  /* Get all the virtual base types that this type uses.  The
+     TREE_VALUE slot holds the virtual baseclass type.  Note that
+     get_vbase_types makes copies of the virtual base BINFOs, so that
+     the vbase_types are unshared.  */
+  CLASSTYPE_VBASECLASSES (rec) = vbase_types = get_vbase_types (rec);
 
   my_friendly_assert (TREE_CODE (TYPE_SIZE (rec)) == INTEGER_CST, 19970302);
   const_size = TREE_INT_CST_LOW (TYPE_SIZE (rec));
@@ -761,6 +762,11 @@ layout_basetypes (rec, max)
       else
        {
          my_friendly_assert (TREE_TYPE (field) == basetype, 23897);
+
+         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));
@@ -774,6 +780,14 @@ layout_basetypes (rec, max)
     {
       BINFO_INHERITANCE_CHAIN (vbase_types) = TYPE_BINFO (rec);
       unshare_base_binfos (vbase_types);
+
+      if (extra_warnings)
+       {
+         tree basetype = BINFO_TYPE (vbase_types);
+         if (get_base_distance (basetype, rec, 0, (tree*)0) == -2)
+           cp_warning ("virtual base `%T' inaccessible in `%T' due to ambiguity",
+                       basetype, rec);
+       }
     }
 
   return max;
@@ -1198,15 +1212,12 @@ get_decl_list (value)
    VTABLE is the virtual function table with which to initialize
    sub-objects of type TYPE.
 
-   VIRTUALS are the virtual functions sitting in VTABLE.
-
-   CHAIN are more associations we must retain.  */
+   VIRTUALS are the virtual functions sitting in VTABLE.  */
 
 tree
-make_binfo (offset, binfo, vtable, virtuals, chain)
+make_binfo (offset, binfo, vtable, virtuals)
      tree offset, binfo;
      tree vtable, virtuals;
-     tree chain;
 {
   tree new_binfo = make_tree_vec (7);
   tree type;
@@ -1219,10 +1230,6 @@ make_binfo (offset, binfo, vtable, virtuals, chain)
       binfo = TYPE_BINFO (binfo);
     }
 
-  TREE_CHAIN (new_binfo) = chain;
-  if (chain)
-    TREE_USED (new_binfo) = TREE_USED (chain);
-
   TREE_TYPE (new_binfo) = TYPE_MAIN_VARIANT (type);
   BINFO_OFFSET (new_binfo) = offset;
   BINFO_VTABLE (new_binfo) = vtable;
@@ -1251,13 +1258,22 @@ binfo_value (elem, type)
   return get_binfo (elem, type, 0);
 }
 
+/* Reverse 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.  */
+
 tree
-reverse_path (path)
+reverse_path (path, copy)
      tree path;
+     int copy;
 {
   register tree prev = 0, tmp, next;
   for (tmp = path; tmp; tmp = next)
     {
+      if (copy) 
+       tmp = copy_node (tmp);
       next = BINFO_INHERITANCE_CHAIN (tmp);
       BINFO_INHERITANCE_CHAIN (tmp) = prev;
       prev = tmp;
diff --git a/gcc/testsuite/g++.old-deja/g++.other/lookup2.C b/gcc/testsuite/g++.old-deja/g++.other/lookup2.C
new file mode 100644 (file)
index 0000000..0772399
--- /dev/null
@@ -0,0 +1,13 @@
+// Build don't link:
+
+struct B { 
+  int i;
+};
+
+struct D: virtual public B {
+  int i;
+};
+
+struct D2 : public D {
+  void f() { i = 3; }
+};
diff --git a/gcc/testsuite/g++.old-deja/g++.pt/lookup5.C b/gcc/testsuite/g++.old-deja/g++.pt/lookup5.C
new file mode 100644 (file)
index 0000000..e38b222
--- /dev/null
@@ -0,0 +1,14 @@
+// Build don't link:
+
+struct B { 
+  int i;
+};
+
+struct D: public B {
+  int i;
+};
+
+template <class T>
+struct D2 : public D {
+  void f() { i = 3; }
+};