From 9c01326d9a6d56c381ef139a2c25953f483feec8 Mon Sep 17 00:00:00 2001 From: Richard Guenther Date: Sun, 4 Jan 2009 19:51:18 +0000 Subject: re PR libstdc++/38720 (_Relative_pointer_impl invokes undefined behavior) 2009-01-04 Richard Guenther PR libstdc++/38720 * include/ext/pointer.h (_Relative_pointer_impl): Use an unsigned integer type for storage, arithmetic and comparisons. * testsuite/ext/ext_pointer/1_neg.cc: Adjust line numbers. From-SVN: r143058 --- libstdc++-v3/include/ext/pointer.h | 40 ++++++++++++++++++++++++-------------- 1 file changed, 25 insertions(+), 15 deletions(-) (limited to 'libstdc++-v3/include/ext/pointer.h') diff --git a/libstdc++-v3/include/ext/pointer.h b/libstdc++-v3/include/ext/pointer.h index 5c764cf..ff409b6 100644 --- a/libstdc++-v3/include/ext/pointer.h +++ b/libstdc++-v3/include/ext/pointer.h @@ -42,6 +42,7 @@ #include #include #include +#include _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx) @@ -111,9 +112,8 @@ _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx) if (_M_diff == 1) return 0; else - return reinterpret_cast<_Tp*>( - const_cast(reinterpret_cast(this)) - + _M_diff); + return reinterpret_cast<_Tp*>(reinterpret_cast<_UIntPtrType>(this) + + _M_diff); } void @@ -122,21 +122,26 @@ _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx) if (!__arg) _M_diff = 1; else - _M_diff = reinterpret_cast(__arg) - - reinterpret_cast(this); + _M_diff = reinterpret_cast<_UIntPtrType>(__arg) + - reinterpret_cast<_UIntPtrType>(this); } // Comparison of pointers inline bool operator<(const _Relative_pointer_impl& __rarg) const - { return (this->get() < __rarg.get()); } + { return (reinterpret_cast<_UIntPtrType>(this->get()) + < reinterpret_cast<_UIntPtrType>(__rarg.get())); } inline bool operator==(const _Relative_pointer_impl& __rarg) const - { return (this->get() == __rarg.get()); } + { return (reinterpret_cast<_UIntPtrType>(this->get()) + == reinterpret_cast<_UIntPtrType>(__rarg.get())); } private: - std::ptrdiff_t _M_diff; + typedef __gnu_cxx::__conditional_type< + (sizeof(unsigned long) >= sizeof(void*)), + unsigned long, unsigned long long>::__type _UIntPtrType; + _UIntPtrType _M_diff; }; /** @@ -155,8 +160,8 @@ _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx) if (_M_diff == 1) return 0; else - return reinterpret_cast( - (reinterpret_cast(this)) + _M_diff); + return reinterpret_cast + (reinterpret_cast<_UIntPtrType>(this) + _M_diff); } void @@ -165,21 +170,26 @@ _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx) if (!__arg) _M_diff = 1; else - _M_diff = reinterpret_cast(__arg) - - reinterpret_cast(this); + _M_diff = reinterpret_cast<_UIntPtrType>(__arg) + - reinterpret_cast<_UIntPtrType>(this); } // Comparison of pointers inline bool operator<(const _Relative_pointer_impl& __rarg) const - { return (this->get() < __rarg.get()); } + { return (reinterpret_cast<_UIntPtrType>(this->get()) + < reinterpret_cast<_UIntPtrType>(__rarg.get())); } inline bool operator==(const _Relative_pointer_impl& __rarg) const - { return (this->get() == __rarg.get()); } + { return (reinterpret_cast<_UIntPtrType>(this->get()) + == reinterpret_cast<_UIntPtrType>(__rarg.get())); } private: - std::ptrdiff_t _M_diff; + typedef __gnu_cxx::__conditional_type + <(sizeof(unsigned long) >= sizeof(void*)), + unsigned long, unsigned long long>::__type _UIntPtrType; + _UIntPtrType _M_diff; }; /** -- cgit v1.1