This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Re: [C++] Fix 3130, 3131


Nathan Sidwell wrote:
> 
> Hi,
> here's a patch for 3130 and 3131. It builds and tests ok on
oops, typo in patch. This one's ok. BTW bootstrap just succeeded.

nathan
-- 
Dr Nathan Sidwell   ::   http://www.codesourcery.com   ::   CodeSourcery LLC
         'But that's a lie.' - 'Yes it is. What's your point?'
nathan@codesourcery.com : http://www.cs.bris.ac.uk/~nathan/ : nathan@acm.org
2001-06-12  Nathan Sidwell  <nathan@codesourcery.com>

	PR c++/3130, c++/3131
	* cp-tree.h (BINFO_UNSHARED_MARKED): New #define.
	* class.c (force_canonical_binfo_r): Move
	BINFO_UNSHARED_MARKED, BINFO_LOST_PRIMARY_P. Don't move
	virtual bases unless they're primary and what they're primary
	too has been moved.
	(dfs_unshared_virtual_bases): Use BINFO_UNSHARED_MARKED. Cope
	with morally virtual bases. Duplicate BINFO_LOST_PRIMARY_P and
	BINFO_PRIMARY_BASE_OF. Clear BINFO_VTABLE for all but the most
	derived binfo.
	(mark_primary_bases): Use BINFO_UNSHARED_MARKED.
	(layout_nonempty_base_or_field): Add most derived type
	parameter. Adjust.
	(layout_empty_base): Likewise.
	(build_base_field): Likewise.
	(build_base_fields): Likewise.
	(propagate_binfo_offsets): Add most derived type
	parameter. Skip non canonical virtual bases too.
	(dfs_set_offset_for_unshared_vbases): Don't skip primary
	bases. Do skip canonical bases.
	(layout_virtual_bases): Adjust.
	(layout_class_type): Adjust.
	(dfs_get_primary_binfo): Build list of virtual primary base
	candidates.
	(get_primary_binfo): Check that the shared virtual primary
	base candidate was found first.
	(accumulate_vtbl_inits): Don't do anything for non-vptr
	containing binfos. For case 1 primary virtual bases, keep
	checking that we've not emerged from the hierarchy of RTTI_BINFO.

