72be3d638cd35d585c54aeb8e68c70b58542fec2
[WebKit-https.git] / Source / WTF / wtf / Assertions.h
1 /*
2  * Copyright (C) 2003, 2006, 2007, 2013 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 /*
30    no namespaces because this file has to be includable from C and Objective-C
31
32    Note, this file uses many GCC extensions, but it should be compatible with
33    C, Objective C, C++, and Objective C++.
34
35    For non-debug builds, everything is disabled by default.
36    Defining any of the symbols explicitly prevents this from having any effect.
37 */
38
39 #include <inttypes.h>
40 #include <stdarg.h>
41 #include <stdbool.h>
42 #include <stddef.h>
43
44 #ifdef NDEBUG
45 /* Disable ASSERT* macros in release mode. */
46 #define ASSERTIONS_DISABLED_DEFAULT 1
47 #else
48 #define ASSERTIONS_DISABLED_DEFAULT 0
49 #endif
50
51 #ifndef BACKTRACE_DISABLED
52 #define BACKTRACE_DISABLED ASSERTIONS_DISABLED_DEFAULT
53 #endif
54
55 #ifndef ASSERT_DISABLED
56 #define ASSERT_DISABLED ASSERTIONS_DISABLED_DEFAULT
57 #endif
58
59 #ifndef ASSERT_MSG_DISABLED
60 #define ASSERT_MSG_DISABLED ASSERTIONS_DISABLED_DEFAULT
61 #endif
62
63 #ifndef ASSERT_ARG_DISABLED
64 #define ASSERT_ARG_DISABLED ASSERTIONS_DISABLED_DEFAULT
65 #endif
66
67 #ifndef FATAL_DISABLED
68 #define FATAL_DISABLED ASSERTIONS_DISABLED_DEFAULT
69 #endif
70
71 #ifndef ERROR_DISABLED
72 #define ERROR_DISABLED ASSERTIONS_DISABLED_DEFAULT
73 #endif
74
75 #ifndef LOG_DISABLED
76 #define LOG_DISABLED ASSERTIONS_DISABLED_DEFAULT
77 #endif
78
79 #if COMPILER(GCC)
80 #define WTF_PRETTY_FUNCTION __PRETTY_FUNCTION__
81 #else
82 #define WTF_PRETTY_FUNCTION __FUNCTION__
83 #endif
84
85 /* WTF logging functions can process %@ in the format string to log a NSObject* but the printf format attribute
86    emits a warning when %@ is used in the format string.  Until <rdar://problem/5195437> is resolved we can't include
87    the attribute when being used from Objective-C code in case it decides to use %@. */
88 #if COMPILER(GCC) && !defined(__OBJC__)
89 #define WTF_ATTRIBUTE_PRINTF(formatStringArgument, extraArguments) __attribute__((__format__(printf, formatStringArgument, extraArguments)))
90 #else
91 #define WTF_ATTRIBUTE_PRINTF(formatStringArgument, extraArguments)
92 #endif
93
94 #if PLATFORM(IOS)
95 /* For a project that uses WTF but has no config.h, we need to explicitly set the export defines here. */
96 #ifndef WTF_EXPORT_PRIVATE
97 #define WTF_EXPORT_PRIVATE
98 #endif
99 #endif // PLATFORM(IOS)
100
101 /* These helper functions are always declared, but not necessarily always defined if the corresponding function is disabled. */
102
103 #ifdef __cplusplus
104 extern "C" {
105 #endif
106
107 /* CRASH() - Raises a fatal error resulting in program termination and triggering either the debugger or the crash reporter.
108
109    Use CRASH() in response to known, unrecoverable errors like out-of-memory.
110    Macro is enabled in both debug and release mode.
111    To test for unknown errors and verify assumptions, use ASSERT instead, to avoid impacting performance in release builds.
112
113    Signals are ignored by the crash reporter on OS X so we must do better.
114 */
115 #if COMPILER(CLANG) || COMPILER(MSVC)
116 #define NO_RETURN_DUE_TO_CRASH NO_RETURN
117 #else
118 #define NO_RETURN_DUE_TO_CRASH
119 #endif
120
121 typedef enum { WTFLogChannelOff, WTFLogChannelOn } WTFLogChannelState;
122
123 typedef struct {
124     WTFLogChannelState state;
125     const char* name;
126 } WTFLogChannel;
127
128 WTF_EXPORT_PRIVATE void WTFReportAssertionFailure(const char* file, int line, const char* function, const char* assertion);
129 WTF_EXPORT_PRIVATE void WTFReportAssertionFailureWithMessage(const char* file, int line, const char* function, const char* assertion, const char* format, ...) WTF_ATTRIBUTE_PRINTF(5, 6);
130 WTF_EXPORT_PRIVATE void WTFReportArgumentAssertionFailure(const char* file, int line, const char* function, const char* argName, const char* assertion);
131 WTF_EXPORT_PRIVATE void WTFReportFatalError(const char* file, int line, const char* function, const char* format, ...) WTF_ATTRIBUTE_PRINTF(4, 5);
132 WTF_EXPORT_PRIVATE void WTFReportError(const char* file, int line, const char* function, const char* format, ...) WTF_ATTRIBUTE_PRINTF(4, 5);
133 WTF_EXPORT_PRIVATE void WTFLog(WTFLogChannel*, const char* format, ...) WTF_ATTRIBUTE_PRINTF(2, 3);
134 WTF_EXPORT_PRIVATE void WTFLogVerbose(const char* file, int line, const char* function, WTFLogChannel*, const char* format, ...) WTF_ATTRIBUTE_PRINTF(5, 6);
135 WTF_EXPORT_PRIVATE void WTFLogAlwaysV(const char* format, va_list);
136 WTF_EXPORT_PRIVATE void WTFLogAlways(const char* format, ...) WTF_ATTRIBUTE_PRINTF(1, 2);
137 WTF_EXPORT_PRIVATE NO_RETURN_DUE_TO_CRASH void WTFLogAlwaysAndCrash(const char* format, ...) WTF_ATTRIBUTE_PRINTF(1, 2);
138 WTF_EXPORT_PRIVATE WTFLogChannel* WTFLogChannelByName(WTFLogChannel*[], size_t count, const char*);
139 WTF_EXPORT_PRIVATE void WTFInitializeLogChannelStatesFromString(WTFLogChannel*[], size_t count, const char*);
140
141 WTF_EXPORT_PRIVATE void WTFGetBacktrace(void** stack, int* size);
142 WTF_EXPORT_PRIVATE void WTFReportBacktrace();
143 WTF_EXPORT_PRIVATE void WTFPrintBacktrace(void** stack, int size);
144
145 typedef void (*WTFCrashHookFunction)();
146 WTF_EXPORT_PRIVATE void WTFSetCrashHook(WTFCrashHookFunction);
147 WTF_EXPORT_PRIVATE void WTFInstallReportBacktraceOnCrashHook();
148
149 WTF_EXPORT_PRIVATE bool WTFIsDebuggerAttached();
150
151 #ifdef __cplusplus
152 }
153 #endif
154
155 #ifndef CRASH
156 #define CRASH() WTFCrash()
157 #endif
158
159 #ifdef __cplusplus
160 extern "C" {
161 #endif
162     WTF_EXPORT_PRIVATE NO_RETURN_DUE_TO_CRASH void WTFCrash();
163 #ifdef __cplusplus
164 }
165 #endif
166
167 #ifndef CRASH_WITH_SECURITY_IMPLICATION
168 #define CRASH_WITH_SECURITY_IMPLICATION() WTFCrashWithSecurityImplication()
169 #endif
170
171 #ifdef __cplusplus
172 extern "C" {
173 #endif
174     WTF_EXPORT_PRIVATE NO_RETURN_DUE_TO_CRASH void WTFCrashWithSecurityImplication();
175 #ifdef __cplusplus
176 }
177 #endif
178
179 /* BACKTRACE
180
181   Print a backtrace to the same location as ASSERT messages.
182 */
183
184 #if BACKTRACE_DISABLED
185
186 #define BACKTRACE() ((void)0)
187
188 #else
189
190 #define BACKTRACE() do { \
191     WTFReportBacktrace(); \
192 } while(false)
193
194 #endif
195
196 /* ASSERT, ASSERT_NOT_REACHED, ASSERT_UNUSED
197
198   These macros are compiled out of release builds.
199   Expressions inside them are evaluated in debug builds only.
200 */
201
202 #if OS(WINDOWS)
203 /* FIXME: Change to use something other than ASSERT to avoid this conflict with the underlying platform */
204 #undef ASSERT
205 #endif
206
207 #if ASSERT_DISABLED
208
209 #define ASSERT(assertion) ((void)0)
210 #define ASSERT_AT(assertion, file, line, function) ((void)0)
211 #define ASSERT_NOT_REACHED() ((void)0)
212 #define NO_RETURN_DUE_TO_ASSERT
213
214 #define ASSERT_UNUSED(variable, assertion) ((void)variable)
215
216 #ifdef ADDRESS_SANITIZER
217 #define ASSERT_WITH_SECURITY_IMPLICATION(assertion) \
218     (!(assertion) ? \
219         (WTFReportAssertionFailure(__FILE__, __LINE__, WTF_PRETTY_FUNCTION, #assertion), \
220          CRASH_WITH_SECURITY_IMPLICATION()) : \
221         (void)0)
222
223 #define ASSERT_WITH_SECURITY_IMPLICATION_DISABLED 0
224 #else
225 #define ASSERT_WITH_SECURITY_IMPLICATION(assertion) ((void)0)
226 #define ASSERT_WITH_SECURITY_IMPLICATION_DISABLED 1
227 #endif
228
229 #else
230
231 #define ASSERT(assertion) \
232     (!(assertion) ? \
233         (WTFReportAssertionFailure(__FILE__, __LINE__, WTF_PRETTY_FUNCTION, #assertion), \
234          CRASH()) : \
235         (void)0)
236
237 #define ASSERT_AT(assertion, file, line, function) \
238     (!(assertion) ? \
239         (WTFReportAssertionFailure(file, line, function, #assertion), \
240          CRASH()) :                                                   \
241         (void)0)
242
243 #define ASSERT_NOT_REACHED() do { \
244     WTFReportAssertionFailure(__FILE__, __LINE__, WTF_PRETTY_FUNCTION, 0); \
245     CRASH(); \
246 } while (0)
247
248 #define ASSERT_UNUSED(variable, assertion) ASSERT(assertion)
249
250 #define NO_RETURN_DUE_TO_ASSERT NO_RETURN_DUE_TO_CRASH
251
252 /* ASSERT_WITH_SECURITY_IMPLICATION
253  
254    Failure of this assertion indicates a possible security vulnerability.
255    Class of vulnerabilities that it tests include bad casts, out of bounds
256    accesses, use-after-frees, etc. Please file a bug using the security
257    template - https://bugs.webkit.org/enter_bug.cgi?product=Security.
258  
259 */
260 #define ASSERT_WITH_SECURITY_IMPLICATION(assertion) \
261     (!(assertion) ? \
262         (WTFReportAssertionFailure(__FILE__, __LINE__, WTF_PRETTY_FUNCTION, #assertion), \
263          CRASH_WITH_SECURITY_IMPLICATION()) : \
264         (void)0)
265 #define ASSERT_WITH_SECURITY_IMPLICATION_DISABLED 0
266 #endif
267
268 /* ASSERT_WITH_MESSAGE */
269
270 #if ASSERT_MSG_DISABLED
271 #define ASSERT_WITH_MESSAGE(assertion, ...) ((void)0)
272 #else
273 #define ASSERT_WITH_MESSAGE(assertion, ...) do \
274     if (!(assertion)) { \
275         WTFReportAssertionFailureWithMessage(__FILE__, __LINE__, WTF_PRETTY_FUNCTION, #assertion, __VA_ARGS__); \
276         CRASH(); \
277     } \
278 while (0)
279 #endif
280
281 /* ASSERT_WITH_MESSAGE_UNUSED */
282
283 #if ASSERT_MSG_DISABLED
284 #define ASSERT_WITH_MESSAGE_UNUSED(variable, assertion, ...) ((void)variable)
285 #else
286 #define ASSERT_WITH_MESSAGE_UNUSED(variable, assertion, ...) do \
287     if (!(assertion)) { \
288         WTFReportAssertionFailureWithMessage(__FILE__, __LINE__, WTF_PRETTY_FUNCTION, #assertion, __VA_ARGS__); \
289         CRASH(); \
290     } \
291 while (0)
292 #endif
293                         
294                         
295 /* ASSERT_ARG */
296
297 #if ASSERT_ARG_DISABLED
298
299 #define ASSERT_ARG(argName, assertion) ((void)0)
300
301 #else
302
303 #define ASSERT_ARG(argName, assertion) do \
304     if (!(assertion)) { \
305         WTFReportArgumentAssertionFailure(__FILE__, __LINE__, WTF_PRETTY_FUNCTION, #argName, #assertion); \
306         CRASH(); \
307     } \
308 while (0)
309
310 #endif
311
312 /* COMPILE_ASSERT */
313 #ifndef COMPILE_ASSERT
314 #if COMPILER_SUPPORTS(C_STATIC_ASSERT)
315 /* Unlike static_assert below, this also works in plain C code. */
316 #define COMPILE_ASSERT(exp, name) _Static_assert((exp), #name)
317 #else
318 #define COMPILE_ASSERT(exp, name) static_assert((exp), #name)
319 #endif
320 #endif
321
322 /* FATAL */
323
324 #if FATAL_DISABLED
325 #define FATAL(...) ((void)0)
326 #else
327 #define FATAL(...) do { \
328     WTFReportFatalError(__FILE__, __LINE__, WTF_PRETTY_FUNCTION, __VA_ARGS__); \
329     CRASH(); \
330 } while (0)
331 #endif
332
333 /* LOG_ERROR */
334
335 #if ERROR_DISABLED
336 #define LOG_ERROR(...) ((void)0)
337 #else
338 #define LOG_ERROR(...) WTFReportError(__FILE__, __LINE__, WTF_PRETTY_FUNCTION, __VA_ARGS__)
339 #endif
340
341 /* LOG */
342
343 #if LOG_DISABLED
344 #define LOG(channel, ...) ((void)0)
345 #else
346 #define LOG(channel, ...) WTFLog(&JOIN_LOG_CHANNEL_WITH_PREFIX(LOG_CHANNEL_PREFIX, channel), __VA_ARGS__)
347 #define JOIN_LOG_CHANNEL_WITH_PREFIX(prefix, channel) JOIN_LOG_CHANNEL_WITH_PREFIX_LEVEL_2(prefix, channel)
348 #define JOIN_LOG_CHANNEL_WITH_PREFIX_LEVEL_2(prefix, channel) prefix ## channel
349 #endif
350
351 /* LOG_VERBOSE */
352
353 #if LOG_DISABLED
354 #define LOG_VERBOSE(channel, ...) ((void)0)
355 #else
356 #define LOG_VERBOSE(channel, ...) WTFLogVerbose(__FILE__, __LINE__, WTF_PRETTY_FUNCTION, &JOIN_LOG_CHANNEL_WITH_PREFIX(LOG_CHANNEL_PREFIX, channel), __VA_ARGS__)
357 #endif
358
359 /* UNREACHABLE_FOR_PLATFORM */
360
361 #if COMPILER(CLANG)
362 // This would be a macro except that its use of #pragma works best around
363 // a function. Hence it uses macro naming convention.
364 #pragma clang diagnostic push
365 #pragma clang diagnostic ignored "-Wmissing-noreturn"
366 static inline void UNREACHABLE_FOR_PLATFORM()
367 {
368     CRASH();
369 }
370 #pragma clang diagnostic pop
371 #else
372 #define UNREACHABLE_FOR_PLATFORM() ASSERT_NOT_REACHED()
373 #endif
374
375 #if ASSERT_DISABLED
376 #define RELEASE_ASSERT(assertion) (UNLIKELY(!(assertion)) ? (CRASH()) : (void)0)
377 #define RELEASE_ASSERT_WITH_MESSAGE(assertion, ...) RELEASE_ASSERT(assertion)
378 #define RELEASE_ASSERT_NOT_REACHED() CRASH()
379 #else
380 #define RELEASE_ASSERT(assertion) ASSERT(assertion)
381 #define RELEASE_ASSERT_WITH_MESSAGE(assertion, ...) ASSERT_WITH_MESSAGE(assertion, __VA_ARGS__)
382 #define RELEASE_ASSERT_NOT_REACHED() ASSERT_NOT_REACHED()
383 #endif
384
385 /* TYPE CAST */
386
387 // FIXME: This macro should be removed once the code base is ported to using
388 // the new SPECIALIZE_TYPE_TRAITS_*() macro.
389 #define TYPE_CASTS_BASE(ToClassName, argumentType, argumentName, pointerPredicate, referencePredicate) \
390 inline ToClassName* to##ToClassName(argumentType* argumentName) \
391 { \
392     ASSERT_WITH_SECURITY_IMPLICATION(!argumentName || (pointerPredicate)); \
393     return static_cast<ToClassName*>(argumentName); \
394 } \
395 inline const ToClassName* to##ToClassName(const argumentType* argumentName) \
396 { \
397     ASSERT_WITH_SECURITY_IMPLICATION(!argumentName || (pointerPredicate)); \
398     return static_cast<const ToClassName*>(argumentName); \
399 } \
400 inline ToClassName& to##ToClassName(argumentType& argumentName) \
401 { \
402     ASSERT_WITH_SECURITY_IMPLICATION(referencePredicate); \
403     return static_cast<ToClassName&>(argumentName); \
404 } \
405 inline const ToClassName& to##ToClassName(const argumentType& argumentName) \
406 { \
407     ASSERT_WITH_SECURITY_IMPLICATION(referencePredicate); \
408     return static_cast<const ToClassName&>(argumentName); \
409 } \
410 void to##ToClassName(const ToClassName*); \
411 void to##ToClassName(const ToClassName&);
412
413 #endif /* WTF_Assertions_h */