Commit 9c01326d by Richard Guenther Committed by Richard Biener

re PR libstdc++/38720 (_Relative_pointer_impl invokes undefined behavior)

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.
	* testsuite/ext/ext_pointer/1_neg.cc: Adjust line numbers.

From-SVN: r143058
parent 70e72065
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.
* testsuite/ext/ext_pointer/1_neg.cc: Adjust line numbers.
2009-01-04 Paolo Carlini <paolo.carlini@oracle.com> 2009-01-04 Paolo Carlini <paolo.carlini@oracle.com>
PR libstdc++/38719 PR libstdc++/38719
......
...@@ -42,6 +42,7 @@ ...@@ -42,6 +42,7 @@
#include <iosfwd> #include <iosfwd>
#include <bits/stl_iterator_base_types.h> #include <bits/stl_iterator_base_types.h>
#include <ext/cast.h> #include <ext/cast.h>
#include <ext/type_traits.h>
_GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx) _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx)
...@@ -111,9 +112,8 @@ _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx) ...@@ -111,9 +112,8 @@ _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx)
if (_M_diff == 1) if (_M_diff == 1)
return 0; return 0;
else else
return reinterpret_cast<_Tp*>( return reinterpret_cast<_Tp*>(reinterpret_cast<_UIntPtrType>(this)
const_cast<char*>(reinterpret_cast<const char*>(this)) + _M_diff);
+ _M_diff);
} }
void void
...@@ -122,21 +122,26 @@ _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx) ...@@ -122,21 +122,26 @@ _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx)
if (!__arg) if (!__arg)
_M_diff = 1; _M_diff = 1;
else else
_M_diff = reinterpret_cast<char*>(__arg) _M_diff = reinterpret_cast<_UIntPtrType>(__arg)
- reinterpret_cast<char*>(this); - reinterpret_cast<_UIntPtrType>(this);
} }
// Comparison of pointers // Comparison of pointers
inline bool inline bool
operator<(const _Relative_pointer_impl& __rarg) const 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 inline bool
operator==(const _Relative_pointer_impl& __rarg) const operator==(const _Relative_pointer_impl& __rarg) const
{ return (this->get() == __rarg.get()); } { return (reinterpret_cast<_UIntPtrType>(this->get())
== reinterpret_cast<_UIntPtrType>(__rarg.get())); }
private: 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) ...@@ -155,8 +160,8 @@ _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx)
if (_M_diff == 1) if (_M_diff == 1)
return 0; return 0;
else else
return reinterpret_cast<const _Tp*>( return reinterpret_cast<const _Tp*>
(reinterpret_cast<const char*>(this)) + _M_diff); (reinterpret_cast<_UIntPtrType>(this) + _M_diff);
} }
void void
...@@ -165,21 +170,26 @@ _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx) ...@@ -165,21 +170,26 @@ _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx)
if (!__arg) if (!__arg)
_M_diff = 1; _M_diff = 1;
else else
_M_diff = reinterpret_cast<const char*>(__arg) _M_diff = reinterpret_cast<_UIntPtrType>(__arg)
- reinterpret_cast<const char*>(this); - reinterpret_cast<_UIntPtrType>(this);
} }
// Comparison of pointers // Comparison of pointers
inline bool inline bool
operator<(const _Relative_pointer_impl& __rarg) const 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 inline bool
operator==(const _Relative_pointer_impl& __rarg) const operator==(const _Relative_pointer_impl& __rarg) const
{ return (this->get() == __rarg.get()); } { return (reinterpret_cast<_UIntPtrType>(this->get())
== reinterpret_cast<_UIntPtrType>(__rarg.get())); }
private: 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;
}; };
/** /**
......
...@@ -100,13 +100,13 @@ void test01(void) { ...@@ -100,13 +100,13 @@ void test01(void) {
aptr5 = __const_pointer_cast<B_pointer>(cbptr); // ok aptr5 = __const_pointer_cast<B_pointer>(cbptr); // ok
} }
// { dg-error "invalid conversion " "" { target *-*-* } 289 } // { dg-error "invalid conversion " "" { target *-*-* } 299 }
// { dg-error "initializing argument 1 of" "" { target *-*-* } 289 } // { dg-error "initializing argument 1 of" "" { target *-*-* } 299 }
// { dg-error "invalid conversion " "" { target *-*-* } 295 } // { dg-error "invalid conversion " "" { target *-*-* } 305 }
// { dg-error "initializing argument 1 of" "" { target *-*-* } 295 } // { dg-error "initializing argument 1 of" "" { target *-*-* } 305 }
// { dg-error "invalid conversion " "" { target *-*-* } 312 } // { dg-error "invalid conversion " "" { target *-*-* } 322 }
// { dg-error "initializing argument 1 of" "" { target *-*-* } 312 } // { dg-error "initializing argument 1 of" "" { target *-*-* } 322 }
// { dg-error "invalid conversion " "" { target *-*-* } 320 } // { dg-error "invalid conversion " "" { target *-*-* } 330 }
// { dg-error "initializing argument 1 of" "" { target *-*-* } 320 } // { dg-error "initializing argument 1 of" "" { target *-*-* } 330 }
// { dg-excess-errors "In constructor" } // { dg-excess-errors "In constructor" }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment