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 to dfs_find_final_overrider


The old logic failed to handle the case where there was a previous
best overrider ambiguous with a new one; basically, it would never catch
ambiguities.  Fixed; test below.

This is a regression from 2.95.

Tested i686-pc-linux-gnu, applied to trunk.  Again, I think this will go
onto the branch after the 3.0 release has gone out.

2001-06-14  Jason Merrill  <jason_merrill@redhat.com>

	* class.c (dfs_find_final_overrider): Fix logic.

*** class.c.~1~	Wed Jun 13 21:01:18 2001
--- class.c	Thu Jun 14 12:54:20 2001
*************** dfs_find_final_overrider (binfo, data)
*** 2582,2613 ****
  	      ffod->overriding_fn = method;
  	      ffod->overriding_base = TREE_VALUE (path);
  	    }
! 	  /* If we found the same overrider we already have, then
! 	     we just need to check that we're finding it in the same
! 	     place.  */
! 	  else if (ffod->overriding_fn == method)
  	    {
! 	      if (ffod->overriding_base
! 		  && (!tree_int_cst_equal 
  		      (BINFO_OFFSET (TREE_VALUE (path)),
  		       BINFO_OFFSET (ffod->overriding_base))))
  		{
  		  ffod->candidates 
  		    = build_tree_list (NULL_TREE,
  				       ffod->overriding_fn);
  		  ffod->overriding_fn = NULL_TREE;
  		  ffod->overriding_base = NULL_TREE;
  		}
  	    }
- 	  /* If there was already an overrider, and it overrides this
- 	     function, then the old overrider is still the best
- 	     candidate.  */
- 	  else if (ffod->overriding_fn
- 		   && strictly_overrides (ffod->overriding_fn,
- 					  method))
- 	    ;
  	  else
  	    {
  	      tree candidates;
  	      bool incomparable = false;
  
--- 2582,2625 ----
  	      ffod->overriding_fn = method;
  	      ffod->overriding_base = TREE_VALUE (path);
  	    }
! 	  else if (ffod->overriding_fn)
  	    {
! 	      /* We had a best overrider; let's see how this compares.  */
! 
! 	      if (ffod->overriding_fn == method
! 		  && (tree_int_cst_equal 
  		      (BINFO_OFFSET (TREE_VALUE (path)),
  		       BINFO_OFFSET (ffod->overriding_base))))
+ 		/* We found the same overrider we already have, and in the
+ 		   same place; it's still the best.  */;
+ 	      else if (strictly_overrides (ffod->overriding_fn, method))
+ 		/* The old function overrides this function; it's still the
+ 		   best.  */;
+ 	      else if (strictly_overrides (method, ffod->overriding_fn))
+ 		{
+ 		  /* The new function overrides the old; it's now the
+ 		     best.  */
+ 		  ffod->overriding_fn = method;
+ 		  ffod->overriding_base = TREE_VALUE (path);
+ 		}
+ 	      else
  		{
+ 		  /* Ambiguous.  */
  		  ffod->candidates 
  		    = build_tree_list (NULL_TREE,
  				       ffod->overriding_fn);
+ 		  if (method != ffod->overriding_fn)
+ 		    ffod->candidates 
+ 		      = tree_cons (NULL_TREE, method, ffod->candidates);
  		  ffod->overriding_fn = NULL_TREE;
  		  ffod->overriding_base = NULL_TREE;
  		}
  	    }
  	  else
  	    {
+ 	      /* We had a list of ambiguous overrides; let's see how this
+ 		 new one compares.  */
+ 
  	      tree candidates;
  	      bool incomparable = false;
  
Index: override2.C
===================================================================
RCS file: override2.C
diff -N override2.C
*** /dev/null	Tue May  5 13:32:27 1998
--- override2.C	Thu Jun 14 05:04:40 2001
***************
*** 0 ****
--- 1,9 ----
+ // Copyright (C) 2001 Free Software Foundation, Inc.
+ // Contributed by Jason Merrill 14 Jun 2001 <jason@redhat.com>
+ 
+ // Test for diagnosis of missing final overrider.
+ 
+ struct A { virtual void f (); };
+ struct B1: virtual A { virtual void f (); };
+ struct B2: virtual A { virtual void f (); };
+ struct C: public B1, public B2 {}; // ERROR - no final overrider

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