Unreviewed, rolling out r234489.
[WebKit-https.git] / Source / WTF / wtf / Assertions.h
1 /*
2  * Copyright (C) 2003-2017 Apple Inc.  All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
24  */
25
26 #ifndef WTF_Assertions_h
27 #define WTF_Assertions_h
28
29 #include <wtf/Platform.h>
30
31 /*
32    no namespaces because this file has to be includable from C and Objective-C
33
34    Note, this file uses many GCC extensions, but it should be compatible with
35    C, Objective C, C++, and Objective C++.
36
37    For non-debug builds, everything is disabled by default except for "always
38    on" logging. Defining any of the symbols explicitly prevents this from
39    having any effect.
40 */
41
42 #undef __STDC_FORMAT_MACROS
43 #define __STDC_FORMAT_MACROS
44 #include <inttypes.h>
45 #include <stdarg.h>
46 #include <stdbool.h>
47 #include <stddef.h>
48 #include <wtf/ExportMacros.h>
49
50 #if USE(OS_LOG)
51 #include <os/log.h>
52 #endif
53
54 #ifdef __cplusplus
55 #include <type_traits>
56
57 #if OS(WINDOWS)
58 #if !COMPILER(GCC_OR_CLANG)
59 extern "C" void _ReadWriteBarrier(void);
60 #pragma intrinsic(_ReadWriteBarrier)
61 #endif
62 #include <intrin.h>
63 #endif
64 #endif
65
66 #ifdef NDEBUG
67 /* Disable ASSERT* macros in release mode. */
68 #define ASSERTIONS_DISABLED_DEFAULT 1
69 #else
70 #define ASSERTIONS_DISABLED_DEFAULT 0
71 #endif
72
73 #ifndef BACKTRACE_DISABLED
74 #define BACKTRACE_DISABLED ASSERTIONS_DISABLED_DEFAULT
75 #endif
76
77 #ifndef ASSERT_DISABLED
78 #define ASSERT_DISABLED ASSERTIONS_DISABLED_DEFAULT
79 #endif
80
81 #ifndef ASSERT_MSG_DISABLED
82 #define ASSERT_MSG_DISABLED ASSERTIONS_DISABLED_DEFAULT
83 #endif
84
85 #ifndef ASSERT_ARG_DISABLED
86 #define ASSERT_ARG_DISABLED ASSERTIONS_DISABLED_DEFAULT
87 #endif
88
89 #ifndef FATAL_DISABLED
90 #define FATAL_DISABLED ASSERTIONS_DISABLED_DEFAULT
91 #endif
92
93 #ifndef ERROR_DISABLED
94 #define ERROR_DISABLED ASSERTIONS_DISABLED_DEFAULT
95 #endif
96
97 #ifndef LOG_DISABLED
98 #define LOG_DISABLED ASSERTIONS_DISABLED_DEFAULT
99 #endif
100
101 #ifndef RELEASE_LOG_DISABLED
102 #define RELEASE_LOG_DISABLED !(USE(OS_LOG))
103 #endif
104
105 #if COMPILER(GCC_OR_CLANG)
106 #define WTF_PRETTY_FUNCTION __PRETTY_FUNCTION__
107 #else
108 #define WTF_PRETTY_FUNCTION __FUNCTION__
109 #endif
110
111 #if COMPILER(MINGW)
112 /* By default MinGW emits warnings when C99 format attributes are used, even if __USE_MINGW_ANSI_STDIO is defined */
113 #define WTF_ATTRIBUTE_PRINTF(formatStringArgument, extraArguments) __attribute__((__format__(gnu_printf, formatStringArgument, extraArguments)))
114 #elif COMPILER(GCC_OR_CLANG) && !defined(__OBJC__)
115 /* WTF logging functions can process %@ in the format string to log a NSObject* but the printf format attribute
116    emits a warning when %@ is used in the format string.  Until <rdar://problem/5195437> is resolved we can't include
117    the attribute when being used from Objective-C code in case it decides to use %@. */
118 #define WTF_ATTRIBUTE_PRINTF(formatStringArgument, extraArguments) __attribute__((__format__(printf, formatStringArgument, extraArguments)))
119 #else
120 #define WTF_ATTRIBUTE_PRINTF(formatStringArgument, extraArguments)
121 #endif
122
123 #if PLATFORM(IOS)
124 /* For a project that uses WTF but has no config.h, we need to explicitly set the export defines here. */
125 #ifndef WTF_EXPORT_PRIVATE
126 #define WTF_EXPORT_PRIVATE
127 #endif
128 #endif // PLATFORM(IOS)
129
130 /* These helper functions are always declared, but not necessarily always defined if the corresponding function is disabled. */
131
132 #ifdef __cplusplus
133 extern "C" {
134 #endif
135
136 /* CRASH() - Raises a fatal error resulting in program termination and triggering either the debugger or the crash reporter.
137
138    Use CRASH() in response to known, unrecoverable errors like out-of-memory.
139    Macro is enabled in both debug and release mode.
140    To test for unknown errors and verify assumptions, use ASSERT instead, to avoid impacting performance in release builds.
141
142    Signals are ignored by the crash reporter on OS X so we must do better.
143 */
144 #if COMPILER(GCC_OR_CLANG) || COMPILER(MSVC)
145 #define NO_RETURN_DUE_TO_CRASH NO_RETURN
146 #else
147 #define NO_RETURN_DUE_TO_CRASH
148 #endif
149
150 typedef enum { WTFLogChannelOff, WTFLogChannelOn, WTFLogChannelOnWithAccumulation } WTFLogChannelState;
151 typedef enum { WTFLogLevelAlways, WTFLogLevelError, WTFLogLevelWarning, WTFLogLevelInfo, WTFLogLevelDebug } WTFLogLevel;
152
153 typedef struct {
154     WTFLogChannelState state;
155     const char* name;
156     WTFLogLevel level;
157 #if !RELEASE_LOG_DISABLED
158     const char* subsystem;
159     __unsafe_unretained os_log_t osLogChannel;
160 #endif
161 } WTFLogChannel;
162
163 #define LOG_CHANNEL(name) JOIN_LOG_CHANNEL_WITH_PREFIX(LOG_CHANNEL_PREFIX, name)
164 #define LOG_CHANNEL_ADDRESS(name) &LOG_CHANNEL(name),
165 #define JOIN_LOG_CHANNEL_WITH_PREFIX(prefix, channel) JOIN_LOG_CHANNEL_WITH_PREFIX_LEVEL_2(prefix, channel)
166 #define JOIN_LOG_CHANNEL_WITH_PREFIX_LEVEL_2(prefix, channel) prefix ## channel
167
168 #define LOG_CHANNEL_WEBKIT_SUBSYSTEM "com.apple.WebKit"
169
170 #define DECLARE_LOG_CHANNEL(name) \
171     extern WTFLogChannel LOG_CHANNEL(name);
172
173 #if !defined(DEFINE_LOG_CHANNEL)
174 #if RELEASE_LOG_DISABLED
175 #define DEFINE_LOG_CHANNEL(name, subsystem) \
176     WTFLogChannel LOG_CHANNEL(name) = { WTFLogChannelOff, #name, WTFLogLevelError };
177 #else
178 #define DEFINE_LOG_CHANNEL(name, subsystem) \
179     WTFLogChannel LOG_CHANNEL(name) = { WTFLogChannelOff, #name, WTFLogLevelError, subsystem, OS_LOG_DEFAULT };
180 #endif
181 #endif
182
183 WTF_EXPORT_PRIVATE void WTFReportNotImplementedYet(const char* file, int line, const char* function);
184 WTF_EXPORT_PRIVATE void WTFReportAssertionFailure(const char* file, int line, const char* function, const char* assertion);
185 WTF_EXPORT_PRIVATE void WTFReportAssertionFailureWithMessage(const char* file, int line, const char* function, const char* assertion, const char* format, ...) WTF_ATTRIBUTE_PRINTF(5, 6);
186 WTF_EXPORT_PRIVATE void WTFReportArgumentAssertionFailure(const char* file, int line, const char* function, const char* argName, const char* assertion);
187 WTF_EXPORT_PRIVATE void WTFReportFatalError(const char* file, int line, const char* function, const char* format, ...) WTF_ATTRIBUTE_PRINTF(4, 5);
188 WTF_EXPORT_PRIVATE void WTFReportError(const char* file, int line, const char* function, const char* format, ...) WTF_ATTRIBUTE_PRINTF(4, 5);
189 WTF_EXPORT_PRIVATE void WTFLog(WTFLogChannel*, const char* format, ...) WTF_ATTRIBUTE_PRINTF(2, 3);
190 WTF_EXPORT_PRIVATE void WTFLogVerbose(const char* file, int line, const char* function, WTFLogChannel*, const char* format, ...) WTF_ATTRIBUTE_PRINTF(5, 6);
191 WTF_EXPORT_PRIVATE void WTFLogAlwaysV(const char* format, va_list);
192 WTF_EXPORT_PRIVATE void WTFLogAlways(const char* format, ...) WTF_ATTRIBUTE_PRINTF(1, 2);
193 WTF_EXPORT_PRIVATE NO_RETURN_DUE_TO_CRASH void WTFLogAlwaysAndCrash(const char* format, ...) WTF_ATTRIBUTE_PRINTF(1, 2);
194 WTF_EXPORT_PRIVATE WTFLogChannel* WTFLogChannelByName(WTFLogChannel*[], size_t count, const char*);
195 WTF_EXPORT_PRIVATE void WTFInitializeLogChannelStatesFromString(WTFLogChannel*[], size_t count, const char*);
196 WTF_EXPORT_PRIVATE void WTFLogWithLevel(WTFLogChannel*, WTFLogLevel, const char* format, ...) WTF_ATTRIBUTE_PRINTF(3, 4);
197 WTF_EXPORT_PRIVATE void WTFSetLogChannelLevel(WTFLogChannel*, WTFLogLevel);
198 WTF_EXPORT_PRIVATE bool WTFWillLogWithLevel(WTFLogChannel*, WTFLogLevel);
199
200 WTF_EXPORT_PRIVATE void WTFGetBacktrace(void** stack, int* size);
201 WTF_EXPORT_PRIVATE void WTFReportBacktrace(void);
202 WTF_EXPORT_PRIVATE void WTFPrintBacktrace(void** stack, int size);
203 #if !RELEASE_LOG_DISABLED
204 WTF_EXPORT_PRIVATE void WTFReleaseLogStackTrace(WTFLogChannel*);
205 #endif
206
207 WTF_EXPORT_PRIVATE bool WTFIsDebuggerAttached(void);
208
209 #if COMPILER(MSVC)
210 #define WTFBreakpointTrap()  __debugbreak()
211 #elif ASAN_ENABLED
212 #define WTFBreakpointTrap()  __builtin_trap()
213 #elif CPU(X86_64) || CPU(X86)
214 #define WTFBreakpointTrap()  asm volatile ("int3")
215 #elif CPU(ARM_THUMB2)
216 #define WTFBreakpointTrap()  asm volatile ("bkpt #0")
217 #elif CPU(ARM64)
218 #define WTFBreakpointTrap()  asm volatile ("brk #0")
219 #else
220 #define WTFBreakpointTrap() WTFCrash() // Not implemented.
221 #endif
222
223 #if COMPILER(MSVC)
224 #define WTFBreakpointTrapUnderConstexprContext() __debugbreak()
225 #else
226 #define WTFBreakpointTrapUnderConstexprContext() __builtin_trap()
227 #endif
228
229 #ifndef CRASH
230
231 #if defined(NDEBUG) && OS(DARWIN)
232 // Crash with a SIGTRAP i.e EXC_BREAKPOINT.
233 // We are not using __builtin_trap because it is only guaranteed to abort, but not necessarily
234 // trigger a SIGTRAP. Instead, we use inline asm to ensure that we trigger the SIGTRAP.
235 #define CRASH() do { \
236     WTFBreakpointTrap(); \
237     __builtin_unreachable(); \
238 } while (0)
239 #define CRASH_UNDER_CONSTEXPR_CONTEXT() do { \
240     WTFBreakpointTrapUnderConstexprContext(); \
241     __builtin_unreachable(); \
242 } while (0)
243 #else
244 #define CRASH() WTFCrash()
245 #define CRASH_UNDER_CONSTEXPR_CONTEXT() WTFCrash()
246 #endif
247
248 #endif // !defined(CRASH)
249
250 WTF_EXPORT_PRIVATE NO_RETURN_DUE_TO_CRASH void WTFCrash(void);
251
252 #ifndef CRASH_WITH_SECURITY_IMPLICATION
253 #define CRASH_WITH_SECURITY_IMPLICATION() WTFCrashWithSecurityImplication()
254 #endif
255
256 WTF_EXPORT_PRIVATE NO_RETURN_DUE_TO_CRASH void WTFCrashWithSecurityImplication(void);
257
258 #ifdef __cplusplus
259 }
260 #endif
261
262 /* BACKTRACE
263
264   Print a backtrace to the same location as ASSERT messages.
265 */
266
267 #if BACKTRACE_DISABLED
268
269 #define BACKTRACE() ((void)0)
270
271 #else
272
273 #define BACKTRACE() do { \
274     WTFReportBacktrace(); \
275 } while(false)
276
277 #endif
278
279 /* ASSERT, ASSERT_NOT_REACHED, ASSERT_UNUSED
280
281   These macros are compiled out of release builds.
282   Expressions inside them are evaluated in debug builds only.
283 */
284
285 #if OS(WINDOWS)
286 /* FIXME: Change to use something other than ASSERT to avoid this conflict with the underlying platform */
287 #undef ASSERT
288 #endif
289
290 #if ASSERT_DISABLED
291
292 #define ASSERT(assertion, ...) ((void)0)
293 #define ASSERT_UNDER_CONSTEXPR_CONTEXT(assertion) ((void)0)
294 #define ASSERT_AT(assertion, file, line, function) ((void)0)
295 #define ASSERT_NOT_REACHED(...) ((void)0)
296 #define ASSERT_NOT_IMPLEMENTED_YET() ((void)0)
297 #define ASSERT_IMPLIES(condition, assertion) ((void)0)
298 #define NO_RETURN_DUE_TO_ASSERT
299
300 #define ASSERT_UNUSED(variable, assertion, ...) ((void)variable)
301
302 #if ENABLE(SECURITY_ASSERTIONS)
303 #define ASSERT_WITH_SECURITY_IMPLICATION(assertion) \
304     (!(assertion) ? \
305         (WTFReportAssertionFailure(__FILE__, __LINE__, WTF_PRETTY_FUNCTION, #assertion), \
306          CRASH_WITH_SECURITY_IMPLICATION()) : \
307         (void)0)
308
309 #define ASSERT_WITH_SECURITY_IMPLICATION_DISABLED 0
310 #else
311 #define ASSERT_WITH_SECURITY_IMPLICATION(assertion) ((void)0)
312 #define ASSERT_WITH_SECURITY_IMPLICATION_DISABLED 1
313 #endif
314
315 #else
316
317 #define ASSERT(assertion, ...) do { \
318     if (!(assertion)) { \
319         WTFReportAssertionFailure(__FILE__, __LINE__, WTF_PRETTY_FUNCTION, #assertion); \
320         CRASH_WITH_INFO(__VA_ARGS__); \
321     } \
322 } while (0)
323
324 #define ASSERT_UNDER_CONSTEXPR_CONTEXT(assertion) do { \
325     if (!(assertion)) { \
326         WTFReportAssertionFailure(__FILE__, __LINE__, WTF_PRETTY_FUNCTION, #assertion); \
327         CRASH_UNDER_CONSTEXPR_CONTEXT(); \
328     } \
329 } while (0)
330
331 #define ASSERT_AT(assertion, file, line, function) do { \
332     if (!(assertion)) { \
333         WTFReportAssertionFailure(file, line, function, #assertion); \
334         CRASH(); \
335     } \
336 } while (0)
337
338 #define ASSERT_NOT_REACHED(...) do { \
339     WTFReportAssertionFailure(__FILE__, __LINE__, WTF_PRETTY_FUNCTION, 0); \
340     CRASH_WITH_INFO(__VA_ARGS__); \
341 } while (0)
342
343 #define ASSERT_NOT_IMPLEMENTED_YET() do { \
344     WTFReportNotImplementedYet(__FILE__, __LINE__, WTF_PRETTY_FUNCTION); \
345     CRASH(); \
346 } while (0)
347
348 #define ASSERT_IMPLIES(condition, assertion) do { \
349     if ((condition) && !(assertion)) { \
350         WTFReportAssertionFailure(__FILE__, __LINE__, WTF_PRETTY_FUNCTION, #condition " => " #assertion); \
351         CRASH(); \
352     } \
353 } while (0)
354
355 #define ASSERT_UNUSED(variable, assertion, ...) ASSERT(assertion, __VA_ARGS__)
356
357 #define NO_RETURN_DUE_TO_ASSERT NO_RETURN_DUE_TO_CRASH
358
359 /* ASSERT_WITH_SECURITY_IMPLICATION
360  
361    Failure of this assertion indicates a possible security vulnerability.
362    Class of vulnerabilities that it tests include bad casts, out of bounds
363    accesses, use-after-frees, etc. Please file a bug using the security
364    template - https://bugs.webkit.org/enter_bug.cgi?product=Security.
365  
366 */
367 #define ASSERT_WITH_SECURITY_IMPLICATION(assertion) \
368     (!(assertion) ? \
369         (WTFReportAssertionFailure(__FILE__, __LINE__, WTF_PRETTY_FUNCTION, #assertion), \
370          CRASH_WITH_SECURITY_IMPLICATION()) : \
371         (void)0)
372 #define ASSERT_WITH_SECURITY_IMPLICATION_DISABLED 0
373 #endif
374
375 /* ASSERT_WITH_MESSAGE */
376
377 #if ASSERT_MSG_DISABLED
378 #define ASSERT_WITH_MESSAGE(assertion, ...) ((void)0)
379 #else
380 #define ASSERT_WITH_MESSAGE(assertion, ...) do { \
381     if (!(assertion)) { \
382         WTFReportAssertionFailureWithMessage(__FILE__, __LINE__, WTF_PRETTY_FUNCTION, #assertion, __VA_ARGS__); \
383         CRASH(); \
384     } \
385 } while (0)
386 #endif
387
388 /* ASSERT_WITH_MESSAGE_UNUSED */
389
390 #if ASSERT_MSG_DISABLED
391 #define ASSERT_WITH_MESSAGE_UNUSED(variable, assertion, ...) ((void)variable)
392 #else
393 #define ASSERT_WITH_MESSAGE_UNUSED(variable, assertion, ...) do { \
394     if (!(assertion)) { \
395         WTFReportAssertionFailureWithMessage(__FILE__, __LINE__, WTF_PRETTY_FUNCTION, #assertion, __VA_ARGS__); \
396         CRASH(); \
397     } \
398 } while (0)
399 #endif
400                         
401                         
402 /* ASSERT_ARG */
403
404 #if ASSERT_ARG_DISABLED
405
406 #define ASSERT_ARG(argName, assertion) ((void)0)
407
408 #else
409
410 #define ASSERT_ARG(argName, assertion) do { \
411     if (!(assertion)) { \
412         WTFReportArgumentAssertionFailure(__FILE__, __LINE__, WTF_PRETTY_FUNCTION, #argName, #assertion); \
413         CRASH(); \
414     } \
415 } while (0)
416
417 #endif
418
419 /* COMPILE_ASSERT */
420 #ifndef COMPILE_ASSERT
421 #if COMPILER_SUPPORTS(C_STATIC_ASSERT)
422 /* Unlike static_assert below, this also works in plain C code. */
423 #define COMPILE_ASSERT(exp, name) _Static_assert((exp), #name)
424 #else
425 #define COMPILE_ASSERT(exp, name) static_assert((exp), #name)
426 #endif
427 #endif
428
429 /* FATAL */
430
431 #if FATAL_DISABLED
432 #define FATAL(...) ((void)0)
433 #else
434 #define FATAL(...) do { \
435     WTFReportFatalError(__FILE__, __LINE__, WTF_PRETTY_FUNCTION, __VA_ARGS__); \
436     CRASH(); \
437 } while (0)
438 #endif
439
440 /* LOG_ERROR */
441
442 #if ERROR_DISABLED
443 #define LOG_ERROR(...) ((void)0)
444 #else
445 #define LOG_ERROR(...) WTFReportError(__FILE__, __LINE__, WTF_PRETTY_FUNCTION, __VA_ARGS__)
446 #endif
447
448 /* LOG */
449
450 #if LOG_DISABLED
451 #define LOG(channel, ...) ((void)0)
452 #else
453 #define LOG(channel, ...) WTFLog(&LOG_CHANNEL(channel), __VA_ARGS__)
454 #endif
455
456 /* LOG_VERBOSE */
457
458 #if LOG_DISABLED
459 #define LOG_VERBOSE(channel, ...) ((void)0)
460 #else
461 #define LOG_VERBOSE(channel, ...) WTFLogVerbose(__FILE__, __LINE__, WTF_PRETTY_FUNCTION, &LOG_CHANNEL(channel), __VA_ARGS__)
462 #endif
463
464 /* LOG_WITH_LEVEL */
465
466 #if LOG_DISABLED
467 #define LOG_WITH_LEVEL(channel, level, ...) ((void)0)
468 #else
469 #define LOG_WITH_LEVEL(channel, level, ...) WTFLogWithLevel(&LOG_CHANNEL(channel), level, __VA_ARGS__)
470 #endif
471
472 /* RELEASE_LOG */
473
474 #if RELEASE_LOG_DISABLED
475 #define RELEASE_LOG(channel, ...) ((void)0)
476 #define RELEASE_LOG_ERROR(channel, ...) LOG_ERROR(__VA_ARGS__)
477 #define RELEASE_LOG_FAULT(channel, ...) LOG_ERROR(__VA_ARGS__)
478
479 #define RELEASE_LOG_IF(isAllowed, channel, ...) ((void)0)
480 #define RELEASE_LOG_ERROR_IF(isAllowed, channel, ...) do { if (isAllowed) RELEASE_LOG_ERROR(channel, __VA_ARGS__); } while (0)
481
482 #define RELEASE_LOG_WITH_LEVEL(channel, level, ...) ((void)0)
483 #define RELEASE_LOG_WITH_LEVEL_IF(isAllowed, channel, level, ...) do { if (isAllowed) RELEASE_LOG_WITH_LEVEL(channel, level, __VA_ARGS__); } while (0)
484
485 #define RELEASE_LOG_STACKTRACE(channel) ((void)0)
486 #else
487 #define RELEASE_LOG(channel, ...) os_log(LOG_CHANNEL(channel).osLogChannel, __VA_ARGS__)
488 #define RELEASE_LOG_ERROR(channel, ...) os_log_error(LOG_CHANNEL(channel).osLogChannel, __VA_ARGS__)
489 #define RELEASE_LOG_FAULT(channel, ...) os_log_fault(LOG_CHANNEL(channel).osLogChannel, __VA_ARGS__)
490 #define RELEASE_LOG_INFO(channel, ...) os_log_info(LOG_CHANNEL(channel).osLogChannel, __VA_ARGS__)
491
492 #define RELEASE_LOG_IF(isAllowed, channel, ...) do { if (isAllowed) RELEASE_LOG(      channel, __VA_ARGS__); } while (0)
493 #define RELEASE_LOG_ERROR_IF(isAllowed, channel, ...) do { if (isAllowed) RELEASE_LOG_ERROR(channel, __VA_ARGS__); } while (0)
494 #define RELEASE_LOG_INFO_IF(isAllowed, channel, ...) do { if (isAllowed) RELEASE_LOG_INFO(channel, __VA_ARGS__); } while (0)
495
496 #define RELEASE_LOG_WITH_LEVEL(channel, logLevel, ...) do { \
497     if (LOG_CHANNEL(channel).level >= (logLevel)) \
498         os_log(LOG_CHANNEL(channel).osLogChannel, __VA_ARGS__); \
499 } while (0)
500
501 #define RELEASE_LOG_WITH_LEVEL_IF(isAllowed, channel, logLevel, ...) do { \
502     if ((isAllowed) && LOG_CHANNEL(channel).level >= (logLevel)) \
503         os_log(LOG_CHANNEL(channel).osLogChannel, __VA_ARGS__); \
504 } while (0)
505
506 #define RELEASE_LOG_STACKTRACE(channel) WTFReleaseLogStackTrace(&LOG_CHANNEL(channel))
507 #endif
508
509
510 /* RELEASE_ASSERT */
511
512 #if ASSERT_DISABLED
513 #define RELEASE_ASSERT(assertion, ...) do { \
514     if (UNLIKELY(!(assertion))) \
515         CRASH_WITH_INFO(__VA_ARGS__); \
516 } while (0)
517 #define RELEASE_ASSERT_WITH_MESSAGE(assertion, ...) RELEASE_ASSERT(assertion)
518 #define RELEASE_ASSERT_WITH_SECURITY_IMPLICATION(assertion) RELEASE_ASSERT(assertion)
519 #define RELEASE_ASSERT_NOT_REACHED(...) CRASH_WITH_INFO(__VA_ARGS__)
520 #else
521 #define RELEASE_ASSERT(assertion, ...) ASSERT(assertion, __VA_ARGS__)
522 #define RELEASE_ASSERT_WITH_MESSAGE(assertion, ...) ASSERT_WITH_MESSAGE(assertion, __VA_ARGS__)
523 #define RELEASE_ASSERT_WITH_SECURITY_IMPLICATION(assertion) ASSERT_WITH_SECURITY_IMPLICATION(assertion)
524 #define RELEASE_ASSERT_NOT_REACHED() ASSERT_NOT_REACHED()
525 #endif
526
527 #ifdef __cplusplus
528
529 // The combination of line, file, function, and counter should be a unique number per call to this crash. This tricks the compiler into not coalescing calls to WTFCrashWithInfo.
530 // The easiest way to fill these values per translation unit is to pass __LINE__, __FILE__, WTF_PRETTY_FUNCTION, and __COUNTER__.
531 WTF_EXPORT_PRIVATE NO_RETURN_DUE_TO_CRASH NOT_TAIL_CALLED void WTFCrashWithInfo(int line, const char* file, const char* function, int counter, uint64_t reason, uint64_t misc1, uint64_t misc2, uint64_t misc3, uint64_t misc4, uint64_t misc5, uint64_t misc6);
532 WTF_EXPORT_PRIVATE NO_RETURN_DUE_TO_CRASH NOT_TAIL_CALLED void WTFCrashWithInfo(int line, const char* file, const char* function, int counter, uint64_t reason, uint64_t misc1, uint64_t misc2, uint64_t misc3, uint64_t misc4, uint64_t misc5);
533 WTF_EXPORT_PRIVATE NO_RETURN_DUE_TO_CRASH NOT_TAIL_CALLED void WTFCrashWithInfo(int line, const char* file, const char* function, int counter, uint64_t reason, uint64_t misc1, uint64_t misc2, uint64_t misc3, uint64_t misc4);
534 WTF_EXPORT_PRIVATE NO_RETURN_DUE_TO_CRASH NOT_TAIL_CALLED void WTFCrashWithInfo(int line, const char* file, const char* function, int counter, uint64_t reason, uint64_t misc1, uint64_t misc2, uint64_t misc3);
535 WTF_EXPORT_PRIVATE NO_RETURN_DUE_TO_CRASH NOT_TAIL_CALLED void WTFCrashWithInfo(int line, const char* file, const char* function, int counter, uint64_t reason, uint64_t misc1, uint64_t misc2);
536 WTF_EXPORT_PRIVATE NO_RETURN_DUE_TO_CRASH NOT_TAIL_CALLED void WTFCrashWithInfo(int line, const char* file, const char* function, int counter, uint64_t reason, uint64_t misc1);
537 WTF_EXPORT_PRIVATE NO_RETURN_DUE_TO_CRASH NOT_TAIL_CALLED void WTFCrashWithInfo(int line, const char* file, const char* function, int counter, uint64_t reason);
538 NO_RETURN_DUE_TO_CRASH NOT_TAIL_CALLED void WTFCrashWithInfo(int line, const char* file, const char* function, int counter);
539
540 inline void WTFCrashWithInfo(int, const char*, const char*, int)
541 #if COMPILER(CLANG)
542     __attribute__((optnone))
543 #endif
544 {
545     CRASH();
546 }
547
548 namespace WTF {
549 inline void isIntegralType() { }
550
551 template<typename T, typename... Types>
552 void isIntegralType(T, Types... types)
553 {
554     static_assert(std::is_integral<T>::value || std::is_enum<T>::value, "All types need to be integral bitwise_cast to integral type for logging");
555     isIntegralType(types...);
556 }
557 }
558
559 inline void compilerFenceForCrash()
560 {
561 #if OS(WINDOWS) && !COMPILER(GCC_OR_CLANG)
562     _ReadWriteBarrier();
563 #else
564     asm volatile("" ::: "memory");
565 #endif
566 }
567
568 #ifndef CRASH_WITH_INFO
569 // This is useful if you are going to stuff data into registers before crashing. Like the crashWithInfo functions below...
570 // GCC doesn't like the ##__VA_ARGS__ here since this macro is called from another macro so we just CRASH instead there.
571 #if COMPILER(CLANG) || COMPILER(MSVC)
572 #define CRASH_WITH_INFO(...) do { \
573         WTF::isIntegralType(__VA_ARGS__); \
574         compilerFenceForCrash(); \
575         WTFCrashWithInfo(__LINE__, __FILE__, WTF_PRETTY_FUNCTION, __COUNTER__, ##__VA_ARGS__); \
576     } while (false)
577 #else
578 #define CRASH_WITH_INFO(...) CRASH()
579 #endif
580 #endif // CRASH_WITH_INFO
581
582 #ifndef CRASH_WITH_SECURITY_IMPLICATION_AND_INFO
583 #define CRASH_WITH_SECURITY_IMPLICATION_AND_INFO CRASH_WITH_INFO
584 #endif // CRASH_WITH_SECURITY_IMPLICATION_AND_INFO
585
586 #else /* not __cplusplus */
587
588 #ifndef CRASH_WITH_INFO
589 #define CRASH_WITH_INFO() CRASH()
590 #endif
591
592 #endif /* __cplusplus */
593
594 /* UNREACHABLE_FOR_PLATFORM */
595
596 #if COMPILER(CLANG)
597 // This would be a macro except that its use of #pragma works best around
598 // a function. Hence it uses macro naming convention.
599 #pragma clang diagnostic push
600 #pragma clang diagnostic ignored "-Wmissing-noreturn"
601 static inline void UNREACHABLE_FOR_PLATFORM()
602 {
603     // This *MUST* be a release assert. We use it in places where it's better to crash than to keep
604     // going.
605     RELEASE_ASSERT_NOT_REACHED();
606 }
607 #pragma clang diagnostic pop
608 #else
609 #define UNREACHABLE_FOR_PLATFORM() RELEASE_ASSERT_NOT_REACHED()
610 #endif
611
612 #endif /* WTF_Assertions_h */