Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions src/catch2/internal/catch_result_type.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,9 @@ namespace Catch {
constexpr bool isFalseTest( int flags ) {
return ( flags & ResultDisposition::FalseTest ) != 0;
}
constexpr bool shouldTerminateOnFailure( int flags ) {
return ( flags & ResultDisposition::Normal ) != 0;
}
constexpr bool shouldSuppressFailure( int flags ) {
return ( flags & ResultDisposition::SuppressFail ) != 0;
}
Expand Down
108 changes: 108 additions & 0 deletions src/catch2/internal/catch_test_macro_impl.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,12 @@

#include <catch2/catch_user_config.hpp>
#include <catch2/internal/catch_assertion_handler.hpp>
#include <catch2/internal/catch_config_static_analysis_support.hpp>
#include <catch2/internal/catch_preprocessor_internal_stringify.hpp>
#include <catch2/internal/catch_result_type.hpp>
#include <catch2/internal/catch_stringref.hpp>
#include <catch2/internal/catch_source_line_info.hpp>
#include <catch2/internal/catch_unreachable.hpp>

namespace Catch {
namespace Detail {
Expand Down Expand Up @@ -44,6 +47,8 @@ namespace Catch {

#endif

#if !defined( CATCH_CONFIG_EXPERIMENTAL_STATIC_ANALYSIS_SUPPORT )

///////////////////////////////////////////////////////////////////////////////
#define INTERNAL_CATCH_TEST( macroName, resultDisposition, ... ) \
do { /* NOLINT(bugprone-infinite-loop) */ \
Expand All @@ -60,6 +65,25 @@ namespace Catch {
} while( (void)0, (false) && static_cast<const bool&>( !!(__VA_ARGS__) ) ) // the expression 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 &&.

#else // ^^ !CATCH_CONFIG_EXPERIMENTAL_STATIC_ANALYSIS_SUPPORT | vv CATCH_CONFIG_EXPERIMENTAL_STATIC_ANALYSIS_SUPPORT

///////////////////////////////////////////////////////////////////////////////
# define INTERNAL_CATCH_TEST( macroName, resultDisposition, ... ) \
do { \
const bool catchInternalAssertionResult = static_cast<bool>( __VA_ARGS__ ); \
if ( Catch::shouldTerminateOnFailure( resultDisposition ) ) { \
if ( Catch::isFalseTest( resultDisposition ) ) { \
if ( catchInternalAssertionResult ) { Catch::Detail::Unreachable(); } \
} else { \
if ( !catchInternalAssertionResult ) { Catch::Detail::Unreachable(); } \
} \
} \
} while ( false )

#endif // CATCH_CONFIG_EXPERIMENTAL_STATIC_ANALYSIS_SUPPORT

#if !defined( CATCH_CONFIG_EXPERIMENTAL_STATIC_ANALYSIS_SUPPORT )

///////////////////////////////////////////////////////////////////////////////
#define INTERNAL_CATCH_IF( macroName, resultDisposition, ... ) \
INTERNAL_CATCH_TEST( macroName, resultDisposition, __VA_ARGS__ ); \
Expand All @@ -70,6 +94,20 @@ namespace Catch {
INTERNAL_CATCH_TEST( macroName, resultDisposition, __VA_ARGS__ ); \
if( !Catch::Detail::lastAssertionPassed() )

#else // ^^ !CATCH_CONFIG_EXPERIMENTAL_STATIC_ANALYSIS_SUPPORT | vv CATCH_CONFIG_EXPERIMENTAL_STATIC_ANALYSIS_SUPPORT

///////////////////////////////////////////////////////////////////////////////
# define INTERNAL_CATCH_IF( macroName, resultDisposition, ... ) \
if ( __VA_ARGS__ )

///////////////////////////////////////////////////////////////////////////////
# define INTERNAL_CATCH_ELSE( macroName, resultDisposition, ... ) \
if ( !( __VA_ARGS__ ) )

#endif // CATCH_CONFIG_EXPERIMENTAL_STATIC_ANALYSIS_SUPPORT

#if !defined( CATCH_CONFIG_EXPERIMENTAL_STATIC_ANALYSIS_SUPPORT )

///////////////////////////////////////////////////////////////////////////////
#define INTERNAL_CATCH_NO_THROW( macroName, resultDisposition, ... ) \
do { \
Expand All @@ -87,6 +125,27 @@ namespace Catch {
catchAssertionHandler.complete(); \
} while( false )

#else // ^^ !CATCH_CONFIG_EXPERIMENTAL_STATIC_ANALYSIS_SUPPORT | vv CATCH_CONFIG_EXPERIMENTAL_STATIC_ANALYSIS_SUPPORT

///////////////////////////////////////////////////////////////////////////////
# define INTERNAL_CATCH_NO_THROW( macroName, resultDisposition, ... ) \
do { \
try { \
CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
CATCH_INTERNAL_SUPPRESS_USELESS_CAST_WARNINGS \
static_cast<void>(__VA_ARGS__); \
CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \
} catch ( ... ) { \
if ( Catch::shouldTerminateOnFailure( resultDisposition ) ) { \
Catch::Detail::Unreachable(); \
} \
} \
} while ( false )

#endif // CATCH_CONFIG_EXPERIMENTAL_STATIC_ANALYSIS_SUPPORT

#if !defined( CATCH_CONFIG_EXPERIMENTAL_STATIC_ANALYSIS_SUPPORT )

///////////////////////////////////////////////////////////////////////////////
#define INTERNAL_CATCH_THROWS( macroName, resultDisposition, ... ) \
do { \
Expand All @@ -108,6 +167,31 @@ namespace Catch {
catchAssertionHandler.complete(); \
} while( false )

#else // ^^ !CATCH_CONFIG_EXPERIMENTAL_STATIC_ANALYSIS_SUPPORT | vv CATCH_CONFIG_EXPERIMENTAL_STATIC_ANALYSIS_SUPPORT

///////////////////////////////////////////////////////////////////////////////
# define INTERNAL_CATCH_THROWS( macroName, resultDisposition, ... ) \
do { \
bool catchInternalThrew = false; \
try { \
CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
CATCH_INTERNAL_SUPPRESS_UNUSED_RESULT \
CATCH_INTERNAL_SUPPRESS_USELESS_CAST_WARNINGS \
static_cast<void>(__VA_ARGS__); \
CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \
} catch ( ... ) { \
catchInternalThrew = true; \
} \
if ( !catchInternalThrew && \
Catch::shouldTerminateOnFailure( resultDisposition ) ) { \
Catch::Detail::Unreachable(); \
} \
} while ( false )

#endif // CATCH_CONFIG_EXPERIMENTAL_STATIC_ANALYSIS_SUPPORT

#if !defined( CATCH_CONFIG_EXPERIMENTAL_STATIC_ANALYSIS_SUPPORT )

///////////////////////////////////////////////////////////////////////////////
#define INTERNAL_CATCH_THROWS_AS( macroName, exceptionType, resultDisposition, expr ) \
do { \
Expand All @@ -132,6 +216,30 @@ namespace Catch {
catchAssertionHandler.complete(); \
} while( false )

#else // ^^ !CATCH_CONFIG_EXPERIMENTAL_STATIC_ANALYSIS_SUPPORT | vv CATCH_CONFIG_EXPERIMENTAL_STATIC_ANALYSIS_SUPPORT

///////////////////////////////////////////////////////////////////////////////
# define INTERNAL_CATCH_THROWS_AS( macroName, exceptionType, resultDisposition, expr ) \
do { \
bool catchInternalCaughtExpected = false; \
try { \
CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
CATCH_INTERNAL_SUPPRESS_UNUSED_RESULT \
CATCH_INTERNAL_SUPPRESS_USELESS_CAST_WARNINGS \
static_cast<void>(expr); \
CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \
} catch ( exceptionType const& ) { \
catchInternalCaughtExpected = true; \
} catch ( ... ) { \
} \
if ( !catchInternalCaughtExpected && \
Catch::shouldTerminateOnFailure( resultDisposition ) ) { \
Catch::Detail::Unreachable(); \
} \
} while ( false )

#endif // CATCH_CONFIG_EXPERIMENTAL_STATIC_ANALYSIS_SUPPORT



///////////////////////////////////////////////////////////////////////////////
Expand Down