diff options
Diffstat (limited to 'src/util')
-rw-r--r-- | src/util/Assert.cpp | 16 | ||||
-rw-r--r-- | src/util/Assert.h | 53 | ||||
-rw-r--r-- | src/util/exception.h | 2 | ||||
-rw-r--r-- | src/util/options.h | 5 |
4 files changed, 57 insertions, 19 deletions
diff --git a/src/util/Assert.cpp b/src/util/Assert.cpp index 8e2dd9220..f992032ee 100644 --- a/src/util/Assert.cpp +++ b/src/util/Assert.cpp @@ -25,6 +25,10 @@ using namespace std; namespace CVC4 { +#ifdef CVC4_DEBUG +__thread CVC4_PUBLIC const char* s_debugAssertionFailure = NULL; +#endif /* CVC4_DEBUG */ + void AssertionException::construct(const char* header, const char* extra, const char* function, const char* file, unsigned line, const char* fmt, @@ -65,7 +69,13 @@ void AssertionException::construct(const char* header, const char* extra, } setMessage(string(buf)); + +#ifdef CVC4_DEBUG + // we leak buf[] but only in debug mode with assertions failing + s_debugAssertionFailure = buf; +#else /* CVC4_DEBUG */ delete [] buf; +#endif /* CVC4_DEBUG */ } void AssertionException::construct(const char* header, const char* extra, @@ -98,7 +108,13 @@ void AssertionException::construct(const char* header, const char* extra, } setMessage(string(buf)); + +#ifdef CVC4_DEBUG + // we leak buf[] but only in debug mode with assertions failing + s_debugAssertionFailure = buf; +#else /* CVC4_DEBUG */ delete [] buf; +#endif /* CVC4_DEBUG */ } }/* CVC4 namespace */ diff --git a/src/util/Assert.h b/src/util/Assert.h index 3b42f2887..8c230218c 100644 --- a/src/util/Assert.h +++ b/src/util/Assert.h @@ -19,12 +19,13 @@ #include <string> #include <sstream> #include <cstdio> +#include <cstdlib> #include <cstdarg> -#include "util/exception.h" -#include "cvc4_config.h" -#include "config.h" -#include <cassert> +#include "config.h" +#include "cvc4_config.h" +#include "util/exception.h" +#include "util/output.h" namespace CVC4 { @@ -192,14 +193,42 @@ public: } };/* class IllegalArgumentException */ -#define AlwaysAssert(cond, msg...) \ - do { \ - if(EXPECT_FALSE( ! (cond) )) { \ - throw AssertionException(#cond, __PRETTY_FUNCTION__, __FILE__, __LINE__, ## msg); \ - } \ +#ifdef CVC4_DEBUG + +extern __thread CVC4_PUBLIC const char* s_debugAssertionFailure; + +// If we're currently handling an exception, print a warning instead; +// otherwise std::terminate() is called by the runtime and we lose +// details of the exception +#define AlwaysAssert(cond, msg...) \ + do { \ + if(EXPECT_FALSE( ! (cond) )) { \ + if(EXPECT_FALSE( std::uncaught_exception() )) { \ + Warning() << "===========================================" << std::endl \ + << "An assertion failed during stack unwinding:" << std::endl \ + << AssertionException(#cond, __PRETTY_FUNCTION__, __FILE__, __LINE__, ## msg) << std::endl \ + << "===========================================" << std::endl; \ + if(s_debugAssertionFailure != NULL) { \ + Warning() << "The propagating exception is:" << std::endl \ + << s_debugAssertionFailure << std::endl \ + << "===========================================" << std::endl; \ + } \ + } else { \ + throw AssertionException(#cond, __PRETTY_FUNCTION__, __FILE__, __LINE__, ## msg); \ + } \ + } \ } while(0) -#define DtorAlwaysAssert(cond, msg...) \ - assert(EXPECT_TRUE( cond )) +#else /* CVC4_DEBUG */ +// These simpler (but less useful) versions for non-debug builds fails +// with terminate() if thrown during stack unwinding. +# define AlwaysAssert(cond, msg...) \ + do { \ + if(EXPECT_FALSE( ! (cond) )) { \ + throw AssertionException(#cond, __PRETTY_FUNCTION__, __FILE__, __LINE__, ## msg); \ + } \ + } while(0) +#endif /* CVC4_DEBUG */ + #define Unreachable(msg...) \ throw UnreachableCodeException(__PRETTY_FUNCTION__, __FILE__, __LINE__, ## msg) #define Unhandled(msg...) \ @@ -219,11 +248,9 @@ public: #ifdef CVC4_ASSERTIONS # define Assert(cond, msg...) AlwaysAssert(cond, ## msg) -# define DtorAssert(cond, msg...) assert(EXPECT_TRUE( cond )) # define AssertArgument(cond, arg, msg...) AlwaysAssertArgument(cond, arg, ## msg) #else /* ! CVC4_ASSERTIONS */ # define Assert(cond, msg...) /*EXPECT_TRUE( cond )*/ -# define DtorAssert(cond, msg...) /*EXPECT_TRUE( cond )*/ # define AssertArgument(cond, arg, msg...) /*EXPECT_TRUE( cond )*/ #endif /* CVC4_ASSERTIONS */ diff --git a/src/util/exception.h b/src/util/exception.h index b77e7c860..5449d67f7 100644 --- a/src/util/exception.h +++ b/src/util/exception.h @@ -31,7 +31,7 @@ public: Exception(const std::string& msg) : d_msg(msg) {} Exception(const char* msg) : d_msg(msg) {} // Destructor - virtual ~Exception() {} + virtual ~Exception() throw() {} // NON-VIRTUAL METHOD for setting and printing the error message void setMessage(const std::string& msg) { d_msg = msg; } // Printing: feel free to redefine toString(). When inherited, diff --git a/src/util/options.h b/src/util/options.h index 676dc0059..b71acd982 100644 --- a/src/util/options.h +++ b/src/util/options.h @@ -18,7 +18,6 @@ #include <iostream> #include "parser/parser.h" -#include "prop/cnf_conversion.h" namespace CVC4 { @@ -42,9 +41,6 @@ struct CVC4_PUBLIC Options { /** The input language */ parser::Parser::InputLanguage lang; - /** The CNF conversion */ - CVC4::CnfConversion d_cnfConversion; - /** Should we exit after parsing? */ bool parseOnly; @@ -61,7 +57,6 @@ struct CVC4_PUBLIC Options { err(0), verbosity(0), lang(parser::Parser::LANG_AUTO), - d_cnfConversion(CVC4::CNF_VAR_INTRODUCTION), parseOnly(false), semanticChecks(true), memoryMap(false) |