Make warnings in assertions fire for GCC/Clang again

The old code caused warnings to fire under MSVC, and Clang <3.8.
I could not find a GCC version where it worked, but I assume that it
did at some point.

This new code causes all of MSVC, GCC, Clang, in current versions,
to emit signed/unsigned comparison warning in test like this:

```cpp
TEST_CASE() {
    int32_t i = -1;
    uint32_t j = 1;
    REQUIRE(i != j);
}
```

Where previously only MSVC would emit the warning.

Fixes #1880
This commit is contained in:
Martin Hořeňovský 2020-03-18 20:59:25 +01:00
parent 9e09d79946
commit b7b346c3e5
No known key found for this signature in database
GPG Key ID: DE48307B8B0D381A
3 changed files with 25 additions and 2 deletions

View File

@ -41,6 +41,8 @@
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
#define INTERNAL_CATCH_TEST( macroName, resultDisposition, ... ) \ #define INTERNAL_CATCH_TEST( macroName, resultDisposition, ... ) \
do { \ do { \
/* The expression should not be evaluated, but warnings should hopefully be checked */ \
CATCH_INTERNAL_IGNORE_BUT_WARN(__VA_ARGS__); \
Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(__VA_ARGS__), resultDisposition ); \ Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(__VA_ARGS__), resultDisposition ); \
INTERNAL_CATCH_TRY { \ INTERNAL_CATCH_TRY { \
CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \ CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
@ -49,8 +51,7 @@
CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \ CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \
} INTERNAL_CATCH_CATCH( catchAssertionHandler ) \ } INTERNAL_CATCH_CATCH( catchAssertionHandler ) \
INTERNAL_CATCH_REACT( catchAssertionHandler ) \ INTERNAL_CATCH_REACT( catchAssertionHandler ) \
} while( (void)0, (false) && static_cast<bool>( !!(__VA_ARGS__) ) ) // the expression here is never evaluated at runtime but it forces the compiler to give it a look } while( false )
// The double negation silences MSVC's C4800 warning, the static_cast forces short-circuit evaluation if the type has overloaded &&.
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
#define INTERNAL_CATCH_IF( macroName, resultDisposition, ... ) \ #define INTERNAL_CATCH_IF( macroName, resultDisposition, ... ) \

View File

@ -48,6 +48,9 @@
#if defined(__GNUC__) && !defined(__clang__) && !defined(__ICC) #if defined(__GNUC__) && !defined(__clang__) && !defined(__ICC)
# define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION _Pragma( "GCC diagnostic push" ) # define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION _Pragma( "GCC diagnostic push" )
# define CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION _Pragma( "GCC diagnostic pop" ) # define CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION _Pragma( "GCC diagnostic pop" )
# define CATCH_INTERNAL_IGNORE_BUT_WARN(...) (void)__builtin_constant_p(__VA_ARGS__)
#endif #endif
#if defined(__clang__) #if defined(__clang__)
@ -55,6 +58,9 @@
# define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION _Pragma( "clang diagnostic push" ) # define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION _Pragma( "clang diagnostic push" )
# define CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION _Pragma( "clang diagnostic pop" ) # define CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION _Pragma( "clang diagnostic pop" )
# define CATCH_INTERNAL_IGNORE_BUT_WARN(...) (void)__builtin_constant_p(__VA_ARGS__)
# define CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \ # define CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
_Pragma( "clang diagnostic ignored \"-Wexit-time-destructors\"" ) \ _Pragma( "clang diagnostic ignored \"-Wexit-time-destructors\"" ) \
_Pragma( "clang diagnostic ignored \"-Wglobal-constructors\"") _Pragma( "clang diagnostic ignored \"-Wglobal-constructors\"")
@ -134,6 +140,8 @@
# define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION __pragma( warning(push) ) # define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION __pragma( warning(push) )
# define CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION __pragma( warning(pop) ) # define CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION __pragma( warning(pop) )
# define CATCH_INTERNAL_IGNORE_BUT_WARN(...) (void)sizeof(__VA_ARGS__)
# if _MSC_VER >= 1900 // Visual Studio 2015 or newer # if _MSC_VER >= 1900 // Visual Studio 2015 or newer
# define CATCH_INTERNAL_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS # define CATCH_INTERNAL_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS
# endif # endif
@ -332,6 +340,11 @@
# define CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS # define CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS
#endif #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) #if defined(__APPLE__) && defined(__apple_build_version__) && (__clang_major__ < 10)
# undef CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS # undef CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS

View File

@ -205,10 +205,19 @@ namespace { namespace CompilationTests {
inline static void synchronizing_callback( void * ) { } inline static void synchronizing_callback( void * ) { }
} }
#if defined (_MSC_VER)
#pragma warning(push)
// The function pointer comparison below triggers warning because of
// calling conventions
#pragma warning(disable:4244)
#endif
TEST_CASE("#925: comparing function pointer to function address failed to compile", "[!nonportable]" ) { TEST_CASE("#925: comparing function pointer to function address failed to compile", "[!nonportable]" ) {
TestClass test; TestClass test;
REQUIRE(utility::synchronizing_callback != test.testMethod_uponComplete_arg); REQUIRE(utility::synchronizing_callback != test.testMethod_uponComplete_arg);
} }
#if defined (_MSC_VER)
#pragma warning(pop)
#endif
TEST_CASE( "#1027: Bitfields can be captured" ) { TEST_CASE( "#1027: Bitfields can be captured" ) {
struct Y { struct Y {