diff options
| author | Martin Hořeňovský | 2024-10-27 17:08:47 +0100 |
|---|---|---|
| committer | Martin Hořeňovský | 2024-10-27 20:27:03 +0100 |
| commit | e26028880790addff43cc5546de1e39214d86a04 (patch) | |
| tree | 0d3dede7149aa56198e6b0ecb0f8752eb005eeb7 /src/catch2 | |
| parent | 7c2e1fb1b210cf1710549fd8b2df37d700b90178 (diff) | |
| download | catch3-e26028880790addff43cc5546de1e39214d86a04.tar.gz | |
Allow disabling use of __builtin_constant_p in internal macros
Turns out that even in GCC, the expression in `__builtin_cosntant_p`
can end up evaluated and side-effects executed. To allow users to
work around this bug, I added a configuration option to disable its
use in internal macros.
Related to #2925
Diffstat (limited to 'src/catch2')
| -rw-r--r-- | src/catch2/catch_user_config.hpp.in | 9 | ||||
| -rw-r--r-- | src/catch2/internal/catch_compiler_capabilities.hpp | 70 |
2 files changed, 48 insertions, 31 deletions
diff --git a/src/catch2/catch_user_config.hpp.in b/src/catch2/catch_user_config.hpp.in index 10d61937..3acda688 100644 --- a/src/catch2/catch_user_config.hpp.in +++ b/src/catch2/catch_user_config.hpp.in @@ -178,6 +178,15 @@ #endif +#cmakedefine CATCH_CONFIG_USE_BUILTIN_CONSTANT_P +#cmakedefine CATCH_CONFIG_NO_USE_BUILTIN_CONSTANT_P + +#if defined( CATCH_CONFIG_USE_BUILTIN_CONSTANT_P ) && \ + defined( CATCH_CONFIG_NO_USE_BUILTIN_CONSTANT_P ) +# error Cannot force USE_BUILTIN_CONSTANT_P to both ON and OFF +#endif + + // ------ // Simple toggle defines // their value is never used and they cannot be overridden diff --git a/src/catch2/internal/catch_compiler_capabilities.hpp b/src/catch2/internal/catch_compiler_capabilities.hpp index 7f09da51..d544b00c 100644 --- a/src/catch2/internal/catch_compiler_capabilities.hpp +++ b/src/catch2/internal/catch_compiler_capabilities.hpp @@ -62,7 +62,7 @@ # define CATCH_INTERNAL_SUPPRESS_SHADOW_WARNINGS \ _Pragma( "GCC diagnostic ignored \"-Wshadow\"" ) -# define CATCH_INTERNAL_IGNORE_BUT_WARN(...) (void)__builtin_constant_p(__VA_ARGS__) +# define CATCH_INTERNAL_CONFIG_USE_BUILTIN_CONSTANT_P #endif @@ -86,35 +86,13 @@ // clang-cl defines _MSC_VER as well as __clang__, which could cause the // start/stop internal suppression macros to be double defined. #if defined(__clang__) && !defined(_MSC_VER) - +# define CATCH_INTERNAL_CONFIG_USE_BUILTIN_CONSTANT_P # define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION _Pragma( "clang diagnostic push" ) # define CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION _Pragma( "clang diagnostic pop" ) - #endif // __clang__ && !_MSC_VER #if defined(__clang__) -// As of this writing, IBM XL's implementation of __builtin_constant_p has a bug -// which results in calls to destructors being emitted for each temporary, -// without a matching initialization. In practice, this can result in something -// like `std::string::~string` being called on an uninitialized value. -// -// For example, this code will likely segfault under IBM XL: -// ``` -// REQUIRE(std::string("12") + "34" == "1234") -// ``` -// -// Similarly, NVHPC's implementation of `__builtin_constant_p` has a bug which -// results in calls to the immediately evaluated lambda expressions to be -// reported as unevaluated lambdas. -// https://developer.nvidia.com/nvidia_bug/3321845. -// -// Therefore, `CATCH_INTERNAL_IGNORE_BUT_WARN` is not implemented. -# if !defined(__ibmxl__) && !defined(__CUDACC__) && !defined( __NVCOMPILER ) -# define CATCH_INTERNAL_IGNORE_BUT_WARN(...) (void)__builtin_constant_p(__VA_ARGS__) /* NOLINT(cppcoreguidelines-pro-type-vararg, hicpp-vararg) */ -# endif - - # define CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \ _Pragma( "clang diagnostic ignored \"-Wexit-time-destructors\"" ) \ _Pragma( "clang diagnostic ignored \"-Wglobal-constructors\"") @@ -139,6 +117,27 @@ #endif // __clang__ +// As of this writing, IBM XL's implementation of __builtin_constant_p has a bug +// which results in calls to destructors being emitted for each temporary, +// without a matching initialization. In practice, this can result in something +// like `std::string::~string` being called on an uninitialized value. +// +// For example, this code will likely segfault under IBM XL: +// ``` +// REQUIRE(std::string("12") + "34" == "1234") +// ``` +// +// Similarly, NVHPC's implementation of `__builtin_constant_p` has a bug which +// results in calls to the immediately evaluated lambda expressions to be +// reported as unevaluated lambdas. +// https://developer.nvidia.com/nvidia_bug/3321845. +// +// Therefore, `CATCH_INTERNAL_IGNORE_BUT_WARN` is not implemented. +#if defined( __ibmxl__ ) || defined( __CUDACC__ ) || defined( __NVCOMPILER ) +# define CATCH_INTERNAL_CONFIG_NO_USE_BUILTIN_CONSTANT_P +#endif + + //////////////////////////////////////////////////////////////////////////////// // We know some environments not to support full POSIX signals @@ -362,6 +361,22 @@ #endif +// The goal of this macro is to avoid evaluation of the arguments, but +// still have the compiler warn on problems inside... +#if defined( CATCH_INTERNAL_CONFIG_USE_BUILTIN_CONSTANT_P ) && \ + !defined( CATCH_INTERNAL_CONFIG_NO_USE_BUILTIN_CONSTANT_P ) && !defined(CATCH_CONFIG_USE_BUILTIN_CONSTANT_P) +#define CATCH_CONFIG_USE_BUILTIN_CONSTANT_P +#endif + +#if defined( CATCH_CONFIG_USE_BUILTIN_CONSTANT_P ) && \ + !defined( CATCH_CONFIG_NO_USE_BUILTIN_CONSTANT_P ) +# define CATCH_INTERNAL_IGNORE_BUT_WARN( ... ) \ + (void)__builtin_constant_p( __VA_ARGS__ ) /* NOLINT(cppcoreguidelines-pro-type-vararg, \ + hicpp-vararg) */ +#else +# define CATCH_INTERNAL_IGNORE_BUT_WARN( ... ) +#endif + // Even if we do not think the compiler has that warning, we still have // to provide a macro that can be used by the code. #if !defined(CATCH_INTERNAL_START_WARNINGS_SUPPRESSION) @@ -398,13 +413,6 @@ # define CATCH_INTERNAL_SUPPRESS_SHADOW_WARNINGS #endif - -// The goal of this macro is to avoid evaluation of the arguments, but -// still have the compiler warn on problems inside... -#if !defined(CATCH_INTERNAL_IGNORE_BUT_WARN) -# define CATCH_INTERNAL_IGNORE_BUT_WARN(...) -#endif - #if defined(__APPLE__) && defined(__apple_build_version__) && (__clang_major__ < 10) # undef CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS #elif defined(__clang__) && (__clang_major__ < 5) |