aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar Christoph Hertzberg <chtz@informatik.uni-bremen.de>2014-07-22 13:16:44 +0200
committerGravatar Christoph Hertzberg <chtz@informatik.uni-bremen.de>2014-07-22 13:16:44 +0200
commita8283e0ed2d3e42ba8e1c42f51cb08eacc301047 (patch)
treec9c78db74cdb680132a8779db69cf53ee73390ba
parent529e6cb5529f626b7c5cf781bdcd5a5720f904c1 (diff)
Define EIGEN_TRY, EIGEN_CATCH, EIGEN_THROW as suggested by Moritz Klammer.
Make it possible to run unit-tests with exceptions disabled via EIGEN_TEST_NO_EXCEPTIONS flag. Enhanced ctorleak unit-test
-rw-r--r--CMakeLists.txt8
-rw-r--r--Eigen/Core16
-rw-r--r--Eigen/src/Core/util/Macros.h12
-rw-r--r--Eigen/src/Core/util/Memory.h145
-rw-r--r--test/CMakeLists.txt10
-rw-r--r--test/ctorleak.cpp40
-rw-r--r--test/main.h16
7 files changed, 112 insertions, 135 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 470095680..96d6c8701 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -119,7 +119,7 @@ endmacro(ei_add_cxx_compiler_flag)
if(NOT MSVC)
# We assume that other compilers are partly compatible with GNUCC
- set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fexceptions")
+# set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fexceptions")
set(CMAKE_CXX_FLAGS_DEBUG "-g3")
set(CMAKE_CXX_FLAGS_RELEASE "-g0 -O2")
@@ -301,6 +301,12 @@ if(EIGEN_TEST_NO_EXPLICIT_ALIGNMENT)
message(STATUS "Disabling alignment in tests/examples")
endif()
+option(EIGEN_TEST_NO_EXCEPTIONS "Disables C++ exceptions" OFF)
+if(EIGEN_TEST_NO_EXCEPTIONS)
+ ei_add_cxx_compiler_flag("-fno-exceptions")
+ message(STATUS "Disabling exceptions in tests/examples")
+endif()
+
option(EIGEN_TEST_C++0x "Enables all C++0x features." OFF)
include_directories(${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR})
diff --git a/Eigen/Core b/Eigen/Core
index 16e388fa4..9a73fe37b 100644
--- a/Eigen/Core
+++ b/Eigen/Core
@@ -42,6 +42,14 @@
#define EIGEN_USING_STD_MATH(FUNC) using std::FUNC;
#endif
+#if (defined(_CPPUNWIND) || defined(__EXCEPTIONS)) && !defined(__CUDA_ARCH__)
+ #define EIGEN_EXCEPTIONS
+#endif
+
+#ifdef EIGEN_EXCEPTIONS
+ #include <new>
+#endif
+
// then include this file where all our macros are defined. It's really important to do it first because
// it's where we do all the alignment settings (platform detection and honoring the user's will if he
// defined e.g. EIGEN_DONT_ALIGN) so it needs to be done before we do anything with vectorization.
@@ -209,14 +217,6 @@
#include <intrin.h>
#endif
-#if (defined(_CPPUNWIND) || defined(__EXCEPTIONS)) && !defined(__CUDA_ARCH__)
- #define EIGEN_EXCEPTIONS
-#endif
-
-#ifdef EIGEN_EXCEPTIONS
- #include <new>
-#endif
-
/** \brief Namespace containing all symbols from the %Eigen library. */
namespace Eigen {
diff --git a/Eigen/src/Core/util/Macros.h b/Eigen/src/Core/util/Macros.h
index 71e42b125..5e9b0a112 100644
--- a/Eigen/src/Core/util/Macros.h
+++ b/Eigen/src/Core/util/Macros.h
@@ -452,4 +452,16 @@ namespace Eigen {
const RHS \
>
+#ifdef EIGEN_EXCEPTIONS
+# define EIGEN_THROW_X(X) throw X
+# define EIGEN_THROW throw
+# define EIGEN_TRY try
+# define EIGEN_CATCH(X) catch (X)
+#else
+# define EIGEN_THROW_X(X) std::abort()
+# define EIGEN_THROW std::abort()
+# define EIGEN_TRY if (true)
+# define EIGEN_CATCH(X) else
+#endif
+
#endif // EIGEN_MACROS_H
diff --git a/Eigen/src/Core/util/Memory.h b/Eigen/src/Core/util/Memory.h
index 9b3e84fb0..38990566d 100644
--- a/Eigen/src/Core/util/Memory.h
+++ b/Eigen/src/Core/util/Memory.h
@@ -354,20 +354,16 @@ 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
- {
+ EIGEN_TRY
+ {
for (i = 0; i < size; ++i) ::new (ptr + i) T;
return ptr;
- }
-#ifdef EIGEN_EXCEPTIONS
- catch (...)
- {
- destruct_elements_of_array(ptr, i);
- throw;
- }
-#endif
+ }
+ EIGEN_CATCH(...)
+ {
+ destruct_elements_of_array(ptr, i);
+ EIGEN_THROW;
+ }
}
/*****************************************************************************
@@ -389,38 +385,30 @@ 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
+ EIGEN_TRY
+ {
+ return construct_elements_of_array(result, size);
+ }
+ EIGEN_CATCH(...)
+ {
+ aligned_free(result);
+ EIGEN_THROW;
+ }
}
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
+ EIGEN_TRY
+ {
+ return construct_elements_of_array(result, size);
+ }
+ EIGEN_CATCH(...)
+ {
+ conditional_aligned_free<Align>(result);
+ EIGEN_THROW;
+ }
}
/** \internal Deletes objects constructed with aligned_new
@@ -449,21 +437,17 @@ template<typename T, bool Align> inline T* conditional_aligned_realloc_new(T* pt
destruct_elements_of_array(pts+new_size, old_size-new_size);
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)
+ {
+ EIGEN_TRY
{
-#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
+ construct_elements_of_array(result+old_size, new_size-old_size);
+ }
+ EIGEN_CATCH(...)
+ {
+ conditional_aligned_free<Align>(result);
+ EIGEN_THROW;
}
+ }
return result;
}
@@ -473,21 +457,17 @@ template<typename T, bool Align> inline T* conditional_aligned_new_auto(size_t s
check_size_for_overflow<T>(size);
T *result = reinterpret_cast<T*>(conditional_aligned_malloc<Align>(sizeof(T)*size));
if(NumTraits<T>::RequireInitialization)
+ {
+ EIGEN_TRY
{
-#ifdef EIGEN_EXCEPTIONS
- try
-#endif
- {
- construct_elements_of_array(result, size);
- }
-#ifdef EIGEN_EXCEPTIONS
- catch (...)
- {
- conditional_aligned_free<Align>(result);
- throw;
- }
-#endif
+ construct_elements_of_array(result, size);
}
+ EIGEN_CATCH(...)
+ {
+ conditional_aligned_free<Align>(result);
+ EIGEN_THROW;
+ }
+ }
return result;
}
@@ -499,21 +479,17 @@ template<typename T, bool Align> inline T* conditional_aligned_realloc_new_auto(
destruct_elements_of_array(pts+new_size, old_size-new_size);
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))
+ {
+ EIGEN_TRY
{
-#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
+ construct_elements_of_array(result+old_size, new_size-old_size);
+ }
+ EIGEN_CATCH(...)
+ {
+ conditional_aligned_free<Align>(result);
+ EIGEN_THROW;
}
+ }
return result;
}
@@ -713,20 +689,11 @@ template<typename T> class aligned_stack_memory_handler
*****************************************************************************/
#if EIGEN_ALIGN
- #ifdef EIGEN_EXCEPTIONS
- #define EIGEN_MAKE_ALIGNED_OPERATOR_NEW_NOTHROW(NeedsToAlign) \
- void* operator new(size_t size, const std::nothrow_t&) throw() { \
- try { return Eigen::internal::conditional_aligned_malloc<NeedsToAlign>(size); } \
- catch (...) { return 0; } \
- return 0; \
- }
- #else
- #define EIGEN_MAKE_ALIGNED_OPERATOR_NEW_NOTHROW(NeedsToAlign) \
+ #define EIGEN_MAKE_ALIGNED_OPERATOR_NEW_NOTHROW(NeedsToAlign) \
void* operator new(size_t size, const std::nothrow_t&) throw() { \
- return Eigen::internal::conditional_aligned_malloc<NeedsToAlign>(size); \
+ EIGEN_TRY { return Eigen::internal::conditional_aligned_malloc<NeedsToAlign>(size); } \
+ EIGEN_CATCH (...) { return 0; } \
}
- #endif
-
#define EIGEN_MAKE_ALIGNED_OPERATOR_NEW_IF(NeedsToAlign) \
void *operator new(size_t size) { \
return Eigen::internal::conditional_aligned_malloc<NeedsToAlign>(size); \
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
index fed5c0e06..47aefddb8 100644
--- a/test/CMakeLists.txt
+++ b/test/CMakeLists.txt
@@ -158,7 +158,9 @@ ei_add_test(basicstuff)
ei_add_test(linearstructure)
ei_add_test(integer_types)
ei_add_test(unalignedcount)
-ei_add_test(exceptions)
+if(NOT EIGEN_TEST_NO_EXCEPTIONS)
+ ei_add_test(exceptions)
+endif()
ei_add_test(redux)
ei_add_test(visitor)
ei_add_test(block)
@@ -238,7 +240,9 @@ ei_add_test(nesting_ops "${CMAKE_CXX_FLAGS_DEBUG}")
ei_add_test(zerosized)
ei_add_test(dontalign)
ei_add_test(evaluators)
-ei_add_test(sizeoverflow)
+if(NOT EIGEN_TEST_NO_EXCEPTIONS)
+ ei_add_test(sizeoverflow)
+endif()
ei_add_test(prec_inverse_4x4)
ei_add_test(vectorwiseop)
ei_add_test(special_numbers)
@@ -251,8 +255,6 @@ ei_add_test(bicgstab)
ei_add_test(sparselu)
ei_add_test(sparseqr)
-ei_add_test(ctorleak)
-
# ei_add_test(denseLM)
if(QT4_FOUND)
diff --git a/test/ctorleak.cpp b/test/ctorleak.cpp
index f3f4411c8..145d91be4 100644
--- a/test/ctorleak.cpp
+++ b/test/ctorleak.cpp
@@ -28,42 +28,24 @@ struct Foo
unsigned Foo::object_count = 0;
unsigned Foo::object_limit = 0;
-namespace Eigen
-{
- template<>
- struct NumTraits<Foo>
- {
- typedef double Real;
- typedef double NonInteger;
- typedef double Nested;
- enum
- {
- IsComplex = 0,
- IsInteger = 1,
- ReadCost = -1,
- AddCost = -1,
- MulCost = -1,
- IsSigned = 1,
- RequireInitialization = 1
- };
- static inline Real epsilon() { return 1.0; }
- static inline Real dummy_epsilon() { return 0.0; }
- };
-}
void test_ctorleak()
{
+ typedef DenseIndex Index;
Foo::object_count = 0;
- Foo::object_limit = internal::random(0, 14 * 92 - 2);
+ for(int i = 0; i < g_repeat; i++) {
+ Index rows = internal::random<Index>(2,EIGEN_TEST_MAX_SIZE), cols = internal::random<Index>(2,EIGEN_TEST_MAX_SIZE);
+ Foo::object_limit = internal::random(0, rows*cols - 2);
#ifdef EIGEN_EXCEPTIONS
- try
-#endif
+ try
{
- Matrix<Foo, Dynamic, Dynamic> m(14, 92);
- eigen_assert(false); // not reached
- }
+#endif
+ Matrix<Foo, Dynamic, Dynamic> m(rows, cols);
#ifdef EIGEN_EXCEPTIONS
- catch (const Foo::Fail&) { /* ignore */ }
+ VERIFY(false); // not reached if exceptions are enabled
+ }
+ catch (const Foo::Fail&) { /* ignore */ }
#endif
+ }
VERIFY_IS_EQUAL(static_cast<unsigned>(0), Foo::object_count);
}
diff --git a/test/main.h b/test/main.h
index 3ccc2ae88..3295dcb71 100644
--- a/test/main.h
+++ b/test/main.h
@@ -117,13 +117,14 @@ namespace Eigen
if(report_on_cerr_on_assert_failure) \
std::cerr << #a << " " __FILE__ << "(" << __LINE__ << ")\n"; \
Eigen::no_more_assert = true; \
- throw Eigen::eigen_assert_exception(); \
+ EIGEN_THROW_X(Eigen::eigen_assert_exception()); \
} \
else if (Eigen::internal::push_assert) \
{ \
eigen_assert_list.push_back(std::string(EI_PP_MAKE_STRING(__FILE__) " (" EI_PP_MAKE_STRING(__LINE__) ") : " #a) ); \
}
+ #ifdef EIGEN_EXCEPTIONS
#define VERIFY_RAISES_ASSERT(a) \
{ \
Eigen::no_more_assert = false; \
@@ -142,6 +143,7 @@ namespace Eigen
Eigen::report_on_cerr_on_assert_failure = true; \
Eigen::internal::push_assert = false; \
}
+ #endif //EIGEN_EXCEPTIONS
#elif !defined(__CUDACC__) // EIGEN_DEBUG_ASSERTS
// see bug 89. The copy_bool here is working around a bug in gcc <= 4.3
@@ -152,9 +154,10 @@ namespace Eigen
if(report_on_cerr_on_assert_failure) \
eigen_plain_assert(a); \
else \
- throw Eigen::eigen_assert_exception(); \
+ EIGEN_THROW_X(Eigen::eigen_assert_exception()); \
}
- #define VERIFY_RAISES_ASSERT(a) { \
+ #ifdef EIGEN_EXCEPTIONS
+ #define VERIFY_RAISES_ASSERT(a) { \
Eigen::no_more_assert = false; \
Eigen::report_on_cerr_on_assert_failure = false; \
try { \
@@ -164,9 +167,14 @@ namespace Eigen
catch (Eigen::eigen_assert_exception&) { VERIFY(true); } \
Eigen::report_on_cerr_on_assert_failure = true; \
}
-
+ #endif //EIGEN_EXCEPTIONS
#endif // EIGEN_DEBUG_ASSERTS
+#ifndef VERIFY_RAISES_ASSERT
+ #define VERIFY_RAISES_ASSERT(a) \
+ std::cout << "Can't VERIFY_RAISES_ASSERT( " #a " ) with exceptions disabled";
+#endif
+
#if !defined(__CUDACC__)
#define EIGEN_USE_CUSTOM_ASSERT
#endif