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]

[C++ PATCH] overriding virtuals


Hi,

I was working on generating the correct exception specification for synthesized
functions, and that entailed checking virtual dtors correctly -- something that
get_matching_virtual didn't do. I found that checking for overridden virtual
functions was doing much more work than necessary in building up lists
of functions, breaking them down and reorganizing them, and then checking
more functions than necessary. I've reimplemented it with this patch, which
is, I beleive, much clearer about what's happening. In so doing I fixed
one known bug (removed XFAILS) and one previously unknown bug (new testcase).

A future patch will generate synthesized exception specifications.

built & tested on i686-pc-linux-gnu, ok?

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
2000-12-04  Nathan Sidwell  <nathan@codesourcery.com>

	* cp-tree.h (IDENTIFIER_VIRTUAL_P): Document.
	(get_matching_virtual): Remove.
	(look_for_overrides): Declare new function.
	* decl.c (grokfndecl): Don't set IDENTIFIER_VIRTUAL_P or
	DECL_VINDEX here.
	* class.c (check_for_override): Move base class iteration code
	to look_for_overrides.
	* search.c (next_baselink): Remove.
	(get_virtuals_named_this): Remove.
	(get_virtual_destructor): Remove.
	(tree_has_any_destructors_p): Remove.
	(struct gvnt_info): Remove.
	(check_final_overrider): Remove `virtual' from error messages.
	(get_matching_virtuals): Remove. Move functionality to ...
	(look_for_overrides): ... here, and ...
	(look_for_overrides_r): ... here. Set DECL_VIRTUAL_P, if found
	to be overriding.

Index: cp/class.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/class.c,v
retrieving revision 1.343
diff -c -3 -p -r1.343 class.c
*** class.c	2000/11/15 05:07:03	1.343
--- class.c	2000/12/04 17:05:16
*************** static void
*** 2910,2965 ****
  check_for_override (decl, ctype)
       tree decl, ctype;
  {
!   tree binfos = BINFO_BASETYPES (TYPE_BINFO (ctype));
!   int i, n_baselinks = binfos ? TREE_VEC_LENGTH (binfos) : 0;
!   int virtualp = DECL_VIRTUAL_P (decl);
!   int found_overriden_fn = 0;
  
!   for (i = 0; i < n_baselinks; i++)
      {
!       tree base_binfo = TREE_VEC_ELT (binfos, i);
!       if (TYPE_POLYMORPHIC_P (BINFO_TYPE (base_binfo)))
! 	{
! 	  tree tmp = get_matching_virtual
! 	    (base_binfo, decl, DECL_DESTRUCTOR_P (decl));
! 
! 	  if (tmp && !found_overriden_fn)
! 	    {
! 	      /* If this function overrides some virtual in some base
! 		 class, then the function itself is also necessarily
! 		 virtual, even if the user didn't explicitly say so.  */
! 	      DECL_VIRTUAL_P (decl) = 1;
! 
! 	      /* The TMP we really want is the one from the deepest
! 		 baseclass on this path, taking care not to
! 		 duplicate if we have already found it (via another
! 		 path to its virtual baseclass.  */
! 	      if (TREE_CODE (TREE_TYPE (decl)) == FUNCTION_TYPE)
! 		{
! 		  cp_error_at ("`static %#D' cannot be declared", decl);
! 		  cp_error_at ("  since `virtual %#D' declared in base class",
! 			       tmp);
! 		  break;
! 		}
! 	      virtualp = 1;
! 
! 	      /* Set DECL_VINDEX to a value that is neither an
! 		 INTEGER_CST nor the error_mark_node so that
! 		 add_virtual_function will realize this is an
! 		 overridden function.  */
! 	      DECL_VINDEX (decl) 
! 		= tree_cons (tmp, NULL_TREE, DECL_VINDEX (decl));
! 	      
! 	      /* We now know that DECL overrides something,
! 		 which is all that is important.  But, we must
! 		 continue to iterate through all the base-classes
! 		 in order to allow get_matching_virtual to check for
! 		 various illegal overrides.  */
! 	      found_overriden_fn = 1;
! 	    }
! 	}
      }
