catch_compiler_capabilities.h 15 KB

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