diff options
author | Nathan Sidwell <nathan@codesourcery.com> | 2000-05-25 11:13:17 +0000 |
---|---|---|
committer | Nathan Sidwell <nathan@gcc.gnu.org> | 2000-05-25 11:13:17 +0000 |
commit | e2e11048ae4f1436fd315193d89f49c25c0a0aea (patch) | |
tree | 099b40138fa1a7ad00c56458d578f6f197c5d395 | |
parent | bf93f43bb4b949e16227425777ed5667f37cdd20 (diff) | |
download | gcc-e2e11048ae4f1436fd315193d89f49c25c0a0aea.zip gcc-e2e11048ae4f1436fd315193d89f49c25c0a0aea.tar.gz gcc-e2e11048ae4f1436fd315193d89f49c25c0a0aea.tar.bz2 |
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
-rw-r--r-- | gcc/cp/ChangeLog | 10 | ||||
-rw-r--r-- | gcc/cp/tinfo.cc | 11 | ||||
-rw-r--r-- | gcc/cp/tinfo.h | 5 |
3 files changed, 24 insertions, 2 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index a9fea21b..11df3c1 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,13 @@ +2000-05-25 Nathan Sidwell <nathan@codesourcery.com> + + * 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 <mark@codesourcery.com> * cp-tree.h (build_delete): Change prototype. diff --git a/gcc/cp/tinfo.cc b/gcc/cp/tinfo.cc index 375249c..58247e3 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 4173ca6..b52f681 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 { |