1 // Copyright 2016 The Fuchsia Authors
2 // Copyright (c) 2008 Travis Geiselbrecht
3 //
4 // Use of this source code is governed by a MIT-style
5 // license that can be found in the LICENSE file or at
6 // https://opensource.org/licenses/MIT
7 
8 #pragma once
9 
10 #include <zircon/compiler.h>
11 #include <debug.h>
12 
13 #define PANIC(args...) panic(args)
14 
15 #define ASSERT(x) \
16     do {                                                                                          \
17         if (unlikely(!(x))) {                                                                     \
18             PANIC("ASSERT FAILED at (%s:%d): %s\n", __FILE__, __LINE__, #x);                      \
19         }                                                                                         \
20     } while (0)
21 
22 #define ASSERT_MSG(x, msg, msgargs...)                                                            \
23     do {                                                                                          \
24         if (unlikely(!(x))) {                                                                     \
25             PANIC("ASSERT FAILED at (%s:%d): %s\n" msg "\n", __FILE__, __LINE__, #x, ## msgargs); \
26         }                                                                                         \
27     } while (0)
28 
29 // conditionally implement DEBUG_ASSERT based on LK_DEBUGLEVEL in kernel space
30 // user space does not currently implement DEBUG_ASSERT
31 #ifdef LK_DEBUGLEVEL
32 #define DEBUG_ASSERT_IMPLEMENTED (LK_DEBUGLEVEL > 1)
33 #else
34 #define DEBUG_ASSERT_IMPLEMENTED 0
35 #endif
36 
37 #define DEBUG_ASSERT(x) \
38     do {                                                                           \
39         if (DEBUG_ASSERT_IMPLEMENTED && unlikely(!(x))) {                          \
40             PANIC("DEBUG ASSERT FAILED at (%s:%d): %s\n", __FILE__, __LINE__, #x); \
41         }                                                                          \
42     } while (0)
43 
44 #define DEBUG_ASSERT_MSG(x, msg, msgargs...)                        \
45     do {                                                            \
46         if (DEBUG_ASSERT_IMPLEMENTED && unlikely(!(x))) {           \
47             PANIC("DEBUG ASSERT FAILED at (%s:%d): %s\n" msg "\n",  \
48                   __FILE__, __LINE__, #x, ## msgargs);              \
49         }                                                           \
50     } while (0)
51 
52 // implement _COND versions of DEBUG_ASSERT which only emit the body if
53 // DEBUG_ASSERT_IMPLEMENTED is set
54 #if DEBUG_ASSERT_IMPLEMENTED
55 #define DEBUG_ASSERT_COND(x) DEBUG_ASSERT(x)
56 #define DEBUG_ASSERT_MSG_COND(x, msg, msgargs...) DEBUG_ASSERT_MSG(x, msg, msgargs)
57 #else
58 #define DEBUG_ASSERT_COND(x) do { } while (0)
59 #define DEBUG_ASSERT_MSG_COND(x, msg, msgargs...) do { } while (0)
60 #endif
61 
62 // make sure static_assert() is defined, even in C
63 #if !defined(__cplusplus) && !defined(static_assert)
64 #define static_assert(e, msg) _Static_assert(e, msg)
65 #endif
66 
67 #define assert(x) DEBUG_ASSERT(x)
68