This is the mail archive of the gcc-bugs@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: g++ bug on Alpha Linux


>>>>> "Anthony" == Anthony Green <green@cygnus.com> writes:

    Anthony> I just bootstrapped a g++ from the latest cvs sources on
    Anthony> an Alpha Linux box.  When I compile the following code
    Anthony> derived from libgcj with `-c -fno-rtti' I get:

Oops -- my fault.  Fixed thusly.

--
Mark Mitchell                   mark@codesourcery.com
CodeSourcery, LLC               http://www.codesourcery.com

2000-01-30  Mark Mitchell  <mark@codesourcery.com>

	* cp/class.c (build_vtable): Rename to build_primary_vtable.
	(prepare_fresh_vtable): Rename to build_secondary_vtable.
	(make_new_vtable): New function.
	(modify_vtable_entry): Handle generation of new vtables correctly.
	(modify_one_vtable): Remove unused parameter.
	(dfs_fixup_vtable_deltas): Likewise.
	(override_one_vtable): Use build_secondary_vtable.
	(finish_struct_1): Use build_primary_vtable and
	build_secondary_vtable.

Index: testsuite/g++.old-deja/g++.other/virtual7.C
===================================================================
RCS file: virtual7.C
diff -N virtual7.C
*** /dev/null	Tue May  5 13:32:27 1998
--- virtual7.C	Sun Jan 30 20:00:14 2000
***************
*** 0 ****
--- 1,17 ----
+ // Build don't link:
+ // Special g++ Options: -fno-rtti
+ // Origin: Anthony Green <green@cygnus.com>
+ 
+ class _JvObjectPrefix
+ {
+ protected:
+   virtual void finalize (void) = 0;
+ };
+ 
+ class Object : public _JvObjectPrefix
+ {
+ protected:
+   virtual void finalize (void);
+ };
+ 
+ Object x;
Index: cp/class.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/class.c,v
retrieving revision 1.249
diff -c -p -r1.249 class.c
*** class.c	2000/01/29 15:47:14	1.249
--- class.c	2000/01/31 04:00:18
*************** static tree get_vtable_name PARAMS ((tre
*** 80,91 ****
  static tree get_derived_offset PARAMS ((tree, tree));
  static tree get_basefndecls PARAMS ((tree, tree));
  static void set_rtti_entry PARAMS ((tree, tree, tree));
! static void build_vtable PARAMS ((tree, tree));
! static void prepare_fresh_vtable PARAMS ((tree, tree));
  static tree dfs_fixup_vtable_deltas PARAMS ((tree, void *));
  static tree dfs_finish_vtbls PARAMS ((tree, void *));
  static void finish_vtbls PARAMS ((tree));
! static void modify_vtable_entry PARAMS ((tree, tree, tree, tree));
  static void add_virtual_function PARAMS ((tree *, tree *, int *, tree, tree));
  static tree delete_duplicate_fields_1 PARAMS ((tree, tree));
  static void delete_duplicate_fields PARAMS ((tree));
--- 80,91 ----
  static tree get_derived_offset PARAMS ((tree, tree));
  static tree get_basefndecls PARAMS ((tree, tree));
  static void set_rtti_entry PARAMS ((tree, tree, tree));
! static int build_primary_vtable PARAMS ((tree, tree));
! static int build_secondary_vtable PARAMS ((tree, tree));
  static tree dfs_fixup_vtable_deltas PARAMS ((tree, void *));
  static tree dfs_finish_vtbls PARAMS ((tree, void *));
  static void finish_vtbls PARAMS ((tree));
! static void modify_vtable_entry PARAMS ((tree, tree, tree, tree *));
  static void add_virtual_function PARAMS ((tree *, tree *, int *, tree, tree));
  static tree delete_duplicate_fields_1 PARAMS ((tree, tree));
  static void delete_duplicate_fields PARAMS ((tree));
*************** static tree dfs_count_virtuals PARAMS ((
*** 151,156 ****
--- 151,157 ----
  static void start_vtable PARAMS ((tree, int *));
  static void layout_vtable_decl PARAMS ((tree, int));
  static int num_vfun_entries PARAMS ((tree));
+ static int make_new_vtable PARAMS ((tree, tree));
  
  /* Variables shared between class.c and call.c.  */
  
*************** get_vtable_name (type)
*** 903,909 ****
    int i;
    for (i = 0; ptr[i] == OPERATOR_TYPENAME_FORMAT[i]; i++) ;
  #if 0
!   /* We don't take off the numbers; prepare_fresh_vtable uses the
       DECL_ASSEMBLER_NAME for the type, which includes the number
       in `3foo'.  If we were to pull them off here, we'd end up with
       something like `_vt.foo.3bar', instead of a uniform definition.  */
--- 904,910 ----
    int i;
    for (i = 0; ptr[i] == OPERATOR_TYPENAME_FORMAT[i]; i++) ;
  #if 0
!   /* We don't take off the numbers; build_secondary_vtable uses the
       DECL_ASSEMBLER_NAME for the type, which includes the number
       in `3foo'.  If we were to pull them off here, we'd end up with
       something like `_vt.foo.3bar', instead of a uniform definition.  */
*************** tree get_vtable_decl (type, complete)
*** 1042,1054 ****
    return decl;
  }
  
! /* Build a virtual function for type TYPE.
!    If BINFO is non-NULL, build the vtable starting with the initial
!    approximation that it is the same as the one which is the head of
!    the association list.  */
  
! static void
! build_vtable (binfo, type)
       tree binfo, type;
  {
    tree virtuals, decl;
--- 1043,1056 ----
    return decl;
  }
  
! /* Build the primary virtual function table for TYPE.  If BINFO is
!    non-NULL, build the vtable starting with the initial approximation
!    that it is the same as the one which is the head of the association
!    list.  Returns a non-zero value if a new vtable is actually
!    created.  */
  
! static int
! build_primary_vtable (binfo, type)
       tree binfo, type;
  {
    tree virtuals, decl;
*************** build_vtable (binfo, type)
*** 1062,1069 ****
        if (BINFO_NEW_VTABLE_MARKED (binfo))
  	/* We have already created a vtable for this base, so there's
  	   no need to do it again.  */
! 	return;
! 
        virtuals = copy_list (BINFO_VIRTUALS (binfo));
        TREE_TYPE (decl) = TREE_TYPE (BINFO_VTABLE (binfo));
        DECL_SIZE (decl) = TYPE_SIZE (TREE_TYPE (BINFO_VTABLE (binfo)));
--- 1064,1071 ----
        if (BINFO_NEW_VTABLE_MARKED (binfo))
  	/* We have already created a vtable for this base, so there's
  	   no need to do it again.  */
! 	return 0;
!       
        virtuals = copy_list (BINFO_VIRTUALS (binfo));
        TREE_TYPE (decl) = TREE_TYPE (BINFO_VTABLE (binfo));
        DECL_SIZE (decl) = TYPE_SIZE (TREE_TYPE (BINFO_VTABLE (binfo)));
*************** build_vtable (binfo, type)
*** 1092,1097 ****
--- 1094,1100 ----
  
    binfo = TYPE_BINFO (type);
    SET_BINFO_NEW_VTABLE_MARKED (binfo);
+   return 1;
  }
  
  /* Give TYPE a new virtual function table which is initialized
*************** build_vtable (binfo, type)
*** 1108,1115 ****
     an object must remain the same, otherwise a binary incompatibility
     can result.  */
  
! static void
! prepare_fresh_vtable (binfo, for_type)
       tree binfo, for_type;
  {
    tree basetype;
--- 1111,1118 ----
     an object must remain the same, otherwise a binary incompatibility
     can result.  */
  
! static int
! build_secondary_vtable (binfo, for_type)
       tree binfo, for_type;
  {
    tree basetype;
*************** prepare_fresh_vtable (binfo, for_type)
*** 1129,1135 ****
    if (BINFO_NEW_VTABLE_MARKED (binfo))
      /* We already created a vtable for this base.  There's no need to
         do it again.  */
!     return;
  
    basetype = TYPE_MAIN_VARIANT (BINFO_TYPE (binfo));
  
--- 1132,1138 ----
    if (BINFO_NEW_VTABLE_MARKED (binfo))
      /* We already created a vtable for this base.  There's no need to
         do it again.  */
!     return 0;
  
    basetype = TYPE_MAIN_VARIANT (BINFO_TYPE (binfo));
  
*************** prepare_fresh_vtable (binfo, for_type)
*** 1259,1282 ****
  						  current_class_type),
  			170);
    SET_BINFO_NEW_VTABLE_MARKED (binfo);
  }
  
! /* Make V, an entry on the BINFO_VIRTUALS list for BINFO (which is in
!    the hierarchy dominated by T) list FNDECL as its BF_FN.  */
  
  static void
! modify_vtable_entry (t, binfo, fndecl, v)
       tree t;
       tree binfo;
       tree fndecl;
!      tree v;
  {
!   tree base_offset, offset;
!   tree context = DECL_CLASS_CONTEXT (fndecl);
!   tree vfield = TYPE_VFIELD (t);
    tree this_offset;
    tree vcall_index;
  
    offset = get_class_offset (context, t, binfo, fndecl);
  
    /* Find the right offset for ythe this pointer based on the
--- 1262,1312 ----
  						  current_class_type),
  			170);
    SET_BINFO_NEW_VTABLE_MARKED (binfo);
+   return 1;
  }
  
! /* Create a new vtable for BINFO which is the hierarchy dominated by
!    T.  */
  
+ static int
+ make_new_vtable (t, binfo)
+      tree t;
+      tree binfo;
+ {
+   if (binfo == TYPE_BINFO (t))
+     /* In this case, it is *type*'s vtable we are modifying.  We start
+        with the approximation that it's vtable is that of the
+        immediate base class.  */
+     return build_primary_vtable (TYPE_BINFO (DECL_CONTEXT (TYPE_VFIELD (t))), 
+ 				 t);
+   else
+     /* This is our very own copy of `basetype' to play with.  Later,
+        we will fill in all the virtual functions that override the
+        virtual functions in these base classes which are not defined
+        by the current type.  */
+     return build_secondary_vtable (binfo, t);
+ }
+ 
+ /* Make *VIRTUALS, an entry on the BINFO_VIRTUALS list for BINFO
+    (which is in the hierarchy dominated by T) list FNDECL as its
+    BF_FN.  */
+ 
  static void
