class.c (dfs_find_final_overrider): Fix logic.
* class.c (dfs_find_final_overrider): Fix logic. * class.c (update_vtable_entry_for_fn): Uncomment optimization to use virtual thunk instead of non-virtual. (get_matching_virtual): Uncomment. * pt.c (unify): Don't recurse between the POINTER_TYPE and the OFFSET_TYPE. If we're adding cv-quals, the extra ones would be on PARM, not ARG. From-SVN: r43372
This commit is contained in:
parent
630d3d5a68
commit
3ea099f179
|
@ -1,3 +1,15 @@
|
||||||
|
2001-06-14 Jason Merrill <jason_merrill@redhat.com>
|
||||||
|
|
||||||
|
* class.c (dfs_find_final_overrider): Fix logic.
|
||||||
|
|
||||||
|
* class.c (update_vtable_entry_for_fn): Uncomment optimization to use
|
||||||
|
virtual thunk instead of non-virtual.
|
||||||
|
(get_matching_virtual): Uncomment.
|
||||||
|
|
||||||
|
* pt.c (unify): Don't recurse between the POINTER_TYPE and the
|
||||||
|
OFFSET_TYPE. If we're adding cv-quals, the extra ones would be on
|
||||||
|
PARM, not ARG.
|
||||||
|
|
||||||
2001-06-14 Nathan Sidwell <nathan@codesourcery.com>
|
2001-06-14 Nathan Sidwell <nathan@codesourcery.com>
|
||||||
|
|
||||||
* class.c (dfs_accumulate_vtbl_inits): For case 2 & 3, make sure
|
* class.c (dfs_accumulate_vtbl_inits): For case 2 & 3, make sure
|
||||||
|
|
|
@ -2567,32 +2567,44 @@ dfs_find_final_overrider (binfo, data)
|
||||||
ffod->overriding_fn = method;
|
ffod->overriding_fn = method;
|
||||||
ffod->overriding_base = TREE_VALUE (path);
|
ffod->overriding_base = TREE_VALUE (path);
|
||||||
}
|
}
|
||||||
/* If we found the same overrider we already have, then
|
else if (ffod->overriding_fn)
|
||||||
we just need to check that we're finding it in the same
|
|
||||||
place. */
|
|
||||||
else if (ffod->overriding_fn == method)
|
|
||||||
{
|
{
|
||||||
if (ffod->overriding_base
|
/* We had a best overrider; let's see how this compares. */
|
||||||
&& (!tree_int_cst_equal
|
|
||||||
|
if (ffod->overriding_fn == method
|
||||||
|
&& (tree_int_cst_equal
|
||||||
(BINFO_OFFSET (TREE_VALUE (path)),
|
(BINFO_OFFSET (TREE_VALUE (path)),
|
||||||
BINFO_OFFSET (ffod->overriding_base))))
|
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
|
ffod->candidates
|
||||||
= build_tree_list (NULL_TREE,
|
= build_tree_list (NULL_TREE,
|
||||||
ffod->overriding_fn);
|
ffod->overriding_fn);
|
||||||
|
if (method != ffod->overriding_fn)
|
||||||
|
ffod->candidates
|
||||||
|
= tree_cons (NULL_TREE, method, ffod->candidates);
|
||||||
ffod->overriding_fn = NULL_TREE;
|
ffod->overriding_fn = NULL_TREE;
|
||||||
ffod->overriding_base = 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
|
else
|
||||||
{
|
{
|
||||||
|
/* We had a list of ambiguous overrides; let's see how this
|
||||||
|
new one compares. */
|
||||||
|
|
||||||
tree candidates;
|
tree candidates;
|
||||||
bool incomparable = false;
|
bool incomparable = false;
|
||||||
|
|
||||||
|
@ -2692,7 +2704,6 @@ find_final_overrider (t, binfo, fn)
|
||||||
return build_tree_list (ffod.overriding_fn, ffod.overriding_base);
|
return build_tree_list (ffod.overriding_fn, ffod.overriding_base);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
|
||||||
/* Returns the function from the BINFO_VIRTUALS entry in T which matches
|
/* Returns the function from the BINFO_VIRTUALS entry in T which matches
|
||||||
the signature of FUNCTION_DECL FN, or NULL_TREE if none. In other words,
|
the signature of FUNCTION_DECL FN, or NULL_TREE if none. In other words,
|
||||||
the function that the slot in T's primary vtable points to. */
|
the function that the slot in T's primary vtable points to. */
|
||||||
|
@ -2709,7 +2720,6 @@ get_matching_virtual (t, fn)
|
||||||
return BV_FN (f);
|
return BV_FN (f);
|
||||||
return NULL_TREE;
|
return NULL_TREE;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Update an entry in the vtable for BINFO, which is in the hierarchy
|
/* Update an entry in the vtable for BINFO, which is in the hierarchy
|
||||||
dominated by T. FN has been overriden in BINFO; VIRTUALS points to the
|
dominated by T. FN has been overriden in BINFO; VIRTUALS points to the
|
||||||
|
@ -2784,10 +2794,6 @@ update_vtable_entry_for_fn (t, binfo, fn, virtuals)
|
||||||
delta = size_diffop (BINFO_OFFSET (TREE_VALUE (overrider)),
|
delta = size_diffop (BINFO_OFFSET (TREE_VALUE (overrider)),
|
||||||
BINFO_OFFSET (binfo));
|
BINFO_OFFSET (binfo));
|
||||||
|
|
||||||
#if 0
|
|
||||||
/* Disable this optimization pending an ABI change, or until
|
|
||||||
we can force emission of the non-virtual thunk even if we don't
|
|
||||||
use it. */
|
|
||||||
if (! integer_zerop (delta))
|
if (! integer_zerop (delta))
|
||||||
{
|
{
|
||||||
/* We'll need a thunk. But if we have a (perhaps formerly)
|
/* We'll need a thunk. But if we have a (perhaps formerly)
|
||||||
|
@ -2810,7 +2816,6 @@ update_vtable_entry_for_fn (t, binfo, fn, virtuals)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
modify_vtable_entry (t,
|
modify_vtable_entry (t,
|
||||||
|
|
15
gcc/cp/pt.c
15
gcc/cp/pt.c
|
@ -8504,7 +8504,7 @@ unify (tparms, targs, parm, arg, strict)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
if (!(strict & UNIFY_ALLOW_OUTER_LEVEL)
|
if (!(strict & UNIFY_ALLOW_OUTER_LEVEL)
|
||||||
&& TYPE_P (arg) && !CP_TYPE_CONST_P (arg))
|
&& TYPE_P (parm) && !CP_TYPE_CONST_P (parm))
|
||||||
strict &= ~UNIFY_ALLOW_MORE_CV_QUAL;
|
strict &= ~UNIFY_ALLOW_MORE_CV_QUAL;
|
||||||
strict &= ~UNIFY_ALLOW_OUTER_LEVEL;
|
strict &= ~UNIFY_ALLOW_OUTER_LEVEL;
|
||||||
strict &= ~UNIFY_ALLOW_DERIVED;
|
strict &= ~UNIFY_ALLOW_DERIVED;
|
||||||
|
@ -8712,6 +8712,18 @@ unify (tparms, targs, parm, arg, strict)
|
||||||
level of pointers. */
|
level of pointers. */
|
||||||
strict |= (strict_in & UNIFY_ALLOW_DERIVED);
|
strict |= (strict_in & UNIFY_ALLOW_DERIVED);
|
||||||
|
|
||||||
|
if (TREE_CODE (TREE_TYPE (parm)) == OFFSET_TYPE
|
||||||
|
&& TREE_CODE (TREE_TYPE (arg)) == OFFSET_TYPE)
|
||||||
|
{
|
||||||
|
/* Avoid getting confused about cv-quals; don't recurse here.
|
||||||
|
Pointers to members should really be just OFFSET_TYPE, not
|
||||||
|
this two-level nonsense... */
|
||||||
|
|
||||||
|
parm = TREE_TYPE (parm);
|
||||||
|
arg = TREE_TYPE (arg);
|
||||||
|
goto offset;
|
||||||
|
}
|
||||||
|
|
||||||
return unify (tparms, targs, TREE_TYPE (parm),
|
return unify (tparms, targs, TREE_TYPE (parm),
|
||||||
TREE_TYPE (arg), strict);
|
TREE_TYPE (arg), strict);
|
||||||
}
|
}
|
||||||
|
@ -8864,6 +8876,7 @@ unify (tparms, targs, parm, arg, strict)
|
||||||
DEDUCE_EXACT, 0, -1);
|
DEDUCE_EXACT, 0, -1);
|
||||||
|
|
||||||
case OFFSET_TYPE:
|
case OFFSET_TYPE:
|
||||||
|
offset:
|
||||||
if (TREE_CODE (arg) != OFFSET_TYPE)
|
if (TREE_CODE (arg) != OFFSET_TYPE)
|
||||||
return 1;
|
return 1;
|
||||||
if (unify (tparms, targs, TYPE_OFFSET_BASETYPE (parm),
|
if (unify (tparms, targs, TYPE_OFFSET_BASETYPE (parm),
|
||||||
|
|
|
@ -0,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
|
|
@ -0,0 +1,14 @@
|
||||||
|
// Copyright (C) 2001 Free Software Foundation, Inc.
|
||||||
|
// Contributed by Jason Merrill 14 Jun 2001 <jason@redhat.com>
|
||||||
|
|
||||||
|
// Test that deduction can add cv-quals to a pointer-to-member type.
|
||||||
|
|
||||||
|
struct A;
|
||||||
|
int A::* pi;
|
||||||
|
|
||||||
|
template <typename T> void f (const T A::*) {}
|
||||||
|
|
||||||
|
int main ()
|
||||||
|
{
|
||||||
|
f (pi);
|
||||||
|
}
|
|
@ -9,10 +9,12 @@
|
||||||
|
|
||||||
|
|
||||||
template <typename T> void Foo (T const **);
|
template <typename T> void Foo (T const **);
|
||||||
|
template <typename T> void Bar (T const * const *);
|
||||||
void Foo (int); // ERROR - candidate
|
void Foo (int); // ERROR - candidate
|
||||||
void Foo (float); // ERROR - candidate
|
void Foo (float); // ERROR - candidate
|
||||||
|
|
||||||
void baz (int **p1)
|
void baz (int **p1)
|
||||||
{
|
{
|
||||||
Foo (p1); // ERROR - no such function
|
Foo (p1); // ERROR - no such function
|
||||||
|
Bar (p1); // OK
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue