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