! modify_vtable_entry (t, binfo, fndecl, virtuals)
       tree t;
       tree binfo;
       tree fndecl;
!      tree *virtuals;
  {
!   tree base_offset;
!   tree offset;
!   tree context;
    tree this_offset;
    tree vcall_index;
+   tree v;
  
+   v = *virtuals;
+   context = DECL_CLASS_CONTEXT (fndecl);
    offset = get_class_offset (context, t, binfo, fndecl);
  
    /* Find the right offset for ythe this pointer based on the
*************** modify_vtable_entry (t, binfo, fndecl, v
*** 1300,1317 ****
      {
        tree base_fndecl;
  
!       /* Make sure we can modify the derived association with immunity.  */
!       if (binfo == TYPE_BINFO (t))
! 	/* In this case, it is *type*'s vtable we are modifying.  We
! 	   start with the approximation that it's vtable is that of
! 	   the immediate base class.  */
! 	build_vtable (TYPE_BINFO (DECL_CONTEXT (vfield)), t);
!       else
! 	/* This is our very own copy of `basetype' to play with.
! 	   Later, we will fill in all the virtual functions that
! 	   override the virtual functions in these base classes which
! 	   are not defined by the current type.  */
! 	prepare_fresh_vtable (binfo, t);
  
        base_fndecl = BF_FN (v);
        BF_DELTA (v) = this_offset;
--- 1330,1346 ----
      {
        tree base_fndecl;
  
!       /* We need a new vtable for BINFO.  */
!       if (make_new_vtable (t, binfo))
! 	{
! 	  /* If we really did make a new vtable, we also made a copy
! 	     of the BINFO_VIRTUALS list.  Now, we have to find the
! 	     corresponding entry in that list.  */
! 	  *virtuals = BINFO_VIRTUALS (binfo);
! 	  while (BF_FN (*virtuals) != BF_FN (v))
! 	    *virtuals = TREE_CHAIN (*virtuals);
! 	  v = *virtuals;
! 	}
  
        base_fndecl = BF_FN (v);
        BF_DELTA (v) = this_offset;
*************** modify_one_vtable (binfo, t, fndecl)
*** 2948,2971 ****
       tree binfo, t, fndecl;
  {
    tree virtuals;
-   unsigned HOST_WIDE_INT n;
    
    /* If we're support RTTI then we always need a new vtable to point
       to the RTTI information.  Under the new ABI we may need a new
       vtable to contain vcall and vbase offsets.  */
    if (flag_rtti || flag_new_abi)
!     {
!       if (binfo == TYPE_BINFO (t))
! 	build_vtable (TYPE_BINFO (DECL_CONTEXT (TYPE_VFIELD (t))), t);
!       else
! 	prepare_fresh_vtable (binfo, t);
!     }
    if (fndecl == NULL_TREE)
      return;
  
!   for (virtuals = skip_rtti_stuff (binfo, BINFO_TYPE (binfo), &n);
         virtuals;
!        virtuals = TREE_CHAIN (virtuals), ++n)
      {
        tree current_fndecl = BF_FN (virtuals);
  
--- 2977,2995 ----
       tree binfo, t, fndecl;
  {
    tree virtuals;
    
    /* If we're support RTTI then we always need a new vtable to point
       to the RTTI information.  Under the new ABI we may need a new
       vtable to contain vcall and vbase offsets.  */
    if (flag_rtti || flag_new_abi)
!     make_new_vtable (t, binfo);
! 
    if (fndecl == NULL_TREE)
      return;
  
!   for (virtuals = skip_rtti_stuff (binfo, BINFO_TYPE (binfo), NULL);
         virtuals;
!        virtuals = TREE_CHAIN (virtuals))
      {
        tree current_fndecl = BF_FN (virtuals);
  
*************** modify_one_vtable (binfo, t, fndecl)
*** 2977,2983 ****
  			  19990727);
  
        if (current_fndecl && overrides (fndecl, current_fndecl))
! 	modify_vtable_entry (t, binfo, fndecl, virtuals);
      }
  }
  
--- 3001,3007 ----
  			  19990727);
  
        if (current_fndecl && overrides (fndecl, current_fndecl))
! 	modify_vtable_entry (t, binfo, fndecl, &virtuals);
      }
  }
  
