[PATCH] Fix PR38720, rel-pointer problems

Richard Guenther rguenther@suse.de
Sun Jan 4 17:11:00 GMT 2009


This fixes PR38720 by making rel-pointer use an unsigned integer type
for all of its calculations.

Bootstrapped and tested on x86_64-unknown-linux-gnu, ok for trunk?

Thanks,
Richard.

2009-01-04  Richard Guenther  <rguenther@suse.de>

	PR libstdc++/38720
	* include/ext/pointer.h (_Relative_pointer_impl): Use an unsigned
	integer type for storage, arithmetic and comparisons.

Index: libstdc++-v3/include/ext/pointer.h
===================================================================
*** libstdc++-v3/include/ext/pointer.h	(revision 143048)
--- libstdc++-v3/include/ext/pointer.h	(working copy)
***************
*** 42,47 ****
--- 42,48 ----
  #include <iosfwd>
  #include <bits/stl_iterator_base_types.h>
  #include <ext/cast.h>
+ #include <ext/type_traits.h>
  
  _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx)
  
*************** _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx)
*** 111,119 ****
          if (_M_diff == 1)
            return 0;
          else
!           return reinterpret_cast<_Tp*>(
!                  const_cast<char*>(reinterpret_cast<const char*>(this))
!                  + _M_diff);
        }
    
        void 
--- 112,119 ----
          if (_M_diff == 1)
            return 0;
          else
!           return reinterpret_cast<_Tp*>(reinterpret_cast<_UIntPtrType>(this)
! 					+ _M_diff);
        }
    
        void 
*************** _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx)
*** 122,142 ****
          if (!__arg)
            _M_diff = 1;
          else
!           _M_diff = reinterpret_cast<char*>(__arg) 
!                     - reinterpret_cast<char*>(this);
        }
    
        // Comparison of pointers
        inline bool
        operator<(const _Relative_pointer_impl& __rarg) const
!       { return (this->get() < __rarg.get()); }
  
        inline bool
        operator==(const _Relative_pointer_impl& __rarg) const
!       { return (this->get() == __rarg.get()); }
  
      private:
!       std::ptrdiff_t _M_diff;
      };
    
    /**
--- 122,147 ----
          if (!__arg)
            _M_diff = 1;
          else
!           _M_diff = reinterpret_cast<_UIntPtrType>(__arg) 
!                     - reinterpret_cast<_UIntPtrType>(this);
        }
    
        // Comparison of pointers
        inline bool
        operator<(const _Relative_pointer_impl& __rarg) const
!       { return (reinterpret_cast<_UIntPtrType>(this->get())
! 		< reinterpret_cast<_UIntPtrType>(__rarg.get())); }
  
        inline bool
        operator==(const _Relative_pointer_impl& __rarg) const
!       { return (reinterpret_cast<_UIntPtrType>(this->get())
! 		== reinterpret_cast<_UIntPtrType>(__rarg.get())); }
  
      private:
!       typedef __gnu_cxx::__conditional_type<
! 	 (sizeof(unsigned long) >= sizeof(void*)),
! 	 unsigned long, unsigned long long>::__type _UIntPtrType;
!       _UIntPtrType _M_diff;
      };
    
    /**
*************** _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx)
*** 155,162 ****
          if (_M_diff == 1)
            return 0;
          else
!           return reinterpret_cast<const _Tp*>(
!                   (reinterpret_cast<const char*>(this)) + _M_diff);
        }
    
        void 
--- 160,167 ----
          if (_M_diff == 1)
            return 0;
          else
!           return reinterpret_cast<const _Tp*>
! 	      (reinterpret_cast<_UIntPtrType>(this) + _M_diff);
        }
    
        void 
*************** _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx)
*** 165,185 ****
          if (!__arg)
            _M_diff = 1;
          else
!           _M_diff = reinterpret_cast<const char*>(__arg) 
!                     - reinterpret_cast<const char*>(this);
        }
    
        // Comparison of pointers
        inline bool
        operator<(const _Relative_pointer_impl& __rarg) const
!       { return (this->get() < __rarg.get()); }
  
        inline bool
        operator==(const _Relative_pointer_impl& __rarg) const
!       { return (this->get() == __rarg.get()); }
    
      private:
!       std::ptrdiff_t _M_diff;
      };
  
    /**
--- 170,195 ----
          if (!__arg)
            _M_diff = 1;
          else
!           _M_diff = reinterpret_cast<_UIntPtrType>(__arg) 
!                     - reinterpret_cast<_UIntPtrType>(this);
        }
    
        // Comparison of pointers
        inline bool
        operator<(const _Relative_pointer_impl& __rarg) const
!       { return (reinterpret_cast<_UIntPtrType>(this->get())
! 		< reinterpret_cast<_UIntPtrType>(__rarg.get())); }
  
        inline bool
        operator==(const _Relative_pointer_impl& __rarg) const
!       { return (reinterpret_cast<_UIntPtrType>(this->get())
! 		== reinterpret_cast<_UIntPtrType>(__rarg.get())); }
    
      private:
!       typedef __gnu_cxx::__conditional_type
! 	<(sizeof(unsigned long) >= sizeof(void*)),
! 	 unsigned long, unsigned long long>::__type _UIntPtrType;
!       _UIntPtrType _M_diff;
      };
  
    /**



More information about the Libstdc++ mailing list