!   if (virtualp)
      {
        if (DECL_VINDEX (decl) == NULL_TREE)
  	DECL_VINDEX (decl) = error_mark_node;
--- 2910,2933 ----
  check_for_override (decl, ctype)
       tree decl, ctype;
  {
!   if (TREE_CODE (decl) == TEMPLATE_DECL)
!     /* In [temp.mem] we have:
  
!          A specialization of a member function template does not
!          override a virtual function from a base class.  */
!     return;
!   if ((DECL_DESTRUCTOR_P (decl)
!        || IDENTIFIER_VIRTUAL_P (DECL_NAME (decl)))
!       && look_for_overrides (ctype, decl)
!       && !DECL_STATIC_FUNCTION_P (decl))
      {
!       /* Set DECL_VINDEX to a value that is neither an
! 	 INTEGER_CST nor the error_mark_node so that
! 	 add_virtual_function will realize this is an
! 	 overriding function.  */
!       DECL_VINDEX (decl) = decl;
      }
!   if (DECL_VIRTUAL_P (decl))
      {
        if (DECL_VINDEX (decl) == NULL_TREE)
  	DECL_VINDEX (decl) = error_mark_node;
Index: cp/cp-tree.h
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/cp-tree.h,v
retrieving revision 1.544
diff -c -3 -p -r1.544 cp-tree.h
*** cp-tree.h	2000/11/27 12:53:37	1.544
--- cp-tree.h	2000/12/04 17:05:23
*************** struct tree_srcloc
*** 514,520 ****
  #define SET_IDENTIFIER_ERROR_LOCUS(NODE,VALUE)	\
  	SET_LANG_ID(NODE, VALUE, error_locus)
  
! 
  #define IDENTIFIER_VIRTUAL_P(NODE) TREE_LANG_FLAG_1(NODE)
  
  /* Nonzero if this identifier is the prefix for a mangled C++ operator
--- 514,521 ----
  #define SET_IDENTIFIER_ERROR_LOCUS(NODE,VALUE)	\
  	SET_LANG_ID(NODE, VALUE, error_locus)
  
! /* Nonzero if this identifier is used as a virtual function name somewhere
!    (optimizes searches).  */
  #define IDENTIFIER_VIRTUAL_P(NODE) TREE_LANG_FLAG_1(NODE)
  
  /* Nonzero if this identifier is the prefix for a mangled C++ operator
*************** extern tree lookup_field			PARAMS ((tree
*** 4250,4256 ****
  extern int lookup_fnfields_1                    PARAMS ((tree, tree));
  extern tree lookup_fnfields			PARAMS ((tree, tree, int));
  extern tree lookup_member			PARAMS ((tree, tree, int, int));
! extern tree get_matching_virtual		PARAMS ((tree, tree, int));
  extern void get_pure_virtuals		        PARAMS ((tree));
  extern tree init_vbase_pointers			PARAMS ((tree, tree));
  extern void get_vbase_types			PARAMS ((tree));
--- 4251,4257 ----
  extern int lookup_fnfields_1                    PARAMS ((tree, tree));
  extern tree lookup_fnfields			PARAMS ((tree, tree, int));
  extern tree lookup_member			PARAMS ((tree, tree, int, int));
! extern int look_for_overrides			PARAMS ((tree, tree));
  extern void get_pure_virtuals		        PARAMS ((tree));
  extern tree init_vbase_pointers			PARAMS ((tree, tree));
  extern void get_vbase_types			PARAMS ((tree));
Index: cp/decl.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/decl.c,v
retrieving revision 1.720
diff -c -3 -p -r1.720 decl.c
*** decl.c	2000/12/01 22:25:43	1.720
--- decl.c	2000/12/04 17:05:38
*************** grokfndecl (ctype, type, declarator, ori
*** 9036,9047 ****
      return decl;
  
    if (virtualp)
!     {
!       DECL_VIRTUAL_P (decl) = 1;
!       if (DECL_VINDEX (decl) == NULL_TREE)
! 	DECL_VINDEX (decl) = error_mark_node;
!       IDENTIFIER_VIRTUAL_P (DECL_NAME (decl)) = 1;
!     }
  
    return decl;
  }
--- 9036,9042 ----
      return decl;
  
    if (virtualp)
!     DECL_VIRTUAL_P (decl) = 1;
  
    return decl;
  }
Index: cp/search.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/search.c,v
retrieving revision 1.191
diff -c -3 -p -r1.191 search.c
*** search.c	2000/11/27 10:55:30	1.191
--- search.c	2000/12/04 17:05:41
*************** struct vbase_info 
*** 83,89 ****
    tree inits;
  };
  
- static tree next_baselink PARAMS ((tree));
  static tree get_vbase_1 PARAMS ((tree, tree, unsigned int *));
  static tree lookup_field_1 PARAMS ((tree, tree));
  static int lookup_fnfields_here PARAMS ((tree, tree));
--- 83,88 ----
*************** static tree dfs_push_type_decls PARAMS (
*** 110,120 ****
  static tree dfs_push_decls PARAMS ((tree, void *));
  static tree dfs_unuse_fields PARAMS ((tree, void *));
  static tree add_conversions PARAMS ((tree, void *));
- static tree get_virtuals_named_this PARAMS ((tree, tree));
- static tree get_virtual_destructor PARAMS ((tree, void *));
- static tree tree_has_any_destructor_p PARAMS ((tree, void *));
  static int covariant_return_p PARAMS ((tree, tree));
  static int check_final_overrider PARAMS ((tree, tree));
  static struct search_level *push_search_level
  	PARAMS ((struct stack_level *, struct obstack *));
  static struct search_level *pop_search_level
--- 109,117 ----
  static tree dfs_push_decls PARAMS ((tree, void *));
  static tree dfs_unuse_fields PARAMS ((tree, void *));
  static tree add_conversions PARAMS ((tree, void *));
  static int covariant_return_p PARAMS ((tree, tree));
  static int check_final_overrider PARAMS ((tree, tree));
+ static int look_for_overrides_r PARAMS ((tree, tree));
  static struct search_level *push_search_level
  	PARAMS ((struct stack_level *, struct obstack *));
  static struct search_level *pop_search_level
*************** static tree bfs_walk
*** 124,130 ****
  	       void *));
  static tree lookup_field_queue_p PARAMS ((tree, void *));
  static tree lookup_field_r PARAMS ((tree, void *));
- static tree get_virtuals_named_this_r PARAMS ((tree, void *));
  static tree context_for_name_lookup PARAMS ((tree));
  static tree canonical_binfo PARAMS ((tree));
  static tree shared_marked_p PARAMS ((tree, void *));
--- 121,126 ----
*************** dfs_walk (binfo, fn, qfn, data)
*** 1867,1953 ****
    return dfs_walk_real (binfo, 0, fn, qfn, data);
  }
  
- struct gvnt_info 
- {
-   /* The name of the function we are looking for.  */
-   tree name;
-   /* The overloaded functions we have found.  */
-   tree fields;
- };
- 
- /* Called from get_virtuals_named_this via bfs_walk.  */
- 
- static tree
- get_virtuals_named_this_r (binfo, data)
-      tree binfo;
-      void *data;
- {
-   struct gvnt_info *gvnti = (struct gvnt_info *) data;
-   tree type = BINFO_TYPE (binfo);
-   int idx;
- 
-   idx = lookup_fnfields_here (BINFO_TYPE (binfo), gvnti->name);
-   if (idx >= 0)
-     gvnti->fields
-       = tree_cons (binfo, 
- 		   TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (type), idx),
- 		   gvnti->fields);
- 
-   return NULL_TREE;
- }
- 
- /* Return the virtual functions with the indicated NAME in the type
-    indicated by BINFO.  The result is a TREE_LIST whose TREE_PURPOSE
-    indicates the base class from which the TREE_VALUE (an OVERLOAD or
-    just a FUNCTION_DECL) originated.  */
- 
- static tree
- get_virtuals_named_this (binfo, name)
-      tree binfo;
-      tree name;
- {
-   struct gvnt_info gvnti;
-   tree fields;
- 
-   gvnti.name = name;
-   gvnti.fields = NULL_TREE;
- 
-   bfs_walk (binfo, get_virtuals_named_this_r, 0, &gvnti);
- 
-   /* Get to the function decls, and return the first virtual function
-      with this name, if there is one.  */
-   for (fields = gvnti.fields; fields; fields = next_baselink (fields))
-     {
-       tree fndecl;
- 
-       for (fndecl = TREE_VALUE (fields); fndecl; fndecl = OVL_NEXT (fndecl))
- 	if (DECL_VINDEX (OVL_CURRENT (fndecl)))
- 	  return fields;
-     }
-   return NULL_TREE;
- }
- 
- static tree
- get_virtual_destructor (binfo, data)
-      tree binfo;
-      void *data ATTRIBUTE_UNUSED;
- {
-   tree type = BINFO_TYPE (binfo);
-   if (TYPE_HAS_DESTRUCTOR (type)
-       && DECL_VINDEX (TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (type), 1)))
-     return TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (type), 1);
-   return 0;
- }
- 
- static tree
- tree_has_any_destructor_p (binfo, data)
-      tree binfo;
-      void *data ATTRIBUTE_UNUSED;
- {
-   tree type = BINFO_TYPE (binfo);
-   return TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type) ? binfo : NULL_TREE;
- }
- 
  /* Returns > 0 if a function with type DRETTYPE overriding a function
     with type BRETTYPE is covariant, as defined in [class.virtual].
  
--- 1863,1868 ----
*************** check_final_overrider (overrider, basefn
*** 2026,2149 ****
  
        if (pedantic && i == -1)
  	{
! 	  cp_pedwarn_at ("invalid covariant return type for `virtual %#D'", overrider);
! 	  cp_pedwarn_at ("  overriding `virtual %#D' (must be pointer or reference to class)", basefn);
  	}
      }
    else if (IS_AGGR_TYPE_2 (base_return, over_return)
  	   && same_or_base_type_p (base_return, over_return))
      {
!       cp_error_at ("invalid covariant return type for `virtual %#D'", overrider);
!       cp_error_at ("  overriding `virtual %#D' (must use pointer or reference)", basefn);
        return 0;
      }
    else if (IDENTIFIER_ERROR_LOCUS (DECL_ASSEMBLER_NAME (overrider)) == NULL_TREE)
      {
!       cp_error_at ("conflicting return type specified for `virtual %#D'", overrider);
!       cp_error_at ("  overriding `virtual %#D'", basefn);
        SET_IDENTIFIER_ERROR_LOCUS (DECL_ASSEMBLER_NAME (overrider),
                                    DECL_CONTEXT (overrider));
        return 0;
      }
    
    /* Check throw specifier is subset.  */
