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 23118, 22604


This patch fixes two ICEs.

22604 was easy, we already mark invalid covariant overriders. All that was needed was to tell the vtable machinery not to try processing them.

23118 was a little harder. An invalid overload still got added to the *list* of member function, but wasn't added to the *vector*. We process methods in declaration order using the list, but search for overrides using the vector. When a virtual function is only on the list, look_for_overrides_here will fail to find it. The fix is for add_method to return a flag indicating whether the function made it to the method vector, and if it doesn't we don't add it to the method list either.

built & tested on i686-pc-linux-gnu. Mainline & 4.0. Not for 3.4 as these are both ice-on-illformed-after-error.

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

2005-10-18  Nathan Sidwell  <nathan@codesourcery.com>

	PR c++/22604
	* class.c (update_vtable_entry_for_fn): Don't process invalid
	covariant overriders.

	PR c++/23118
	* cp-tree.h (add_method): Add return value.
	* class.c (add_method): Return success indicator.
	* semantics.c (finish_member_declaration): Don't add an invalid
	method to the method list.

Index: cp/class.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/class.c,v
retrieving revision 1.737
diff -c -3 -p -r1.737 class.c
*** cp/class.c	15 Oct 2005 18:13:24 -0000	1.737
--- cp/class.c	18 Oct 2005 12:02:15 -0000
*************** modify_vtable_entry (tree t,
*** 879,887 ****
  
  
  /* Add method METHOD to class TYPE.  If USING_DECL is non-null, it is
!    the USING_DECL naming METHOD.  */
  
! void
  add_method (tree type, tree method, tree using_decl)
  {
    unsigned slot;
--- 879,888 ----
  
  
  /* Add method METHOD to class TYPE.  If USING_DECL is non-null, it is
!    the USING_DECL naming METHOD.  Returns true if the method could be
!    added to the method vec.  */
  
! bool
  add_method (tree type, tree method, tree using_decl)
  {
    unsigned slot;
*************** add_method (tree type, tree method, tree
*** 894,900 ****
    tree current_fns;
  
    if (method == error_mark_node)
!     return;
  
    complete_p = COMPLETE_TYPE_P (type);
    conv_p = DECL_CONV_FN_P (method);
--- 895,901 ----
    tree current_fns;
  
    if (method == error_mark_node)
!     return false;
  
    complete_p = COMPLETE_TYPE_P (type);
    conv_p = DECL_CONV_FN_P (method);
*************** add_method (tree type, tree method, tree
*** 1027,1033 ****
  		{
  		  if (DECL_CONTEXT (fn) == type)
  		    /* Defer to the local function.  */
! 		    return;
  		  if (DECL_CONTEXT (fn) == DECL_CONTEXT (method))
  		    error ("repeated using declaration %q+D", using_decl);
  		  else
--- 1028,1034 ----
  		{
  		  if (DECL_CONTEXT (fn) == type)
  		    /* Defer to the local function.  */
! 		    return false;
  		  if (DECL_CONTEXT (fn) == DECL_CONTEXT (method))
  		    error ("repeated using declaration %q+D", using_decl);
  		  else
*************** add_method (tree type, tree method, tree
*** 1044,1050 ****
  		 declarations because that will confuse things if the
  		 methods have inline definitions.  In particular, we
  		 will crash while processing the definitions.  */
! 	      return;
  	    }
  	}
      }
--- 1045,1051 ----
  		 declarations because that will confuse things if the
  		 methods have inline definitions.  In particular, we
  		 will crash while processing the definitions.  */
! 	      return false;
  	    }
  	}
      }
*************** add_method (tree type, tree method, tree
*** 1069,1074 ****
--- 1070,1076 ----
    else
      /* Replace the current slot.  */
      VEC_replace (tree, method_vec, slot, overload);
+   return true;
  }
  
  /* Subroutines of finish_struct.  */
*************** update_vtable_entry_for_fn (tree t, tree
*** 1980,1986 ****
    if (POINTER_TYPE_P (over_return)
        && TREE_CODE (over_return) == TREE_CODE (base_return)
        && CLASS_TYPE_P (TREE_TYPE (over_return))
!       && CLASS_TYPE_P (TREE_TYPE (base_return)))
      {
        /* If FN is a covariant thunk, we must figure out the adjustment
  	 to the final base FN was converting to. As OVERRIDER_TARGET might
--- 1982,1990 ----
    if (POINTER_TYPE_P (over_return)
        && TREE_CODE (over_return) == TREE_CODE (base_return)
        && CLASS_TYPE_P (TREE_TYPE (over_return))
!       && CLASS_TYPE_P (TREE_TYPE (base_return))
!       /* If the overrider is invalid, don't even try.  */
!       && !DECL_INVALID_OVERRIDER_P (overrider_target))
      {
        /* If FN is a covariant thunk, we must figure out the adjustment
  	 to the final base FN was converting to. As OVERRIDER_TARGET might
Index: cp/cp-tree.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/cp-tree.h,v
retrieving revision 1.1168
diff -c -3 -p -r1.1168 cp-tree.h
*** cp/cp-tree.h	17 Oct 2005 17:25:16 -0000	1.1168
--- cp/cp-tree.h	18 Oct 2005 12:02:18 -0000
*************** extern tree build_vfn_ref			(tree, tree)
*** 3709,3715 ****
  extern tree get_vtable_decl			(tree, int);
  extern void resort_type_method_vec		(void *, void *,
  						 gt_pointer_operator, void *);
! extern void add_method				(tree, tree, tree);
  extern int currently_open_class			(tree);
  extern tree currently_open_derived_class	(tree);
  extern tree finish_struct			(tree, tree);
--- 3709,3715 ----
  extern tree get_vtable_decl			(tree, int);
  extern void resort_type_method_vec		(void *, void *,
  						 gt_pointer_operator, void *);
! extern bool add_method				(tree, tree, tree);
  extern int currently_open_class			(tree);
  extern tree currently_open_derived_class	(tree);
  extern tree finish_struct			(tree, tree);
Index: cp/semantics.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/semantics.c,v
retrieving revision 1.493
diff -c -3 -p -r1.493 semantics.c
*** cp/semantics.c	16 Oct 2005 19:38:56 -0000	1.493
--- cp/semantics.c	18 Oct 2005 12:02:20 -0000
*************** finish_member_declaration (tree decl)
*** 2232,2244 ****
      {
        /* We also need to add this function to the
  	 CLASSTYPE_METHOD_VEC.  */
!       add_method (current_class_type, decl, NULL_TREE);
! 
!       TREE_CHAIN (decl) = TYPE_METHODS (current_class_type);
!       TYPE_METHODS (current_class_type) = decl;
  
!       maybe_add_class_template_decl_list (current_class_type, decl,
! 					  /*friend_p=*/0);
      }
    /* Enter the DECL into the scope of the class.  */
    else if ((TREE_CODE (decl) == USING_DECL && !DECL_DEPENDENT_P (decl))
--- 2232,2245 ----
      {
        /* We also need to add this function to the
  	 CLASSTYPE_METHOD_VEC.  */
!       if (add_method (current_class_type, decl, NULL_TREE))
! 	{
! 	  TREE_CHAIN (decl) = TYPE_METHODS (current_class_type);
! 	  TYPE_METHODS (current_class_type) = decl;
  
! 	  maybe_add_class_template_decl_list (current_class_type, decl,
! 					      /*friend_p=*/0);
! 	}
      }
    /* Enter the DECL into the scope of the class.  */
    else if ((TREE_CODE (decl) == USING_DECL && !DECL_DEPENDENT_P (decl))
// Copyright (C) 2005 Free Software Foundation, Inc.
// Contributed by Nathan Sidwell 18 Oct 2005 <nathan@codesourcery.com>

// PR 22604
// Origin: Volker Reichelt <reichelt@gcc.gnu.org>

struct A;

struct B
{
  virtual A* foo();  // { dg-error "overriding" "" }
};

namespace N
{
  struct A : B
  {
    virtual A* foo(); // { dg-error "invalid covariant" "" }	
  };
}
// Copyright (C) 2005 Free Software Foundation, Inc.
// Contributed by Nathan Sidwell 18 Oct 2005 <nathan@codesourcery.com>

// PR 22604
// Origin: Volker Reichelt <reichelt@gcc.gnu.org>

struct A
{
  void foo();  // { dg-error "with" "" }
  virtual void foo();  // { dg-error "cannot be overloaded" "" }
};

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