aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--Eigen/src/Core/util/Memory.h24
-rw-r--r--test/ctorleak.cpp28
2 files changed, 51 insertions, 1 deletions
diff --git a/Eigen/src/Core/util/Memory.h b/Eigen/src/Core/util/Memory.h
index 4b3dcde3a..9b3e84fb0 100644
--- a/Eigen/src/Core/util/Memory.h
+++ b/Eigen/src/Core/util/Memory.h
@@ -354,16 +354,20 @@ template<typename T> inline void destruct_elements_of_array(T *ptr, size_t size)
template<typename T> inline T* construct_elements_of_array(T *ptr, size_t size)
{
size_t i;
+#ifdef EIGEN_EXCEPTIONS
try
+#endif
{
for (i = 0; i < size; ++i) ::new (ptr + i) T;
return ptr;
}
+#ifdef EIGEN_EXCEPTIONS
catch (...)
{
destruct_elements_of_array(ptr, i);
throw;
}
+#endif
}
/*****************************************************************************
@@ -385,30 +389,38 @@ template<typename T> inline T* aligned_new(size_t size)
{
check_size_for_overflow<T>(size);
T *result = reinterpret_cast<T*>(aligned_malloc(sizeof(T)*size));
+#ifdef EIGEN_EXCEPTIONS
try
+#endif
{
return construct_elements_of_array(result, size);
}
+#ifdef EIGEN_EXCEPTIONS
catch (...)
{
aligned_free(result);
throw;
}
+#endif
}
template<typename T, bool Align> inline T* conditional_aligned_new(size_t size)
{
check_size_for_overflow<T>(size);
T *result = reinterpret_cast<T*>(conditional_aligned_malloc<Align>(sizeof(T)*size));
+#ifdef EIGEN_EXCEPTIONS
try
+#endif
{
return construct_elements_of_array(result, size);
}
+#ifdef EIGEN_EXCEPTIONS
catch (...)
{
conditional_aligned_free<Align>(result);
throw;
}
+#endif
}
/** \internal Deletes objects constructed with aligned_new
@@ -438,15 +450,19 @@ template<typename T, bool Align> inline T* conditional_aligned_realloc_new(T* pt
T *result = reinterpret_cast<T*>(conditional_aligned_realloc<Align>(reinterpret_cast<void*>(pts), sizeof(T)*new_size, sizeof(T)*old_size));
if(new_size > old_size)
{
+#ifdef EIGEN_EXCEPTIONS
try
+#endif
{
construct_elements_of_array(result+old_size, new_size-old_size);
}
+#ifdef EIGEN_EXCEPTIONS
catch (...)
{
conditional_aligned_free<Align>(result);
throw;
}
+#endif
}
return result;
}
@@ -458,15 +474,19 @@ template<typename T, bool Align> inline T* conditional_aligned_new_auto(size_t s
T *result = reinterpret_cast<T*>(conditional_aligned_malloc<Align>(sizeof(T)*size));
if(NumTraits<T>::RequireInitialization)
{
+#ifdef EIGEN_EXCEPTIONS
try
+#endif
{
construct_elements_of_array(result, size);
}
+#ifdef EIGEN_EXCEPTIONS
catch (...)
{
conditional_aligned_free<Align>(result);
throw;
}
+#endif
}
return result;
}
@@ -480,15 +500,19 @@ template<typename T, bool Align> inline T* conditional_aligned_realloc_new_auto(
T *result = reinterpret_cast<T*>(conditional_aligned_realloc<Align>(reinterpret_cast<void*>(pts), sizeof(T)*new_size, sizeof(T)*old_size));
if(NumTraits<T>::RequireInitialization && (new_size > old_size))
{
+#ifdef EIGEN_EXCEPTIONS
try
+#endif
{
construct_elements_of_array(result+old_size, new_size-old_size);
}
+#ifdef EIGEN_EXCEPTIONS
catch (...)
{
conditional_aligned_free<Align>(result);
throw;
}
+#endif
}
return result;
}
diff --git a/test/ctorleak.cpp b/test/ctorleak.cpp
index 72ab94b66..f3f4411c8 100644
--- a/test/ctorleak.cpp
+++ b/test/ctorleak.cpp
@@ -4,11 +4,30 @@
struct Foo
{
+ static unsigned object_count;
+ static unsigned object_limit;
int dummy;
- Foo() { if (!internal::random(0, 10)) throw Foo::Fail(); }
+
+ Foo()
+ {
+#ifdef EIGEN_EXCEPTIONS
+ // TODO: Is this the correct way to handle this?
+ if (Foo::object_count > Foo::object_limit) { throw Foo::Fail(); }
+#endif
+ ++Foo::object_count;
+ }
+
+ ~Foo()
+ {
+ --Foo::object_count;
+ }
+
class Fail : public std::exception {};
};
+unsigned Foo::object_count = 0;
+unsigned Foo::object_limit = 0;
+
namespace Eigen
{
template<>
@@ -34,10 +53,17 @@ namespace Eigen
void test_ctorleak()
{
+ Foo::object_count = 0;
+ Foo::object_limit = internal::random(0, 14 * 92 - 2);
+#ifdef EIGEN_EXCEPTIONS
try
+#endif
{
Matrix<Foo, Dynamic, Dynamic> m(14, 92);
eigen_assert(false); // not reached
}
+#ifdef EIGEN_EXCEPTIONS
catch (const Foo::Fail&) { /* ignore */ }
+#endif
+ VERIFY_IS_EQUAL(static_cast<unsigned>(0), Foo::object_count);
}