!   /* XXX At the moment, punt on an overriding artificial function. We
!      don't generate its exception specifier, so can't check it properly.  */
    if (! DECL_ARTIFICIAL (overrider)
        && !comp_except_specs (base_throw, over_throw, 0))
      {
!       cp_error_at ("looser throw specifier for `virtual %#F'", overrider);
!       cp_error_at ("  overriding `virtual %#F'", basefn);
        return 0;
      }
    return 1;
  }
  
! /* Given a class type TYPE, and a function decl FNDECL, look for a
!    virtual function in TYPE's hierarchy which FNDECL could match as a
!    virtual function.  It doesn't matter which one we find.
! 
!    DTORP is nonzero if we are looking for a destructor.  Destructors
!    need special treatment because they do not match by name.  */
  
! tree
! get_matching_virtual (binfo, fndecl, dtorp)
!      tree binfo, fndecl;
!      int dtorp;
  {
!   tree tmp = NULL_TREE;
  
!   if (TREE_CODE (fndecl) == TEMPLATE_DECL)
!     /* In [temp.mem] we have:
  
!          A specialization of a member function template does not
!          override a virtual function from a base class.  */
!     return NULL_TREE;
  
!   /* Breadth first search routines start searching basetypes
!      of TYPE, so we must perform first ply of search here.  */
!   if (dtorp)
!     return bfs_walk (binfo, get_virtual_destructor,
! 		     tree_has_any_destructor_p, 0);
    else
      {
!       tree drettype, dtypes, btypes, instptr_type;
!       tree baselink, best = NULL_TREE;
!       tree declarator = DECL_NAME (fndecl);
!       if (IDENTIFIER_VIRTUAL_P (declarator) == 0)
! 	return NULL_TREE;
! 
!       baselink = get_virtuals_named_this (binfo, declarator);
!       if (baselink == NULL_TREE)
! 	return NULL_TREE;
! 
!       drettype = TREE_TYPE (TREE_TYPE (fndecl));
!       dtypes = TYPE_ARG_TYPES (TREE_TYPE (fndecl));
!       if (DECL_STATIC_FUNCTION_P (fndecl))
! 	instptr_type = NULL_TREE;
!       else
! 	instptr_type = TREE_TYPE (TREE_VALUE (dtypes));
! 
!       for (; baselink; baselink = next_baselink (baselink))
! 	{
! 	  tree tmps;
! 	  for (tmps = TREE_VALUE (baselink); tmps; tmps = OVL_NEXT (tmps))
  	    {
! 	      tmp = OVL_CURRENT (tmps);
! 	      if (! DECL_VINDEX (tmp))
! 		continue;
! 
! 	      btypes = TYPE_ARG_TYPES (TREE_TYPE (tmp));
! 	      if (instptr_type == NULL_TREE)
! 		{
! 		  if (compparms (TREE_CHAIN (btypes), dtypes))
! 		    /* Caller knows to give error in this case.  */
! 		    return tmp;
! 		  return NULL_TREE;
! 		}
! 
! 	      if (/* The first parameter is the `this' parameter,
! 		     which has POINTER_TYPE, and we can therefore
! 		     safely use TYPE_QUALS, rather than
  		     CP_TYPE_QUALS.  */
! 		  (TYPE_QUALS (TREE_TYPE (TREE_VALUE (btypes)))
! 		   == TYPE_QUALS (instptr_type))
! 		  && compparms (TREE_CHAIN (btypes), TREE_CHAIN (dtypes)))
! 		{
! 	          check_final_overrider (fndecl, tmp);
! 
! 		  /* FNDECL overrides this function.  We continue to
! 		     check all the other functions in order to catch
! 		     errors; it might be that in some other baseclass
! 		     a virtual function was declared with the same
! 		     parameter types, but a different return type.  */
! 		  best = tmp;
! 		}
  	    }
  	}
- 
-       return best;
      }
  }
  
  /* A queue function for dfs_walk that skips any nonprimary virtual
--- 1941,2068 ----
  
        if (pedantic && i == -1)
  	{
! 	  cp_pedwarn_at ("invalid covariant return type for `%#D'", overrider);
! 	  cp_pedwarn_at ("  overriding `%#D' (must be pointer or reference to class)", basefn);
  	}
      }
    else if (IS_AGGR_TYPE_2 (base_return, over_return)
  	   && same_or_base_type_p (base_return, over_return))
      {
!       cp_error_at ("invalid covariant return type for `%#D'", overrider);
!       cp_error_at ("  overriding `%#D' (must use pointer or reference)", basefn);
        return 0;
      }
    else if (IDENTIFIER_ERROR_LOCUS (DECL_ASSEMBLER_NAME (overrider)) == NULL_TREE)
      {
!       cp_error_at ("conflicting return type specified for `%#D'", overrider);
!       cp_error_at ("  overriding `%#D'", basefn);
        SET_IDENTIFIER_ERROR_LOCUS (DECL_ASSEMBLER_NAME (overrider),
                                    DECL_CONTEXT (overrider));
        return 0;
      }
    
    /* Check throw specifier is subset.  */