*************** dfs_fixup_vtable_deltas (binfo, data)
*** 3088,3094 ****
       void *data;
  {
    tree virtuals;
-   unsigned HOST_WIDE_INT n;
    tree t = (tree) data;
  
    while (BINFO_PRIMARY_MARKED_P (binfo))
--- 3112,3117 ----
*************** dfs_fixup_vtable_deltas (binfo, data)
*** 3099,3112 ****
  	return NULL_TREE;
      }
  
!   for (virtuals = skip_rtti_stuff (binfo, BINFO_TYPE (binfo), &n);
         virtuals;
!        virtuals = TREE_CHAIN (virtuals), ++n)
      {
        tree fndecl = BF_FN (virtuals);
  
        if (fndecl)
! 	modify_vtable_entry (t, binfo, fndecl, virtuals);
      }
  
    return NULL_TREE;
--- 3122,3135 ----
  	return NULL_TREE;
      }
  
!   for (virtuals = skip_rtti_stuff (binfo, BINFO_TYPE (binfo), NULL);
         virtuals;
!        virtuals = TREE_CHAIN (virtuals))
      {
        tree fndecl = BF_FN (virtuals);
  
        if (fndecl)
! 	modify_vtable_entry (t, binfo, fndecl, &virtuals);
      }
  
    return NULL_TREE;
