diff options
author | Jason Merrill <jason@redhat.com> | 2020-06-03 23:50:06 -0400 |
---|---|---|
committer | Jason Merrill <jason@redhat.com> | 2020-06-04 15:11:42 -0400 |
commit | 0ddb93ce77374004c49cdfbd748ba35867620cf1 (patch) | |
tree | e72f9c9d166a469f442772331639a2fbf04ee818 /gcc/cp/class.c | |
parent | 8c727bdf4acf28c8315b119a1c8f6d6af745c2af (diff) | |
download | gcc-0ddb93ce77374004c49cdfbd748ba35867620cf1.zip gcc-0ddb93ce77374004c49cdfbd748ba35867620cf1.tar.gz gcc-0ddb93ce77374004c49cdfbd748ba35867620cf1.tar.bz2 |
c++: Fix FE devirt with diamond inheritance [PR95158]
This started breaking in GCC 8 because of the fix for PR15272; after that
change, we (correctly) remember the lookup from template parsing time that
found Base::foo through the non-dependent MiddleB base, and so we overlook
the overrider in MiddleA. But given that, the devirtualization condition
from the fix for PR59031 is insufficient; we know that d has to be a
Derived, and we found Base::foo in Base, but forcing a non-virtual call
gets the wrong function.
Fixed by removing the PR59031 code that the PR67184 patch moved to
build_over_call, and instead looking up the overrider in BINFO_VIRTUALS.
gcc/cp/ChangeLog:
PR c++/95158
* class.c (lookup_vfn_in_binfo): New.
* call.c (build_over_call): Use it.
* cp-tree.h (resolves_to_fixed_type_p): Add default argument.
(lookup_vfn_in_binfo): Declare.
gcc/testsuite/ChangeLog:
PR c++/95158
* g++.dg/template/virtual5.C: New test.
Diffstat (limited to 'gcc/cp/class.c')
-rw-r--r-- | gcc/cp/class.c | 14 |
1 files changed, 14 insertions, 0 deletions
diff --git a/gcc/cp/class.c b/gcc/cp/class.c index 757e010..f8e38ec 100644 --- a/gcc/cp/class.c +++ b/gcc/cp/class.c @@ -2445,6 +2445,20 @@ get_vcall_index (tree fn, tree type) gcc_unreachable (); } +/* Given a DECL_VINDEX of a virtual function found in BINFO, return the final + overrider at that index in the vtable. This should only be used when we + know that BINFO is correct for the dynamic type of the object. */ + +tree +lookup_vfn_in_binfo (tree idx, tree binfo) +{ + int ix = tree_to_shwi (idx); + if (TARGET_VTABLE_USES_DESCRIPTORS) + ix /= MAX (TARGET_VTABLE_USES_DESCRIPTORS, 1); + tree virtuals = BINFO_VIRTUALS (binfo); + return TREE_VALUE (chain_index (ix, virtuals)); +} + /* Update an entry in the vtable for BINFO, which is in the hierarchy dominated by T. FN is the old function; VIRTUALS points to the corresponding position in the new BINFO_VIRTUALS list. IX is the index |