This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
C++ PATCH to dfs_find_final_overrider
- To: gcc-patches at gcc dot gnu dot org
- Subject: C++ PATCH to dfs_find_final_overrider
- From: Jason Merrill <jason_merrill at redhat dot com>
- Date: 14 Jun 2001 13:06:28 +0100
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