*************** override_one_vtable (binfo, old, t)
*** 3194,3200 ****
  	      choose = NEITHER;
  	      if (! BINFO_NEW_VTABLE_MARKED (binfo))
  		{
! 		  prepare_fresh_vtable (binfo, t);
  		  override_one_vtable (binfo, old, t);
  		  return;
  		}
--- 3217,3223 ----
  	      choose = NEITHER;
  	      if (! BINFO_NEW_VTABLE_MARKED (binfo))
  		{
! 		  build_secondary_vtable (binfo, t);
  		  override_one_vtable (binfo, old, t);
  		  return;
  		}
*************** override_one_vtable (binfo, old, t)
*** 3209,3215 ****
  	      choose = NEITHER;
  	      if (! BINFO_NEW_VTABLE_MARKED (binfo))
  		{
! 		  prepare_fresh_vtable (binfo, t);
  		  override_one_vtable (binfo, old, t);
  		  return;
  		}
--- 3232,3238 ----
  	      choose = NEITHER;
  	      if (! BINFO_NEW_VTABLE_MARKED (binfo))
  		{
! 		  build_secondary_vtable (binfo, t);
  		  override_one_vtable (binfo, old, t);
  		  return;
  		}
*************** override_one_vtable (binfo, old, t)
*** 3225,3231 ****
  	  choose = NEITHER;
  	  if (! BINFO_NEW_VTABLE_MARKED (binfo))
  	    {
! 	      prepare_fresh_vtable (binfo, t);
  	      override_one_vtable (binfo, old, t);
  	      return;
  	    }
--- 3248,3254 ----
  	  choose = NEITHER;
  	  if (! BINFO_NEW_VTABLE_MARKED (binfo))
  	    {
! 	      build_secondary_vtable (binfo, t);
  	      override_one_vtable (binfo, old, t);
  	      return;
  	    }
*************** finish_struct_1 (t)
*** 5146,5157 ****
  	      set_rtti_entry (new_virtuals,
  			      convert (ssizetype, integer_zero_node), t);
  	    }
! 	  build_vtable (NULL_TREE, t);
  	}
        else if (! BINFO_NEW_VTABLE_MARKED (TYPE_BINFO (t)))
  	/* Here we know enough to change the type of our virtual
  	   function table, but we will wait until later this function.  */
! 	build_vtable (CLASSTYPE_PRIMARY_BINFO (t), t);
  
        /* If this type has basetypes with constructors, then those
  	 constructors might clobber the virtual function table.  But
--- 5169,5180 ----
  	      set_rtti_entry (new_virtuals,
  			      convert (ssizetype, integer_zero_node), t);
  	    }
! 	  build_primary_vtable (NULL_TREE, t);
  	}
        else if (! BINFO_NEW_VTABLE_MARKED (TYPE_BINFO (t)))
  	/* Here we know enough to change the type of our virtual
  	   function table, but we will wait until later this function.  */
! 	build_primary_vtable (CLASSTYPE_PRIMARY_BINFO (t), t);
  
        /* If this type has basetypes with constructors, then those
  	 constructors might clobber the virtual function table.  But

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