mirror of
https://gitlab.com/libeigen/eigen.git
synced 2025-07-26 14:54:30 +08:00
Fix bug #89: on GCC <= 4.3, use a custom assert implementation to work around a compiler bug
This commit is contained in:
parent
6db8fa7d04
commit
59596efdf7
@ -156,9 +156,13 @@
|
|||||||
// for min/max:
|
// for min/max:
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
|
#if !EIGEN_SAFE_TO_USE_STANDARD_ASSERT_MACRO
|
||||||
|
#include <iostream> // for custom assert implementation
|
||||||
|
#endif
|
||||||
|
|
||||||
// for outputting debug info
|
// for outputting debug info
|
||||||
#ifdef EIGEN_DEBUG_ASSIGN
|
#ifdef EIGEN_DEBUG_ASSIGN
|
||||||
#include<iostream>
|
#include <iostream>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// required for __cpuid, needs to be included after cmath
|
// required for __cpuid, needs to be included after cmath
|
||||||
|
@ -34,10 +34,23 @@
|
|||||||
(EIGEN_MAJOR_VERSION>y || (EIGEN_MAJOR_VERSION>=y && \
|
(EIGEN_MAJOR_VERSION>y || (EIGEN_MAJOR_VERSION>=y && \
|
||||||
EIGEN_MINOR_VERSION>=z))))
|
EIGEN_MINOR_VERSION>=z))))
|
||||||
#ifdef __GNUC__
|
#ifdef __GNUC__
|
||||||
#define EIGEN_GNUC_AT_LEAST(x,y) ((__GNUC__>=x && __GNUC_MINOR__>=y) || __GNUC__>x)
|
#define EIGEN_GNUC_AT_LEAST(x,y) ((__GNUC__==x && __GNUC_MINOR__>=y) || __GNUC__>x)
|
||||||
#else
|
#else
|
||||||
#define EIGEN_GNUC_AT_LEAST(x,y) 0
|
#define EIGEN_GNUC_AT_LEAST(x,y) 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef __GNUC__
|
||||||
|
#define EIGEN_GNUC_AT_MOST(x,y) ((__GNUC__==x && __GNUC_MINOR__<=y) || __GNUC__<x)
|
||||||
|
#else
|
||||||
|
#define EIGEN_GNUC_AT_MOST(x,y) 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if EIGEN_GNUC_AT_MOST(4,3)
|
||||||
|
// see bug 89
|
||||||
|
#define EIGEN_SAFE_TO_USE_STANDARD_ASSERT_MACRO 0
|
||||||
|
#else
|
||||||
|
#define EIGEN_SAFE_TO_USE_STANDARD_ASSERT_MACRO 1
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined(__GNUC__) && (__GNUC__ <= 3)
|
#if defined(__GNUC__) && (__GNUC__ <= 3)
|
||||||
#define EIGEN_GCC3_OR_OLDER 1
|
#define EIGEN_GCC3_OR_OLDER 1
|
||||||
@ -109,31 +122,13 @@
|
|||||||
|
|
||||||
#define EIGEN_DEBUG_VAR(x) std::cerr << #x << " = " << x << std::endl;
|
#define EIGEN_DEBUG_VAR(x) std::cerr << #x << " = " << x << std::endl;
|
||||||
|
|
||||||
#ifdef NDEBUG
|
// concatenate two tokens
|
||||||
# ifndef EIGEN_NO_DEBUG
|
#define EIGEN_CAT2(a,b) a ## b
|
||||||
# define EIGEN_NO_DEBUG
|
#define EIGEN_CAT(a,b) EIGEN_CAT2(a,b)
|
||||||
# endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef eigen_assert
|
// convert a token to a string
|
||||||
#ifdef EIGEN_NO_DEBUG
|
#define EIGEN_MAKESTRING2(a) #a
|
||||||
#define eigen_assert(x)
|
#define EIGEN_MAKESTRING(a) EIGEN_MAKESTRING2(a)
|
||||||
#else
|
|
||||||
#define eigen_assert(x) assert(x)
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef EIGEN_INTERNAL_DEBUGGING
|
|
||||||
#define eigen_internal_assert(x) eigen_assert(x)
|
|
||||||
#else
|
|
||||||
#define eigen_internal_assert(x)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef EIGEN_NO_DEBUG
|
|
||||||
#define EIGEN_ONLY_USED_FOR_DEBUG(x) (void)x
|
|
||||||
#else
|
|
||||||
#define EIGEN_ONLY_USED_FOR_DEBUG(x)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// EIGEN_ALWAYS_INLINE_ATTRIB should be use in the declaration of function
|
// EIGEN_ALWAYS_INLINE_ATTRIB should be use in the declaration of function
|
||||||
// which should be inlined even in debug mode.
|
// which should be inlined even in debug mode.
|
||||||
@ -175,6 +170,64 @@
|
|||||||
#define EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS
|
#define EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS
|
||||||
#define EIGEN_DEFINE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS inline
|
#define EIGEN_DEFINE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS inline
|
||||||
|
|
||||||
|
#ifdef NDEBUG
|
||||||
|
# ifndef EIGEN_NO_DEBUG
|
||||||
|
# define EIGEN_NO_DEBUG
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// eigen_plain_assert is where we implement the workaround for the assert() bug in GCC <= 4.3, see bug 89
|
||||||
|
#ifdef EIGEN_NO_DEBUG
|
||||||
|
#define eigen_plain_assert(x)
|
||||||
|
#else
|
||||||
|
#if EIGEN_SAFE_TO_USE_STANDARD_ASSERT_MACRO
|
||||||
|
namespace Eigen {
|
||||||
|
namespace internal {
|
||||||
|
inline bool copy_bool(bool b) { return b; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#define eigen_plain_assert(x) assert(x)
|
||||||
|
#else
|
||||||
|
// work around bug 89
|
||||||
|
namespace Eigen {
|
||||||
|
namespace internal {
|
||||||
|
// trivial function copying a bool. Must be EIGEN_DONT_INLINE, so we implement it after including Eigen headers.
|
||||||
|
// see bug 89.
|
||||||
|
namespace {
|
||||||
|
EIGEN_DONT_INLINE bool copy_bool(bool b) { return b; }
|
||||||
|
}
|
||||||
|
inline void assert_fail(const char *condition, const char *function, const char *file, int line)
|
||||||
|
{
|
||||||
|
std::cerr << "assertion failed: " << condition << " in function " << function << " at " << file << ":" << line << std::endl;
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#define eigen_plain_assert(x) \
|
||||||
|
do { \
|
||||||
|
if(!Eigen::internal::copy_bool(x)) \
|
||||||
|
Eigen::internal::assert_fail(EIGEN_MAKESTRING(x), __PRETTY_FUNCTION__, __FILE__, __LINE__); \
|
||||||
|
} while(false)
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// eigen_assert can be overridden
|
||||||
|
#ifndef eigen_assert
|
||||||
|
#define eigen_assert(x) eigen_plain_assert(x)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef EIGEN_INTERNAL_DEBUGGING
|
||||||
|
#define eigen_internal_assert(x) eigen_assert(x)
|
||||||
|
#else
|
||||||
|
#define eigen_internal_assert(x)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef EIGEN_NO_DEBUG
|
||||||
|
#define EIGEN_ONLY_USED_FOR_DEBUG(x) (void)x
|
||||||
|
#else
|
||||||
|
#define EIGEN_ONLY_USED_FOR_DEBUG(x)
|
||||||
|
#endif
|
||||||
|
|
||||||
#if (defined __GNUC__)
|
#if (defined __GNUC__)
|
||||||
#define EIGEN_DEPRECATED __attribute__((deprecated))
|
#define EIGEN_DEPRECATED __attribute__((deprecated))
|
||||||
#elif (defined _MSC_VER)
|
#elif (defined _MSC_VER)
|
||||||
@ -244,14 +297,6 @@
|
|||||||
// just an empty macro !
|
// just an empty macro !
|
||||||
#define EIGEN_EMPTY
|
#define EIGEN_EMPTY
|
||||||
|
|
||||||
// concatenate two tokens
|
|
||||||
#define EIGEN_CAT2(a,b) a ## b
|
|
||||||
#define EIGEN_CAT(a,b) EIGEN_CAT2(a,b)
|
|
||||||
|
|
||||||
// convert a token to a string
|
|
||||||
#define EIGEN_MAKESTRING2(a) #a
|
|
||||||
#define EIGEN_MAKESTRING(a) EIGEN_MAKESTRING2(a)
|
|
||||||
|
|
||||||
#if defined(_MSC_VER) && (!defined(__INTEL_COMPILER))
|
#if defined(_MSC_VER) && (!defined(__INTEL_COMPILER))
|
||||||
#define EIGEN_INHERIT_ASSIGNMENT_EQUAL_OPERATOR(Derived) \
|
#define EIGEN_INHERIT_ASSIGNMENT_EQUAL_OPERATOR(Derived) \
|
||||||
using Base::operator =;
|
using Base::operator =;
|
||||||
|
15
test/main.h
15
test/main.h
@ -77,7 +77,6 @@ namespace Eigen
|
|||||||
~eigen_assert_exception() { Eigen::no_more_assert = false; }
|
~eigen_assert_exception() { Eigen::no_more_assert = false; }
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
// If EIGEN_DEBUG_ASSERTS is defined and if no assertion is triggered while
|
// If EIGEN_DEBUG_ASSERTS is defined and if no assertion is triggered while
|
||||||
// one should have been, then the list of excecuted assertions is printed out.
|
// one should have been, then the list of excecuted assertions is printed out.
|
||||||
//
|
//
|
||||||
@ -91,11 +90,10 @@ namespace Eigen
|
|||||||
{
|
{
|
||||||
namespace internal
|
namespace internal
|
||||||
{
|
{
|
||||||
static bool push_assert = false;
|
static bool push_assert = false;
|
||||||
}
|
}
|
||||||
static std::vector<std::string> eigen_assert_list;
|
static std::vector<std::string> eigen_assert_list;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define eigen_assert(a) \
|
#define eigen_assert(a) \
|
||||||
if( (!(a)) && (!no_more_assert) ) \
|
if( (!(a)) && (!no_more_assert) ) \
|
||||||
{ \
|
{ \
|
||||||
@ -129,17 +127,16 @@ namespace Eigen
|
|||||||
}
|
}
|
||||||
|
|
||||||
#else // EIGEN_DEBUG_ASSERTS
|
#else // EIGEN_DEBUG_ASSERTS
|
||||||
|
// see bug 89. The copy_bool here is working around a bug in gcc <= 4.3
|
||||||
#define eigen_assert(a) \
|
#define eigen_assert(a) \
|
||||||
if( (!(a)) && (!no_more_assert) ) \
|
if( (!Eigen::internal::copy_bool(a)) && (!no_more_assert) )\
|
||||||
{ \
|
{ \
|
||||||
Eigen::no_more_assert = true; \
|
Eigen::no_more_assert = true; \
|
||||||
if(report_on_cerr_on_assert_failure) \
|
if(report_on_cerr_on_assert_failure) \
|
||||||
assert(a); \
|
eigen_plain_assert(a); \
|
||||||
else \
|
else \
|
||||||
throw Eigen::eigen_assert_exception(); \
|
throw Eigen::eigen_assert_exception(); \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define VERIFY_RAISES_ASSERT(a) { \
|
#define VERIFY_RAISES_ASSERT(a) { \
|
||||||
Eigen::no_more_assert = false; \
|
Eigen::no_more_assert = false; \
|
||||||
Eigen::report_on_cerr_on_assert_failure = false; \
|
Eigen::report_on_cerr_on_assert_failure = false; \
|
||||||
@ -165,7 +162,6 @@ namespace Eigen
|
|||||||
#define EIGEN_INTERNAL_DEBUGGING
|
#define EIGEN_INTERNAL_DEBUGGING
|
||||||
#include <Eigen/QR> // required for createRandomPIMatrixOfRank
|
#include <Eigen/QR> // required for createRandomPIMatrixOfRank
|
||||||
|
|
||||||
|
|
||||||
static void verify_impl(bool condition, const char *testname, const char *file, int line, const char *condition_as_string)
|
static void verify_impl(bool condition, const char *testname, const char *file, int line, const char *condition_as_string)
|
||||||
{
|
{
|
||||||
if (!condition)
|
if (!condition)
|
||||||
@ -176,7 +172,8 @@ static void verify_impl(bool condition, const char *testname, const char *file,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#define VERIFY(a) verify_impl(a, g_test_stack.back().c_str(), __FILE__, __LINE__, EI_PP_MAKE_STRING(a))
|
#define VERIFY(a) assert(a)
|
||||||
|
//#define VERIFY(a) verify_impl(a, g_test_stack.back().c_str(), __FILE__, __LINE__, EI_PP_MAKE_STRING(a))
|
||||||
|
|
||||||
#define VERIFY_IS_EQUAL(a, b) VERIFY(test_is_equal(a, b))
|
#define VERIFY_IS_EQUAL(a, b) VERIFY(test_is_equal(a, b))
|
||||||
#define VERIFY_IS_APPROX(a, b) VERIFY(test_isApprox(a, b))
|
#define VERIFY_IS_APPROX(a, b) VERIFY(test_isApprox(a, b))
|
||||||
|
Loading…
x
Reference in New Issue
Block a user