CATCH_CONFIG_FAST_COMPILE now disables trys in REQUIRE*
This seems to give about 15% speedup when compiling tests using GCC. The tradeoff is that under certain circumstances, there is a chance for false negative result, when the expression under test throws exception and the test code catches it before it gets to the test runner. Example: ``` cpp TEST_CASE("False negative") { try { REQUIRE(throws() == ""); } catch (...) {} } ``` This test case will succeed, reporting no assertions checked, instead of failing as it would with `CATCH_CONFIG_FAST_COMPILE` disabled. However, just removing the try-catch block inside client's code will fix this, so it is worthwhile. This change does not apply to CHECK* macros, because these are currently specified as continuing on exception and thus need the local try-catch to work as intended.
This commit is contained in:
parent
4dc06bdb70
commit
7a8a0205b4
@ -91,8 +91,13 @@ LeakDetector leakDetector;
|
||||
// If this config identifier is defined then all CATCH macros are prefixed with CATCH_
|
||||
#ifdef CATCH_CONFIG_PREFIX_ALL
|
||||
|
||||
#if defined(CATCH_CONFIG_FAST_COMPILE)
|
||||
#define CATCH_REQUIRE( expr ) INTERNAL_CATCH_TEST_NO_TRY( expr, Catch::ResultDisposition::Normal, "CATCH_REQUIRE" )
|
||||
#define CATCH_REQUIRE_FALSE( expr ) INTERNAL_CATCH_TEST_NO_TRY( expr, Catch::ResultDisposition::Normal | Catch::ResultDisposition::FalseTest, "CATCH_REQUIRE_FALSE" )
|
||||
#else
|
||||
#define CATCH_REQUIRE( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::Normal, "CATCH_REQUIRE" )
|
||||
#define CATCH_REQUIRE_FALSE( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::Normal | Catch::ResultDisposition::FalseTest, "CATCH_REQUIRE_FALSE" )
|
||||
#endif
|
||||
|
||||
#define CATCH_REQUIRE_THROWS( expr ) INTERNAL_CATCH_THROWS( expr, Catch::ResultDisposition::Normal, "", "CATCH_REQUIRE_THROWS" )
|
||||
#define CATCH_REQUIRE_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( expr, exceptionType, Catch::ResultDisposition::Normal, "CATCH_REQUIRE_THROWS_AS" )
|
||||
@ -111,7 +116,13 @@ LeakDetector leakDetector;
|
||||
#define CATCH_CHECK_NOTHROW( expr ) INTERNAL_CATCH_NO_THROW( expr, Catch::ResultDisposition::ContinueOnFailure, "CATCH_CHECK_NOTHROW" )
|
||||
|
||||
#define CATCH_CHECK_THAT( arg, matcher ) INTERNAL_CHECK_THAT( arg, matcher, Catch::ResultDisposition::ContinueOnFailure, "CATCH_CHECK_THAT" )
|
||||
|
||||
#if defined(CATCH_CONFIG_FAST_COMPILE)
|
||||
#define CATCH_REQUIRE_THAT( arg, matcher ) INTERNAL_CHECK_THAT_NO_TRY( arg, matcher, Catch::ResultDisposition::Normal, "CATCH_REQUIRE_THAT" )
|
||||
#else
|
||||
#define CATCH_REQUIRE_THAT( arg, matcher ) INTERNAL_CHECK_THAT( arg, matcher, Catch::ResultDisposition::Normal, "CATCH_REQUIRE_THAT" )
|
||||
#endif
|
||||
|
||||
|
||||
#define CATCH_INFO( msg ) INTERNAL_CATCH_INFO( msg, "CATCH_INFO" )
|
||||
#define CATCH_WARN( msg ) INTERNAL_CATCH_MSG( Catch::ResultWas::Warning, Catch::ResultDisposition::ContinueOnFailure, "CATCH_WARN", msg )
|
||||
@ -162,8 +173,14 @@ LeakDetector leakDetector;
|
||||
// If CATCH_CONFIG_PREFIX_ALL is not defined then the CATCH_ prefix is not required
|
||||
#else
|
||||
|
||||
#if defined(CATCH_CONFIG_FAST_COMPILE)
|
||||
#define REQUIRE( expr ) INTERNAL_CATCH_TEST_NO_TRY( expr, Catch::ResultDisposition::Normal, "REQUIRE" )
|
||||
#define REQUIRE_FALSE( expr ) INTERNAL_CATCH_TEST_NO_TRY( expr, Catch::ResultDisposition::Normal | Catch::ResultDisposition::FalseTest, "REQUIRE_FALSE" )
|
||||
|
||||
#else
|
||||
#define REQUIRE( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::Normal, "REQUIRE" )
|
||||
#define REQUIRE_FALSE( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::Normal | Catch::ResultDisposition::FalseTest, "REQUIRE_FALSE" )
|
||||
#endif
|
||||
|
||||
#define REQUIRE_THROWS( expr ) INTERNAL_CATCH_THROWS( expr, Catch::ResultDisposition::Normal, "", "REQUIRE_THROWS" )
|
||||
#define REQUIRE_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( expr, exceptionType, Catch::ResultDisposition::Normal, "REQUIRE_THROWS_AS" )
|
||||
@ -182,7 +199,13 @@ LeakDetector leakDetector;
|
||||
#define CHECK_NOTHROW( expr ) INTERNAL_CATCH_NO_THROW( expr, Catch::ResultDisposition::ContinueOnFailure, "CHECK_NOTHROW" )
|
||||
|
||||
#define CHECK_THAT( arg, matcher ) INTERNAL_CHECK_THAT( arg, matcher, Catch::ResultDisposition::ContinueOnFailure, "CHECK_THAT" )
|
||||
|
||||
#if defined(CATCH_CONFIG_FAST_COMPILE)
|
||||
#define REQUIRE_THAT( arg, matcher ) INTERNAL_CHECK_THAT_NO_TRY( arg, matcher, Catch::ResultDisposition::Normal, "REQUIRE_THAT" )
|
||||
#else
|
||||
#define REQUIRE_THAT( arg, matcher ) INTERNAL_CHECK_THAT( arg, matcher, Catch::ResultDisposition::Normal, "REQUIRE_THAT" )
|
||||
#endif
|
||||
|
||||
|
||||
#define INFO( msg ) INTERNAL_CATCH_INFO( msg, "INFO" )
|
||||
#define WARN( msg ) INTERNAL_CATCH_MSG( Catch::ResultWas::Warning, Catch::ResultDisposition::ContinueOnFailure, "WARN", msg )
|
||||
|
@ -26,6 +26,33 @@
|
||||
// macro in each assertion
|
||||
#define INTERNAL_CATCH_REACT( resultBuilder ) \
|
||||
resultBuilder.react();
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// 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_TEST_NO_TRY( expr, resultDisposition, macroName ) \
|
||||
do { \
|
||||
Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, #expr, resultDisposition ); \
|
||||
CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS \
|
||||
( __catchResult <= expr ).endExpression(); \
|
||||
CATCH_INTERNAL_UNSUPPRESS_PARENTHESES_WARNINGS \
|
||||
INTERNAL_CATCH_REACT( __catchResult ) \
|
||||
} while( Catch::isTrue( false && static_cast<bool>( !!(expr) ) ) ) // expr here is never evaluated at runtime but it forces the compiler to give it a look
|
||||
// The double negation silences MSVC's C4800 warning, the static_cast forces short-circuit evaluation if the type has overloaded &&.
|
||||
|
||||
#define INTERNAL_CHECK_THAT_NO_TRY( arg, matcher, resultDisposition, macroName ) \
|
||||
do { \
|
||||
Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, #arg ", " #matcher, resultDisposition ); \
|
||||
__catchResult.captureMatch( arg, matcher, #matcher ); \
|
||||
__catchResult.useActiveException( resultDisposition | Catch::ResultDisposition::ContinueOnFailure ); \
|
||||
INTERNAL_CATCH_REACT( __catchResult ) \
|
||||
} while( Catch::alwaysFalse() )
|
||||
|
||||
|
||||
#define INTERNAL_CATCH_
|
||||
|
||||
#else
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// In the event of a failure works out if the debugger needs to be invoked
|
||||
|
Loading…
Reference in New Issue
Block a user