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]

Fix 21427


This patch fixes 21427, a 3.4 ICE.  Although the patch comes from
mainline, the test case is slightly different to that which caused the
mainline ICE.  I'll therefore place the testcase on mainline too.

built & tested on i686-pc-linux-gnu

nathan
-- 
Nathan Sidwell    ::   http://www.codesourcery.com   ::     CodeSourcery LLC
nathan@codesourcery.com    ::     http://www.planetfall.pwp.blueyonder.co.uk

2005-05-08  Nathan Sidwell  <nathan@codesourcery.com>

	PR c++/21427
	Backport 2005-03-01  Nathan Sidwell  <nathan@codesourcery.com>
	* class.c (update_vtable_entry_for_fn): Don't crash on invalid
	covariancy. 

	* cp-tree.h (THUNK_TARGET): Expand comment.
	* method.c (use_thunk): Make sure we also use the target, if that
	is a thunk.

	Backport 2005-02-11  Nathan Sidwell  <nathan@codesourcery.com>
	* class.c (update_vtable_entry_for_fn): Walk the covariant's binfo
	chain rather than using lookup_base.

2005-05-08  Nathan Sidwell  <nathan@codesourcery.com>

	PR c++/21427
	* g++.dg/inherit/covariant13.C: New.
	Backport 2005-03-01  Nathan Sidwell  <nathan@codesourcery.com>
	* g++.dg/inherit/covariant12.C: New.

