Derive-C
Loading...
Searching...
No Matches
panic.h
Go to the documentation of this file.
1#pragma once
2#include <assert.h>
3
6
7// JUSTIFY: Disabled under clangd to avoid spurious errors in C code.
8// - We have tests & fuzz tests with panic defined using C++ headers from gtest & rapidcheck
9// - Hence when analysing a header, clangd assumes this is the header as included for these tests
10// - which results in errors for missing macros (e.g. RC_FAIL)
11// Hence for clangd, we just assume the default implementations
12#if !defined DC_PLACEHOLDERS
13 #if defined DC_PANIC_HEADER
14 #include DC_PANIC_HEADER
15 #endif
16#endif
17
18#if !defined DC_STATIC_ASSERT
19 #if defined DC_STATIC_ASSERT_SUPPORTED
20 #define DC_STATIC_ASSERT _Static_assert
21 #else
22 #define DC_STATIC_ASSERT static_assert
23 #endif
24#endif
25
26#if !defined DC_PANIC
27 #include <stdio.h> // NOLINT(misc-include-cleaner) (for default panic implementation)
28 #include <stdlib.h> // NOLINT(misc-include-cleaner) (for default panic implementation)
29 #define DC_PANIC(str, ...) \
30 do { \
31 fprintf(stderr, "[%s:%d] " str, __FILE__, __LINE__ __VA_OPT__(, ) __VA_ARGS__); \
32 abort(); \
33 } while (0);
34#endif
35
36#if !defined DC_ASSERT
37 #define DC_ASSERT(expr, ...) \
38 if (!(expr)) { \
39 DC_PANIC("assertion " #expr " failed: " __VA_ARGS__); \
40 }
41#endif
42
43#if !defined DC_UNREACHABLE
44 #define DC_UNREACHABLE(...) DC_PANIC("unreachable: " __VA_ARGS__ "\n");
45#endif
46
47#if !defined DC_LIKELY
48 #define DC_LIKELY(x) __builtin_expect(!!(x), 1)
49#endif
50
51#if !defined DC_WHEN
52 #define DC_WHEN(cond, expr) ((cond) ? (expr) : true)
53#endif
54
55#if !defined DC_ASSUME
56 #if !defined NDEBUG
57 #define DC_ASSUME(expr, ...) DC_ASSERT(expr, __VA_ARGS__)
58 #else
59 #if defined(__clang__)
60 #define DC_ASSUME(expr, ...) __builtin_assume(expr)
61 #elif defined(__GNUC__)
62 // GCC doesn't have __builtin_assume, but this pattern has the same effect:
63 #define DC_ASSUME(expr, ...) \
64 do { \
65 if (!(expr)) \
66 __builtin_unreachable(); \
67 } while (0)
68 #else
69 #define DC_ASSUME(expr, ...) ((void)0)
70 #endif
71 #endif
72#endif
73
74// JUSTIFY: `DC_DEBUG_ASSERT` when `DC_ASSUME` exists
75// - Some expressions cannot be used as compiler assumptions.
76#if !defined DC_DEBUG_ASSERT
77 #if !defined NDEBUG
78 #define DC_DEBUG_ASSERT DC_ASSERT
79 #else
80 #define DC_DEBUG_ASSERT(expr, ...) (void)(expr)
81 #endif
82#endif