Throw std::bad_alloc even when exceptions are disabled, by doing new int[size_t(-1)].

Don't throw exceptions on aligned_malloc(0) (just because malloc's retval is null doesn't mean error, if size==0).
Remove EIGEN_NO_EXCEPTIONS option, use only compiler standard defines. Either exceptions are enabled or they aren't.
This commit is contained in:
Benoit Jacob 2011-10-17 08:44:44 -04:00
parent dcbc985a28
commit 16b638c159
3 changed files with 32 additions and 35 deletions

View File

@ -167,7 +167,7 @@
#include <intrin.h> #include <intrin.h>
#endif #endif
#if (defined(_CPPUNWIND) || defined(__EXCEPTIONS)) && !defined(EIGEN_NO_EXCEPTIONS) #if defined(_CPPUNWIND) || defined(__EXCEPTIONS)
#define EIGEN_EXCEPTIONS #define EIGEN_EXCEPTIONS
#endif #endif

View File

@ -37,7 +37,6 @@ namespace internal {
template<typename Index> template<typename Index>
void check_rows_cols_for_overflow(Index rows, Index cols) void check_rows_cols_for_overflow(Index rows, Index cols)
{ {
#ifdef EIGEN_EXCEPTIONS
// http://hg.mozilla.org/mozilla-central/file/6c8a909977d3/xpcom/ds/CheckedInt.h#l242 // http://hg.mozilla.org/mozilla-central/file/6c8a909977d3/xpcom/ds/CheckedInt.h#l242
// we assume Index is signed // we assume Index is signed
Index max_index = (size_t(1) << (8 * sizeof(Index) - 1)) - 1; // assume Index is signed Index max_index = (size_t(1) << (8 * sizeof(Index) - 1)) - 1; // assume Index is signed
@ -45,11 +44,7 @@ void check_rows_cols_for_overflow(Index rows, Index cols)
: (rows == 0 || cols == 0) ? false : (rows == 0 || cols == 0) ? false
: (rows > max_index / cols); : (rows > max_index / cols);
if (error) if (error)
throw std::bad_alloc(); throw_std_bad_alloc();
#else
(void) rows;
(void) cols;
#endif
} }
template <typename Derived, typename OtherDerived = Derived, bool IsVector = static_cast<bool>(Derived::IsVectorAtCompileTime)> struct conservative_resize_like_impl; template <typename Derived, typename OtherDerived = Derived, bool IsVector = static_cast<bool>(Derived::IsVectorAtCompileTime)> struct conservative_resize_like_impl;

View File

@ -82,6 +82,15 @@
namespace internal { namespace internal {
void throw_std_bad_alloc()
{
#ifdef EIGEN_EXCEPTIONS
throw std::bad_alloc();
#else
new int[size_t(-1)];
#endif
}
/***************************************************************************** /*****************************************************************************
*** Implementation of handmade aligned functions *** *** Implementation of handmade aligned functions ***
*****************************************************************************/ *****************************************************************************/
@ -192,7 +201,7 @@ inline void check_that_malloc_is_allowed()
#endif #endif
/** \internal Allocates \a size bytes. The returned pointer is guaranteed to have 16 bytes alignment. /** \internal Allocates \a size bytes. The returned pointer is guaranteed to have 16 bytes alignment.
* On allocation error, the returned pointer is null, and if exceptions are enabled then a std::bad_alloc is thrown. * On allocation error, the returned pointer is null, and std::bad_alloc is thrown.
*/ */
inline void* aligned_malloc(size_t size) inline void* aligned_malloc(size_t size)
{ {
@ -213,10 +222,9 @@ inline void* aligned_malloc(size_t size)
result = handmade_aligned_malloc(size); result = handmade_aligned_malloc(size);
#endif #endif
#ifdef EIGEN_EXCEPTIONS if(!result && size)
if(result == 0) throw_std_bad_alloc();
throw std::bad_alloc();
#endif
return result; return result;
} }
@ -241,7 +249,7 @@ inline void aligned_free(void *ptr)
/** /**
* \internal * \internal
* \brief Reallocates an aligned block of memory. * \brief Reallocates an aligned block of memory.
* \throws std::bad_alloc if EIGEN_EXCEPTIONS are defined. * \throws std::bad_alloc on allocation failure
**/ **/
inline void* aligned_realloc(void *ptr, size_t new_size, size_t old_size) inline void* aligned_realloc(void *ptr, size_t new_size, size_t old_size)
{ {
@ -269,10 +277,9 @@ inline void* aligned_realloc(void *ptr, size_t new_size, size_t old_size)
result = handmade_aligned_realloc(ptr,new_size,old_size); result = handmade_aligned_realloc(ptr,new_size,old_size);
#endif #endif
#ifdef EIGEN_EXCEPTIONS if (!result && new_size)
if (result==0 && new_size!=0) throw_std_bad_alloc();
throw std::bad_alloc();
#endif
return result; return result;
} }
@ -281,7 +288,7 @@ inline void* aligned_realloc(void *ptr, size_t new_size, size_t old_size)
*****************************************************************************/ *****************************************************************************/
/** \internal Allocates \a size bytes. If Align is true, then the returned ptr is 16-byte-aligned. /** \internal Allocates \a size bytes. If Align is true, then the returned ptr is 16-byte-aligned.
* On allocation error, the returned pointer is null, and if exceptions are enabled then a std::bad_alloc is thrown. * On allocation error, the returned pointer is null, and a std::bad_alloc is thrown.
*/ */
template<bool Align> inline void* conditional_aligned_malloc(size_t size) template<bool Align> inline void* conditional_aligned_malloc(size_t size)
{ {
@ -293,9 +300,8 @@ template<> inline void* conditional_aligned_malloc<false>(size_t size)
check_that_malloc_is_allowed(); check_that_malloc_is_allowed();
void *result = std::malloc(size); void *result = std::malloc(size);
#ifdef EIGEN_EXCEPTIONS if(!result && size)
if(!result) throw std::bad_alloc(); throw_std_bad_alloc();
#endif
return result; return result;
} }
@ -350,16 +356,12 @@ template<typename T> inline void destruct_elements_of_array(T *ptr, size_t size)
template<typename T> template<typename T>
inline void check_size_for_overflow(size_t size) inline void check_size_for_overflow(size_t size)
{ {
#ifdef EIGEN_EXCEPTIONS
if(size > size_t(-1) / sizeof(T)) if(size > size_t(-1) / sizeof(T))
throw std::bad_alloc(); throw_std_bad_alloc();
#else
(void) size;
#endif
} }
/** \internal Allocates \a size objects of type T. The returned pointer is guaranteed to have 16 bytes alignment. /** \internal Allocates \a size objects of type T. The returned pointer is guaranteed to have 16 bytes alignment.
* On allocation error, the returned pointer is undefined, but if exceptions are enabled then a std::bad_alloc is thrown. * On allocation error, the returned pointer is undefined, but a std::bad_alloc is thrown.
* The default constructor of T is called. * The default constructor of T is called.
*/ */
template<typename T> inline T* aligned_new(size_t size) template<typename T> inline T* aligned_new(size_t size)