yassert.h 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. #pragma once
  2. #include "defaults.h"
  3. #include "src_root.h"
  4. #include "backtrace.h"
  5. #if defined(_MSC_VER)
  6. #include <new>
  7. #if defined(_DEBUG)
  8. #if defined(_CRTDBG_MAP_ALLOC)
  9. #include <cstdlib> /* definitions for malloc/calloc */
  10. #include <malloc.h> /* must be before their redefinitions as _*_dbg() */
  11. #endif
  12. #include <crtdbg.h>
  13. #else
  14. #endif
  15. #include <cassert>
  16. #elif defined(__GNUC__)
  17. #ifdef _sun_
  18. #include <alloca.h>
  19. #endif
  20. #include <cassert>
  21. #endif
  22. #if !defined(_MSC_VER)
  23. #if defined(__has_builtin) && __has_builtin(__debugbreak)
  24. // Do nothing, use __debugbreak builtin
  25. #elif defined(__has_builtin) && __has_builtin(__builtin_debugtrap)
  26. inline void __debugbreak() {
  27. __builtin_debugtrap();
  28. }
  29. #else
  30. inline void __debugbreak() {
  31. #if defined(__x86_64__) || defined(__i386__)
  32. __asm__ volatile("int $3\n");
  33. #else
  34. assert(0);
  35. #endif
  36. }
  37. #endif
  38. inline bool YaIsDebuggerPresent() {
  39. return false;
  40. }
  41. #else
  42. // __debugbreak is intrinsic in MSVC
  43. extern "C" {
  44. __declspec(dllimport) int __stdcall IsDebuggerPresent();
  45. }
  46. inline bool YaIsDebuggerPresent() {
  47. return IsDebuggerPresent() != 0;
  48. }
  49. #endif
  50. inline void YaDebugBreak() {
  51. __debugbreak();
  52. }
  53. #undef Y_ASSERT
  54. #if !defined(NDEBUG) && !defined(__GCCXML__)
  55. #define Y_HIT_DEBUGGER() \
  56. do { \
  57. if (YaIsDebuggerPresent()) { \
  58. __debugbreak(); \
  59. } \
  60. } while (false)
  61. #else
  62. #define Y_HIT_DEBUGGER() Y_SEMICOLON_GUARD
  63. #endif
  64. namespace NPrivate {
  65. /// method should not be used directly
  66. [[noreturn]] void Panic(const TStaticBuf& file, int line, const char* function, const char* expr, const char* format, ...) noexcept Y_PRINTF_FORMAT(5, 6);
  67. } // namespace NPrivate
  68. /// Assert that does not depend on NDEBUG macro and outputs message like printf
  69. #define Y_ABORT_UNLESS(expr, ...) \
  70. do { \
  71. if (Y_UNLIKELY(!(expr))) { \
  72. Y_HIT_DEBUGGER(); \
  73. /* NOLINTNEXTLINE */ \
  74. ::NPrivate::Panic(__SOURCE_FILE_IMPL__, __LINE__, __FUNCTION__, #expr, " " __VA_ARGS__); \
  75. } \
  76. } while (false)
  77. #define Y_ABORT_IF(expr, ...) Y_ABORT_UNLESS(!(expr), __VA_ARGS__)
  78. #define Y_ABORT(...) Y_ABORT_UNLESS(false, __VA_ARGS__)
  79. #ifndef NDEBUG
  80. /// Assert that depend on NDEBUG macro and outputs message like printf
  81. #define Y_DEBUG_ABORT_UNLESS Y_ABORT_UNLESS
  82. #else
  83. #define Y_DEBUG_ABORT_UNLESS(expr, ...) \
  84. do { \
  85. if (false) { \
  86. bool __xxx = static_cast<bool>(expr); \
  87. Y_UNUSED(__xxx); \
  88. } \
  89. } while (false)
  90. #endif
  91. #define Y_ASSERT(a) Y_DEBUG_ABORT_UNLESS(a)
  92. #define Y_DEBUG_ABORT(...) Y_DEBUG_ABORT_UNLESS(false, __VA_ARGS__)