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]
Other format: [Raw text]

[C++ PATCH]: Fix some covariant thunk bugs


Hi,
I've installed this patch, which fixes some bugs in the covariant thunk
machinery.

booted and tested on i686-pc-linux-gnu.

nathan
--
Nathan Sidwell    ::   http://www.codesourcery.com   ::     CodeSourcery LLC
         The voices in my head said this was stupid too
nathan@codesourcery.com : http://www.cs.bris.ac.uk/~nathan/ : nathan@acm.org

2002-12-30  Nathan Sidwell  <nathan@codesourcery.com>

	* cp-tree.h (THUNK_TARGET): New macro.
	(THUNK_VIRTUAL_OFFSET): For result thunks it is always a binfo.
	(finish_thunk): Remove offset parms.
	* class.c (find_final_overrider): Look through thunks.
	(get_vcall_index): Use THUNK_TARGET.
	(update_vtable_entry_for_fn): Look through thunks. Set covariant
	fixed offset here. Adjust finish_thunk call.
	(build_vtbl_initializer): Adjust finish_thunk calls.
	* mangle.c (mangle_call_offset): Remove superfluous if.
	(mangle_thunk): Adjust.
	* method.c (make_thunk): Adjust.
	(finish_thunk): Adjust.
	(thunk_adjust): Remove assert.
	(use_thunk): Use THUNK_TARGET
	* dump1.c (cp_dump_tree): Adjust thunk dumping.

2002-12-30  Nathan Sidwell  <nathan@codesourcery.com>

	* g++.dg/inherit/covariant5.C: New test.
	* g++.dg/inherit/covariant6.C: New test.
	* g++.dg/inherit/covariant7.C: New test.