!   /* XXX At the moment, punt with artificial functions. We
!      don't generate their exception specifiers, so can't check properly.  */
    if (! DECL_ARTIFICIAL (overrider)
        && !comp_except_specs (base_throw, over_throw, 0))
      {
!       cp_error_at ("looser throw specifier for `%#F'", overrider);
!       cp_error_at ("  overriding `%#F'", basefn);
        return 0;
      }
    return 1;
  }
  
! /* Given a class TYPE, and a function decl FNDECL, look for
!    virtual functions in TYPE's hierarchy which FNDECL overrides.
!    We do not look in TYPE itself, only its bases.
!    
!    Returns non-zero, if we find any. Set FNDECL's DECL_VIRTUAL_P, if we
!    find that it overrides anything.
!    
!    We check that every function which is overridden, is correctly
!    overridden.  */
  
! int
! look_for_overrides (type, fndecl)
!      tree type, fndecl;
  {
!   tree binfo = TYPE_BINFO (type);
!   tree basebinfos = BINFO_BASETYPES (binfo);
!   int nbasebinfos = basebinfos ? TREE_VEC_LENGTH (basebinfos) : 0;
!   int ix;
!   int found = 0;
  
!   for (ix = 0; ix != nbasebinfos; ix++)
!     {
!       tree basetype = BINFO_TYPE (TREE_VEC_ELT (basebinfos, ix));
!       
!       if (TYPE_POLYMORPHIC_P (basetype))
!         found += look_for_overrides_r (basetype, fndecl);
!     }
!   return found;
! }
  
