This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

[C++ PATCH] new-abi catch matcher


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;
  };

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]