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#if COMPILER(GCC) && !defined(__OBJC__)
120#define WTF_ATTRIBUTE_PRINTF(formatStringArgument, extraArguments) __attribute__((__format__(printf, formatStringArgument, extraArguments)))
121#else
122#define WTF_ATTRIBUTE_PRINTF(formatStringArgument, extraArguments)
123#endif
124
125/* These helper functions are always declared, but not necessarily always defined if the corresponding function is disabled. */
126
127#ifdef __cplusplus
128extern "C" {
129#endif
130
131typedef enum { WTFLogChannelOff, WTFLogChannelOn } WTFLogChannelState;
132
133typedef struct {
134 unsigned mask;
135 const char *defaultName;
136 WTFLogChannelState state;
137} WTFLogChannel;
138
139WTF_EXPORT_PRIVATE void WTFReportAssertionFailure(const char* file, int line, const char* function, const char* assertion);
140WTF_EXPORT_PRIVATE void WTFReportAssertionFailureWithMessage(const char* file, int line, const char* function, const char* assertion, const char* format, ...) WTF_ATTRIBUTE_PRINTF(5, 6);
141WTF_EXPORT_PRIVATE void WTFReportArgumentAssertionFailure(const char* file, int line, const char* function, const char* argName, const char* assertion);
142WTF_EXPORT_PRIVATE void WTFReportFatalError(const char* file, int line, const char* function, const char* format, ...) WTF_ATTRIBUTE_PRINTF(4, 5);
143WTF_EXPORT_PRIVATE void WTFReportError(const char* file, int line, const char* function, const char* format, ...) WTF_ATTRIBUTE_PRINTF(4, 5);
144WTF_EXPORT_PRIVATE void WTFLog(WTFLogChannel*, const char* format, ...) WTF_ATTRIBUTE_PRINTF(2, 3);
145WTF_EXPORT_PRIVATE void WTFLogVerbose(const char* file, int line, const char* function, WTFLogChannel*, const char* format, ...) WTF_ATTRIBUTE_PRINTF(5, 6);
146WTF_EXPORT_PRIVATE void WTFLogAlways(const char* format, ...) WTF_ATTRIBUTE_PRINTF(1, 2);
147
148WTF_EXPORT_PRIVATE void WTFGetBacktrace(void** stack, int* size);
149WTF_EXPORT_PRIVATE void WTFReportBacktrace();
150WTF_EXPORT_PRIVATE void WTFPrintBacktrace(void** stack, int size);
151
152typedef void (*WTFCrashHookFunction)();
153WTF_EXPORT_PRIVATE void WTFSetCrashHook(WTFCrashHookFunction);
154WTF_EXPORT_PRIVATE void WTFInvokeCrashHook();
155WTF_EXPORT_PRIVATE void WTFInstallReportBacktraceOnCrashHook();
156
157#ifdef __cplusplus
158}
159#endif
160
161/* CRASH() - Raises a fatal error resulting in program termination and triggering either the debugger or the crash reporter.
162
163 Use CRASH() in response to known, unrecoverable errors like out-of-memory.
164 Macro is enabled in both debug and release mode.
165 To test for unknown errors and verify assumptions, use ASSERT instead, to avoid impacting performance in release builds.
166
167 Signals are ignored by the crash reporter on OS X so we must do better.
168*/
169#ifndef CRASH
170#if COMPILER(CLANG) || COMPILER(GCC)
171#define CRASH() \
172 (WTFReportBacktrace(), \
173 WTFInvokeCrashHook(), \
174 (*(int *)(uintptr_t)0xbbadbeef = 0), \
175 __builtin_trap())
176#else
177#define CRASH() \
178 (WTFReportBacktrace(), \
179 WTFInvokeCrashHook(), \
180 (*(int *)(uintptr_t)0xbbadbeef = 0), \
181 ((void(*)())0)() /* More reliable, but doesn't say BBADBEEF */ \
182 )
183#endif
184#endif
185
186#if COMPILER(CLANG)
187#define NO_RETURN_DUE_TO_CRASH NO_RETURN
188#else
189#define NO_RETURN_DUE_TO_CRASH
190#endif
191
192
193/* BACKTRACE
194
195 Print a backtrace to the same location as ASSERT messages.
196*/
197
198#if BACKTRACE_DISABLED
199
200#define BACKTRACE() ((void)0)
201
202#else
203
204#define BACKTRACE() do { \
205 WTFReportBacktrace(); \
206} while(false)
207
208#endif
209
210/* ASSERT, ASSERT_NOT_REACHED, ASSERT_UNUSED
211
212 These macros are compiled out of release builds.
213 Expressions inside them are evaluated in debug builds only.
214*/
215
216#if OS(WINCE)
217/* FIXME: We include this here only to avoid a conflict with the ASSERT macro. */
218#include <windows.h>
219#undef min
220#undef max
221#undef ERROR
222#endif
223
224#if OS(WINDOWS)
225/* FIXME: Change to use something other than ASSERT to avoid this conflict with the underlying platform */
226#undef ASSERT
227#endif
228
229#if ASSERT_DISABLED
230
231#define ASSERT(assertion) ((void)0)
232#define ASSERT_AT(assertion, file, line, function) ((void)0)
233#define ASSERT_NOT_REACHED() ((void)0)
234#define NO_RETURN_DUE_TO_ASSERT
235
236#if COMPILER(RVCT)
237template<typename T>
238inline void assertUnused(T& x) { (void)x; }
239#define ASSERT_UNUSED(variable, assertion) (assertUnused(variable))
240#else
241#define ASSERT_UNUSED(variable, assertion) ((void)variable)
242#endif
243
244#else
245
246#define ASSERT(assertion) \
247 (!(assertion) ? \
248 (WTFReportAssertionFailure(__FILE__, __LINE__, WTF_PRETTY_FUNCTION, #assertion), \
249 CRASH()) : \
250 (void)0)
251
252#define ASSERT_AT(assertion, file, line, function) \
253 (!(assertion) ? \
254 (WTFReportAssertionFailure(file, line, function, #assertion), \
255 CRASH()) : \
256 (void)0)
257
258#define ASSERT_NOT_REACHED() do { \
259 WTFReportAssertionFailure(__FILE__, __LINE__, WTF_PRETTY_FUNCTION, NULL); \
260 CRASH(); \
261} while (0)
262
263#define ASSERT_UNUSED(variable, assertion) ASSERT(assertion)
264
265#define NO_RETURN_DUE_TO_ASSERT NO_RETURN_DUE_TO_CRASH
266
267#endif
268
269/* ASSERT_WITH_SECURITY_IMPLICATION
270
271 Failure of this assertion indicates a possible security vulnerability.
272 Class of vulnerabilities that it tests include bad casts, out of bounds
273 accesses, use-after-frees, etc. Please file a bug using the security
274 template - https://bugs.webkit.org/enter_bug.cgi?product=Security.
275
276*/
277#ifdef ADDRESS_SANITIZER
278
279#define ASSERT_WITH_SECURITY_IMPLICATION(assertion) \
280 (!(assertion) ? \
281 (WTFReportAssertionFailure(__FILE__, __LINE__, WTF_PRETTY_FUNCTION, #assertion), \
282 CRASH()) : \
283 (void)0)
284
285#else
286
287#define ASSERT_WITH_SECURITY_IMPLICATION(assertion) ASSERT(assertion)
288
289#endif
290
291/* ASSERT_WITH_MESSAGE */
292
293#if COMPILER(MSVC7_OR_LOWER)
294#define ASSERT_WITH_MESSAGE(assertion) ((void)0)
295#elif ASSERT_MSG_DISABLED
296#define ASSERT_WITH_MESSAGE(assertion, ...) ((void)0)
297#else
298#define ASSERT_WITH_MESSAGE(assertion, ...) do \
299 if (!(assertion)) { \
300 WTFReportAssertionFailureWithMessage(__FILE__, __LINE__, WTF_PRETTY_FUNCTION, #assertion, __VA_ARGS__); \
301 CRASH(); \
302 } \
303while (0)
304#endif
305
306/* ASSERT_WITH_MESSAGE_UNUSED */
307
308#if COMPILER(MSVC7_OR_LOWER)
309#define ASSERT_WITH_MESSAGE_UNUSED(variable, assertion) ((void)0)
310#elif ASSERT_MSG_DISABLED
311#if COMPILER(INTEL) && !OS(WINDOWS) || COMPILER(RVCT)
312template<typename T>
313inline void assertWithMessageUnused(T& x) { (void)x; }
314#define ASSERT_WITH_MESSAGE_UNUSED(variable, assertion, ...) (assertWithMessageUnused(variable))
315#else
316#define ASSERT_WITH_MESSAGE_UNUSED(variable, assertion, ...) ((void)variable)
317#endif
318#else
319#define ASSERT_WITH_MESSAGE_UNUSED(variable, assertion, ...) do \
320 if (!(assertion)) { \
321 WTFReportAssertionFailureWithMessage(__FILE__, __LINE__, WTF_PRETTY_FUNCTION, #assertion, __VA_ARGS__); \
322 CRASH(); \
323 } \
324while (0)
325#endif
326
327
328/* ASSERT_ARG */
329
330#if ASSERT_ARG_DISABLED
331
332#define ASSERT_ARG(argName, assertion) ((void)0)
333
334#else
335
336#define ASSERT_ARG(argName, assertion) do \
337 if (!(assertion)) { \
338 WTFReportArgumentAssertionFailure(__FILE__, __LINE__, WTF_PRETTY_FUNCTION, #argName, #assertion); \
339 CRASH(); \
340 } \
341while (0)
342
343#endif
344
345/* COMPILE_ASSERT */
346#ifndef COMPILE_ASSERT
347#if COMPILER_SUPPORTS(C_STATIC_ASSERT)
348/* Unlike static_assert below, this also works in plain C code. */
349#define COMPILE_ASSERT(exp, name) _Static_assert((exp), #name)
350#elif COMPILER_SUPPORTS(CXX_STATIC_ASSERT)
351#define COMPILE_ASSERT(exp, name) static_assert((exp), #name)
352#else
353#define COMPILE_ASSERT(exp, name) typedef int dummy##name [(exp) ? 1 : -1]
354#endif
355#endif
356
357/* FATAL */
358
359#if COMPILER(MSVC7_OR_LOWER)
360#define FATAL() ((void)0)
361#elif FATAL_DISABLED
362#define FATAL(...) ((void)0)
363#else
364#define FATAL(...) do { \
365 WTFReportFatalError(__FILE__, __LINE__, WTF_PRETTY_FUNCTION, __VA_ARGS__); \
366 CRASH(); \
367} while (0)
368#endif
369
370/* LOG_ERROR */
371
372#if COMPILER(MSVC7_OR_LOWER)
373#define LOG_ERROR() ((void)0)
374#elif ERROR_DISABLED
375#define LOG_ERROR(...) ((void)0)
376#else
377#define LOG_ERROR(...) WTFReportError(__FILE__, __LINE__, WTF_PRETTY_FUNCTION, __VA_ARGS__)
378#endif
379
380/* LOG */
381
382#if COMPILER(MSVC7_OR_LOWER)
383#define LOG() ((void)0)
384#elif LOG_DISABLED
385#define LOG(channel, ...) ((void)0)
386#else
387#define LOG(channel, ...) WTFLog(&JOIN_LOG_CHANNEL_WITH_PREFIX(LOG_CHANNEL_PREFIX, channel), __VA_ARGS__)
388#define JOIN_LOG_CHANNEL_WITH_PREFIX(prefix, channel) JOIN_LOG_CHANNEL_WITH_PREFIX_LEVEL_2(prefix, channel)
389#define JOIN_LOG_CHANNEL_WITH_PREFIX_LEVEL_2(prefix, channel) prefix ## channel
390#endif
391
392/* LOG_VERBOSE */
393
394#if COMPILER(MSVC7_OR_LOWER)
395#define LOG_VERBOSE(channel) ((void)0)
396#elif LOG_DISABLED
397#define LOG_VERBOSE(channel, ...) ((void)0)
398#else
399#define LOG_VERBOSE(channel, ...) WTFLogVerbose(__FILE__, __LINE__, WTF_PRETTY_FUNCTION, &JOIN_LOG_CHANNEL_WITH_PREFIX(LOG_CHANNEL_PREFIX, channel), __VA_ARGS__)
400#endif
401
402/* UNREACHABLE_FOR_PLATFORM */
403
404#if COMPILER(CLANG)
405// This would be a macro except that its use of #pragma works best around
406// a function. Hence it uses macro naming convention.
407#pragma clang diagnostic push
408#pragma clang diagnostic ignored "-Wmissing-noreturn"
409static inline void UNREACHABLE_FOR_PLATFORM()
410{
411 ASSERT_NOT_REACHED();
412}
413#pragma clang diagnostic pop
414#else
415#define UNREACHABLE_FOR_PLATFORM() ASSERT_NOT_REACHED()
416#endif
417
418#if ASSERT_DISABLED
419#define RELEASE_ASSERT(assertion) (UNLIKELY(!(assertion)) ? (CRASH()) : (void)0)
420#define RELEASE_ASSERT_WITH_MESSAGE(assertion, ...) RELEASE_ASSERT(assertion)
421#define RELEASE_ASSERT_NOT_REACHED() CRASH()
422#else
423#define RELEASE_ASSERT(assertion) ASSERT(assertion)
424#define RELEASE_ASSERT_WITH_MESSAGE(assertion, ...) ASSERT_WITH_MESSAGE(assertion, __VA_ARGS__)
425#define RELEASE_ASSERT_NOT_REACHED() ASSERT_NOT_REACHED()
426#endif
427
428#endif /* WTF_Assertions_h */
429

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