Update Catch to v1.12.2 with latest bugfixes
It solves compilation errors with GCC 11.3 on Ubuntu 22.04
This commit is contained in:
parent
253a4abad4
commit
37db7a83f3
247
extlibs/headers/catch.hpp
vendored
247
extlibs/headers/catch.hpp
vendored
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Catch v1.12.2
|
||||
* Generated: 2018-05-14 15:10:01.112442
|
||||
* Generated: 2022-12-21 23:22:34.433382
|
||||
* ----------------------------------------------------------
|
||||
* 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\nsc\nnop\nli r0, 37\nli r4, 2\nsc\nnop\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,9 +6395,12 @@ 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
|
||||
//! Signals fatal error message to the run context
|
||||
inline void reportFatal( std::string const& message ) {
|
||||
IContext& context = Catch::getCurrentContext();
|
||||
IResultCapture* resultCapture = context.getResultCapture();
|
||||
@ -6432,8 +6438,31 @@ namespace Catch {
|
||||
# if !defined ( CATCH_CONFIG_WINDOWS_SEH )
|
||||
|
||||
namespace Catch {
|
||||
struct FatalConditionHandler {
|
||||
void reset() {}
|
||||
class FatalConditionHandler {
|
||||
bool m_started = 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() {}
|
||||
void disengage_platform() {}
|
||||
|
||||
public:
|
||||
// Should also have platform-specific implementations as needed
|
||||
FatalConditionHandler() {}
|
||||
~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();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@ -6453,8 +6482,6 @@ namespace Catch {
|
||||
{ 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) {
|
||||
@ -6466,41 +6493,62 @@ namespace Catch {
|
||||
return EXCEPTION_CONTINUE_SEARCH;
|
||||
}
|
||||
|
||||
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;
|
||||
// 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;
|
||||
|
||||
class FatalConditionHandler {
|
||||
bool m_started = 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() {
|
||||
// Register as first handler in current chain
|
||||
exceptionHandlerHandle = AddVectoredExceptionHandler(1, handleVectoredException);
|
||||
// Pass in guarantee size to be filled
|
||||
SetThreadStackGuarantee(&guaranteeSize);
|
||||
if (!exceptionHandlerHandle) {
|
||||
throw std::runtime_error("Could not register vectored exception handler");
|
||||
}
|
||||
}
|
||||
|
||||
static void reset() {
|
||||
if (isSet) {
|
||||
// Unregister handler and restore the old guarantee
|
||||
RemoveVectoredExceptionHandler(exceptionHandlerHandle);
|
||||
SetThreadStackGuarantee(&guaranteeSize);
|
||||
void disengage_platform() {
|
||||
if (!RemoveVectoredExceptionHandler(exceptionHandlerHandle)) {
|
||||
throw std::runtime_error("Could not unregister vectored exception handler");
|
||||
}
|
||||
exceptionHandlerHandle = CATCH_NULL;
|
||||
isSet = false;
|
||||
}
|
||||
|
||||
public:
|
||||
FatalConditionHandler() {
|
||||
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.";
|
||||
}
|
||||
}
|
||||
|
||||
~FatalConditionHandler() {
|
||||
reset();
|
||||
// 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();
|
||||
}
|
||||
private:
|
||||
static bool isSet;
|
||||
static ULONG guaranteeSize;
|
||||
static PVOID exceptionHandlerHandle;
|
||||
};
|
||||
|
||||
bool FatalConditionHandler::isSet = false;
|
||||
ULONG FatalConditionHandler::guaranteeSize = 0;
|
||||
PVOID FatalConditionHandler::exceptionHandlerHandle = CATCH_NULL;
|
||||
|
||||
} // namespace Catch
|
||||
|
||||
# endif // CATCH_CONFIG_WINDOWS_SEH
|
||||
@ -6510,8 +6558,31 @@ namespace Catch {
|
||||
# if !defined(CATCH_CONFIG_POSIX_SIGNALS)
|
||||
|
||||
namespace Catch {
|
||||
struct FatalConditionHandler {
|
||||
void reset() {}
|
||||
class FatalConditionHandler {
|
||||
bool m_started = 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() {}
|
||||
void disengage_platform() {}
|
||||
|
||||
public:
|
||||
// Should also have platform-specific implementations as needed
|
||||
FatalConditionHandler() {}
|
||||
~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();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@ -6535,15 +6606,33 @@ namespace Catch {
|
||||
{ SIGABRT, "SIGABRT - Abort (abnormal termination) signal" }
|
||||
};
|
||||
|
||||
struct FatalConditionHandler {
|
||||
// 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 bool isSet;
|
||||
static struct sigaction oldSigActions [sizeof(signalDefs)/sizeof(SignalDefs)];
|
||||
static char* altStackMem = CATCH_NULL;
|
||||
static std::size_t altStackSize = 0;
|
||||
static stack_t oldSigStack;
|
||||
static char altStackMem[SIGSTKSZ];
|
||||
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);
|
||||
}
|
||||
|
||||
static void handleSignal( int sig ) {
|
||||
std::string name = "<unknown signal>";
|
||||
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) {
|
||||
@ -6551,13 +6640,22 @@ namespace Catch {
|
||||
break;
|
||||
}
|
||||
}
|
||||
reset();
|
||||
reportFatal(name);
|
||||
// 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 );
|
||||
}
|
||||
|
||||
FatalConditionHandler() {
|
||||
isSet = true;
|
||||
class FatalConditionHandler {
|
||||
bool m_started = 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;
|
||||
@ -6572,26 +6670,42 @@ namespace Catch {
|
||||
}
|
||||
}
|
||||
|
||||
void disengage_platform() {
|
||||
restorePreviousSignalHandlers();
|
||||
}
|
||||
|
||||
public:
|
||||
FatalConditionHandler() {
|
||||
assert(!altStackMem && "Cannot initialize POSIX signal handler when one already exists");
|
||||
if (altStackSize == 0) {
|
||||
altStackSize = SIGSTKSZ;
|
||||
}
|
||||
altStackMem = new char[altStackSize]();
|
||||
}
|
||||
|
||||
~FatalConditionHandler() {
|
||||
reset();
|
||||
delete[] altStackMem;
|
||||
// We signal that another instance can be constructed by zeroing
|
||||
// out the pointer.
|
||||
altStackMem = CATCH_NULL;
|
||||
}
|
||||
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;
|
||||
|
||||
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();
|
||||
}
|
||||
};
|
||||
|
||||
bool FatalConditionHandler::isSet = false;
|
||||
struct sigaction FatalConditionHandler::oldSigActions[sizeof(signalDefs)/sizeof(SignalDefs)] = {};
|
||||
stack_t FatalConditionHandler::oldSigStack = {};
|
||||
char FatalConditionHandler::altStackMem[SIGSTKSZ] = {};
|
||||
#if defined(__GNUC__)
|
||||
# pragma GCC diagnostic pop
|
||||
#endif
|
||||
|
||||
} // namespace Catch
|
||||
|
||||
@ -6599,6 +6713,23 @@ namespace Catch {
|
||||
|
||||
#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 +7069,8 @@ namespace Catch {
|
||||
}
|
||||
|
||||
void invokeActiveTestCase() {
|
||||
FatalConditionHandler fatalConditionHandler; // Handle signals
|
||||
FatalConditionHandlerGuard _(&m_fatalConditionhandler);
|
||||
m_activeTestCase->invoke();
|
||||
fatalConditionHandler.reset();
|
||||
}
|
||||
|
||||
private:
|
||||
@ -6978,6 +7108,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;
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user