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

source code of qtdeclarative/src/3rdparty/masm/wtf/Assertions.h