Index: cp/class.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/class.c,v
retrieving revision 1.358.2.23
diff -c -3 -p -r1.358.2.23 class.c
*** class.c	2001/06/12 08:49:16	1.358.2.23
--- class.c	2001/06/12 16:32:41
*************** static void check_field_decl PARAMS ((tr
*** 144,152 ****
  static void check_field_decls PARAMS ((tree, tree *, int *, int *, int *, 
  				     int *));
  static bool build_base_field PARAMS ((record_layout_info, tree, int *,
! 				     splay_tree));
  static bool build_base_fields PARAMS ((record_layout_info, int *,
! 				      splay_tree));
  static tree build_vbase_pointer_fields PARAMS ((record_layout_info, int *));
  static tree build_vtbl_or_vbase_field PARAMS ((tree, tree, tree, tree, tree,
  					       int *));
--- 144,152 ----
  static void check_field_decls PARAMS ((tree, tree *, int *, int *, int *, 
  				     int *));
  static bool build_base_field PARAMS ((record_layout_info, tree, int *,
! 				     splay_tree, tree));
  static bool build_base_fields PARAMS ((record_layout_info, int *,
! 				      splay_tree, tree));
  static tree build_vbase_pointer_fields PARAMS ((record_layout_info, int *));
  static tree build_vtbl_or_vbase_field PARAMS ((tree, tree, tree, tree, tree,
  					       int *));
*************** static void layout_class_type PARAMS ((t
*** 159,165 ****
  static void fixup_pending_inline PARAMS ((tree));
  static void fixup_inline_methods PARAMS ((tree));
  static void set_primary_base PARAMS ((tree, tree, int *));
! static void propagate_binfo_offsets PARAMS ((tree, tree));
  static void layout_virtual_bases PARAMS ((tree, splay_tree));
  static tree dfs_set_offset_for_unshared_vbases PARAMS ((tree, void *));
  static void build_vbase_offset_vtbl_entries PARAMS ((tree, vtbl_init_data *));
--- 159,165 ----
  static void fixup_pending_inline PARAMS ((tree));
  static void fixup_inline_methods PARAMS ((tree));
  static void set_primary_base PARAMS ((tree, tree, int *));
! static void propagate_binfo_offsets PARAMS ((tree, tree, tree));
  static void layout_virtual_bases PARAMS ((tree, splay_tree));
  static tree dfs_set_offset_for_unshared_vbases PARAMS ((tree, void *));
  static void build_vbase_offset_vtbl_entries PARAMS ((tree, vtbl_init_data *));
*************** static void initialize_vtable PARAMS ((t
*** 181,189 ****
  static void initialize_array PARAMS ((tree, tree));
  static void layout_nonempty_base_or_field PARAMS ((record_layout_info,
  						   tree, tree,
! 						   splay_tree));
  static unsigned HOST_WIDE_INT end_of_class PARAMS ((tree, int));
! static bool layout_empty_base PARAMS ((tree, tree, splay_tree));
  static void accumulate_vtbl_inits PARAMS ((tree, tree, tree, tree, tree));
  static tree dfs_accumulate_vtbl_inits PARAMS ((tree, tree, tree, tree,
  					       tree));
--- 181,189 ----
  static void initialize_array PARAMS ((tree, tree));
  static void layout_nonempty_base_or_field PARAMS ((record_layout_info,
  						   tree, tree,
! 						   splay_tree, tree));
  static unsigned HOST_WIDE_INT end_of_class PARAMS ((tree, int));
! static bool layout_empty_base PARAMS ((tree, tree, splay_tree, tree));
  static void accumulate_vtbl_inits PARAMS ((tree, tree, tree, tree, tree));
  static tree dfs_accumulate_vtbl_inits PARAMS ((tree, tree, tree, tree,
  					       tree));
*************** force_canonical_binfo_r (to, from, type,
*** 1691,1696 ****
--- 1691,1700 ----
    BINFO_INDIRECT_PRIMARY_P (to)
            = BINFO_INDIRECT_PRIMARY_P (from);
    BINFO_INDIRECT_PRIMARY_P (from) = 0;
+   BINFO_UNSHARED_MARKED (to) = BINFO_UNSHARED_MARKED (from);
+   BINFO_UNSHARED_MARKED (from) = 0;
+   BINFO_LOST_PRIMARY_P (to) = BINFO_LOST_PRIMARY_P (from);
+   BINFO_LOST_PRIMARY_P (from) = 0;
    if (BINFO_PRIMARY_P (from))
      {
        tree primary = BINFO_PRIMARY_BASE_OF (from);
*************** force_canonical_binfo_r (to, from, type,
*** 1704,1710 ****
        BINFO_PRIMARY_BASE_OF (to) = primary;
        BINFO_PRIMARY_BASE_OF (from) = NULL_TREE;
      }
!   my_friendly_assert (same_type_p (BINFO_TYPE (to), BINFO_TYPE (from)), 20010104);
    mappings = tree_cons (from, to, mappings);
    for (i = 0; i != n_baseclasses; i++)
      {
--- 1708,1715 ----
        BINFO_PRIMARY_BASE_OF (to) = primary;
        BINFO_PRIMARY_BASE_OF (from) = NULL_TREE;
      }
!   my_friendly_assert (same_type_p (BINFO_TYPE (to), BINFO_TYPE (from)),
! 		      20010104);
    mappings = tree_cons (from, to, mappings);
    for (i = 0; i != n_baseclasses; i++)
      {
*************** force_canonical_binfo_r (to, from, type,
*** 1713,1721 ****
        
        if (TREE_VIA_VIRTUAL (from_binfo))
          {
!           tree shared_binfo = binfo_for_vbase (BINFO_TYPE (from_binfo), type);
!           
!           if (shared_binfo == from_binfo)
              force_canonical_binfo (to_binfo, from_binfo, type, mappings);
          }
        else
--- 1718,1727 ----
        
        if (TREE_VIA_VIRTUAL (from_binfo))
          {
! 	  if (BINFO_PRIMARY_P (from_binfo) &&
! 	      purpose_member (BINFO_PRIMARY_BASE_OF (from_binfo), mappings))
! 	    /* This base is a primary of some binfo we have already
! 	       reseated. We must reseat this one too.  */
              force_canonical_binfo (to_binfo, from_binfo, type, mappings);
          }
        else
*************** mark_primary_virtual_base (binfo, base_b
*** 1779,1785 ****
    delta = size_diffop (BINFO_OFFSET (binfo), BINFO_OFFSET (base_binfo));
    if (!integer_zerop (delta))
      {
!       propagate_binfo_offsets (base_binfo, delta);
        BINFO_OFFSET (base_binfo) = BINFO_OFFSET (binfo);
      }
    return base_binfo;
--- 1785,1791 ----
    delta = size_diffop (BINFO_OFFSET (binfo), BINFO_OFFSET (base_binfo));
    if (!integer_zerop (delta))
      {
!       propagate_binfo_offsets (base_binfo, delta, type);
        BINFO_OFFSET (base_binfo) = BINFO_OFFSET (binfo);
      }
    return base_binfo;
*************** mark_primary_virtual_base (binfo, base_b
*** 1787,1805 ****
  
  /* If BINFO is an unmarked virtual binfo for a class with a primary virtual
     base, then BINFO has no primary base in this graph.  Called from
!    mark_primary_bases. */
  
  static tree dfs_unshared_virtual_bases (binfo, data)
       tree binfo;
!      void *data ATTRIBUTE_UNUSED;
  {
!   if (TREE_VIA_VIRTUAL (binfo) && !BINFO_MARKED (binfo)
!       && CLASSTYPE_HAS_PRIMARY_BASE_P (BINFO_TYPE (binfo))
!       && TREE_VIA_VIRTUAL (CLASSTYPE_PRIMARY_BINFO (BINFO_TYPE (binfo))))
!     BINFO_LOST_PRIMARY_P (binfo) = 1;
! 
!   CLEAR_BINFO_MARKED (binfo);
    
    return NULL;
  }
  
--- 1793,1835 ----
  
  /* If BINFO is an unmarked virtual binfo for a class with a primary virtual
     base, then BINFO has no primary base in this graph.  Called from
!    mark_primary_bases.  DATA is the most derived type. */
  
  static tree dfs_unshared_virtual_bases (binfo, data)
       tree binfo;
!      void *data;
  {
!   tree t = (tree) data;
!   
!   if (!BINFO_UNSHARED_MARKED (binfo)
!       && CLASSTYPE_HAS_PRIMARY_BASE_P (BINFO_TYPE (binfo)))
!     {
!       /* This morally virtual base has a primary base when it
!          is a complete object. We need to locate the shared instance
!          of this binfo in the type dominated by T. We duplicate the
!          primary base information from there to here.  */
!       tree vbase;
!       tree unshared_base;
!       
!       for (vbase = binfo; !TREE_VIA_VIRTUAL (vbase);
! 	   vbase = BINFO_INHERITANCE_CHAIN (vbase))
! 	continue;
!       unshared_base = get_original_base (binfo,
! 					 binfo_for_vbase (BINFO_TYPE (vbase),
! 							  t));
!       my_friendly_assert (unshared_base != binfo, 20010612);
!       BINFO_LOST_PRIMARY_P (binfo) = BINFO_LOST_PRIMARY_P (unshared_base);
!       if (!BINFO_LOST_PRIMARY_P (binfo))
! 	      BINFO_PRIMARY_BASE_OF (get_primary_binfo (binfo)) = binfo;
!     }
!   
!   if (binfo != TYPE_BINFO (t))
!     /* The vtable fields will have been copied when duplicating the
!        base binfos. That information is bogus, make sure we don't try
!        and use it. */
!     BINFO_VTABLE (binfo) = NULL_TREE;
    
+   BINFO_UNSHARED_MARKED (binfo) = 0;
    return NULL;
  }
  
*************** mark_primary_bases (type)
*** 1828,1839 ****
  
        if (base_binfo)
          BINFO_PRIMARY_BASE_OF (base_binfo) = binfo;
!       SET_BINFO_MARKED (binfo);
      }
!   /* There could remain unshared virtual bases which were not visited
       in the inheritance graph walk. These bases will have lost their
!      primary base (should they have one). We must now find them. */
!   dfs_walk (TYPE_BINFO (type), dfs_unshared_virtual_bases, NULL, NULL);
  }
  
  /* Make the BINFO the primary base of T.  */
--- 1858,1870 ----
  
        if (base_binfo)
          BINFO_PRIMARY_BASE_OF (base_binfo) = binfo;
!       
!       BINFO_UNSHARED_MARKED (binfo) = 1;
      }
!   /* There could remain unshared morally virtual bases which were not visited
       in the inheritance graph walk. These bases will have lost their
!      virtual primary base (should they have one). We must now find them. */
!   dfs_walk (TYPE_BINFO (type), dfs_unshared_virtual_bases, NULL, type);
  }
  
  /* Make the BINFO the primary base of T.  */
*************** layout_conflict_p (type, offset, offsets
*** 3948,3962 ****
  /* DECL is a FIELD_DECL corresponding either to a base subobject of a
     non-static data member of the type indicated by RLI.  BINFO is the
     binfo corresponding to the base subobject, OFFSETS maps offsets to
!    types already located at those offsets.  This function determines
!    the position of the DECL.  */
  
  static void
! layout_nonempty_base_or_field (rli, decl, binfo, offsets)
       record_layout_info rli;
       tree decl;
       tree binfo;
       splay_tree offsets;
  {
    tree offset = NULL_TREE;
    tree type = TREE_TYPE (decl);
--- 3979,3994 ----
  /* DECL is a FIELD_DECL corresponding either to a base subobject of a
     non-static data member of the type indicated by RLI.  BINFO is the
     binfo corresponding to the base subobject, OFFSETS maps offsets to
!    types already located at those offsets.  T is the most derived
!    type.  This function determines the position of the DECL.  */
  
  static void
! layout_nonempty_base_or_field (rli, decl, binfo, offsets, t)
       record_layout_info rli;
       tree decl;
       tree binfo;
       splay_tree offsets;
+      tree t;
  {
    tree offset = NULL_TREE;
    tree type = TREE_TYPE (decl);
*************** layout_nonempty_base_or_field (rli, decl
*** 4013,4036 ****
  	break;
      }
  
!   /* Now that we know where it wil be placed, update its
       BINFO_OFFSET.  */
    if (binfo && CLASS_TYPE_P (BINFO_TYPE (binfo)))
      propagate_binfo_offsets (binfo, 
! 			     convert (ssizetype, offset));
  }
  
  /* Layout the empty base BINFO.  EOC indicates the byte currently just
     past the end of the class, and should be correctly aligned for a
     class of the type indicated by BINFO; OFFSETS gives the offsets of
!    the empty bases allocated so far. Return non-zero iff we added it
!    at the end. */
  
  static bool
! layout_empty_base (binfo, eoc, offsets)
       tree binfo;
       tree eoc;
       splay_tree offsets;
  {
    tree alignment;
    tree basetype = BINFO_TYPE (binfo);
--- 4045,4069 ----
  	break;
      }
  
!   /* Now that we know where it will be placed, update its
       BINFO_OFFSET.  */
    if (binfo && CLASS_TYPE_P (BINFO_TYPE (binfo)))
      propagate_binfo_offsets (binfo, 
! 			     convert (ssizetype, offset), t);
  }
  
  /* Layout the empty base BINFO.  EOC indicates the byte currently just
     past the end of the class, and should be correctly aligned for a
     class of the type indicated by BINFO; OFFSETS gives the offsets of
!    the empty bases allocated so far. T is the most derived
!    type.  Return non-zero iff we added it at the end. */
  
  static bool
! layout_empty_base (binfo, eoc, offsets, t)
       tree binfo;
       tree eoc;
       splay_tree offsets;
+      tree t;
  {
    tree alignment;
    tree basetype = BINFO_TYPE (binfo);
*************** layout_empty_base (binfo, eoc, offsets)
*** 4050,4056 ****
        /* That didn't work.  Now, we move forward from the next
  	 available spot in the class.  */
        atend = true;
!       propagate_binfo_offsets (binfo, convert (ssizetype, eoc));
        while (1) 
  	{
  	  if (!layout_conflict_p (BINFO_TYPE (binfo),
--- 4083,4089 ----
        /* That didn't work.  Now, we move forward from the next
  	 available spot in the class.  */
        atend = true;
!       propagate_binfo_offsets (binfo, convert (ssizetype, eoc), t);
        while (1) 
  	{
  	  if (!layout_conflict_p (BINFO_TYPE (binfo),
*************** layout_empty_base (binfo, eoc, offsets)
*** 4061,4067 ****
  	    break;
  
  	  /* There's overlap here, too.  Bump along to the next spot.  */
! 	  propagate_binfo_offsets (binfo, alignment);
  	}
      }
    return atend;
--- 4094,4100 ----
  	    break;
  
  	  /* There's overlap here, too.  Bump along to the next spot.  */
! 	  propagate_binfo_offsets (binfo, alignment, t);
  	}
      }
    return atend;
*************** layout_empty_base (binfo, eoc, offsets)
*** 4070,4084 ****
  /* Build a FIELD_DECL for the base given by BINFO in the class
     indicated by RLI.  If the new object is non-empty, clear *EMPTY_P.
     *BASE_ALIGN is a running maximum of the alignments of any base
!    class.  OFFSETS gives the location of empty base subobjects. Return
!    non-zero if the new object cannot be nearly-empty. */
  
  static bool
! build_base_field (rli, binfo, empty_p, offsets)
       record_layout_info rli;
       tree binfo;
       int *empty_p;
       splay_tree offsets;
  {
    tree basetype = BINFO_TYPE (binfo);
    tree decl;
--- 4103,4119 ----
  /* Build a FIELD_DECL for the base given by BINFO in the class
     indicated by RLI.  If the new object is non-empty, clear *EMPTY_P.
     *BASE_ALIGN is a running maximum of the alignments of any base
!    class.  OFFSETS gives the location of empty base subobjects.  T is
!    the most derived type.  Return non-zero if the new object cannot be
!    nearly-empty. */
  
  static bool
! build_base_field (rli, binfo, empty_p, offsets, t)
       record_layout_info rli;
       tree binfo;
       int *empty_p;
       splay_tree offsets;
+      tree t;
  {
    tree basetype = BINFO_TYPE (binfo);
    tree decl;
*************** build_base_field (rli, binfo, empty_p, o
*** 4106,4112 ****
        /* Try to place the field.  It may take more than one try if we
  	 have a hard time placing the field without putting two
  	 objects of the same type at the same address.  */
!       layout_nonempty_base_or_field (rli, decl, binfo, offsets);
      }
    else
      {
--- 4141,4147 ----
        /* Try to place the field.  It may take more than one try if we
  	 have a hard time placing the field without putting two
  	 objects of the same type at the same address.  */
!       layout_nonempty_base_or_field (rli, decl, binfo, offsets, t);
      }
    else
      {
*************** build_base_field (rli, binfo, empty_p, o
*** 4116,4122 ****
  	 byte-aligned.  */
        eoc = tree_low_cst (rli_size_unit_so_far (rli), 0);
        eoc = CEIL (eoc, DECL_ALIGN_UNIT (decl)) * DECL_ALIGN_UNIT (decl);
!       atend |= layout_empty_base (binfo, size_int (eoc), offsets);
      }
  
    /* Record the offsets of BINFO and its base subobjects.  */
--- 4151,4157 ----
  	 byte-aligned.  */
        eoc = tree_low_cst (rli_size_unit_so_far (rli), 0);
        eoc = CEIL (eoc, DECL_ALIGN_UNIT (decl)) * DECL_ALIGN_UNIT (decl);
!       atend |= layout_empty_base (binfo, size_int (eoc), offsets, t);
      }
  
    /* Record the offsets of BINFO and its base subobjects.  */
*************** build_base_field (rli, binfo, empty_p, o
*** 4128,4141 ****
  }
  
  /* Layout all of the non-virtual base classes.  Record empty
!    subobjects in OFFSETS. Return non-zero if the type cannot be nearly
!    empty.  */
  
  static bool
! build_base_fields (rli, empty_p, offsets)
       record_layout_info rli;
       int *empty_p;
       splay_tree offsets;
  {
    /* Chain to hold all the new FIELD_DECLs which stand in for base class
       subobjects.  */
--- 4163,4177 ----
  }
  
  /* Layout all of the non-virtual base classes.  Record empty
!    subobjects in OFFSETS.  T is the most derived type.  Return
!    non-zero if the type cannot be nearly empty.  */
  
  static bool
! build_base_fields (rli, empty_p, offsets, t)
       record_layout_info rli;
       int *empty_p;
       splay_tree offsets;
+      tree t;
  {
    /* Chain to hold all the new FIELD_DECLs which stand in for base class
       subobjects.  */
*************** build_base_fields (rli, empty_p, offsets
*** 4148,4154 ****
       first.  */
    if (CLASSTYPE_HAS_PRIMARY_BASE_P (rec))
      build_base_field (rli, CLASSTYPE_PRIMARY_BINFO (rec), 
! 		      empty_p, offsets);
  
    /* Now allocate the rest of the bases.  */
    for (i = 0; i < n_baseclasses; ++i)
--- 4184,4190 ----
       first.  */
    if (CLASSTYPE_HAS_PRIMARY_BASE_P (rec))
      build_base_field (rli, CLASSTYPE_PRIMARY_BINFO (rec), 
! 		      empty_p, offsets, t);
  
    /* Now allocate the rest of the bases.  */
    for (i = 0; i < n_baseclasses; ++i)
*************** build_base_fields (rli, empty_p, offsets
*** 4169,4175 ****
  	  && !BINFO_PRIMARY_P (base_binfo))
  	continue;
  
!       atend |= build_base_field (rli, base_binfo, empty_p, offsets);
      }
    return atend;
  }
--- 4205,4211 ----
  	  && !BINFO_PRIMARY_P (base_binfo))
  	continue;
  
!       atend |= build_base_field (rli, base_binfo, empty_p, offsets, t);
      }
    return atend;
  }
*************** fixup_inline_methods (type)
*** 4743,4751 ****
     OFFSET, which is a type offset, is number of bytes.  */
  
  static void
! propagate_binfo_offsets (binfo, offset)
       tree binfo;
       tree offset;
  {
    int i;
    tree primary_binfo;
--- 4779,4788 ----
     OFFSET, which is a type offset, is number of bytes.  */
  
  static void
! propagate_binfo_offsets (binfo, offset, t)
       tree binfo;
       tree offset;
+      tree t;
  {
    int i;
    tree primary_binfo;
*************** propagate_binfo_offsets (binfo, offset)
*** 4766,4774 ****
      {
        tree base_binfo;
  
!       /* On the first through the loop, do the primary base.  Because
! 	 the primary base need not be an immediate base, we must
! 	 handle the primary base specially.  */
        if (i == -1) 
  	{
  	  if (!primary_binfo) 
--- 4803,4811 ----
      {
        tree base_binfo;
  
!       /* On the first time through the loop, do the primary base.
! 	 Because the primary base need not be an immediate base, we
! 	 must handle the primary base specially.  */
        if (i == -1) 
  	{
  	  if (!primary_binfo) 
*************** propagate_binfo_offsets (binfo, offset)
*** 4784,4795 ****
  	    continue;
  	}
  
!       /* Skip virtual bases that aren't our primary base.  */
        if (TREE_VIA_VIRTUAL (base_binfo)
! 	  && BINFO_PRIMARY_BASE_OF (base_binfo) != binfo)
  	continue;
  
!       propagate_binfo_offsets (base_binfo, offset);
      }
  }
  
--- 4821,4833 ----
  	    continue;
  	}
  
!       /* Skip virtual bases that aren't our canonical primary base.  */
        if (TREE_VIA_VIRTUAL (base_binfo)
! 	  && (BINFO_PRIMARY_BASE_OF (base_binfo) != binfo
! 	      || base_binfo != binfo_for_vbase (BINFO_TYPE (base_binfo), t)))
  	continue;
  
!       propagate_binfo_offsets (base_binfo, offset, t);
      }
  }
  
*************** dfs_set_offset_for_unshared_vbases (binf
*** 4803,4817 ****
    /* If this is a virtual base, make sure it has the same offset as
       the shared copy.  If it's a primary base, then we know it's
       correct.  */
!   if (TREE_VIA_VIRTUAL (binfo) && !BINFO_PRIMARY_P (binfo))
      {
        tree t = (tree) data;
        tree vbase;
        tree offset;
        
        vbase = binfo_for_vbase (BINFO_TYPE (binfo), t);
!       offset = size_diffop (BINFO_OFFSET (vbase), BINFO_OFFSET (binfo));
!       propagate_binfo_offsets (binfo, offset);
      }
  
    return NULL_TREE;
--- 4841,4858 ----
    /* If this is a virtual base, make sure it has the same offset as
       the shared copy.  If it's a primary base, then we know it's
       correct.  */
!   if (TREE_VIA_VIRTUAL (binfo))
      {
        tree t = (tree) data;
        tree vbase;
        tree offset;
        
        vbase = binfo_for_vbase (BINFO_TYPE (binfo), t);
!       if (vbase != binfo)
! 	{
! 	  offset = size_diffop (BINFO_OFFSET (vbase), BINFO_OFFSET (binfo));
! 	  propagate_binfo_offsets (binfo, offset, t);
! 	}
      }
  
    return NULL_TREE;
*************** layout_virtual_bases (t, offsets)
*** 4881,4887 ****
  	  if (is_empty_class (basetype))
  	    layout_empty_base (vbase,
  			       size_int (CEIL (dsize, BITS_PER_UNIT)),
! 			       offsets);
  	  else
  	    {
  	      tree offset;
--- 4922,4928 ----
  	  if (is_empty_class (basetype))
  	    layout_empty_base (vbase,
  			       size_int (CEIL (dsize, BITS_PER_UNIT)),
! 			       offsets, t);
  	  else
  	    {
  	      tree offset;
*************** layout_virtual_bases (t, offsets)
*** 4892,4898 ****
  					     BINFO_OFFSET (vbase)));
  
  	      /* And compute the offset of the virtual base.  */
! 	      propagate_binfo_offsets (vbase, offset);
  	      /* Every virtual baseclass takes a least a UNIT, so that
  		 we can take it's address and get something different
  		 for each base.  */
--- 4933,4939 ----
  					     BINFO_OFFSET (vbase)));
  
  	      /* And compute the offset of the virtual base.  */
! 	      propagate_binfo_offsets (vbase, offset, t);
  	      /* Every virtual baseclass takes a least a UNIT, so that
  		 we can take it's address and get something different
  		 for each base.  */
*************** layout_class_type (t, empty_p, vfuns_p, 
*** 5070,5076 ****
    /* Build FIELD_DECLs for all of the non-virtual base-types.  */
    empty_base_offsets = splay_tree_new (splay_tree_compare_integer_csts, 
  				       NULL, NULL);
!   if (build_base_fields (rli, empty_p, empty_base_offsets))
      CLASSTYPE_NEARLY_EMPTY_P (t) = 0;
    
    /* Add pointers to all of our virtual base-classes.  */
--- 5111,5117 ----
    /* Build FIELD_DECLs for all of the non-virtual base-types.  */
    empty_base_offsets = splay_tree_new (splay_tree_compare_integer_csts, 
  				       NULL, NULL);
!   if (build_base_fields (rli, empty_p, empty_base_offsets, t))
      CLASSTYPE_NEARLY_EMPTY_P (t) = 0;
    
    /* Add pointers to all of our virtual base-classes.  */
*************** layout_class_type (t, empty_p, vfuns_p, 
*** 5132,5138 ****
  	padding = NULL_TREE;
  
        layout_nonempty_base_or_field (rli, field, NULL_TREE,
! 				     empty_base_offsets);
  
        /* If we needed additional padding after this field, add it
  	 now.  */
--- 5173,5179 ----
  	padding = NULL_TREE;
  
        layout_nonempty_base_or_field (rli, field, NULL_TREE,
! 				     empty_base_offsets, t);
  
        /* If we needed additional padding after this field, add it
  	 now.  */
*************** layout_class_type (t, empty_p, vfuns_p, 
*** 5149,5155 ****
  	  DECL_USER_ALIGN (padding_field) = 0;
  	  layout_nonempty_base_or_field (rli, padding_field,
  					 NULL_TREE, 
! 					 empty_base_offsets);
  	}
      }
  
--- 5190,5196 ----
  	  DECL_USER_ALIGN (padding_field) = 0;
  	  layout_nonempty_base_or_field (rli, padding_field,
  					 NULL_TREE, 
! 					 empty_base_offsets, t);
  	}
      }
  
*************** get_vtbl_decl_for_binfo (binfo)
*** 6733,6750 ****
    return decl;
  }
  
! /* Called from get_primary_binfo via dfs_walk.  */
  
  static tree
  dfs_get_primary_binfo (binfo, data)
       tree binfo;
       void *data;
  {
!   tree primary_base = (tree) data;
  
    if (TREE_VIA_VIRTUAL (binfo) 
!       && same_type_p (BINFO_TYPE (binfo), BINFO_TYPE (primary_base)))
!     return binfo;
    
    return NULL_TREE;
  }
--- 6774,6797 ----
    return decl;
  }
  
! /* Called from get_primary_binfo via dfs_walk.  DATA is a TREE_LIST
!    who's TREE_PURPOSE is the TYPE of the required primary base and
!    who's TREE_VALUE is a list of candidate binfos that we fill in. */
  
  static tree
  dfs_get_primary_binfo (binfo, data)
       tree binfo;
       void *data;
  {
!   tree cons = (tree) data;
!   tree primary_base = TREE_PURPOSE (cons);
  
    if (TREE_VIA_VIRTUAL (binfo) 
!       && same_type_p (BINFO_TYPE (binfo), primary_base))
!     /* This is the right type of binfo, but it might be an unshared
!        instance, and the shared instance is later in the dfs walk.  We
!        must keep looking.  */
!     TREE_VALUE (cons) = tree_cons (NULL, binfo, TREE_VALUE (cons));
    
    return NULL_TREE;
  }
*************** get_primary_binfo (binfo)
*** 6762,6768 ****
  {
    tree primary_base;
    tree result;
! 
    primary_base = CLASSTYPE_PRIMARY_BINFO (BINFO_TYPE (binfo));
    if (!primary_base)
      return NULL_TREE;
--- 6809,6816 ----
  {
    tree primary_base;
    tree result;
!   tree virtuals;
!   
    primary_base = CLASSTYPE_PRIMARY_BINFO (BINFO_TYPE (binfo));
    if (!primary_base)
      return NULL_TREE;
*************** get_primary_binfo (binfo)
*** 6790,6798 ****
  
    /* For a primary virtual base, we have to scan the entire hierarchy
       rooted at BINFO; the virtual base could be an indirect virtual
!      base.  */
!   result = dfs_walk (binfo, dfs_get_primary_binfo, NULL, primary_base);
!   my_friendly_assert (result != NULL_TREE, 20000730);
    return result;
  }
  
--- 6838,6885 ----
  
    /* For a primary virtual base, we have to scan the entire hierarchy
       rooted at BINFO; the virtual base could be an indirect virtual
!      base.  There could be more than one instance of the primary base
!      in the hierarchy, and if one is the canonical binfo we want that
!      one.  If it exists, it should be the first one we find, but as a
!      consistency check we find them all and make sure.  */
!   virtuals = build_tree_list (BINFO_TYPE (primary_base), NULL_TREE);
!   dfs_walk (binfo, dfs_get_primary_binfo, NULL, virtuals);
!   virtuals = TREE_VALUE (virtuals);
!   
!   /* We must have found at least one instance.  */
!   my_friendly_assert (virtuals, 20010612);
! 
!   if (TREE_CHAIN (virtuals))
!     {
!       /* We found more than one instance of the base. We must make
!          sure that, if one is the canonical one, it is the first one
!          we found. As the chain is in reverse dfs order, that means
!          the last on the list.  */
!       tree complete_binfo;
!       tree canonical;
!       
!       for (complete_binfo = binfo;
! 	   BINFO_INHERITANCE_CHAIN (complete_binfo);
! 	   complete_binfo = BINFO_INHERITANCE_CHAIN (complete_binfo))
! 	continue;
!       canonical = binfo_for_vbase (BINFO_TYPE (primary_base),
! 				   BINFO_TYPE (complete_binfo));
!       
!       for (; virtuals; virtuals = TREE_CHAIN (virtuals))
! 	{
! 	  result = TREE_VALUE (virtuals);
! 
! 	  if (canonical == result)
! 	    {
! 	      /* This is the unshared instance. Make sure it was the
! 		 first one found.  */
! 	      my_friendly_assert (!TREE_CHAIN (virtuals), 20010612);
! 	      break;
! 	    }
! 	}
!     }
!   else
!     result = TREE_VALUE (virtuals);
    return result;
  }
  
*************** accumulate_vtbl_inits (binfo, orig_binfo
*** 7493,7498 ****
--- 7580,7589 ----
  				   BINFO_TYPE (orig_binfo)),
  		      20000517);
  
+   /* If it doesn't have a vpte, we don't do anything. */
+   if (!TYPE_CONTAINS_VPTR_P (BINFO_TYPE (binfo)))
+     return;
+   
    /* If we're building a construction vtable, we're not interested in
       subobjects that don't require construction vtables.  */
    if (ctor_vtbl_p 
*************** dfs_accumulate_vtbl_inits (binfo, orig_b
*** 7578,7587 ****
  
  	      for (; b; b = BINFO_PRIMARY_BASE_OF (b))
  		{
  		  primary = b;
  		  orig_primary = BINFO_PRIMARY_BASE_OF (orig_primary);
- 		  if (b == rtti_binfo)
- 		    break;
  		}
  	    }
  	  else
--- 7669,7688 ----
  
  	      for (; b; b = BINFO_PRIMARY_BASE_OF (b))
  		{
+ 		  tree probe;
+ 
+ 		  /* See if B is still within the hierarchy starting
+ 		     at RTTI_BINFO. */
+ 		  for (probe = b; probe;
+ 		       probe = BINFO_INHERITANCE_CHAIN (probe))
+ 		    if (probe == rtti_binfo)
+ 		      break;
+ 		  
+ 		  if (!probe)
+ 		    break;
+ 		  
  		  primary = b;
  		  orig_primary = BINFO_PRIMARY_BASE_OF (orig_primary);
  		}
  	    }
  	  else
Index: cp/cp-tree.h
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/cp-tree.h,v
retrieving revision 1.572.2.29
diff -c -3 -p -r1.572.2.29 cp-tree.h
*** cp-tree.h	2001/06/06 21:51:10	1.572.2.29
--- cp-tree.h	2001/06/12 16:32:53
*************** struct lang_type
*** 1656,1661 ****
--- 1656,1665 ----
     inheritance is indicated by the absence of the other two flags, not
     by TREE_VIA_PRIVATE, which is unused.  */
  
+ /* Mark the binfo, whether shared or not. Each instance of a virtual
+    base can be separately marked.  */
+ #define BINFO_UNSHARED_MARKED(NODE) TREE_LANG_FLAG_0(NODE)
+ 
  /* Nonzero means marked by DFS or BFS search, including searches
     by `get_binfo' and `get_base_distance'.  */
  #define BINFO_MARKED(NODE) (TREE_VIA_VIRTUAL(NODE)?CLASSTYPE_MARKED(BINFO_TYPE(NODE)):TREE_LANG_FLAG_0(NODE))

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]