! /* Look in TYPE for virtual functions overridden by FNDECL. Check both
!    TYPE itself and its bases. */
  
! static int
! look_for_overrides_r (type, fndecl)
!      tree type, fndecl;
! {
!   int ix;
!   
!   if (DECL_DESTRUCTOR_P (fndecl))
!     ix = CLASSTYPE_DESTRUCTOR_SLOT;
    else
+     ix = lookup_fnfields_here (type, DECL_NAME (fndecl));
+   if (ix >= 0)
      {
!       tree fns = TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (type), ix);
!       tree dtypes = TYPE_ARG_TYPES (TREE_TYPE (fndecl));
!       tree thistype = DECL_STATIC_FUNCTION_P (fndecl)
!                       ? NULL_TREE : TREE_TYPE (TREE_VALUE (dtypes));
!   
!       for (; fns; fns = OVL_NEXT (fns))
!         {
!           tree fn = OVL_CURRENT (fns);
!           tree btypes = TYPE_ARG_TYPES (TREE_TYPE (fn));
!           
!           if (!DECL_VIRTUAL_P (fn))
!             ;
! 	  else if (thistype == NULL_TREE)
  	    {
! 	      if (compparms (TREE_CHAIN (btypes), dtypes))
!                 {
!                   /* A static member function cannot match an inherited
!                      virtual member function.  */
!                   cp_error_at ("`%#D' cannot be declared", fndecl);
!                   cp_error_at ("  since `%#D' declared in base class", fn);
!                   return 1;
!                 }
!             }
!           else
!             {
!               if (/* The first parameter is the `this' parameter,
! 	             which has POINTER_TYPE, and we can therefore
! 	             safely use TYPE_QUALS, rather than
  		     CP_TYPE_QUALS.  */
! 	          (TYPE_QUALS (TREE_TYPE (TREE_VALUE (btypes)))
! 	           == TYPE_QUALS (thistype))
! 	          && compparms (TREE_CHAIN (btypes), TREE_CHAIN (dtypes)))
!                 {
!                   /* It's definitely virtual, even if not explicitly set.  */
!                   DECL_VIRTUAL_P (fndecl) = 1;
! 	          check_final_overrider (fndecl, fn);
! 	      
! 	          return 1;
! 	        }
  	    }
  	}
      }
