diff --git a/cmake/internal_utils.cmake b/cmake/internal_utils.cmake index d497ca1f..93e6dbb7 100644 --- a/cmake/internal_utils.cmake +++ b/cmake/internal_utils.cmake @@ -55,7 +55,7 @@ macro(config_compiler_and_linker) if (MSVC) # Newlines inside flags variables break CMake's NMake generator. # TODO(vladl@google.com): Add -RTCs and -RTCu to debug builds. - set(cxx_base_flags "-GS -W4 -WX -wd4127 -wd4251 -wd4275 -nologo -J -Zi") + set(cxx_base_flags "-GS -W4 -WX -wd4251 -wd4275 -nologo -J -Zi") if (MSVC_VERSION LESS 1400) # 1400 is Visual Studio 2005 # Suppress spurious warnings MSVC 7.1 sometimes issues. # Forcing value to bool. @@ -66,6 +66,15 @@ macro(config_compiler_and_linker) # Resolved overload was found by argument-dependent lookup. set(cxx_base_flags "${cxx_base_flags} -wd4675") endif() + if (MSVC_VERSION LESS 1500) # 1500 is Visual Studio 2008 + # Conditional expression is constant. + # When compiling with /W4, we get several instances of C4127 + # (Conditional expression is constant). In our code, we disable that + # warning on a case-by-case basis. However, on Visual Studio 2005, + # the warning fires on std::list. Therefore on that compiler and earlier, + # we disable the warning project-wide. + set(cxx_base_flags "${cxx_base_flags} -wd4127") + endif() if (NOT (MSVC_VERSION LESS 1700)) # 1700 is Visual Studio 2012. # Suppress "unreachable code" warning on VS 2012 and later. # http://stackoverflow.com/questions/3232669 explains the issue. diff --git a/include/gtest/gtest-printers.h b/include/gtest/gtest-printers.h index 8ce52b60..852d44a7 100644 --- a/include/gtest/gtest-printers.h +++ b/include/gtest/gtest-printers.h @@ -835,7 +835,9 @@ struct TuplePrefixPrinter { template static void PrintPrefixTo(const Tuple& t, ::std::ostream* os) { TuplePrefixPrinter::PrintPrefixTo(t, os); + GTEST_INTENTIONAL_CONST_COND_PUSH_ if (N > 1) { + GTEST_INTENTIONAL_CONST_COND_POP_ *os << ", "; } UniversalPrinter< diff --git a/include/gtest/internal/gtest-port.h b/include/gtest/internal/gtest-port.h index 4bc1e690..a1176760 100644 --- a/include/gtest/internal/gtest-port.h +++ b/include/gtest/internal/gtest-port.h @@ -197,6 +197,10 @@ // GTEST_DISALLOW_ASSIGN_ - disables operator=. // GTEST_DISALLOW_COPY_AND_ASSIGN_ - disables copy ctor and operator=. // GTEST_MUST_USE_RESULT_ - declares that a function's result must be used. +// GTEST_INTENTIONAL_CONST_COND_PUSH_ - start code section where MSVC C4127 is +// suppressed (constant conditional). +// GTEST_INTENTIONAL_CONST_COND_POP_ - finish code section where MSVC C4127 +// is suppressed. // // C++11 feature wrappers: // @@ -834,6 +838,25 @@ using ::std::tuple_size; # define GTEST_MOVE_(x) x #endif +// MS C++ compiler emits warning when a conditional expression is compile time +// constant. In some contexts this warning is false positive and needs to be +// suppressed. Use the following two macros in such cases: +// +// GTEST_INTENTIONAL_CONST_COND_PUSH_ +// while (true) { +// GTEST_INTENTIONAL_CONST_COND_POP_ +// } +#if defined(_MSC_VER) +# define GTEST_INTENTIONAL_CONST_COND_PUSH_ \ + __pragma(warning(push)) \ + __pragma(warning(disable: 4127)) +# define GTEST_INTENTIONAL_CONST_COND_POP_ \ + __pragma(warning(pop)) +#else +# define GTEST_INTENTIONAL_CONST_COND_PUSH_ +# define GTEST_INTENTIONAL_CONST_COND_POP_ +#endif + // Determine whether the compiler supports Microsoft's Structured Exception // Handling. This is supported by several Windows compilers but generally // does not exist on any other system. @@ -1248,7 +1271,9 @@ inline To DownCast_(From* f) { // so we only accept pointers // for compile-time type checking, and has no overhead in an // optimized build at run-time, as it will be optimized away // completely. + GTEST_INTENTIONAL_CONST_COND_PUSH_ if (false) { + GTEST_INTENTIONAL_CONST_COND_POP_ const To to = NULL; ::testing::internal::ImplicitCast_(to); } diff --git a/test/gtest_premature_exit_test.cc b/test/gtest_premature_exit_test.cc index f6b6be9a..fcfc623e 100644 --- a/test/gtest_premature_exit_test.cc +++ b/test/gtest_premature_exit_test.cc @@ -100,7 +100,9 @@ TEST_F(PrematureExitDeathTest, FileExistsDuringExecutionOfDeathTest) { // Tests that TEST_PREMATURE_EXIT_FILE is set where it's expected to // be set. TEST_F(PrematureExitTest, TestPrematureExitFileEnvVarIsSet) { + GTEST_INTENTIONAL_CONST_COND_PUSH_ if (kTestPrematureExitFileEnvVarShouldBeSet) { + GTEST_INTENTIONAL_CONST_COND_POP_ const char* const filepath = GetEnv("TEST_PREMATURE_EXIT_FILE"); ASSERT_TRUE(filepath != NULL); ASSERT_NE(*filepath, '\0');