C++ PATCH for missed error

Mark Mitchell mark@markmitchell.com
Fri Feb 26 11:59:00 GMT 1999


  We didn't always flag illegal overrides of virtual functions;
whether or not we caught the order depended on the ordering of the
base classes in which the virtuals appeared.  This patch fixes this
problem. 

-- 
Mark Mitchell 			mark@markmitchell.com
Mark Mitchell Consulting	http://www.markmitchell.com

Index: testsuite/g++.old-deja/g++.other/virtual4.C
===================================================================
RCS file: virtual4.C
diff -N virtual4.C
*** /dev/null	Sat Dec  5 20:30:03 1998
--- virtual4.C	Fri Feb 26 11:46:41 1999
***************
*** 0 ****
--- 1,25 ----
+ // Build don't link:
+ 
+ class A {
+ public:
+   virtual int foo() = 0; // ERROR - original definition
+ };
+ 
+ class B {
+ public:
+     virtual double foo() = 0;
+ };
+ 
+ class C
+   : public A, public B
+ {
+ public:
+   virtual double foo() { return 2; } // ERROR - conflicting return type
+ };
+ 
+ class D
+   : public B, public A
+ {
+ public:
+   virtual double foo() { return 2; } // ERROR - conflicting return type
+ };
Index: testsuite/cp/class.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/cp/class.c,v
retrieving revision 1.130
diff -c -p -r1.130 class.c
*** class.c	1999/02/21 16:38:13	1.130
--- class.c	1999/02/26 19:46:45
*************** check_for_override (decl, ctype)
*** 2991,2996 ****
--- 2991,2997 ----
    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++)
      {
*************** check_for_override (decl, ctype)
*** 3000,3006 ****
  	  tree tmp = get_matching_virtual
  	    (base_binfo, decl,
  	     DESTRUCTOR_NAME_P (DECL_ASSEMBLER_NAME (decl)));
! 	  if (tmp)
  	    {
  	      /* If this function overrides some virtual in some base
  		 class, then the function itself is also necessarily
--- 3001,3008 ----
  	  tree tmp = get_matching_virtual
  	    (base_binfo, decl,
  	     DESTRUCTOR_NAME_P (DECL_ASSEMBLER_NAME (decl)));
! 
! 	  if (tmp && !found_overriden_fn)
  	    {
  	      /* If this function overrides some virtual in some base
  		 class, then the function itself is also necessarily
*************** check_for_override (decl, ctype)
*** 3021,3046 ****
  		}
  	      virtualp = 1;
  
- #if 0 /* The signature of an overriding function is not changed.  */
- 	      {
- 		/* The argument types may have changed...  */
- 		tree type = TREE_TYPE (decl);
- 		tree argtypes = TYPE_ARG_TYPES (type);
- 		tree base_variant = TREE_TYPE (TREE_VALUE (argtypes));
- 		tree raises = TYPE_RAISES_EXCEPTIONS (type);
- 
- 		argtypes = commonparms (TREE_CHAIN (TYPE_ARG_TYPES (TREE_TYPE (tmp))),
- 					TREE_CHAIN (argtypes));
- 		/* But the return type has not.  */
- 		type = build_cplus_method_type (base_variant, TREE_TYPE (type), argtypes);
- 		if (raises)
- 		  type = build_exception_variant (type, raises);
- 		TREE_TYPE (decl) = type;
- 	      }
- #endif
  	      DECL_VINDEX (decl)
  		= tree_cons (NULL_TREE, tmp, DECL_VINDEX (decl));
! 	      break;
  	    }
  	}
      }
--- 3023,3037 ----
  		}
  	      virtualp = 1;
  
  	      DECL_VINDEX (decl)
  		= tree_cons (NULL_TREE, tmp, 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;
  	    }
  	}
      }
Index: testsuite/cp/search.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/cp/search.c,v
retrieving revision 1.78
diff -c -p -r1.78 search.c
*** search.c	1999/02/21 16:38:20	1.78
--- search.c	1999/02/26 19:47:07
*************** get_matching_virtual (binfo, fndecl, dto
*** 1887,1900 ****
  		      cp_error_at ("  overriding definition as `%#D'", tmp);
  		      SET_IDENTIFIER_ERROR_LOCUS (name, basetype);
  		    }
! 		  break;
  		}
- 	    }
- 	  /* If not at the end */
- 	  if (tmps)
- 	    {
- 	      best = tmp;
- 	      break;
  	    }
  	}
  
--- 1887,1900 ----
  		      cp_error_at ("  overriding definition as `%#D'", tmp);
  		      SET_IDENTIFIER_ERROR_LOCUS (name, basetype);
  		    }
! 
! 		  /* 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;
  		}
  	    }
  	}
  


More information about the Gcc-patches mailing list