diff --git a/include/internal/catch_assertionhandler.cpp b/include/internal/catch_assertionhandler.cpp index d53b09fa..8d99e3d0 100644 --- a/include/internal/catch_assertionhandler.cpp +++ b/include/internal/catch_assertionhandler.cpp @@ -14,7 +14,7 @@ #include "catch_debugger.h" #include "catch_interfaces_registry_hub.h" -#include // !TBD +#include namespace Catch { @@ -58,6 +58,12 @@ namespace Catch { { getCurrentContext().getResultCapture()->assertionStarting( m_assertionInfo ); } + AssertionHandler::~AssertionHandler() { + if ( m_inExceptionGuard ) { + handle( ResultWas::ThrewException, "Exception translation was disabled by CATCH_CONFIG_FAST_COMPILE" ); + getCurrentContext().getResultCapture()->exceptionEarlyReported(); + } + } void AssertionHandler::handle( ITransientExpression const& expr ) { @@ -125,4 +131,14 @@ namespace Catch { handle( ResultWas::ThrewException, Catch::translateActiveException().c_str() ); } + void AssertionHandler::setExceptionGuard() { + assert( m_inExceptionGuard == false ); + m_inExceptionGuard = true; + } + void AssertionHandler::unsetExceptionGuard() { + assert( m_inExceptionGuard == true ); + m_inExceptionGuard = false; + } + + } // namespace Catch diff --git a/include/internal/catch_assertionhandler.h b/include/internal/catch_assertionhandler.h index 18137448..dbbd5157 100644 --- a/include/internal/catch_assertionhandler.h +++ b/include/internal/catch_assertionhandler.h @@ -36,12 +36,15 @@ namespace Catch { AssertionInfo m_assertionInfo; bool m_shouldDebugBreak = false; bool m_shouldThrow = false; + bool m_inExceptionGuard = false; + public: AssertionHandler ( StringRef macroName, SourceLineInfo const& lineInfo, StringRef capturedExpression, ResultDisposition::Flags resultDisposition ); + ~AssertionHandler(); void handle( ITransientExpression const& expr ); @@ -60,6 +63,8 @@ namespace Catch { void reactWithoutDebugBreak() const; void useActiveException( ResultDisposition::Flags resultDisposition ); void useActiveException(); + void setExceptionGuard(); + void unsetExceptionGuard(); }; } // namespace Catch diff --git a/include/internal/catch_capture.hpp b/include/internal/catch_capture.hpp index 13101ec6..b13b9fe6 100644 --- a/include/internal/catch_capture.hpp +++ b/include/internal/catch_capture.hpp @@ -26,14 +26,17 @@ // macro in each assertion #define INTERNAL_CATCH_REACT( resultBuilder ) \ resultBuilder.react(); +#define INTERNAL_CATCH_REACT2( handler ) \ + handler.reactWithDebugBreak(); /////////////////////////////////////////////////////////////////////////////// // Another way to speed-up compilation is to omit local try-catch for REQUIRE* // macros. // This can potentially cause false negative, if the test code catches // the exception before it propagates back up to the runner. -#define INTERNAL_CATCH_TRY -#define INTERNAL_CATCH_CATCH( capturer, disposition ) +#define INTERNAL_CATCH_TRY( capturer ) capturer.setExceptionGuard(); +#define INTERNAL_CATCH_CATCH( capturer, disposition ) capturer.unsetExceptionGuard(); +#define INTERNAL_CATCH_CATCH2( capturer ) capturer.unsetExceptionGuard(); #else // CATCH_CONFIG_FAST_COMPILE @@ -47,9 +50,9 @@ resultBuilder.react(); #define INTERNAL_CATCH_REACT2( handler ) \ if( handler.shouldDebugBreak() ) CATCH_BREAK_INTO_DEBUGGER(); \ - handler.reactWithDebugBreak(); + handler.reactWithoutDebugBreak(); -#define INTERNAL_CATCH_TRY try +#define INTERNAL_CATCH_TRY( capturer ) try #define INTERNAL_CATCH_CATCH( capturer, disposition ) catch(...) { capturer.useActiveException( disposition ); } #define INTERNAL_CATCH_CATCH2( capturer ) catch(...) { capturer.useActiveException(); } @@ -59,7 +62,7 @@ #define INTERNAL_CATCH_TEST( macroName, resultDisposition, ... ) \ do { \ Catch::AssertionHandler catchAssertionHandler( macroName, CATCH_INTERNAL_LINEINFO, #__VA_ARGS__, resultDisposition ); \ - INTERNAL_CATCH_TRY { \ + INTERNAL_CATCH_TRY( catchAssertionHandler ) { \ CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS \ catchAssertionHandler.handle( Catch::Decomposer() <= __VA_ARGS__ ); \ CATCH_INTERNAL_UNSUPPRESS_PARENTHESES_WARNINGS \ @@ -147,7 +150,7 @@ #define INTERNAL_CHECK_THAT( macroName, matcher, resultDisposition, arg ) \ do { \ Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, #arg ", " #matcher, resultDisposition ); \ - INTERNAL_CATCH_TRY { \ + INTERNAL_CATCH_TRY( __catchResult ) { \ __catchResult.captureMatch( arg, matcher, #matcher ); \ } INTERNAL_CATCH_CATCH( __catchResult, resultDisposition ) \ INTERNAL_CATCH_REACT( __catchResult ) \