From e2e11048ae4f1436fd315193d89f49c25c0a0aea Mon Sep 17 00:00:00 2001 From: Nathan Sidwell Date: Thu, 25 May 2000 11:13:17 +0000 Subject: [PATCH] tinfo.h (__user_type_info::contained_virtual_p): New predicate. * tinfo.h (__user_type_info::contained_virtual_p): New predicate. * tinfo.cc (__user_type_info::do_upcast): Fix bug with diamond shaped heirarchy. (__vmi_class_type_info::__do_upcast): Fix bug with NULL pointer to diamond shaped heirarchy. Add early out for mixed diamond and duplicate shaped heirarchy. From-SVN: r34163 --- gcc/cp/ChangeLog | 10 ++++++++++ gcc/cp/tinfo.cc | 11 +++++++++-- gcc/cp/tinfo.h | 5 +++++ 3 files changed, 24 insertions(+), 2 deletions(-) diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index a9fea21b4b3..11df3c13d85 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,13 @@ +2000-05-25 Nathan Sidwell + + * tinfo.h (__user_type_info::contained_virtual_p): New + predicate. + * tinfo.cc (__user_type_info::do_upcast): Fix bug with diamond + shaped heirarchy. + (__vmi_class_type_info::__do_upcast): Fix bug with NULL pointer to + diamond shaped heirarchy. Add early out for mixed diamond and + duplicate shaped heirarchy. + 2000-05-24 Mark Mitchell * cp-tree.h (build_delete): Change prototype. diff --git a/gcc/cp/tinfo.cc b/gcc/cp/tinfo.cc index 375249c29a1..58247e398fe 100644 --- a/gcc/cp/tinfo.cc +++ b/gcc/cp/tinfo.cc @@ -286,7 +286,8 @@ do_upcast (sub_kind access_path, sub_access = sub_kind (sub_access | contained_virtual_mask); if (base_list[i].access != PUBLIC) sub_access = sub_kind (sub_access & ~contained_public_mask); - if (base_list[i].base->do_upcast (sub_access, target, p, result2)) + if (base_list[i].base->do_upcast (sub_access, target, p, result2) + && !contained_virtual_p (result2.whole2target)) return true; // must fail if (result2.base_type) { @@ -321,6 +322,8 @@ do_upcast (sub_kind access_path, result.whole2target = contained_ambig; return true; } + result.whole2target + = sub_kind (result.whole2target | result2.whole2target); } } } @@ -1095,8 +1098,10 @@ __do_upcast (const __class_type_info *dst, const void *obj_ptr, } else { + if (!virtual_p (result.part2dst)) + return true; // cannot have another path if (!(vmi_flags & diamond_shaped_mask)) - return true; // cannot have a more accessible base + return true; // cannot have a more accessible path } } else if (result.dst_ptr != result2.dst_ptr) @@ -1125,6 +1130,8 @@ __do_upcast (const __class_type_info *dst, const void *obj_ptr, result.part2dst = __contained_ambig; return true; } + result.part2dst + = __sub_kind (result.part2dst | result2.part2dst); } } } diff --git a/gcc/cp/tinfo.h b/gcc/cp/tinfo.h index 4173ca6eec0..b52f681a3a8 100644 --- a/gcc/cp/tinfo.h +++ b/gcc/cp/tinfo.h @@ -79,6 +79,11 @@ struct __user_type_info : public std::type_info { return (access_path & (contained_mask | contained_virtual_mask)) == contained_mask; } + static inline bool contained_virtual_p (sub_kind access_path) + { + return (access_path & (contained_mask | contained_virtual_mask)) + == (contained_mask | contained_virtual_mask); + } struct upcast_result {