summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Hořeňovský <martin.horenovsky@gmail.com>2020-03-18 20:59:25 +0100
committerMartin Hořeňovský <martin.horenovsky@gmail.com>2020-03-19 09:45:41 +0100
commitb7b346c3e56030d19ac58d33326b69bbaf226552 (patch)
tree1a75042517e65540e55c6d2b2b863b19ffdc1ac1
parent9e09d79946b0c4afd815341684c7c4dc4f40c20b (diff)
downloadcatch2-b7b346c3e56030d19ac58d33326b69bbaf226552.tar.gz
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
-rw-r--r--include/internal/catch_capture.hpp5
-rw-r--r--include/internal/catch_compiler_capabilities.h13
-rw-r--r--projects/SelfTest/UsageTests/Compilation.tests.cpp9
3 files changed, 25 insertions, 2 deletions
diff --git a/include/internal/catch_capture.hpp b/include/internal/catch_capture.hpp
index ba842c3e..482646e8 100644
--- a/include/internal/catch_capture.hpp
+++ b/include/internal/catch_capture.hpp
@@ -41,6 +41,8 @@
///////////////////////////////////////////////////////////////////////////////
#define INTERNAL_CATCH_TEST( macroName, resultDisposition, ... ) \
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 ); \
INTERNAL_CATCH_TRY { \
CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
@@ -49,8 +51,7 @@
CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \
} INTERNAL_CATCH_CATCH( 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
- // The double negation silences MSVC's C4800 warning, the static_cast forces short-circuit evaluation if the type has overloaded &&.
+ } while( false )
///////////////////////////////////////////////////////////////////////////////
#define INTERNAL_CATCH_IF( macroName, resultDisposition, ... ) \
diff --git a/include/internal/catch_compiler_capabilities.h b/include/internal/catch_compiler_capabilities.h
index 9eebd8de..0ea76137 100644
--- a/include/internal/catch_compiler_capabilities.h
+++ b/include/internal/catch_compiler_capabilities.h
@@ -48,6 +48,9 @@
#if defined(__GNUC__) && !defined(__clang__) && !defined(__ICC)
# define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION _Pragma( "GCC diagnostic push" )
# define CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION _Pragma( "GCC diagnostic pop" )
+
+# define CATCH_INTERNAL_IGNORE_BUT_WARN(...) (void)__builtin_constant_p(__VA_ARGS__)
+
#endif
#if defined(__clang__)
@@ -55,6 +58,9 @@
# define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION _Pragma( "clang diagnostic push" )
# 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 \
_Pragma( "clang diagnostic ignored \"-Wexit-time-destructors\"" ) \
_Pragma( "clang diagnostic ignored \"-Wglobal-constructors\"")
@@ -134,6 +140,8 @@
# define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION __pragma( warning(push) )
# 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
# define CATCH_INTERNAL_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS
# endif
@@ -332,6 +340,11 @@
# define CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_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
diff --git a/projects/SelfTest/UsageTests/Compilation.tests.cpp b/projects/SelfTest/UsageTests/Compilation.tests.cpp
index 11d136a4..d2ccce05 100644
--- a/projects/SelfTest/UsageTests/Compilation.tests.cpp
+++ b/projects/SelfTest/UsageTests/Compilation.tests.cpp
@@ -205,10 +205,19 @@ namespace { namespace CompilationTests {
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]" ) {
TestClass test;
REQUIRE(utility::synchronizing_callback != test.testMethod_uponComplete_arg);
}
+#if defined (_MSC_VER)
+#pragma warning(pop)
+#endif
TEST_CASE( "#1027: Bitfields can be captured" ) {
struct Y {