1 /*
2  *  Created by Phil on 15/04/2013.
3  *  Copyright 2013 Two Blue Cubes Ltd. All rights reserved.
4  *
5  *  Distributed under the Boost Software License, Version 1.0. (See accompanying
6  *  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
7  */
8 #ifndef TWOBLUECUBES_CATCH_COMPILER_CAPABILITIES_HPP_INCLUDED
9 #define TWOBLUECUBES_CATCH_COMPILER_CAPABILITIES_HPP_INCLUDED
10 
11 // Detect a number of compiler features - by compiler
12 // The following features are defined:
13 //
14 // CATCH_CONFIG_COUNTER : is the __COUNTER__ macro supported?
15 // CATCH_CONFIG_WINDOWS_SEH : is Windows SEH supported?
16 // CATCH_CONFIG_POSIX_SIGNALS : are POSIX signals supported?
17 // CATCH_CONFIG_DISABLE_EXCEPTIONS : Are exceptions enabled?
18 // ****************
19 // Note to maintainers: if new toggles are added please document them
20 // in configuration.md, too
21 // ****************
22 
23 // In general each macro has a _NO_<feature name> form
24 // (e.g. CATCH_CONFIG_NO_POSIX_SIGNALS) which disables the feature.
25 // Many features, at point of detection, define an _INTERNAL_ macro, so they
26 // can be combined, en-mass, with the _NO_ forms later.
27 
28 #include "catch_platform.h"
29 
30 #ifdef __cplusplus
31 
32 #  if (__cplusplus >= 201402L) || (defined(_MSVC_LANG) && _MSVC_LANG >= 201402L)
33 #    define CATCH_CPP14_OR_GREATER
34 #  endif
35 
36 #  if (__cplusplus >= 201703L) || (defined(_MSVC_LANG) && _MSVC_LANG >= 201703L)
37 #    define CATCH_CPP17_OR_GREATER
38 #  endif
39 
40 #endif
41 
42 #if defined(CATCH_CPP17_OR_GREATER)
43 #  define CATCH_INTERNAL_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS
44 #endif
45 
46 // We have to avoid both ICC and Clang, because they try to mask themselves
47 // as gcc, and we want only GCC in this block
48 #if defined(__GNUC__) && !defined(__clang__) && !defined(__ICC)
49 #    define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION _Pragma( "GCC diagnostic push" )
50 #    define CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION  _Pragma( "GCC diagnostic pop" )
51 #endif
52 
53 #if defined(__clang__)
54 
55 #    define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION _Pragma( "clang diagnostic push" )
56 #    define CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION  _Pragma( "clang diagnostic pop" )
57 
58 #    define CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
59          _Pragma( "clang diagnostic ignored \"-Wexit-time-destructors\"" ) \
60          _Pragma( "clang diagnostic ignored \"-Wglobal-constructors\"")
61 
62 #    define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS \
63          _Pragma( "clang diagnostic ignored \"-Wparentheses\"" )
64 
65 #    define CATCH_INTERNAL_SUPPRESS_UNUSED_WARNINGS \
66          _Pragma( "clang diagnostic ignored \"-Wunused-variable\"" )
67 
68 #    define CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS \
69          _Pragma( "clang diagnostic ignored \"-Wgnu-zero-variadic-macro-arguments\"" )
70 
71 #    define CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS \
72          _Pragma( "clang diagnostic ignored \"-Wunused-template\"" )
73 
74 #endif // __clang__
75 
76 
77 ////////////////////////////////////////////////////////////////////////////////
78 // Assume that non-Windows platforms support posix signals by default
79 #if !defined(CATCH_PLATFORM_WINDOWS)
80     #define CATCH_INTERNAL_CONFIG_POSIX_SIGNALS
81 #endif
82 
83 ////////////////////////////////////////////////////////////////////////////////
84 // We know some environments not to support full POSIX signals
85 #if defined(__CYGWIN__) || defined(__QNX__) || defined(__EMSCRIPTEN__) || defined(__DJGPP__)
86     #define CATCH_INTERNAL_CONFIG_NO_POSIX_SIGNALS
87 #endif
88 
89 #ifdef __OS400__
90 #       define CATCH_INTERNAL_CONFIG_NO_POSIX_SIGNALS
91 #       define CATCH_CONFIG_COLOUR_NONE
92 #endif
93 
94 ////////////////////////////////////////////////////////////////////////////////
95 // Android somehow still does not support std::to_string
96 #if defined(__ANDROID__)
97 #    define CATCH_INTERNAL_CONFIG_NO_CPP11_TO_STRING
98 #    define CATCH_INTERNAL_CONFIG_ANDROID_LOGWRITE
99 #endif
100 
101 ////////////////////////////////////////////////////////////////////////////////
102 // Not all Windows environments support SEH properly
103 #if defined(__MINGW32__)
104 #    define CATCH_INTERNAL_CONFIG_NO_WINDOWS_SEH
105 #endif
106 
107 ////////////////////////////////////////////////////////////////////////////////
108 // PS4
109 #if defined(__ORBIS__)
110 #    define CATCH_INTERNAL_CONFIG_NO_NEW_CAPTURE
111 #endif
112 
113 ////////////////////////////////////////////////////////////////////////////////
114 // Cygwin
115 #ifdef __CYGWIN__
116 
117 // Required for some versions of Cygwin to declare gettimeofday
118 // see: http://stackoverflow.com/questions/36901803/gettimeofday-not-declared-in-this-scope-cygwin
119 #   define _BSD_SOURCE
120 // some versions of cygwin (most) do not support std::to_string. Use the libstd check.
121 // https://gcc.gnu.org/onlinedocs/gcc-4.8.2/libstdc++/api/a01053_source.html line 2812-2813
122 # if !((__cplusplus >= 201103L) && defined(_GLIBCXX_USE_C99) \
123            && !defined(_GLIBCXX_HAVE_BROKEN_VSWPRINTF))
124 
125 #    define CATCH_INTERNAL_CONFIG_NO_CPP11_TO_STRING
126 
127 # endif
128 #endif // __CYGWIN__
129 
130 ////////////////////////////////////////////////////////////////////////////////
131 // Visual C++
132 #if defined(_MSC_VER)
133 
134 #  define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION __pragma( warning(push) )
135 #  define CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION  __pragma( warning(pop) )
136 
137 #  if _MSC_VER >= 1900 // Visual Studio 2015 or newer
138 #    define CATCH_INTERNAL_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS
139 #  endif
140 
141 // Universal Windows platform does not support SEH
142 // Or console colours (or console at all...)
143 #  if defined(WINAPI_FAMILY) && (WINAPI_FAMILY == WINAPI_FAMILY_APP)
144 #    define CATCH_CONFIG_COLOUR_NONE
145 #  else
146 #    define CATCH_INTERNAL_CONFIG_WINDOWS_SEH
147 #  endif
148 
149 // MSVC traditional preprocessor needs some workaround for __VA_ARGS__
150 // _MSVC_TRADITIONAL == 0 means new conformant preprocessor
151 // _MSVC_TRADITIONAL == 1 means old traditional non-conformant preprocessor
152 #  if !defined(__clang__) // Handle Clang masquerading for msvc
153 #    if !defined(_MSVC_TRADITIONAL) || (defined(_MSVC_TRADITIONAL) && _MSVC_TRADITIONAL)
154 #      define CATCH_INTERNAL_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
155 #    endif // MSVC_TRADITIONAL
156 #  endif // __clang__
157 
158 #endif // _MSC_VER
159 
160 #if defined(_REENTRANT) || defined(_MSC_VER)
161 // Enable async processing, as -pthread is specified or no additional linking is required
162 # define CATCH_INTERNAL_CONFIG_USE_ASYNC
163 #endif // _MSC_VER
164 
165 ////////////////////////////////////////////////////////////////////////////////
166 // Check if we are compiled with -fno-exceptions or equivalent
167 #if defined(__EXCEPTIONS) || defined(__cpp_exceptions) || defined(_CPPUNWIND)
168 #  define CATCH_INTERNAL_CONFIG_EXCEPTIONS_ENABLED
169 #endif
170 
171 ////////////////////////////////////////////////////////////////////////////////
172 // DJGPP
173 #ifdef __DJGPP__
174 #  define CATCH_INTERNAL_CONFIG_NO_WCHAR
175 #endif // __DJGPP__
176 
177 ////////////////////////////////////////////////////////////////////////////////
178 // Embarcadero C++Build
179 #if defined(__BORLANDC__)
180     #define CATCH_INTERNAL_CONFIG_POLYFILL_ISNAN
181 #endif
182 
183 ////////////////////////////////////////////////////////////////////////////////
184 
185 // Use of __COUNTER__ is suppressed during code analysis in
186 // CLion/AppCode 2017.2.x and former, because __COUNTER__ is not properly
187 // handled by it.
188 // Otherwise all supported compilers support COUNTER macro,
189 // but user still might want to turn it off
190 #if ( !defined(__JETBRAINS_IDE__) || __JETBRAINS_IDE__ >= 20170300L )
191     #define CATCH_INTERNAL_CONFIG_COUNTER
192 #endif
193 
194 
195 ////////////////////////////////////////////////////////////////////////////////
196 
197 // RTX is a special version of Windows that is real time.
198 // This means that it is detected as Windows, but does not provide
199 // the same set of capabilities as real Windows does.
200 #if defined(UNDER_RTSS) || defined(RTX64_BUILD)
201     #define CATCH_INTERNAL_CONFIG_NO_WINDOWS_SEH
202     #define CATCH_INTERNAL_CONFIG_NO_ASYNC
203     #define CATCH_CONFIG_COLOUR_NONE
204 #endif
205 
206 #if defined(__UCLIBC__)
207 #define CATCH_INTERNAL_CONFIG_GLOBAL_NEXTAFTER
208 #endif
209 
210 // Various stdlib support checks that require __has_include
211 #if defined(__has_include)
212   // Check if string_view is available and usable
213   #if __has_include(<string_view>) && defined(CATCH_CPP17_OR_GREATER)
214   #    define CATCH_INTERNAL_CONFIG_CPP17_STRING_VIEW
215   #endif
216 
217   // Check if optional is available and usable
218   #  if __has_include(<optional>) && defined(CATCH_CPP17_OR_GREATER)
219   #    define CATCH_INTERNAL_CONFIG_CPP17_OPTIONAL
220   #  endif // __has_include(<optional>) && defined(CATCH_CPP17_OR_GREATER)
221 
222   // Check if byte is available and usable
223   #  if __has_include(<cstddef>) && defined(CATCH_CPP17_OR_GREATER)
224   #    define CATCH_INTERNAL_CONFIG_CPP17_BYTE
225   #  endif // __has_include(<cstddef>) && defined(CATCH_CPP17_OR_GREATER)
226 
227   // Check if variant is available and usable
228   #  if __has_include(<variant>) && defined(CATCH_CPP17_OR_GREATER)
229   #    if defined(__clang__) && (__clang_major__ < 8)
230          // work around clang bug with libstdc++ https://bugs.llvm.org/show_bug.cgi?id=31852
231          // fix should be in clang 8, workaround in libstdc++ 8.2
232   #      include <ciso646>
233   #      if defined(__GLIBCXX__) && defined(_GLIBCXX_RELEASE) && (_GLIBCXX_RELEASE < 9)
234   #        define CATCH_CONFIG_NO_CPP17_VARIANT
235   #      else
236   #        define CATCH_INTERNAL_CONFIG_CPP17_VARIANT
237   #      endif // defined(__GLIBCXX__) && defined(_GLIBCXX_RELEASE) && (_GLIBCXX_RELEASE < 9)
238   #    else
239   #      define CATCH_INTERNAL_CONFIG_CPP17_VARIANT
240   #    endif // defined(__clang__) && (__clang_major__ < 8)
241   #  endif // __has_include(<variant>) && defined(CATCH_CPP17_OR_GREATER)
242 #endif // defined(__has_include)
243 
244 
245 #if defined(CATCH_INTERNAL_CONFIG_COUNTER) && !defined(CATCH_CONFIG_NO_COUNTER) && !defined(CATCH_CONFIG_COUNTER)
246 #   define CATCH_CONFIG_COUNTER
247 #endif
248 #if defined(CATCH_INTERNAL_CONFIG_WINDOWS_SEH) && !defined(CATCH_CONFIG_NO_WINDOWS_SEH) && !defined(CATCH_CONFIG_WINDOWS_SEH) && !defined(CATCH_INTERNAL_CONFIG_NO_WINDOWS_SEH)
249 #   define CATCH_CONFIG_WINDOWS_SEH
250 #endif
251 // This is set by default, because we assume that unix compilers are posix-signal-compatible by default.
252 #if defined(CATCH_INTERNAL_CONFIG_POSIX_SIGNALS) && !defined(CATCH_INTERNAL_CONFIG_NO_POSIX_SIGNALS) && !defined(CATCH_CONFIG_NO_POSIX_SIGNALS) && !defined(CATCH_CONFIG_POSIX_SIGNALS)
253 #   define CATCH_CONFIG_POSIX_SIGNALS
254 #endif
255 // This is set by default, because we assume that compilers with no wchar_t support are just rare exceptions.
256 #if !defined(CATCH_INTERNAL_CONFIG_NO_WCHAR) && !defined(CATCH_CONFIG_NO_WCHAR) && !defined(CATCH_CONFIG_WCHAR)
257 #   define CATCH_CONFIG_WCHAR
258 #endif
259 
260 #if !defined(CATCH_INTERNAL_CONFIG_NO_CPP11_TO_STRING) && !defined(CATCH_CONFIG_NO_CPP11_TO_STRING) && !defined(CATCH_CONFIG_CPP11_TO_STRING)
261 #    define CATCH_CONFIG_CPP11_TO_STRING
262 #endif
263 
264 #if defined(CATCH_INTERNAL_CONFIG_CPP17_OPTIONAL) && !defined(CATCH_CONFIG_NO_CPP17_OPTIONAL) && !defined(CATCH_CONFIG_CPP17_OPTIONAL)
265 #  define CATCH_CONFIG_CPP17_OPTIONAL
266 #endif
267 
268 #if defined(CATCH_INTERNAL_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS) && !defined(CATCH_CONFIG_NO_CPP17_UNCAUGHT_EXCEPTIONS) && !defined(CATCH_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS)
269 #  define CATCH_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS
270 #endif
271 
272 #if defined(CATCH_INTERNAL_CONFIG_CPP17_STRING_VIEW) && !defined(CATCH_CONFIG_NO_CPP17_STRING_VIEW) && !defined(CATCH_CONFIG_CPP17_STRING_VIEW)
273 #  define CATCH_CONFIG_CPP17_STRING_VIEW
274 #endif
275 
276 #if defined(CATCH_INTERNAL_CONFIG_CPP17_VARIANT) && !defined(CATCH_CONFIG_NO_CPP17_VARIANT) && !defined(CATCH_CONFIG_CPP17_VARIANT)
277 #  define CATCH_CONFIG_CPP17_VARIANT
278 #endif
279 
280 #if defined(CATCH_INTERNAL_CONFIG_CPP17_BYTE) && !defined(CATCH_CONFIG_NO_CPP17_BYTE) && !defined(CATCH_CONFIG_CPP17_BYTE)
281 #  define CATCH_CONFIG_CPP17_BYTE
282 #endif
283 
284 
285 #if defined(CATCH_CONFIG_EXPERIMENTAL_REDIRECT)
286 #  define CATCH_INTERNAL_CONFIG_NEW_CAPTURE
287 #endif
288 
289 #if defined(CATCH_INTERNAL_CONFIG_NEW_CAPTURE) && !defined(CATCH_INTERNAL_CONFIG_NO_NEW_CAPTURE) && !defined(CATCH_CONFIG_NO_NEW_CAPTURE) && !defined(CATCH_CONFIG_NEW_CAPTURE)
290 #  define CATCH_CONFIG_NEW_CAPTURE
291 #endif
292 
293 #if !defined(CATCH_INTERNAL_CONFIG_EXCEPTIONS_ENABLED) && !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
294 #  define CATCH_CONFIG_DISABLE_EXCEPTIONS
295 #endif
296 
297 #if defined(CATCH_INTERNAL_CONFIG_POLYFILL_ISNAN) && !defined(CATCH_CONFIG_NO_POLYFILL_ISNAN) && !defined(CATCH_CONFIG_POLYFILL_ISNAN)
298 #  define CATCH_CONFIG_POLYFILL_ISNAN
299 #endif
300 
301 #if defined(CATCH_INTERNAL_CONFIG_USE_ASYNC)  && !defined(CATCH_INTERNAL_CONFIG_NO_ASYNC) && !defined(CATCH_CONFIG_NO_USE_ASYNC) && !defined(CATCH_CONFIG_USE_ASYNC)
302 #  define CATCH_CONFIG_USE_ASYNC
303 #endif
304 
305 #if defined(CATCH_INTERNAL_CONFIG_ANDROID_LOGWRITE) && !defined(CATCH_CONFIG_NO_ANDROID_LOGWRITE) && !defined(CATCH_CONFIG_ANDROID_LOGWRITE)
306 #  define CATCH_CONFIG_ANDROID_LOGWRITE
307 #endif
308 
309 #if defined(CATCH_INTERNAL_CONFIG_GLOBAL_NEXTAFTER) && !defined(CATCH_CONFIG_NO_GLOBAL_NEXTAFTER) && !defined(CATCH_CONFIG_GLOBAL_NEXTAFTER)
310 #  define CATCH_CONFIG_GLOBAL_NEXTAFTER
311 #endif
312 
313 
314 // Even if we do not think the compiler has that warning, we still have
315 // to provide a macro that can be used by the code.
316 #if !defined(CATCH_INTERNAL_START_WARNINGS_SUPPRESSION)
317 #   define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION
318 #endif
319 #if !defined(CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION)
320 #   define CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION
321 #endif
322 #if !defined(CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS)
323 #   define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS
324 #endif
325 #if !defined(CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS)
326 #   define CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS
327 #endif
328 #if !defined(CATCH_INTERNAL_SUPPRESS_UNUSED_WARNINGS)
329 #   define CATCH_INTERNAL_SUPPRESS_UNUSED_WARNINGS
330 #endif
331 #if !defined(CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS)
332 #   define CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS
333 #endif
334 
335 
336 #if defined(__APPLE__) && defined(__apple_build_version__) && (__clang_major__ < 10)
337 #   undef CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS
338 #elif defined(__clang__) && (__clang_major__ < 5)
339 #   undef CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS
340 #endif
341 
342 #if !defined(CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS)
343 #   define CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS
344 #endif
345 
346 #if defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
347 #define CATCH_TRY if ((true))
348 #define CATCH_CATCH_ALL if ((false))
349 #define CATCH_CATCH_ANON(type) if ((false))
350 #else
351 #define CATCH_TRY try
352 #define CATCH_CATCH_ALL catch (...)
353 #define CATCH_CATCH_ANON(type) catch (type)
354 #endif
355 
356 #if defined(CATCH_INTERNAL_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR) && !defined(CATCH_CONFIG_NO_TRADITIONAL_MSVC_PREPROCESSOR) && !defined(CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR)
357 #define CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
358 #endif
359 
360 #endif // TWOBLUECUBES_CATCH_COMPILER_CAPABILITIES_HPP_INCLUDED
361 
362