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 // Only GCC compiler should be used in this block, so other compilers trying to 43 // mask themselves as GCC should be ignored. 44 #if defined(__GNUC__) && !defined(__clang__) && !defined(__ICC) && !defined(__CUDACC__) && !defined(__LCC__) 45 # define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION _Pragma( "GCC diagnostic push" ) 46 # define CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION _Pragma( "GCC diagnostic pop" ) 47 48 # define CATCH_INTERNAL_IGNORE_BUT_WARN(...) (void)__builtin_constant_p(__VA_ARGS__) 49 50 #endif 51 52 #if defined(__clang__) 53 54 # define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION _Pragma( "clang diagnostic push" ) 55 # define CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION _Pragma( "clang diagnostic pop" ) 56 57 // As of this writing, IBM XL's implementation of __builtin_constant_p has a bug 58 // which results in calls to destructors being emitted for each temporary, 59 // without a matching initialization. In practice, this can result in something 60 // like `std::string::~string` being called on an uninitialized value. 61 // 62 // For example, this code will likely segfault under IBM XL: 63 // ``` 64 // REQUIRE(std::string("12") + "34" == "1234") 65 // ``` 66 // 67 // Therefore, `CATCH_INTERNAL_IGNORE_BUT_WARN` is not implemented. 68 # if !defined(__ibmxl__) && !defined(__CUDACC__) 69 # define CATCH_INTERNAL_IGNORE_BUT_WARN(...) (void)__builtin_constant_p(__VA_ARGS__) /* NOLINT(cppcoreguidelines-pro-type-vararg, hicpp-vararg) */ 70 # endif 71 72 73 # define CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \ 74 _Pragma( "clang diagnostic ignored \"-Wexit-time-destructors\"" ) \ 75 _Pragma( "clang diagnostic ignored \"-Wglobal-constructors\"") 76 77 # define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS \ 78 _Pragma( "clang diagnostic ignored \"-Wparentheses\"" ) 79 80 # define CATCH_INTERNAL_SUPPRESS_UNUSED_WARNINGS \ 81 _Pragma( "clang diagnostic ignored \"-Wunused-variable\"" ) 82 83 # define CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS \ 84 _Pragma( "clang diagnostic ignored \"-Wgnu-zero-variadic-macro-arguments\"" ) 85 86 # define CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS \ 87 _Pragma( "clang diagnostic ignored \"-Wunused-template\"" ) 88 89 #endif // __clang__ 90 91 92 //////////////////////////////////////////////////////////////////////////////// 93 // Assume that non-Windows platforms support posix signals by default 94 #if !defined(CATCH_PLATFORM_WINDOWS) 95 #define CATCH_INTERNAL_CONFIG_POSIX_SIGNALS 96 #endif 97 98 //////////////////////////////////////////////////////////////////////////////// 99 // We know some environments not to support full POSIX signals 100 #if defined(__CYGWIN__) || defined(__QNX__) || defined(__EMSCRIPTEN__) || defined(__DJGPP__) 101 #define CATCH_INTERNAL_CONFIG_NO_POSIX_SIGNALS 102 #endif 103 104 #ifdef __OS400__ 105 # define CATCH_INTERNAL_CONFIG_NO_POSIX_SIGNALS 106 # define CATCH_CONFIG_COLOUR_NONE 107 #endif 108 109 //////////////////////////////////////////////////////////////////////////////// 110 // Android somehow still does not support std::to_string 111 #if defined(__ANDROID__) 112 # define CATCH_INTERNAL_CONFIG_NO_CPP11_TO_STRING 113 # define CATCH_INTERNAL_CONFIG_ANDROID_LOGWRITE 114 #endif 115 116 //////////////////////////////////////////////////////////////////////////////// 117 // Not all Windows environments support SEH properly 118 #if defined(__MINGW32__) 119 # define CATCH_INTERNAL_CONFIG_NO_WINDOWS_SEH 120 #endif 121 122 //////////////////////////////////////////////////////////////////////////////// 123 // PS4 124 #if defined(__ORBIS__) 125 # define CATCH_INTERNAL_CONFIG_NO_NEW_CAPTURE 126 #endif 127 128 //////////////////////////////////////////////////////////////////////////////// 129 // Cygwin 130 #ifdef __CYGWIN__ 131 132 // Required for some versions of Cygwin to declare gettimeofday 133 // see: http://stackoverflow.com/questions/36901803/gettimeofday-not-declared-in-this-scope-cygwin 134 # define _BSD_SOURCE 135 // some versions of cygwin (most) do not support std::to_string. Use the libstd check. 136 // https://gcc.gnu.org/onlinedocs/gcc-4.8.2/libstdc++/api/a01053_source.html line 2812-2813 137 # if !((__cplusplus >= 201103L) && defined(_GLIBCXX_USE_C99) \ 138 && !defined(_GLIBCXX_HAVE_BROKEN_VSWPRINTF)) 139 140 # define CATCH_INTERNAL_CONFIG_NO_CPP11_TO_STRING 141 142 # endif 143 #endif // __CYGWIN__ 144 145 //////////////////////////////////////////////////////////////////////////////// 146 // Visual C++ 147 #if defined(_MSC_VER) 148 149 # define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION __pragma( warning(push) ) 150 # define CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION __pragma( warning(pop) ) 151 152 153 // Universal Windows platform does not support SEH 154 // Or console colours (or console at all...) 155 # if defined(WINAPI_FAMILY) && (WINAPI_FAMILY == WINAPI_FAMILY_APP) 156 # define CATCH_CONFIG_COLOUR_NONE 157 # else 158 # define CATCH_INTERNAL_CONFIG_WINDOWS_SEH 159 # endif 160 161 // MSVC traditional preprocessor needs some workaround for __VA_ARGS__ 162 // _MSVC_TRADITIONAL == 0 means new conformant preprocessor 163 // _MSVC_TRADITIONAL == 1 means old traditional non-conformant preprocessor 164 # if !defined(__clang__) // Handle Clang masquerading for msvc 165 # if !defined(_MSVC_TRADITIONAL) || (defined(_MSVC_TRADITIONAL) && _MSVC_TRADITIONAL) 166 # define CATCH_INTERNAL_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR 167 # endif // MSVC_TRADITIONAL 168 # endif // __clang__ 169 170 #endif // _MSC_VER 171 172 #if defined(_REENTRANT) || defined(_MSC_VER) 173 // Enable async processing, as -pthread is specified or no additional linking is required 174 # define CATCH_INTERNAL_CONFIG_USE_ASYNC 175 #endif // _MSC_VER 176 177 //////////////////////////////////////////////////////////////////////////////// 178 // Check if we are compiled with -fno-exceptions or equivalent 179 #if defined(__EXCEPTIONS) || defined(__cpp_exceptions) || defined(_CPPUNWIND) 180 # define CATCH_INTERNAL_CONFIG_EXCEPTIONS_ENABLED 181 #endif 182 183 //////////////////////////////////////////////////////////////////////////////// 184 // DJGPP 185 #ifdef __DJGPP__ 186 # define CATCH_INTERNAL_CONFIG_NO_WCHAR 187 #endif // __DJGPP__ 188 189 //////////////////////////////////////////////////////////////////////////////// 190 // Embarcadero C++Build 191 #if defined(__BORLANDC__) 192 #define CATCH_INTERNAL_CONFIG_POLYFILL_ISNAN 193 #endif 194 195 //////////////////////////////////////////////////////////////////////////////// 196 197 // Use of __COUNTER__ is suppressed during code analysis in 198 // CLion/AppCode 2017.2.x and former, because __COUNTER__ is not properly 199 // handled by it. 200 // Otherwise all supported compilers support COUNTER macro, 201 // but user still might want to turn it off 202 #if ( !defined(__JETBRAINS_IDE__) || __JETBRAINS_IDE__ >= 20170300L ) 203 #define CATCH_INTERNAL_CONFIG_COUNTER 204 #endif 205 206 207 //////////////////////////////////////////////////////////////////////////////// 208 209 // RTX is a special version of Windows that is real time. 210 // This means that it is detected as Windows, but does not provide 211 // the same set of capabilities as real Windows does. 212 #if defined(UNDER_RTSS) || defined(RTX64_BUILD) 213 #define CATCH_INTERNAL_CONFIG_NO_WINDOWS_SEH 214 #define CATCH_INTERNAL_CONFIG_NO_ASYNC 215 #define CATCH_CONFIG_COLOUR_NONE 216 #endif 217 218 #if !defined(_GLIBCXX_USE_C99_MATH_TR1) 219 #define CATCH_INTERNAL_CONFIG_GLOBAL_NEXTAFTER 220 #endif 221 222 // Various stdlib support checks that require __has_include 223 #if defined(__has_include) 224 // Check if string_view is available and usable 225 #if __has_include(<string_view>) && defined(CATCH_CPP17_OR_GREATER) 226 # define CATCH_INTERNAL_CONFIG_CPP17_STRING_VIEW 227 #endif 228 229 // Check if optional is available and usable 230 # if __has_include(<optional>) && defined(CATCH_CPP17_OR_GREATER) 231 # define CATCH_INTERNAL_CONFIG_CPP17_OPTIONAL 232 # endif // __has_include(<optional>) && defined(CATCH_CPP17_OR_GREATER) 233 234 // Check if byte is available and usable 235 # if __has_include(<cstddef>) && defined(CATCH_CPP17_OR_GREATER) 236 # include <cstddef> 237 # if defined(__cpp_lib_byte) && (__cpp_lib_byte > 0) 238 # define CATCH_INTERNAL_CONFIG_CPP17_BYTE 239 # endif 240 # endif // __has_include(<cstddef>) && defined(CATCH_CPP17_OR_GREATER) 241 242 // Check if variant is available and usable 243 # if __has_include(<variant>) && defined(CATCH_CPP17_OR_GREATER) 244 # if defined(__clang__) && (__clang_major__ < 8) 245 // work around clang bug with libstdc++ https://bugs.llvm.org/show_bug.cgi?id=31852 246 // fix should be in clang 8, workaround in libstdc++ 8.2 247 # include <ciso646> 248 # if defined(__GLIBCXX__) && defined(_GLIBCXX_RELEASE) && (_GLIBCXX_RELEASE < 9) 249 # define CATCH_CONFIG_NO_CPP17_VARIANT 250 # else 251 # define CATCH_INTERNAL_CONFIG_CPP17_VARIANT 252 # endif // defined(__GLIBCXX__) && defined(_GLIBCXX_RELEASE) && (_GLIBCXX_RELEASE < 9) 253 # else 254 # define CATCH_INTERNAL_CONFIG_CPP17_VARIANT 255 # endif // defined(__clang__) && (__clang_major__ < 8) 256 # endif // __has_include(<variant>) && defined(CATCH_CPP17_OR_GREATER) 257 #endif // defined(__has_include) 258 259 260 #if defined(CATCH_INTERNAL_CONFIG_COUNTER) && !defined(CATCH_CONFIG_NO_COUNTER) && !defined(CATCH_CONFIG_COUNTER) 261 # define CATCH_CONFIG_COUNTER 262 #endif 263 #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) 264 # define CATCH_CONFIG_WINDOWS_SEH 265 #endif 266 // This is set by default, because we assume that unix compilers are posix-signal-compatible by default. 267 #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) 268 # define CATCH_CONFIG_POSIX_SIGNALS 269 #endif 270 // This is set by default, because we assume that compilers with no wchar_t support are just rare exceptions. 271 #if !defined(CATCH_INTERNAL_CONFIG_NO_WCHAR) && !defined(CATCH_CONFIG_NO_WCHAR) && !defined(CATCH_CONFIG_WCHAR) 272 # define CATCH_CONFIG_WCHAR 273 #endif 274 275 #if !defined(CATCH_INTERNAL_CONFIG_NO_CPP11_TO_STRING) && !defined(CATCH_CONFIG_NO_CPP11_TO_STRING) && !defined(CATCH_CONFIG_CPP11_TO_STRING) 276 # define CATCH_CONFIG_CPP11_TO_STRING 277 #endif 278 279 #if defined(CATCH_INTERNAL_CONFIG_CPP17_OPTIONAL) && !defined(CATCH_CONFIG_NO_CPP17_OPTIONAL) && !defined(CATCH_CONFIG_CPP17_OPTIONAL) 280 # define CATCH_CONFIG_CPP17_OPTIONAL 281 #endif 282 283 #if defined(CATCH_INTERNAL_CONFIG_CPP17_STRING_VIEW) && !defined(CATCH_CONFIG_NO_CPP17_STRING_VIEW) && !defined(CATCH_CONFIG_CPP17_STRING_VIEW) 284 # define CATCH_CONFIG_CPP17_STRING_VIEW 285 #endif 286 287 #if defined(CATCH_INTERNAL_CONFIG_CPP17_VARIANT) && !defined(CATCH_CONFIG_NO_CPP17_VARIANT) && !defined(CATCH_CONFIG_CPP17_VARIANT) 288 # define CATCH_CONFIG_CPP17_VARIANT 289 #endif 290 291 #if defined(CATCH_INTERNAL_CONFIG_CPP17_BYTE) && !defined(CATCH_CONFIG_NO_CPP17_BYTE) && !defined(CATCH_CONFIG_CPP17_BYTE) 292 # define CATCH_CONFIG_CPP17_BYTE 293 #endif 294 295 296 #if defined(CATCH_CONFIG_EXPERIMENTAL_REDIRECT) 297 # define CATCH_INTERNAL_CONFIG_NEW_CAPTURE 298 #endif 299 300 #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) 301 # define CATCH_CONFIG_NEW_CAPTURE 302 #endif 303 304 #if !defined(CATCH_INTERNAL_CONFIG_EXCEPTIONS_ENABLED) && !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS) 305 # define CATCH_CONFIG_DISABLE_EXCEPTIONS 306 #endif 307 308 #if defined(CATCH_INTERNAL_CONFIG_POLYFILL_ISNAN) && !defined(CATCH_CONFIG_NO_POLYFILL_ISNAN) && !defined(CATCH_CONFIG_POLYFILL_ISNAN) 309 # define CATCH_CONFIG_POLYFILL_ISNAN 310 #endif 311 312 #if defined(CATCH_INTERNAL_CONFIG_USE_ASYNC) && !defined(CATCH_INTERNAL_CONFIG_NO_ASYNC) && !defined(CATCH_CONFIG_NO_USE_ASYNC) && !defined(CATCH_CONFIG_USE_ASYNC) 313 # define CATCH_CONFIG_USE_ASYNC 314 #endif 315 316 #if defined(CATCH_INTERNAL_CONFIG_ANDROID_LOGWRITE) && !defined(CATCH_CONFIG_NO_ANDROID_LOGWRITE) && !defined(CATCH_CONFIG_ANDROID_LOGWRITE) 317 # define CATCH_CONFIG_ANDROID_LOGWRITE 318 #endif 319 320 #if defined(CATCH_INTERNAL_CONFIG_GLOBAL_NEXTAFTER) && !defined(CATCH_CONFIG_NO_GLOBAL_NEXTAFTER) && !defined(CATCH_CONFIG_GLOBAL_NEXTAFTER) 321 # define CATCH_CONFIG_GLOBAL_NEXTAFTER 322 #endif 323 324 325 // Even if we do not think the compiler has that warning, we still have 326 // to provide a macro that can be used by the code. 327 #if !defined(CATCH_INTERNAL_START_WARNINGS_SUPPRESSION) 328 # define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION 329 #endif 330 #if !defined(CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION) 331 # define CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION 332 #endif 333 #if !defined(CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS) 334 # define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS 335 #endif 336 #if !defined(CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS) 337 # define CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS 338 #endif 339 #if !defined(CATCH_INTERNAL_SUPPRESS_UNUSED_WARNINGS) 340 # define CATCH_INTERNAL_SUPPRESS_UNUSED_WARNINGS 341 #endif 342 #if !defined(CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS) 343 # define CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS 344 #endif 345 346 // The goal of this macro is to avoid evaluation of the arguments, but 347 // still have the compiler warn on problems inside... 348 #if !defined(CATCH_INTERNAL_IGNORE_BUT_WARN) 349 # define CATCH_INTERNAL_IGNORE_BUT_WARN(...) 350 #endif 351 352 #if defined(__APPLE__) && defined(__apple_build_version__) && (__clang_major__ < 10) 353 # undef CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS 354 #elif defined(__clang__) && (__clang_major__ < 5) 355 # undef CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS 356 #endif 357 358 #if !defined(CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS) 359 # define CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS 360 #endif 361 362 #if defined(CATCH_CONFIG_DISABLE_EXCEPTIONS) 363 #define CATCH_TRY if ((true)) 364 #define CATCH_CATCH_ALL if ((false)) 365 #define CATCH_CATCH_ANON(type) if ((false)) 366 #else 367 #define CATCH_TRY try 368 #define CATCH_CATCH_ALL catch (...) 369 #define CATCH_CATCH_ANON(type) catch (type) 370 #endif 371 372 #if defined(CATCH_INTERNAL_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR) && !defined(CATCH_CONFIG_NO_TRADITIONAL_MSVC_PREPROCESSOR) && !defined(CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR) 373 #define CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR 374 #endif 375 376 #endif // TWOBLUECUBES_CATCH_COMPILER_CAPABILITIES_HPP_INCLUDED 377 378