+   /* We failed to find one declared in this class. Look in its bases.  */
+   return look_for_overrides (type, fndecl);
  }
  
  /* A queue function for dfs_walk that skips any nonprimary virtual
*************** get_pure_virtuals (type)
*** 2319,2341 ****
  	    cp_error ("`%#D' needs a final overrider", base_fndecl);
  	}
      }
- }
- 
- static tree
- next_baselink (baselink)
-      tree baselink;
- {
-   tree tmp = TREE_TYPE (baselink);
-   baselink = TREE_CHAIN (baselink);
-   while (tmp)
-     {
-       /* @@ does not yet add previous base types.  */
-       baselink = tree_cons (TREE_PURPOSE (tmp), TREE_VALUE (tmp),
- 			    baselink);
-       TREE_TYPE (baselink) = TREE_TYPE (tmp);
-       tmp = TREE_CHAIN (tmp);
-     }
-   return baselink;
  }
  
  /* DEPTH-FIRST SEARCH ROUTINES.  */
--- 2238,2243 ----
Index: testsuite/g++.old-deja/g++.eh/spec6.C
===================================================================
RCS file: /cvs/gcc/egcs/gcc/testsuite/g++.old-deja/g++.eh/spec6.C,v
retrieving revision 1.3
diff -c -3 -p -r1.3 spec6.C
*** spec6.C	1999/08/04 09:09:21	1.3
--- spec6.C	2000/12/04 17:05:05
*************** struct A
*** 92,98 ****
    virtual void wobble(int) throw(E *);    // ERROR - overriding 
    virtual void wabble(int) throw(E *);
    virtual void wubble(int) throw(E *, H *);
!   virtual ~A() throw();                   // ERROR - overriding XFAIL
  };
  
  struct B : A
--- 92,98 ----
    virtual void wobble(int) throw(E *);    // ERROR - overriding 
    virtual void wabble(int) throw(E *);
    virtual void wubble(int) throw(E *, H *);
!   virtual ~A() throw();                   // ERROR - overriding
  };
  
  struct B : A
*************** struct C : A, A1
*** 133,141 ****
  
  struct D : A, A1
  {
!   // The xfail here is because we don't have the check in the right place to
!   // catch dtor failings.
!   virtual ~D() throw(int); // ERROR - looser throw - A::~A() - XFAIL
  };
  
  // [except.spec] 5, types shall not be defined in exception specifiers
--- 133,139 ----
  
  struct D : A, A1
  {
!   virtual ~D() throw(int); // ERROR - looser throw - A::~A()
  };
  
  // [except.spec] 5, types shall not be defined in exception specifiers
// Build don't link:

// Copyright (C) 2000 Free Software Foundation, Inc.
// Contributed by Nathan Sidwell 14 Nov 2000 <nathan@codesourcery.com>

// We failed to spot a static member which overrode a virtual

struct A
{
  virtual int foo (char);
  static int foo ();
  virtual int foo (int);    // ERROR - this function
  static int foo (float);
  virtual int foo (double);
};

struct B : A
{
  static int foo (int);   // ERROR - cannot override
};

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