Index: cp/class.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/class.c,v
retrieving revision 1.504
diff -c -3 -p -r1.504 class.c
*** cp/class.c	30 Dec 2002 12:46:12 -0000	1.504
--- cp/class.c	30 Dec 2002 13:32:25 -0000
*************** find_final_overrider (derived, binfo, fn
*** 2299,2304 ****
--- 2299,2307 ----
       
       The solution is to look at all paths to BINFO.  If we find
       different overriders along any two, then there is a problem.  */
+   if (DECL_THUNK_P (fn))
+     fn = THUNK_TARGET (fn);
+   
    ffod.fn = fn;
    ffod.declaring_base = binfo;
    ffod.most_derived_type = BINFO_TYPE (derived);
*************** get_vcall_index (tree fn, tree type)
*** 2328,2335 ****
  {
    tree v;
  
!   if (DECL_RESULT_THUNK_P (fn))
!     fn = TREE_OPERAND (DECL_INITIAL (fn), 0);
  
    for (v = CLASSTYPE_VCALL_INDICES (type); v; v = TREE_CHAIN (v))
      if ((DECL_DESTRUCTOR_P (fn) && DECL_DESTRUCTOR_P (TREE_PURPOSE (v)))
--- 2331,2338 ----
  {
    tree v;
  
!   if (DECL_THUNK_P (fn))
!     fn = THUNK_TARGET (fn);
  
    for (v = CLASSTYPE_VCALL_INDICES (type); v; v = TREE_CHAIN (v))
      if ((DECL_DESTRUCTOR_P (fn) && DECL_DESTRUCTOR_P (TREE_PURPOSE (v)))
*************** update_vtable_entry_for_fn (t, binfo, fn
*** 2360,2370 ****
--- 2363,2377 ----
    tree first_defn;
    bool lost = false;
  
+   if (DECL_THUNK_P (fn))
+     fn = THUNK_TARGET (fn);
+   
    /* Find the nearest primary base (possibly binfo itself) which defines
       this function; this is the class the caller will convert to when
       calling FN through BINFO.  */
    for (b = binfo; ; b = get_primary_binfo (b))
      {
+       my_friendly_assert (b, 20021227);
        if (look_for_overrides_here (BINFO_TYPE (b), fn))
  	break;
  
*************** update_vtable_entry_for_fn (t, binfo, fn
*** 2408,2417 ****
  		/* If the covariant type is within the class hierarchy
  		   we are currently laying out, the vbase index is not
  		   yet known, so we have to remember the virtual base
! 		   binfo for the moment.  The thunk will be finished
! 		   in build_vtbl_initializer, where we'll know the
! 		   vtable index of the virtual base.  */
! 		virtual_offset = binfo_for_vbase (BINFO_TYPE (binfo), t);
  	      }
  	    
  	    /* Replace the overriding function with a covariant thunk.
--- 2415,2425 ----
  		/* If the covariant type is within the class hierarchy
  		   we are currently laying out, the vbase index is not
  		   yet known, so we have to remember the virtual base
! 		   binfo. */
! 		virtual_offset = binfo_for_vbase (BINFO_TYPE (binfo),
! 						  TREE_TYPE (over_return));
! 		fixed_offset = size_diffop (fixed_offset,
! 					    BINFO_OFFSET (virtual_offset));
  	      }
  	    
  	    /* Replace the overriding function with a covariant thunk.
*************** update_vtable_entry_for_fn (t, binfo, fn
*** 2421,2427 ****
  				fixed_offset, virtual_offset);
  	    TREE_PURPOSE (overrider) = thunk;
  	    if (!virtual_offset && !DECL_NAME (thunk))
! 	      finish_thunk (thunk, fixed_offset, NULL_TREE);
  	  }
        }
    }
--- 2429,2435 ----
  				fixed_offset, virtual_offset);
  	    TREE_PURPOSE (overrider) = thunk;
  	    if (!virtual_offset && !DECL_NAME (thunk))
! 	      finish_thunk (thunk);
  	  }
        }
    }
*************** build_vtbl_initializer (binfo, orig_binf
*** 7739,7756 ****
        tree init = NULL_TREE;
        
        fn = BV_FN (v);
!       fn_original = (DECL_RESULT_THUNK_P (fn)
! 		     ? TREE_OPERAND (DECL_INITIAL (fn), 0)
! 		     : fn);
!       /* Finish an unfinished covariant thunk. */
!       if (DECL_RESULT_THUNK_P (fn) && !DECL_NAME (fn))
! 	{
! 	  tree binfo = THUNK_VIRTUAL_OFFSET (fn);
! 	  tree fixed_offset = size_int (THUNK_FIXED_OFFSET (fn));
! 	  tree virtual_offset = BINFO_VPTR_FIELD (binfo);
! 	  
! 	  fixed_offset = size_diffop (fixed_offset, BINFO_OFFSET (binfo));
! 	  finish_thunk (fn, fixed_offset, virtual_offset);
  	}
        
        /* If the only definition of this function signature along our
--- 7747,7758 ----
        tree init = NULL_TREE;
        
        fn = BV_FN (v);
!       fn_original = fn;
!       if (DECL_THUNK_P (fn))
! 	{
! 	  if (!DECL_NAME (fn))
! 	    finish_thunk (fn);
! 	  fn_original = THUNK_TARGET (fn);
  	}
        
        /* If the only definition of this function signature along our
*************** build_vtbl_initializer (binfo, orig_binf
*** 7796,7802 ****
  	    {
  	      fn = make_thunk (fn, /*this_adjusting=*/1, delta, vcall_index);
  	      if (!DECL_NAME (fn))
! 		finish_thunk (fn, delta, THUNK_VIRTUAL_OFFSET (fn));
  	    }
  	  /* Take the address of the function, considering it to be of an
  	     appropriate generic type.  */
--- 7798,7804 ----
  	    {
  	      fn = make_thunk (fn, /*this_adjusting=*/1, delta, vcall_index);
  	      if (!DECL_NAME (fn))
! 		finish_thunk (fn);
  	    }
  	  /* Take the address of the function, considering it to be of an
  	     appropriate generic type.  */
Index: cp/cp-tree.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/cp-tree.h,v
retrieving revision 1.786
diff -c -3 -p -r1.786 cp-tree.h
*** cp/cp-tree.h	29 Dec 2002 14:53:04 -0000	1.786
--- cp/cp-tree.h	30 Dec 2002 13:32:38 -0000
*************** struct lang_decl GTY(())
*** 1791,1796 ****
--- 1790,1798 ----
      {
        struct full_lang_decl 
        {
+ 	/* For a non-thunk function decl, this is a tree list of
+   	   friendly classes. For a thunk function decl, it is the
+   	   thunked to function decl.  */
  	tree befriending_classes;
  	
  	/* For a non-virtual FUNCTION_DECL, this is
*************** struct lang_decl GTY(())
*** 2977,2990 ****
  /* An integer indicating how many bytes should be subtracted from the
     this or result pointer when this function is called.  */
  #define THUNK_FIXED_OFFSET(DECL) \
!   (DECL_LANG_SPECIFIC (DECL)->u.f.fixed_offset)
  
! /* A tree indicating how many bytes should be added to the
!    vtable for the this or result pointer to find the vcall or vbase
!    offset.  (The vptr is always located at offset zero from the
!    this or result pointer.)  If NULL, then there is no virtual adjust.  */
  #define THUNK_VIRTUAL_OFFSET(DECL) \
!   (LANG_DECL_U2_CHECK (DECL, 0)->virtual_offset)
  
  /* These macros provide convenient access to the various _STMT nodes
     created when parsing template declarations.  */
--- 2979,2998 ----
  /* An integer indicating how many bytes should be subtracted from the
     this or result pointer when this function is called.  */
  #define THUNK_FIXED_OFFSET(DECL) \
!   (DECL_LANG_SPECIFIC (VAR_OR_FUNCTION_DECL_CHECK (DECL))->u.f.fixed_offset)
  
! /* A tree indicating how to perform the virtual adjustment. For a this
!    adjusting thunk it is the number of bytes to be added to the vtable
!    to find the vcall offset. For a result adjusting thunk, it is the
!    binfo of the relevant virtual base.  The vptr is always located at
!    offset zero from the this or result pointer.  If NULL, then there
!    is no virtual adjust.  */
  #define THUNK_VIRTUAL_OFFSET(DECL) \
!   (LANG_DECL_U2_CHECK (VAR_OR_FUNCTION_DECL_CHECK (DECL), 0)->virtual_offset)
! 
! /* For thunk NODE, this is the FUNCTION_DECL thunked to.  */
! #define THUNK_TARGET(NODE)				\
!   (DECL_LANG_SPECIFIC (NODE)->u.f.befriending_classes)
  
  /* These macros provide convenient access to the various _STMT nodes
     created when parsing template declarations.  */
*************** extern void set_mangled_name_for_decl (t
*** 3990,3996 ****
  extern tree build_opfncall (enum tree_code, int, tree, tree, tree);
  extern tree hack_identifier (tree, tree);
  extern tree make_thunk (tree, bool, tree, tree);
! extern void finish_thunk (tree, tree, tree);
  extern void use_thunk (tree, bool);
  extern void synthesize_method (tree);
  extern tree implicitly_declare_fn (special_function_kind, tree, bool);
--- 3998,4004 ----
  extern tree build_opfncall (enum tree_code, int, tree, tree, tree);
  extern tree hack_identifier (tree, tree);
  extern tree make_thunk (tree, bool, tree, tree);
! extern void finish_thunk (tree);
  extern void use_thunk (tree, bool);
  extern void synthesize_method (tree);
  extern tree implicitly_declare_fn (special_function_kind, tree, bool);
Index: cp/dump.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/dump.c,v
retrieving revision 1.66
diff -c -3 -p -r1.66 dump.c
*** cp/dump.c	30 Dec 2002 12:46:13 -0000	1.66
--- cp/dump.c	30 Dec 2002 13:32:39 -0000
*************** cp_dump_tree (dump_info, t)
*** 336,348 ****
  	}
        else
  	{
  	  dump_string (di, "thunk");
  	  if (DECL_THIS_THUNK_P (t))
  	    dump_string (di, "this adjusting");
  	  else
! 	    dump_string (di, "result adjusting");
  	  dump_int (di, "fixd", THUNK_FIXED_OFFSET (t));
! 	  dump_child ("virt", THUNK_VIRTUAL_OFFSET (t));
  	  dump_child ("fn", DECL_INITIAL (t));
  	}
        break;
--- 336,355 ----
  	}
        else
  	{
+ 	  tree virt = THUNK_VIRTUAL_OFFSET (t);
+ 	  
  	  dump_string (di, "thunk");
  	  if (DECL_THIS_THUNK_P (t))
  	    dump_string (di, "this adjusting");
  	  else
! 	    {
! 	      dump_string (di, "result adjusting");
! 	      if (virt)
! 		virt = BINFO_VPTR_FIELD (virt);
! 	    }
  	  dump_int (di, "fixd", THUNK_FIXED_OFFSET (t));
! 	  if (virt)
! 	    dump_int (di, "virt", tree_low_cst (virt, 0));
  	  dump_child ("fn", DECL_INITIAL (t));
  	}
        break;
Index: cp/mangle.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/mangle.c,v
retrieving revision 1.64
diff -c -3 -p -r1.64 mangle.c
*** cp/mangle.c	16 Dec 2002 18:22:17 -0000	1.64
--- cp/mangle.c	30 Dec 2002 13:32:44 -0000
*************** mangle_call_offset (fixed_offset, virtua
*** 2545,2554 ****
       tree fixed_offset;
       tree virtual_offset;
  {
!   if (virtual_offset)
!     write_char (virtual_offset ? 'v' : 'h');
!   else
!     write_char ('h');
  
    /* For either flavor, write the fixed offset.  */
    write_integer_cst (fixed_offset);
--- 2545,2551 ----
       tree fixed_offset;
       tree virtual_offset;
  {
!   write_char (virtual_offset ? 'v' : 'h');
  
    /* For either flavor, write the fixed offset.  */
    write_integer_cst (fixed_offset);
*************** mangle_thunk (fn_decl, this_adjusting, f
*** 2590,2613 ****
    write_string ("_Z");
    write_char ('T');
    
!   if (this_adjusting && !DECL_RESULT_THUNK_P (fn_decl))
!     /* Plain this adjusting thunk.  */
!     mangle_call_offset (fixed_offset, virtual_offset);
!   else if (!this_adjusting)
      {
        /* Covariant thunk with no this adjustment */
        write_char ('c');
        mangle_call_offset (integer_zero_node, NULL_TREE);
        mangle_call_offset (fixed_offset, virtual_offset);
      }
    else
      {
        /* This adjusting thunk to covariant thunk.  */
        write_char ('c');
        mangle_call_offset (fixed_offset, virtual_offset);
!       mangle_call_offset (ssize_int (THUNK_FIXED_OFFSET (fn_decl)),
! 			  THUNK_VIRTUAL_OFFSET (fn_decl));
!       fn_decl = TREE_OPERAND (DECL_INITIAL (fn_decl), 0);
      }
  
    /* Scoped name.  */
--- 2587,2613 ----
    write_string ("_Z");
    write_char ('T');
    
!   if (!this_adjusting)
      {
        /* Covariant thunk with no this adjustment */
        write_char ('c');
        mangle_call_offset (integer_zero_node, NULL_TREE);
        mangle_call_offset (fixed_offset, virtual_offset);
      }
+   else if (!DECL_THUNK_P (fn_decl))
+     /* Plain this adjusting thunk.  */
+     mangle_call_offset (fixed_offset, virtual_offset);
    else
      {
        /* This adjusting thunk to covariant thunk.  */
        write_char ('c');
        mangle_call_offset (fixed_offset, virtual_offset);
!       fixed_offset = ssize_int (THUNK_FIXED_OFFSET (fn_decl));
!       virtual_offset = THUNK_VIRTUAL_OFFSET (fn_decl);
!       if (virtual_offset)
! 	virtual_offset = BINFO_VPTR_FIELD (virtual_offset);
!       mangle_call_offset (fixed_offset, virtual_offset);
!       fn_decl = THUNK_TARGET (fn_decl);
      }
  
    /* Scoped name.  */
Index: cp/method.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/method.c,v
retrieving revision 1.240
diff -c -3 -p -r1.240 method.c
*** cp/method.c	28 Dec 2002 08:03:40 -0000	1.240
--- cp/method.c	30 Dec 2002 13:32:47 -0000
*************** make_thunk (tree function, bool this_adj
*** 261,268 ****
    
    /* See if we already have the thunk in question.  For this_adjusting
       thunks VIRTUAL_OFFSET will be an INTEGER_CST, for covariant thunks it
!      will be a BINFO (because of the organization of the layout
!      algorithm). */
    for (thunk = DECL_THUNKS (function); thunk; thunk = TREE_CHAIN (thunk))
      if (DECL_THIS_THUNK_P (thunk) == this_adjusting
   	&& THUNK_FIXED_OFFSET (thunk) == d
--- 261,267 ----
    
    /* See if we already have the thunk in question.  For this_adjusting
       thunks VIRTUAL_OFFSET will be an INTEGER_CST, for covariant thunks it
!      will be a BINFO. */
    for (thunk = DECL_THUNKS (function); thunk; thunk = TREE_CHAIN (thunk))
      if (DECL_THIS_THUNK_P (thunk) == this_adjusting
   	&& THUNK_FIXED_OFFSET (thunk) == d
*************** make_thunk (tree function, bool this_adj
*** 281,287 ****
  
    thunk = build_decl (FUNCTION_DECL, NULL_TREE, TREE_TYPE (function));
    DECL_LANG_SPECIFIC (thunk) = DECL_LANG_SPECIFIC (function);
!   cxx_dup_lang_specific_decl (function);
    DECL_CONTEXT (thunk) = DECL_CONTEXT (function);
    TREE_READONLY (thunk) = TREE_READONLY (function);
    TREE_THIS_VOLATILE (thunk) = TREE_THIS_VOLATILE (function);
--- 280,286 ----
  
    thunk = build_decl (FUNCTION_DECL, NULL_TREE, TREE_TYPE (function));
    DECL_LANG_SPECIFIC (thunk) = DECL_LANG_SPECIFIC (function);
!   cxx_dup_lang_specific_decl (thunk);
    DECL_CONTEXT (thunk) = DECL_CONTEXT (function);
    TREE_READONLY (thunk) = TREE_READONLY (function);
    TREE_THIS_VOLATILE (thunk) = TREE_THIS_VOLATILE (function);
*************** make_thunk (tree function, bool this_adj
*** 289,296 ****
    if (flag_weak)
      comdat_linkage (thunk);
    SET_DECL_THUNK_P (thunk, this_adjusting);
!   DECL_INITIAL (thunk) = build1 (ADDR_EXPR, vfunc_ptr_type_node, function);
!   THUNK_FIXED_OFFSET (thunk) = tree_low_cst (fixed_offset, 0);
    THUNK_VIRTUAL_OFFSET (thunk) = virtual_offset;
    
    /* The thunk itself is not a constructor or destructor, even if
--- 288,295 ----
    if (flag_weak)
      comdat_linkage (thunk);
    SET_DECL_THUNK_P (thunk, this_adjusting);
!   THUNK_TARGET (thunk) = function;
!   THUNK_FIXED_OFFSET (thunk) = d;
    THUNK_VIRTUAL_OFFSET (thunk) = virtual_offset;
    
    /* The thunk itself is not a constructor or destructor, even if
*************** make_thunk (tree function, bool this_adj
*** 320,339 ****
    return thunk;
  }
  
! /* Finish THUNK, a thunk decl. FIXED_OFFSET and VIRTUAL_OFFSET are the
!    adjustments to apply.  */
  
  void
! finish_thunk (tree thunk, tree fixed_offset, tree virtual_offset)
  {
    tree function, name;
!   
    my_friendly_assert (!DECL_NAME (thunk) && DECL_THUNK_P (thunk), 20021127);
!   function = TREE_OPERAND (DECL_INITIAL (thunk), 0);
    name = mangle_thunk (function, DECL_THIS_THUNK_P (thunk),
! 			    fixed_offset, virtual_offset);
!   THUNK_FIXED_OFFSET (thunk) = tree_low_cst (fixed_offset, 0);
!   THUNK_VIRTUAL_OFFSET (thunk) = virtual_offset;
    DECL_NAME (thunk) = name;
    SET_DECL_ASSEMBLER_NAME (thunk, name);
  }
--- 319,339 ----
    return thunk;
  }
  
! /* Finish THUNK, a thunk decl.  */
  
  void
! finish_thunk (tree thunk)
  {
    tree function, name;
!   tree fixed_offset = ssize_int (THUNK_FIXED_OFFSET (thunk));
!   tree virtual_offset = THUNK_VIRTUAL_OFFSET (thunk);
! 
    my_friendly_assert (!DECL_NAME (thunk) && DECL_THUNK_P (thunk), 20021127);
!   if (virtual_offset && DECL_RESULT_THUNK_P (thunk))
!     virtual_offset = BINFO_VPTR_FIELD (virtual_offset);
!   function = THUNK_TARGET (thunk);
    name = mangle_thunk (function, DECL_THIS_THUNK_P (thunk),
! 		       fixed_offset, virtual_offset);
    DECL_NAME (thunk) = name;
    SET_DECL_ASSEMBLER_NAME (thunk, name);
  }
*************** thunk_adjust (tree ptr, bool this_adjust
*** 358,366 ****
      {
        tree vtable;
  
-       /* It shouldn't be a binfo any more. */
-       my_friendly_assert (TREE_CODE (virtual_offset) == INTEGER_CST, 20021127);
-       
        ptr = save_expr (ptr);
        /* The vptr is always at offset zero in the object.  */
        vtable = build1 (NOP_EXPR,
--- 358,363 ----
*************** thunk_adjust (tree ptr, bool this_adjust
*** 392,401 ****
  void
  use_thunk (tree thunk_fndecl, bool emit_p)
  {
-   tree fnaddr;
    tree function;
    tree virtual_offset;
    HOST_WIDE_INT fixed_offset, virtual_value;
  
    /* We should have called finish_thunk to give it a name. */
    my_friendly_assert (DECL_NAME (thunk_fndecl), 20021127);
--- 389,398 ----
  void
  use_thunk (tree thunk_fndecl, bool emit_p)
  {
    tree function;
    tree virtual_offset;
    HOST_WIDE_INT fixed_offset, virtual_value;
+   bool this_adjusting = DECL_THIS_THUNK_P (thunk_fndecl);
  
    /* We should have called finish_thunk to give it a name. */
    my_friendly_assert (DECL_NAME (thunk_fndecl), 20021127);
*************** use_thunk (tree thunk_fndecl, bool emit_
*** 403,410 ****
    if (TREE_ASM_WRITTEN (thunk_fndecl))
      return;
    
!   fnaddr = DECL_INITIAL (thunk_fndecl);
!   if (TREE_CODE (DECL_INITIAL (thunk_fndecl)) != ADDR_EXPR)
      /* We already turned this thunk into an ordinary function.
         There's no need to process this thunk again.  */
      return;
--- 400,407 ----
    if (TREE_ASM_WRITTEN (thunk_fndecl))
      return;
    
!   function = THUNK_TARGET (thunk_fndecl);
!   if (DECL_RESULT (thunk_fndecl))
      /* We already turned this thunk into an ordinary function.
         There's no need to process this thunk again.  */
      return;
*************** use_thunk (tree thunk_fndecl, bool emit_
*** 414,420 ****
  
    /* Figure out what function is being thunked to.  It's referenced in
       this translation unit.  */
-   function = TREE_OPERAND (fnaddr, 0);
    TREE_ADDRESSABLE (function) = 1;
    mark_used (function);
    TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (function)) = 1;
--- 411,416 ----
*************** use_thunk (tree thunk_fndecl, bool emit_
*** 424,432 ****
    fixed_offset = THUNK_FIXED_OFFSET (thunk_fndecl);
    virtual_offset = THUNK_VIRTUAL_OFFSET (thunk_fndecl);
  
!   virtual_value = (virtual_offset
! 		   ? tree_low_cst (virtual_offset, /*pos=*/0) : 0);
!   my_friendly_assert (!virtual_offset || virtual_value, 20021026);
    
    /* And, if we need to emit the thunk, it's used.  */
    mark_used (thunk_fndecl);
--- 420,434 ----
    fixed_offset = THUNK_FIXED_OFFSET (thunk_fndecl);
    virtual_offset = THUNK_VIRTUAL_OFFSET (thunk_fndecl);
  
!   if (virtual_offset)
!     {
!       if (!this_adjusting)
! 	virtual_offset = BINFO_VPTR_FIELD (virtual_offset);
!       virtual_value = tree_low_cst (virtual_offset, /*pos=*/0);
!       my_friendly_assert (virtual_value, 20021026);
!     }
!   else
!     virtual_value = 0;
    
    /* And, if we need to emit the thunk, it's used.  */
    mark_used (thunk_fndecl);
*************** use_thunk (tree thunk_fndecl, bool emit_
*** 447,456 ****
    /* The back-end expects DECL_INITIAL to contain a BLOCK, so we
       create one.  */
    DECL_INITIAL (thunk_fndecl) = make_node (BLOCK);
!   BLOCK_VARS (DECL_INITIAL (thunk_fndecl)) 
!     = DECL_ARGUMENTS (thunk_fndecl);
! 
!   if (DECL_THIS_THUNK_P (thunk_fndecl)
        && targetm.asm_out.can_output_mi_thunk (thunk_fndecl, fixed_offset,
  					      virtual_value, function))
      {
--- 449,457 ----
    /* The back-end expects DECL_INITIAL to contain a BLOCK, so we
       create one.  */
    DECL_INITIAL (thunk_fndecl) = make_node (BLOCK);
!   BLOCK_VARS (DECL_INITIAL (thunk_fndecl)) = DECL_ARGUMENTS (thunk_fndecl);
!   
!   if (this_adjusting
        && targetm.asm_out.can_output_mi_thunk (thunk_fndecl, fixed_offset,
  					      virtual_value, function))
      {
*************** use_thunk (tree thunk_fndecl, bool emit_
*** 502,508 ****
  
        t = a;
        
!       if (DECL_THIS_THUNK_P (thunk_fndecl))
  	t = thunk_adjust (t, /*this_adjusting=*/1,
  			  fixed_offset, virtual_offset);
        
--- 503,509 ----
  
        t = a;
        
!       if (this_adjusting)
  	t = thunk_adjust (t, /*this_adjusting=*/1,
  			  fixed_offset, virtual_offset);
        
*************** use_thunk (tree thunk_fndecl, bool emit_
*** 512,518 ****
  	t = tree_cons (NULL_TREE, a, t);
        t = nreverse (t);
        t = build_call (function, t);
!       if (DECL_RESULT_THUNK_P (thunk_fndecl))
  	t = thunk_adjust (t, /*this_adjusting=*/0,
  			  fixed_offset, virtual_offset);
        
--- 513,519 ----
  	t = tree_cons (NULL_TREE, a, t);
        t = nreverse (t);
        t = build_call (function, t);
!       if (!this_adjusting)
  	t = thunk_adjust (t, /*this_adjusting=*/0,
  			  fixed_offset, virtual_offset);
        
Index: testsuite/ChangeLog
===================================================================
RCS file: /cvs/gcc/gcc/gcc/testsuite/ChangeLog,v
retrieving revision 1.2283
diff -c -3 -p -r1.2283 ChangeLog
*** testsuite/ChangeLog	29 Dec 2002 17:01:45 -0000	1.2283
--- testsuite/ChangeLog	30 Dec 2002 13:33:18 -0000
***************
*** 1,3 ****
--- 1,9 ----
+ 2002-12-30  Nathan Sidwell  <nathan@codesourcery.com>
+ 
+ 	* g++.dg/inherit/covariant5.C: New test.
+ 	* g++.dg/inherit/covariant6.C: New test.
+ 	* g++.dg/inherit/covariant7.C: New test.
+ 
  2002-12-29  Kriang Lerdsuwanakij  <lerdsuwa@users.sourceforge.net>
  
  	PR c++/2739
Index: testsuite/g++.dg/inherit/covariant5.C
===================================================================
RCS file: testsuite/g++.dg/inherit/covariant5.C
diff -N testsuite/g++.dg/inherit/covariant5.C
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- testsuite/g++.dg/inherit/covariant5.C	30 Dec 2002 13:33:27 -0000
***************
*** 0 ****
--- 1,27 ----
+ // { dg-do compile }
+ 
+ // Copyright (C) 2002 Free Software Foundation, Inc.
+ // Contributed by Nathan Sidwell 27 Dec 2002 <nathan@codesourcery.com>
+ 
+ // We ICE'd
+ 
+ struct c0 {};
+ 
+ struct c1 : virtual c0
+ {
+   virtual c0 &f2();
+ };
+ 
+ struct c3 : c1
+ {
+   virtual c1 &f2();
+ };
+ 
+ c1 &c3::f2()
+ {
+   throw 0;
+ }
+ 
+ struct c4 : virtual c3
+ {
+ };
Index: testsuite/g++.dg/inherit/covariant6.C
===================================================================
RCS file: testsuite/g++.dg/inherit/covariant6.C
diff -N testsuite/g++.dg/inherit/covariant6.C
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- testsuite/g++.dg/inherit/covariant6.C	30 Dec 2002 13:33:27 -0000
***************
*** 0 ****
--- 1,27 ----
+ // { dg-do compile }
+ 
+ // Copyright (C) 2002 Free Software Foundation, Inc.
+ // Contributed by Nathan Sidwell 27 Dec 2002 <nathan@codesourcery.com>
+ 
+ // We ICE'd
+ 
+ struct c0 {};
+ 
+ struct c1 : virtual c0
+ {
+   virtual c0 &f2();
+ };
+ 
+ struct c3 : virtual c1
+ {
+   virtual c1 &f2();
+ };
+ 
+ c1 &c3::f2()
+ {
+   throw 0;
+ }
+ 
+ struct c4 : virtual c3
+ {
+ };
Index: testsuite/g++.dg/inherit/covariant7.C
===================================================================
RCS file: testsuite/g++.dg/inherit/covariant7.C
diff -N testsuite/g++.dg/inherit/covariant7.C
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- testsuite/g++.dg/inherit/covariant7.C	30 Dec 2002 13:33:27 -0000
***************
*** 0 ****
--- 1,33 ----
+ // { dg-do compile }
+ 
+ // Copyright (C) 2002 Free Software Foundation, Inc.
+ // Contributed by Nathan Sidwell 27 Dec 2002 <nathan@codesourcery.com>
+ 
+ // We ICE'd
+ 
+ struct c0 {};
+ 
+ struct c1 : virtual c0
+ {
+   virtual c0 &f2() volatile;
+ };
+ 
+ struct c2 
+ {
+   int m;
+ };
+ 
+ struct c3 : virtual c0, virtual c1, c2
+ {
+   virtual c1 &f2() volatile;
+ };
+ 
+ struct c4 : virtual c3, virtual c0, virtual c1
+ {
+   int m;
+ };
+ 
+ struct c6 : c0, c3, c4
+ { // { dg-warning "direct base" "" }
+   virtual c1 &f2() volatile;
+ };

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