This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[C++ PATCH] new-abi catch matcher
- To: gcc-patches at gcc dot gnu dot org
- Subject: [C++ PATCH] new-abi catch matcher
- From: Nathan Sidwell <nathan at codesourcery dot com>
- Date: Wed, 24 May 2000 15:20:59 +0100
- Organization: CodeSourcery, LLC
Hi,
I've installed the attached which updates the catch matching algorithm
in line with the updated type_info flags. No change in old abi, but tested
all the same on i686-pc-linux-gnu
Doing this, I uncovered a bug in the old-abi catch matcher, for which a
patch and test case will be forthcoming.
nathan
--
Dr Nathan Sidwell :: http://www.codesourcery.com :: CodeSourcery LLC
'But that's a lie.' - 'Yes it is. What's your point?'
nathan@codesourcery.com : http://www.cs.bris.ac.uk/~nathan/ : nathan@acm.org
2000-05-22 Nathan Sidwell <nathan@codesourcery.com>
Update new-abi upcast algorithm.
* inc/cxxabi.h (__class_type_info::__do_upcast): Change
prototype and meaning of return value.
(__si_class_type_info::__do_upcast): Likewise.
(__vmi_class_type_info::__do_upcast): Likewise.
* tinfo.cc (__class_type_info::__upcast_result): Replace
whole2dst with part2dst. Adjust ctor.
(__class_type_info::__do_upcast): Adjust call of worker function.
(__class_type_info::__do_upcast): Adjust.
(__si_class_type_info::__do_upcast): Adjust. Use parent's
__do_upcast.
(__vmi_class_type_info::__do_upcast): Likewise. Fix private
virtual base in diamond heirarchy bug.
Index: cp/tinfo.cc
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/tinfo.cc,v
retrieving revision 1.30
diff -c -3 -p -r1.30 tinfo.cc
*** tinfo.cc 2000/05/12 16:10:02 1.30
--- tinfo.cc 2000/05/22 09:05:32
*************** __vmi_class_type_info::
*** 662,668 ****
struct __class_type_info::__upcast_result
{
const void *dst_ptr; // pointer to caught object
! __sub_kind whole2dst; // path from most derived object to target
int src_details; // hints about the source type heirarchy
const __class_type_info *base_type; // where we found the target,
// if in vbase the __class_type_info of vbase
--- 662,668 ----
struct __class_type_info::__upcast_result
{
const void *dst_ptr; // pointer to caught object
! __sub_kind part2dst; // path from current base to target
int src_details; // hints about the source type heirarchy
const __class_type_info *base_type; // where we found the target,
// if in vbase the __class_type_info of vbase
*************** struct __class_type_info::__upcast_resul
*** 670,676 ****
// else NULL
public:
__upcast_result (int d)
! :dst_ptr (NULL), whole2dst (__unknown), src_details (d), base_type (NULL)
{}
};
--- 670,676 ----
// else NULL
public:
__upcast_result (int d)
! :dst_ptr (NULL), part2dst (__unknown), src_details (d), base_type (NULL)
{}
};
*************** __do_upcast (const __class_type_info *ds
*** 709,718 ****
{
__upcast_result result (__vmi_class_type_info::__flags_unknown_mask);
! if (__do_upcast (__contained_public, dst_type, *obj_ptr, result))
return false;
*obj_ptr = const_cast <void *> (result.dst_ptr);
! return contained_public_p (result.whole2dst);
}
inline __class_type_info::__sub_kind __class_type_info::
--- 709,719 ----
{
__upcast_result result (__vmi_class_type_info::__flags_unknown_mask);
! __do_upcast (dst_type, *obj_ptr, result);
! if (!contained_public_p (result.part2dst))
return false;
*obj_ptr = const_cast <void *> (result.dst_ptr);
! return true;
}
inline __class_type_info::__sub_kind __class_type_info::
*************** __do_dyncast (ptrdiff_t src2dst,
*** 1025,1071 ****
}
bool __class_type_info::
! __do_upcast (__sub_kind access_path,
! const __class_type_info *dst, const void *obj,
__upcast_result &__restrict result) const
{
if (*this == *dst)
{
result.dst_ptr = obj;
result.base_type = nonvirtual_base_type;
! result.whole2dst = access_path;
! return contained_nonpublic_p (access_path);
}
return false;
}
bool __si_class_type_info::
! __do_upcast (__sub_kind access_path,
! const __class_type_info *dst, const void *obj_ptr,
__upcast_result &__restrict result) const
{
! if (*this == *dst)
! {
! result.dst_ptr = obj_ptr;
! result.base_type = nonvirtual_base_type;
! result.whole2dst = access_path;
! return contained_nonpublic_p (access_path);
! }
! return base->__do_upcast (access_path, dst, obj_ptr, result);
}
bool __vmi_class_type_info::
! __do_upcast (__sub_kind access_path,
! const __class_type_info *dst, const void *obj_ptr,
__upcast_result &__restrict result) const
{
! if (*this == *dst)
! {
! result.dst_ptr = obj_ptr;
! result.base_type = nonvirtual_base_type;
! result.whole2dst = access_path;
! return contained_nonpublic_p (access_path);
! }
int src_details = result.src_details;
if (src_details & __flags_unknown_mask)
--- 1026,1060 ----
}
bool __class_type_info::
! __do_upcast (const __class_type_info *dst, const void *obj,
__upcast_result &__restrict result) const
{
if (*this == *dst)
{
result.dst_ptr = obj;
result.base_type = nonvirtual_base_type;
! result.part2dst = __contained_public;
! return true;
}
return false;
}
bool __si_class_type_info::
! __do_upcast (const __class_type_info *dst, const void *obj_ptr,
__upcast_result &__restrict result) const
{
! if (__class_type_info::__do_upcast (dst, obj_ptr, result))
! return true;
!
! return base->__do_upcast (dst, obj_ptr, result);
}
bool __vmi_class_type_info::
! __do_upcast (const __class_type_info *dst, const void *obj_ptr,
__upcast_result &__restrict result) const
{
! if (__class_type_info::__do_upcast (dst, obj_ptr, result))
! return true;
int src_details = result.src_details;
if (src_details & __flags_unknown_mask)
*************** __do_upcast (__sub_kind access_path,
*** 1075,1121 ****
{
__upcast_result result2 (src_details);
const void *base = obj_ptr;
- __sub_kind sub_access = access_path;
ptrdiff_t offset = vmi_bases[i].__offset ();
bool is_virtual = vmi_bases[i].__is_virtual_p ();
! if (!vmi_bases[i].__is_public_p ())
! {
! if (!(src_details & non_diamond_repeat_mask))
! // original cannot have an ambiguous base
! continue;
! sub_access = __sub_kind (sub_access & ~__contained_public_mask);
! }
! if (is_virtual)
! sub_access = __sub_kind (sub_access | __contained_virtual_mask);
if (base)
base = convert_to_base (base, is_virtual, offset);
! if (vmi_bases[i].base->__do_upcast (sub_access, dst, base, result2))
! return true; // must fail
! if (result2.base_type)
{
if (result2.base_type == nonvirtual_base_type && is_virtual)
result2.base_type = vmi_bases[i].base;
if (!result.base_type)
{
result = result2;
! if (!(vmi_flags & non_diamond_repeat_mask))
! // cannot have an ambiguous other base
! return false;
}
else if (result.dst_ptr != result2.dst_ptr)
{
// Found an ambiguity.
result.dst_ptr = NULL;
! result.whole2dst = __contained_ambig;
return true;
}
else if (result.dst_ptr)
{
// Ok, found real object via a virtual path.
! result.whole2dst
! = __sub_kind (result.whole2dst | result2.whole2dst);
}
else
{
--- 1064,1116 ----
{
__upcast_result result2 (src_details);
const void *base = obj_ptr;
ptrdiff_t offset = vmi_bases[i].__offset ();
bool is_virtual = vmi_bases[i].__is_virtual_p ();
+ bool is_public = vmi_bases[i].__is_public_p ();
! if (!is_public && !(src_details & non_diamond_repeat_mask))
! // original cannot have an ambiguous base, so skip private bases
! continue;
!
if (base)
base = convert_to_base (base, is_virtual, offset);
! if (vmi_bases[i].base->__do_upcast (dst, base, result2))
{
if (result2.base_type == nonvirtual_base_type && is_virtual)
result2.base_type = vmi_bases[i].base;
+ if (contained_p (result2.part2dst) && !is_public)
+ result2.part2dst = __sub_kind (result2.part2dst & ~__contained_public_mask);
+
if (!result.base_type)
{
result = result2;
! if (!contained_p (result.part2dst))
! return true; // found ambiguously
!
! if (result.part2dst & __contained_public_mask)
! {
! if (!(vmi_flags & non_diamond_repeat_mask))
! return true; // cannot have an ambiguous other base
! }
! else
! {
! if (!(vmi_flags & diamond_shaped_mask))
! return true; // cannot have a more accessible base
! }
}
else if (result.dst_ptr != result2.dst_ptr)
{
// Found an ambiguity.
result.dst_ptr = NULL;
! result.part2dst = __contained_ambig;
return true;
}
else if (result.dst_ptr)
{
// Ok, found real object via a virtual path.
! result.part2dst
! = __sub_kind (result.part2dst | result2.part2dst);
}
else
{
*************** __do_upcast (__sub_kind access_path,
*** 1127,1139 ****
{
// Already ambiguous, not virtual or via different virtuals.
// Cannot match.
! result.whole2dst = __contained_ambig;
return true;
}
}
}
}
! return false;
}
// this is the external interface to the dynamic cast machinery
--- 1122,1134 ----
{
// Already ambiguous, not virtual or via different virtuals.
// Cannot match.
! result.part2dst = __contained_ambig;
return true;
}
}
}
}
! return result.part2dst != __unknown;
}
// this is the external interface to the dynamic cast machinery
Index: cp/inc/cxxabi.h
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/inc/cxxabi.h,v
retrieving revision 1.12
diff -c -3 -p -r1.12 cxxabi.h
*** cxxabi.h 2000/05/08 20:52:32 1.12
--- cxxabi.h 2000/05/22 09:05:33
*************** protected:
*** 266,276 ****
public:
! /* Helper for upcast. See if DST is us, or one of our bases. ACCESS_PATH */
! /* gives the access from the start object. Return TRUE if we know the upcast */
! /* fails. */
! virtual bool __do_upcast (__sub_kind __access_path,
! const __class_type_info *__dst,
const void *__obj,
__upcast_result &__restrict __result) const;
--- 266,274 ----
public:
! /* Helper for upcast. See if DST is us, or one of our bases. */
! /* Return false if not found, true if found. */
! virtual bool __do_upcast (const __class_type_info *__dst,
const void *__obj,
__upcast_result &__restrict __result) const;
*************** protected:
*** 341,348 ****
const void *__obj_ptr,
const __class_type_info *__src_type,
const void *__sub_ptr) const;
! virtual bool __do_upcast (__sub_kind __access_path,
! const __class_type_info *__dst,
const void *__obj,
__upcast_result &__restrict __result) const;
};
--- 339,345 ----
const void *__obj_ptr,
const __class_type_info *__src_type,
const void *__sub_ptr) const;
! virtual bool __do_upcast (const __class_type_info *__dst,
const void *__obj,
__upcast_result &__restrict __result) const;
};
*************** protected:
*** 391,398 ****
const void *__obj_ptr,
const __class_type_info *__src_type,
const void *__src_ptr) const;
! virtual bool __do_upcast (__sub_kind __access_path,
! const __class_type_info *__dst,
const void *__obj,
__upcast_result &__restrict __result) const;
};
--- 388,394 ----
const void *__obj_ptr,
const __class_type_info *__src_type,
const void *__src_ptr) const;
! virtual bool __do_upcast (const __class_type_info *__dst,
const void *__obj,
__upcast_result &__restrict __result) const;
};