@ -1,6 +1,6 @@
/*
* Catch v1 .12 .2
* Generated : 2018 - 05 - 14 15 : 10 : 01.112442
* Generated : 2023 - 01 - 17 08 : 45 : 40.979381
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
* This file has been merged from multiple headers . Please don ' t edit it directly
* Copyright ( c ) 2012 Two Blue Cubes Ltd . All rights reserved .
@ -214,7 +214,7 @@
////////////////////////////////////////////////////////////////////////////////
// Use variadic macros if the compiler supports them
# if ( defined _MSC_VER && _MSC_VER > 1400 && !defined __EDGE__) || \
# if ( defined _MSC_VER && _MSC_VER >= 1400 && !defined __EDGE__) || \
( defined __WAVE__ & & __WAVE_HAS_VARIADICS ) | | \
( defined __GNUC__ & & __GNUC__ > = 3 ) | | \
( ! defined __cplusplus & & __STDC_VERSION__ > = 199901L | | __cplusplus > = 201103L )
@ -2129,6 +2129,9 @@ namespace Catch{
# define CATCH_TRAP() \
__asm__ ( " li r0, 20 \n sc \n nop \n li r0, 37 \n li r4, 2 \n sc \n nop \n " \
: : : " memory " , " r0 " , " r3 " , " r4 " ) /* NOLINT */
# elif defined(__aarch64__)
// Backport of https://github.com/catchorg/Catch2/commit/a25c1a24af8bffd35727a888a307ff0280cf9387
# define CATCH_TRAP() __asm__(".inst 0xd4200000")
# else
# define CATCH_TRAP() __asm__("int $3\n" : : /* NOLINT */ )
# endif
@ -6392,18 +6395,21 @@ CATCH_INTERNAL_UNSUPPRESS_ETD_WARNINGS
// #included from: catch_fatal_condition.hpp
# define TWOBLUECUBES_CATCH_FATAL_CONDITION_H_INCLUDED
# include <cassert>
# include <stdexcept>
namespace Catch {
// Report the error condition
inline void reportFatal ( std : : string const & message ) {
IContext & context = Catch : : getCurrentContext ( ) ;
IResultCapture * resultCapture = context . getResultCapture ( ) ;
resultCapture - > handleFatalErrorCondition ( message ) ;
}
//! Signals fatal error message to the run context
inline void reportFatal ( std : : string const & message ) {
IContext & context = Catch : : getCurrentContext ( ) ;
IResultCapture * resultCapture = context . getResultCapture ( ) ;
resultCapture - > handleFatalErrorCondition ( message ) ;
}
} // namespace Catch
# if defined ( CATCH_PLATFORM_WINDOWS ) /////////////////////////////////////////
# if defined(CATCH_PLATFORM_WINDOWS) /////////////////////////////////////////
// #included from: catch_windows_h_proxy.h
# define TWOBLUECUBES_CATCH_WINDOWS_H_PROXY_H_INCLUDED
@ -6429,176 +6435,307 @@ namespace Catch {
# endif
# if !defined ( CATCH_CONFIG_WINDOWS_SEH )
# if !defined(CATCH_CONFIG_WINDOWS_SEH)
namespace Catch {
struct FatalConditionHandler {
void reset ( ) { }
} ;
}
class FatalConditionHandler {
bool m_started ;
// Install/disengage implementation for specific platform.
// Should be if-defed to work on current platform, can assume
// engage-disengage 1:1 pairing.
void engage_platform ( ) { }
void disengage_platform ( ) { }
public :
// Should also have platform-specific implementations as needed
FatalConditionHandler ( ) : m_started ( false ) { }
~ FatalConditionHandler ( ) { }
void engage ( ) {
assert ( ! m_started & & " Handler cannot be installed twice. " ) ;
m_started = true ;
engage_platform ( ) ;
}
void disengage ( ) {
assert ( m_started & &
" Handler cannot be uninstalled without being installed first " ) ;
m_started = false ;
disengage_platform ( ) ;
}
} ;
} // namespace Catch
# else // CATCH_CONFIG_WINDOWS_SEH is defined
# else // CATCH_CONFIG_WINDOWS_SEH is defined
namespace Catch {
struct SignalDefs { DWORD id ; const char * name ; } ;
extern SignalDefs signalDefs [ ] ;
// There is no 1-1 mapping between signals and windows exceptions.
// Windows can easily distinguish between SO and SigSegV,
// but SigInt, SigTerm, etc are handled differently.
SignalDefs signalDefs [ ] = {
{ EXCEPTION_ILLEGAL_INSTRUCTION , " SIGILL - Illegal instruction signal " } ,
{ EXCEPTION_STACK_OVERFLOW , " SIGSEGV - Stack overflow " } ,
{ EXCEPTION_ACCESS_VIOLATION , " SIGSEGV - Segmentation violation signal " } ,
{ EXCEPTION_INT_DIVIDE_BY_ZERO , " Divide by zero error " } ,
} ;
struct SignalDefs {
DWORD id ;
const char * name ;
} ;
extern SignalDefs signalDefs [ ] ;
// There is no 1-1 mapping between signals and windows exceptions.
// Windows can easily distinguish between SO and SigSegV,
// but SigInt, SigTerm, etc are handled differently.
SignalDefs signalDefs [ ] = {
{ EXCEPTION_ILLEGAL_INSTRUCTION , " SIGILL - Illegal instruction signal " } ,
{ EXCEPTION_STACK_OVERFLOW , " SIGSEGV - Stack overflow " } ,
{ EXCEPTION_ACCESS_VIOLATION , " SIGSEGV - Segmentation violation signal " } ,
{ EXCEPTION_INT_DIVIDE_BY_ZERO , " Divide by zero error " } ,
} ;
struct FatalConditionHandler {
static LONG CALLBACK
handleVectoredException ( PEXCEPTION_POINTERS ExceptionInfo ) {
for ( int i = 0 ; i < sizeof ( signalDefs ) / sizeof ( SignalDefs ) ; + + i ) {
if ( ExceptionInfo - > ExceptionRecord - > ExceptionCode = = signalDefs [ i ] . id ) {
reportFatal ( signalDefs [ i ] . name ) ;
}
}
// If its not an exception we care about, pass it along.
// This stops us from eating debugger breaks etc.
return EXCEPTION_CONTINUE_SEARCH ;
}
static LONG CALLBACK handleVectoredException ( PEXCEPTION_POINTERS ExceptionInfo ) {
for ( int i = 0 ; i < sizeof ( signalDefs ) / sizeof ( SignalDefs ) ; + + i ) {
if ( ExceptionInfo - > ExceptionRecord - > ExceptionCode = = signalDefs [ i ] . id ) {
reportFatal ( signalDefs [ i ] . name ) ;
}
}
// If its not an exception we care about, pass it along.
// This stops us from eating debugger breaks etc.
return EXCEPTION_CONTINUE_SEARCH ;
}
// Since we do not support multiple instantiations, we put these
// into global variables and rely on cleaning them up in outlined
// constructors/destructors
static PVOID exceptionHandlerHandle = CATCH_NULL ;
FatalConditionHandler ( ) {
isSet = true ;
// 32k seems enough for Catch to handle stack overflow,
// but the value was found experimentally, so there is no strong guarantee
guaranteeSize = 32 * 1024 ;
exceptionHandlerHandle = CATCH_NULL ;
// Register as first handler in current chain
exceptionHandlerHandle = AddVectoredExceptionHandler ( 1 , handleVectoredException ) ;
// Pass in guarantee size to be filled
SetThreadStackGuarantee ( & guaranteeSize ) ;
}
class FatalConditionHandler {
bool m_started ;
static void reset ( ) {
if ( isSet ) {
// Unregister handler and restore the old guarantee
RemoveVectoredExceptionHandler ( exceptionHandlerHandle ) ;
SetThreadStackGuarantee ( & guaranteeSize ) ;
exceptionHandlerHandle = CATCH_NULL ;
isSet = false ;
}
}
// Install/disengage implementation for specific platform.
// Should be if-defed to work on current platform, can assume
// engage-disengage 1:1 pairing.
~ FatalConditionHandler ( ) {
reset ( ) ;
}
private :
static bool isSet ;
static ULONG guaranteeSize ;
static PVOID exceptionHandlerHandle ;
} ;
void engage_platform ( ) {
// Register as first handler in current chain
exceptionHandlerHandle =
AddVectoredExceptionHandler ( 1 , handleVectoredException ) ;
if ( ! exceptionHandlerHandle ) {
throw std : : runtime_error ( " Could not register vectored exception handler " ) ;
}
}
void disengage_platform ( ) {
if ( ! RemoveVectoredExceptionHandler ( exceptionHandlerHandle ) ) {
throw std : : runtime_error (
" Could not unregister vectored exception handler " ) ;
}
exceptionHandlerHandle = CATCH_NULL ;
}
bool FatalConditionHandler : : isSet = false ;
ULONG FatalConditionHandler : : guaranteeSize = 0 ;
PVOID FatalConditionHandler : : exceptionHandlerHandle = CATCH_NULL ;
public :
FatalConditionHandler ( ) : m_started ( false ) {
ULONG guaranteeSize = static_cast < ULONG > ( 32 * 1024 ) ;
if ( ! SetThreadStackGuarantee ( & guaranteeSize ) ) {
// We do not want to fully error out, because needing
// the stack reserve should be rare enough anyway.
Catch : : cerr ( ) < < " Failed to reserve piece of stack. "
< < " Stack overflows will not be reported successfully. " ;
}
}
// We do not attempt to unset the stack guarantee, because
// Windows does not support lowering the stack size guarantee.
~ FatalConditionHandler ( ) { }
void engage ( ) {
assert ( ! m_started & & " Handler cannot be installed twice. " ) ;
m_started = true ;
engage_platform ( ) ;
}
void disengage ( ) {
assert ( m_started & &
" Handler cannot be uninstalled without being installed first " ) ;
m_started = false ;
disengage_platform ( ) ;
}
} ;
} // namespace Catch
# endif // CATCH_CONFIG_WINDOWS_SEH
# endif // CATCH_CONFIG_WINDOWS_SEH
# else // Not Windows - assumed to be POSIX compatible //////////////////////////
# if !defined(CATCH_CONFIG_POSIX_SIGNALS)
# if !defined(CATCH_CONFIG_POSIX_SIGNALS)
namespace Catch {
struct FatalConditionHandler {
void reset ( ) { }
} ;
}
class FatalConditionHandler {
bool m_started ;
# else // CATCH_CONFIG_POSIX_SIGNALS is defined
// Install/disengage implementation for specific platform.
// Should be if-defed to work on current platform, can assume
// engage-disengage 1:1 pairing.
void engage_platform ( ) { }
void disengage_platform ( ) { }
public :
// Should also have platform-specific implementations as needed
FatalConditionHandler ( ) : m_started ( false ) { }
~ FatalConditionHandler ( ) { }
void engage ( ) {
assert ( ! m_started & & " Handler cannot be installed twice. " ) ;
m_started = true ;
engage_platform ( ) ;
}
void disengage ( ) {
assert ( m_started & &
" Handler cannot be uninstalled without being installed first " ) ;
m_started = false ;
disengage_platform ( ) ;
}
} ;
} // namespace Catch
# else // CATCH_CONFIG_POSIX_SIGNALS is defined
# include <signal.h>
namespace Catch {
struct SignalDefs {
int id ;
const char * name ;
} ;
extern SignalDefs signalDefs [ ] ;
SignalDefs signalDefs [ ] = {
{ SIGINT , " SIGINT - Terminal interrupt signal " } ,
{ SIGILL , " SIGILL - Illegal instruction signal " } ,
{ SIGFPE , " SIGFPE - Floating point error signal " } ,
{ SIGSEGV , " SIGSEGV - Segmentation violation signal " } ,
{ SIGTERM , " SIGTERM - Termination request signal " } ,
{ SIGABRT , " SIGABRT - Abort (abnormal termination) signal " }
} ;
struct FatalConditionHandler {
static bool isSet ;
static struct sigaction oldSigActions [ sizeof ( signalDefs ) / sizeof ( SignalDefs ) ] ;
static stack_t oldSigStack ;
static char altStackMem [ SIGSTKSZ ] ;
static void handleSignal ( int sig ) {
std : : string name = " <unknown signal> " ;
for ( std : : size_t i = 0 ; i < sizeof ( signalDefs ) / sizeof ( SignalDefs ) ; + + i ) {
SignalDefs & def = signalDefs [ i ] ;
if ( sig = = def . id ) {
name = def . name ;
break ;
}
}
reset ( ) ;
reportFatal ( name ) ;
raise ( sig ) ;
}
struct SignalDefs {
int id ;
const char * name ;
} ;
extern SignalDefs signalDefs [ ] ;
SignalDefs signalDefs [ ] = {
{ SIGINT , " SIGINT - Terminal interrupt signal " } ,
{ SIGILL , " SIGILL - Illegal instruction signal " } ,
{ SIGFPE , " SIGFPE - Floating point error signal " } ,
{ SIGSEGV , " SIGSEGV - Segmentation violation signal " } ,
{ SIGTERM , " SIGTERM - Termination request signal " } ,
{ SIGABRT , " SIGABRT - Abort (abnormal termination) signal " } } ;
// Older GCCs trigger -Wmissing-field-initializers for T foo = {}
// which is zero initialization, but not explicit. We want to avoid
// that.
# if defined(__GNUC__)
# pragma GCC diagnostic push
# pragma GCC diagnostic ignored "-Wmissing-field-initializers"
# endif
static char * altStackMem = CATCH_NULL ;
static std : : size_t altStackSize = 0 ;
static stack_t oldSigStack ;
static struct sigaction oldSigActions [ sizeof ( signalDefs ) / sizeof ( SignalDefs ) ] ;
static void restorePreviousSignalHandlers ( ) {
// We set signal handlers back to the previous ones. Hopefully
// nobody overwrote them in the meantime, and doesn't expect
// their signal handlers to live past ours given that they
// installed them after ours..
for ( std : : size_t i = 0 ; i < sizeof ( signalDefs ) / sizeof ( SignalDefs ) ; + + i ) {
sigaction ( signalDefs [ i ] . id , & oldSigActions [ i ] , CATCH_NULL ) ;
}
// Return the old stack
sigaltstack ( & oldSigStack , CATCH_NULL ) ;
}
FatalConditionHandler ( ) {
isSet = true ;
stack_t sigStack ;
sigStack . ss_sp = altStackMem ;
sigStack . ss_size = SIGSTKSZ ;
sigStack . ss_flags = 0 ;
sigaltstack ( & sigStack , & oldSigStack ) ;
struct sigaction sa = { 0 } ;
static void handleSignal ( int sig ) {
char const * name = " <unknown signal> " ;
for ( std : : size_t i = 0 ; i < sizeof ( signalDefs ) / sizeof ( SignalDefs ) ; + + i ) {
SignalDefs & def = signalDefs [ i ] ;
if ( sig = = def . id ) {
name = def . name ;
break ;
}
}
// We need to restore previous signal handlers and let them do
// their thing, so that the users can have the debugger break
// when a signal is raised, and so on.
restorePreviousSignalHandlers ( ) ;
reportFatal ( name ) ;
raise ( sig ) ;
}
sa . sa_handler = handleSignal ;
sa . sa_flags = SA_ONSTACK ;
for ( std : : size_t i = 0 ; i < sizeof ( signalDefs ) / sizeof ( SignalDefs ) ; + + i ) {
sigaction ( signalDefs [ i ] . id , & sa , & oldSigActions [ i ] ) ;
}
}
class FatalConditionHandler {
bool m_started ;
~ FatalConditionHandler ( ) {
reset ( ) ;
}
static void reset ( ) {
if ( isSet ) {
// Set signals back to previous values -- hopefully nobody overwrote them in the meantime
for ( std : : size_t i = 0 ; i < sizeof ( signalDefs ) / sizeof ( SignalDefs ) ; + + i ) {
sigaction ( signalDefs [ i ] . id , & oldSigActions [ i ] , CATCH_NULL ) ;
}
// Return the old stack
sigaltstack ( & oldSigStack , CATCH_NULL ) ;
isSet = false ;
}
}
} ;
// Install/disengage implementation for specific platform.
// Should be if-defed to work on current platform, can assume
// engage-disengage 1:1 pairing.
void engage_platform ( ) {
stack_t sigStack ;
sigStack . ss_sp = altStackMem ;
sigStack . ss_size = SIGSTKSZ ;
sigStack . ss_flags = 0 ;
sigaltstack ( & sigStack , & oldSigStack ) ;
struct sigaction sa = { 0 } ;
sa . sa_handler = handleSignal ;
sa . sa_flags = SA_ONSTACK ;
for ( std : : size_t i = 0 ; i < sizeof ( signalDefs ) / sizeof ( SignalDefs ) ; + + i ) {
sigaction ( signalDefs [ i ] . id , & sa , & oldSigActions [ i ] ) ;
}
}
void disengage_platform ( ) { restorePreviousSignalHandlers ( ) ; }
bool FatalConditionHandler : : isSet = false ;
struct sigaction FatalConditionHandler : : oldSigActions [ sizeof ( signalDefs ) / sizeof ( SignalDefs ) ] = { } ;
stack_t FatalConditionHandler : : oldSigStack = { } ;
char FatalConditionHandler : : altStackMem [ SIGSTKSZ ] = { } ;
public :
FatalConditionHandler ( ) : m_started ( false ) {
assert ( ! altStackMem & &
" Cannot initialize POSIX signal handler when one already exists " ) ;
if ( altStackSize = = 0 ) {
altStackSize = SIGSTKSZ ;
}
altStackMem = new char [ altStackSize ] ( ) ;
}
~ FatalConditionHandler ( ) {
delete [ ] altStackMem ;
// We signal that another instance can be constructed by zeroing
// out the pointer.
altStackMem = CATCH_NULL ;
}
void engage ( ) {
assert ( ! m_started & & " Handler cannot be installed twice. " ) ;
m_started = true ;
engage_platform ( ) ;
}
void disengage ( ) {
assert ( m_started & &
" Handler cannot be uninstalled without being installed first " ) ;
m_started = false ;
disengage_platform ( ) ;
}
} ;
# if defined(__GNUC__)
# pragma GCC diagnostic pop
# endif
} // namespace Catch
# endif // CATCH_CONFIG_POSIX_SIGNALS
# endif // CATCH_CONFIG_POSIX_SIGNALS
# endif // not Windows
namespace Catch {
//! Simple RAII guard for (dis)engaging the FatalConditionHandler
class FatalConditionHandlerGuard {
FatalConditionHandler * m_handler ;
public :
FatalConditionHandlerGuard ( FatalConditionHandler * handler )
: m_handler ( handler ) {
m_handler - > engage ( ) ;
}
~ FatalConditionHandlerGuard ( ) { m_handler - > disengage ( ) ; }
} ;
} // end namespace Catch
# include <cassert>
# include <set>
# include <string>
@ -6938,9 +7075,8 @@ namespace Catch {
}
void invokeActiveTestCase ( ) {
FatalConditionHandler fatalConditionHandler ; // Handle signals
FatalConditionHandlerGuard _ ( & m_fatalConditionhandler ) ;
m_activeTestCase - > invoke ( ) ;
fatalConditionHandler . reset ( ) ;
}
private :
@ -6978,6 +7114,7 @@ namespace Catch {
std : : vector < SectionEndInfo > m_unfinishedSections ;
std : : vector < ITracker * > m_activeSections ;
TrackerContext m_trackerContext ;
FatalConditionHandler m_fatalConditionhandler ;
size_t m_prevPassed ;
bool m_shouldReportUnexpected ;
} ;