Suppress "Conditional expression is constant" warning on Visual Studio.


git-svn-id: http://googletest.googlecode.com/svn/trunk@677 861a406c-534a-0410-8894-cb66d6ee9925
diff --git a/cmake/internal_utils.cmake b/cmake/internal_utils.cmake
index d497ca1..93e6dbb 100644
--- a/cmake/internal_utils.cmake
+++ b/cmake/internal_utils.cmake
@@ -55,7 +55,7 @@
   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 @@
       # 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 8ce52b6..852d44a 100644
--- a/include/gtest/gtest-printers.h
+++ b/include/gtest/gtest-printers.h
@@ -835,7 +835,9 @@
   template <typename Tuple>
   static void PrintPrefixTo(const Tuple& t, ::std::ostream* os) {
     TuplePrefixPrinter<N - 1>::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 4bc1e69..a117676 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 @@
 # 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 @@
   // 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_<From*>(to);
   }
diff --git a/test/gtest_premature_exit_test.cc b/test/gtest_premature_exit_test.cc
index f6b6be9..fcfc623 100644
--- a/test/gtest_premature_exit_test.cc
+++ b/test/gtest_premature_exit_test.cc
@@ -100,7 +100,9 @@
 // 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');