diff --git a/AK/Assertions.cpp b/AK/Assertions.cpp index 9334a49ad57..e0bceefe9b5 100644 --- a/AK/Assertions.cpp +++ b/AK/Assertions.cpp @@ -96,6 +96,27 @@ void ak_verification_failed(char const* message) else ERRORLN("VERIFICATION FAILED: {}", message); +#if defined(AK_HAS_BACKTRACE_HEADER) + dump_backtrace(); +#endif + __builtin_trap(); +} + +void ak_assertion_failed(char const* message) +{ +#if defined(AK_OS_SERENITY) || defined(AK_OS_ANDROID) + bool colorize_output = true; +#elif defined(AK_OS_WINDOWS) + bool colorize_output = false; +#else + bool colorize_output = isatty(STDERR_FILENO) == 1; +#endif + + if (colorize_output) + ERRORLN("\033[31;1mASSERTION FAILED\033[0m: {}", message); + else + ERRORLN("ASSERTION FAILED: {}", message); + #if defined(AK_HAS_BACKTRACE_HEADER) dump_backtrace(); #endif diff --git a/AK/Assertions.h b/AK/Assertions.h index ba28c914b5e..7355fefeda9 100644 --- a/AK/Assertions.h +++ b/AK/Assertions.h @@ -20,3 +20,15 @@ static constexpr bool TODO = false; #define TODO_RISCV64() VERIFY(TODO) /* NOLINT(cert-dcl03-c,misc-static-assert) No, this can't be static_assert, it's a runtime check */ #define TODO_PPC64() VERIFY(TODO) /* NOLINT(cert-dcl03-c,misc-static-assert) No, this can't be static_assert, it's a runtime check */ #define TODO_PPC() VERIFY(TODO) /* NOLINT(cert-dcl03-c,misc-static-assert) No, this can't be static_assert, it's a runtime check */ + +#ifdef NDEBUG +extern "C" __attribute__((noreturn)) void ak_assertion_failed(char const*); +# define ASSERT(expr) \ + (__builtin_expect(!(expr), 0) \ + ? ak_assertion_failed(#expr " at " __FILE__ ":" __stringify(__LINE__)) \ + : (void)0) +# define ASSERT_NOT_REACHED ASSERT(false) /* NOLINT(cert-dcl03-c,misc-static-assert) No, this can't be static_assert, it's a runtime check */ +#else +# define ASSERT(expr) +# define ASSERT_NOT_REACHED() __builtin_unreachable() +#endif