Index: cp/class.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/class.c,v
retrieving revision 1.595.4.10
diff -c -3 -p -r1.595.4.10 class.c
*** cp/class.c	21 Feb 2005 21:11:46 -0000	1.595.4.10
--- cp/class.c	8 May 2005 19:45:47 -0000
*************** update_vtable_entry_for_fn (tree t, tree
*** 2116,2121 ****
--- 2116,2124 ----
           also be converting to the return type of FN, we have to
           combine the two conversions here.  */
        tree fixed_offset, virtual_offset;
+ 
+       over_return = TREE_TYPE (over_return);
+       base_return = TREE_TYPE (base_return);
        
        if (DECL_THUNK_P (fn))
  	{
*************** update_vtable_entry_for_fn (tree t, tree
*** 2133,2164 ****
  	virtual_offset =
  	  TREE_VALUE (purpose_member
  		      (BINFO_TYPE (virtual_offset),
! 		       CLASSTYPE_VBASECLASSES (TREE_TYPE (over_return))));
!       else if (!same_type_p (TREE_TYPE (over_return),
! 			     TREE_TYPE (base_return)))
! 	{
! 	  /* There was no existing virtual thunk (which takes
! 	     precedence).  */
! 	  tree thunk_binfo;
! 	  base_kind kind;
  	  
! 	  thunk_binfo = lookup_base (TREE_TYPE (over_return),
! 				     TREE_TYPE (base_return),
! 				     ba_check | ba_quiet, &kind);
! 
! 	  if (thunk_binfo && (kind == bk_via_virtual
! 			      || !BINFO_OFFSET_ZEROP (thunk_binfo)))
  	    {
  	      tree offset = convert (ssizetype, BINFO_OFFSET (thunk_binfo));
  
! 	      if (kind == bk_via_virtual)
  		{
! 		  /* We convert via virtual base. Find the virtual
! 		     base and adjust the fixed offset to be from there.  */
! 		  while (!TREE_VIA_VIRTUAL (thunk_binfo))
! 		    thunk_binfo = BINFO_INHERITANCE_CHAIN (thunk_binfo);
! 
! 		  virtual_offset = thunk_binfo;
  		  offset = size_diffop
  		    (offset, convert
  		     (ssizetype, BINFO_OFFSET (virtual_offset)));
--- 2136,2186 ----
  	virtual_offset =
  	  TREE_VALUE (purpose_member
  		      (BINFO_TYPE (virtual_offset),
! 		       CLASSTYPE_VBASECLASSES (over_return)));
!       else if (!same_type_ignoring_top_level_qualifiers_p
! 	       (over_return, base_return))
! 	{
!   	  /* There was no existing virtual thunk (which takes
! 	     precedence).  So find the binfo of the base function's
! 	     return type within the overriding function's return type.
! 	     We cannot call lookup base here, because we're inside a
! 	     dfs_walk, and will therefore clobber the BINFO_MARKED
! 	     flags.  Fortunately we know the covariancy is valid (it
! 	     has already been checked), so we can just iterate along
! 	     the binfos, which have been chained in inheritance graph
! 	     order.  Of course it is lame that we have to repeat the
! 	     search here anyway -- we should really be caching pieces
! 	     of the vtable and avoiding this repeated work.  */
! 	  tree thunk_binfo, base_binfo;
! 
! 	  /* Find the base binfo within the overriding function's
! 	     return type.  We will always find a thunk_binfo, except
! 	     when the covariancy is invalid (which we will have
! 	     already diagnosed).  */
! 	  for (base_binfo = TYPE_BINFO (base_return),
! 	       thunk_binfo = TYPE_BINFO (over_return);
! 	       thunk_binfo;
! 	       thunk_binfo = TREE_CHAIN (thunk_binfo))
! 	    if (same_type_p (BINFO_TYPE (thunk_binfo),
! 			     BINFO_TYPE (base_binfo)))
! 	      break;
  	  
! 	  /* See if virtual inheritance is involved.  */
! 	  for (virtual_offset = thunk_binfo;
! 	       virtual_offset;
! 	       virtual_offset = BINFO_INHERITANCE_CHAIN (virtual_offset))
! 	    if (TREE_VIA_VIRTUAL (virtual_offset))
! 	      break;
! 	  
! 	  if (virtual_offset
! 	      || (thunk_binfo && !BINFO_OFFSET_ZEROP (thunk_binfo)))
  	    {
  	      tree offset = convert (ssizetype, BINFO_OFFSET (thunk_binfo));
  
! 	      if (virtual_offset)
  		{
! 		  /* We convert via virtual base.  Adjust the fixed
! 		     offset to be from there.  */
  		  offset = size_diffop
  		    (offset, convert
  		     (ssizetype, BINFO_OFFSET (virtual_offset)));
Index: cp/cp-tree.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/cp-tree.h,v
retrieving revision 1.946.4.19
diff -c -3 -p -r1.946.4.19 cp-tree.h
*** cp/cp-tree.h	25 Apr 2005 19:58:28 -0000	1.946.4.19
--- cp/cp-tree.h	8 May 2005 19:45:59 -0000
*************** struct lang_decl GTY(())
*** 2917,2923 ****
  #define THUNK_ALIAS(DECL) \
    (DECL_LANG_SPECIFIC (FUNCTION_DECL_CHECK (DECL))->decl_flags.u.thunk_alias)
  
! /* For thunk NODE, this is the FUNCTION_DECL thunked to.  */
  #define THUNK_TARGET(NODE)				\
    (DECL_LANG_SPECIFIC (NODE)->u.f.befriending_classes)
  
--- 2917,2924 ----
  #define THUNK_ALIAS(DECL) \
    (DECL_LANG_SPECIFIC (FUNCTION_DECL_CHECK (DECL))->decl_flags.u.thunk_alias)
  
! /* For thunk NODE, this is the FUNCTION_DECL thunked to.  It is
!    possible for the target to be a thunk too.  */
  #define THUNK_TARGET(NODE)				\
    (DECL_LANG_SPECIFIC (NODE)->u.f.befriending_classes)
  
Index: cp/method.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/method.c,v
retrieving revision 1.275.4.5
diff -c -3 -p -r1.275.4.5 method.c
*** cp/method.c	17 Dec 2004 16:19:19 -0000	1.275.4.5
--- cp/method.c	8 May 2005 19:46:23 -0000
*************** use_thunk (tree thunk_fndecl, bool emit_
*** 357,362 ****
--- 357,366 ----
         There's no need to process this thunk again.  */
      return;
  
+   if (DECL_THUNK_P (function))
+     /* The target is itself a thunk, process it now.  */
+     use_thunk (function, emit_p);
+   
    /* Thunks are always addressable; they only appear in vtables.  */
    TREE_ADDRESSABLE (thunk_fndecl) = 1;
  
Index: testsuite/g++.dg/inherit/covariant12.C
===================================================================
RCS file: testsuite/g++.dg/inherit/covariant12.C
diff -N testsuite/g++.dg/inherit/covariant12.C
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- testsuite/g++.dg/inherit/covariant12.C	8 May 2005 19:47:39 -0000
***************
*** 0 ****
--- 1,18 ----
+ // Copyright (C) 2004 Free Software Foundation, Inc.
+ // Contributed by Nathan Sidwell 27 Feb 2005<nathan@codesourcery.com>
+ 
+ // PR 20232: ICE on invalid
+ 
+ struct T { };
+ 
+ struct S;
+ 
+ struct B
+ {
+   virtual T *Foo (); // { dg-error "overriding" "" }
+ };
+ 
+ struct D : B
+ {
+   virtual S *Foo (); // { dg-error "invalid covariant" "" }
+ };
Index: testsuite/g++.dg/inherit/covariant13.C
===================================================================
RCS file: testsuite/g++.dg/inherit/covariant13.C
diff -N testsuite/g++.dg/inherit/covariant13.C
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- testsuite/g++.dg/inherit/covariant13.C	8 May 2005 19:47:39 -0000
***************
*** 0 ****
--- 1,25 ----
+ // Copyright (C) 2004 Free Software Foundation, Inc.
+ // Contributed by Nathan Sidwell 8 May 2005<nathan@codesourcery.com>
+ 
+ // Origin:Andrew Pinski: pinskia@gcc.gnu.org
+ // PR 21427: ICE on valid
+ 
+ struct B1 { 
+   public: 
+     virtual void foo(); 
+ }; 
+  
+ struct B2 { 
+   public: 
+     virtual B2 & bar() = 0; 
+ }; 
+  
+ struct I : public B1, B2 { 
+   public: 
+     virtual ~I(); 
+     virtual I & bar(); 
+ }; 
+  
+ struct D : public I { 
+     virtual ~D(); 
+ }; 

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