Bugzilla – Attachment 104 Details for
Bug 89
Crashes and wrong results due to GCC <=4.3 compiler bug with asserts inside of Eigen's code
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
Log In
[x]
|
Forgot Password
Login:
[x]
This bugzilla service is closed. All entries have been migrated to
https://gitlab.com/libeigen/eigen
[patch]
makes 100% tests pass: use custom assert, and introduce copy_bool non-inline function
tweak_assert (text/plain), 9.22 KB, created by
Benoit Jacob
on 2011-02-16 14:03:59 UTC
(
hide
)
Description:
makes 100% tests pass: use custom assert, and introduce copy_bool non-inline function
Filename:
MIME Type:
Creator:
Benoit Jacob
Created:
2011-02-16 14:03:59 UTC
Size:
9.22 KB
patch
obsolete
># HG changeset patch ># Parent 01c6559289569ead8eb8a4e80b16fa959b3b10af > >diff --git a/Eigen/Core b/Eigen/Core >--- a/Eigen/Core >+++ b/Eigen/Core >@@ -151,19 +151,23 @@ > #include <iosfwd> > #include <cstring> > #include <string> > #include <limits> > #include <climits> // for CHAR_BIT > // for min/max: > #include <algorithm> > >+#if !EIGEN_SAFE_TO_USE_STANDARD_ASSERT_MACRO >+#include <iostream> // for custom assert implementation >+#endif >+ > // for outputting debug info > #ifdef EIGEN_DEBUG_ASSIGN >-#include<iostream> >+#include <iostream> > #endif > > // required for __cpuid, needs to be included after cmath > #if defined(_MSC_VER) && (defined(_M_IX86)||defined(_M_X64)) > #include <intrin.h> > #endif > > #if (defined(_CPPUNWIND) || defined(__EXCEPTIONS)) && !defined(EIGEN_NO_EXCEPTIONS) >diff --git a/Eigen/src/Core/util/Macros.h b/Eigen/src/Core/util/Macros.h >--- a/Eigen/src/Core/util/Macros.h >+++ b/Eigen/src/Core/util/Macros.h >@@ -29,20 +29,33 @@ > #define EIGEN_WORLD_VERSION 2 > #define EIGEN_MAJOR_VERSION 93 > #define EIGEN_MINOR_VERSION 0 > > #define EIGEN_VERSION_AT_LEAST(x,y,z) (EIGEN_WORLD_VERSION>x || (EIGEN_WORLD_VERSION>=x && \ > (EIGEN_MAJOR_VERSION>y || (EIGEN_MAJOR_VERSION>=y && \ > EIGEN_MINOR_VERSION>=z)))) > #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 > #define EIGEN_GNUC_AT_LEAST(x,y) 0 > #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) > #define EIGEN_GCC3_OR_OLDER 1 > #else > #define EIGEN_GCC3_OR_OLDER 0 > #endif > > // 16 byte alignment is only useful for vectorization. Since it affects the ABI, we need to enable >@@ -104,41 +117,23 @@ > * - single precision Cwise::sin() and Cwise::cos() when SSE vectorization is enabled. > */ > #ifndef EIGEN_FAST_MATH > #define EIGEN_FAST_MATH 1 > #endif > > #define EIGEN_DEBUG_VAR(x) std::cerr << #x << " = " << x << std::endl; > >-#ifdef NDEBUG >-# ifndef EIGEN_NO_DEBUG >-# define EIGEN_NO_DEBUG >-# endif >-#endif >+// concatenate two tokens >+#define EIGEN_CAT2(a,b) a ## b >+#define EIGEN_CAT(a,b) EIGEN_CAT2(a,b) > >-#ifndef eigen_assert >-#ifdef EIGEN_NO_DEBUG >-#define eigen_assert(x) >-#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 >+// convert a token to a string >+#define EIGEN_MAKESTRING2(a) #a >+#define EIGEN_MAKESTRING(a) EIGEN_MAKESTRING2(a) > > // EIGEN_ALWAYS_INLINE_ATTRIB should be use in the declaration of function > // which should be inlined even in debug mode. > // FIXME with the always_inline attribute, > // gcc 3.4.x reports the following compilation error: > // Eval.h:91: sorry, unimplemented: inlining failed in call to 'const Eigen::Eval<Derived> Eigen::MatrixBase<Scalar, Derived>::eval() const' > // : function body not available > #if EIGEN_GNUC_AT_LEAST(4,0) >@@ -170,16 +165,74 @@ > > // this macro allows to get rid of linking errors about multiply defined functions. > // - static is not very good because it prevents definitions from different object files to be merged. > // So static causes the resulting linked executable to be bloated with multiple copies of the same function. > // - inline is not perfect either as it unwantedly hints the compiler toward inlining the function. > #define EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS > #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__) > #define EIGEN_DEPRECATED __attribute__((deprecated)) > #elif (defined _MSC_VER) > #define EIGEN_DEPRECATED __declspec(deprecated) > #else > #define EIGEN_DEPRECATED > #endif > >@@ -239,24 +292,16 @@ > #else > #define EIGEN_DEFAULT_IO_FORMAT Eigen::IOFormat() > #endif > #endif > > // just an empty macro ! > #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)) > #define EIGEN_INHERIT_ASSIGNMENT_EQUAL_OPERATOR(Derived) \ > using Base::operator =; > #else > #define EIGEN_INHERIT_ASSIGNMENT_EQUAL_OPERATOR(Derived) \ > using Base::operator =; \ > EIGEN_STRONG_INLINE Derived& operator=(const Derived& other) \ > { \ >diff --git a/test/main.h b/test/main.h >--- a/test/main.h >+++ b/test/main.h >@@ -86,17 +86,17 @@ namespace Eigen > // and might even introduce side effects that would hide > // some memory errors. > #ifdef EIGEN_DEBUG_ASSERTS > > namespace Eigen > { > namespace internal > { >- static bool push_assert = false; >+ static bool push_assert = false; > } > static std::vector<std::string> eigen_assert_list; > } > > #define eigen_assert(a) \ > if( (!(a)) && (!no_more_assert) ) \ > { \ > if(report_on_cerr_on_assert_failure) \ >@@ -124,27 +124,26 @@ namespace Eigen > } catch (Eigen::eigen_assert_exception) { \ > Eigen::internal::push_assert = false; VERIFY(true); \ > } \ > Eigen::report_on_cerr_on_assert_failure = true; \ > Eigen::internal::push_assert = false; \ > } > > #else // EIGEN_DEBUG_ASSERTS >- >+ // see bug 89. The copy_bool here is working around a bug in gcc <= 4.3 > #define eigen_assert(a) \ >- if( (!(a)) && (!no_more_assert) ) \ >+ if( (!Eigen::internal::copy_bool(a)) && (!no_more_assert) )\ > { \ > Eigen::no_more_assert = true; \ > if(report_on_cerr_on_assert_failure) \ >- assert(a); \ >+ eigen_plain_assert(a); \ > else \ > throw Eigen::eigen_assert_exception(); \ > } >- > #define VERIFY_RAISES_ASSERT(a) { \ > Eigen::no_more_assert = false; \ > Eigen::report_on_cerr_on_assert_failure = false; \ > try { \ > a; \ > VERIFY(Eigen::should_raise_an_assert && # a); \ > } \ > catch (Eigen::eigen_assert_exception&) { VERIFY(true); } \ >@@ -160,17 +159,16 @@ namespace Eigen > #define VERIFY_RAISES_ASSERT(a) {} > > #endif // EIGEN_NO_ASSERTION_CHECKING > > > #define EIGEN_INTERNAL_DEBUGGING > #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) > { > if (!condition) > { > std::cerr << "Test " << testname << " failed in " << file << " (" << line << ")" \ > << std::endl << " " << condition_as_string << std::endl << std::endl; \ > abort(); > }
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 89
:
17
|
18
|
19
|
96
|
98
|
100
|
101
|
102
|
103
| 104