Merge branch 'master' into 9A681768AABE08D1EFA5CA77528236A4
diff --git a/googlemock/include/gmock/gmock-generated-matchers.h b/googlemock/include/gmock/gmock-generated-matchers.h
index 0d46d23..41d5304 100644
--- a/googlemock/include/gmock/gmock-generated-matchers.h
+++ b/googlemock/include/gmock/gmock-generated-matchers.h
@@ -1381,8 +1381,8 @@
 // ================
 //
 // To learn more about using these macros, please search for 'MATCHER'
-// on https://github.com/google/googletest/blob/master/googlemock/docs/
-// CookBook.md
+// on
+// https://github.com/google/googletest/blob/master/googlemock/docs/CookBook.md
 
 #define MATCHER(name, description)\
   class name##Matcher {\
diff --git a/googlemock/include/gmock/gmock-generated-matchers.h.pump b/googlemock/include/gmock/gmock-generated-matchers.h.pump
index 9fe0fd7..1a59fed 100644
--- a/googlemock/include/gmock/gmock-generated-matchers.h.pump
+++ b/googlemock/include/gmock/gmock-generated-matchers.h.pump
@@ -592,7 +592,8 @@
 // ================
 //
 // To learn more about using these macros, please search for 'MATCHER'
-// on https://github.com/google/googletest/blob/master/googlemock/docs/CookBook.md
+// on
+// https://github.com/google/googletest/blob/master/googlemock/docs/CookBook.md
 
 $range i 0..n
 $for i
diff --git a/googletest/include/gtest/gtest-typed-test.h b/googletest/include/gtest/gtest-typed-test.h
index 61d8907..29b0859 100644
--- a/googletest/include/gtest/gtest-typed-test.h
+++ b/googletest/include/gtest/gtest-typed-test.h
@@ -83,6 +83,24 @@
 
 TYPED_TEST(FooTest, HasPropertyA) { ... }
 
+// TYPED_TEST_CASE takes an optional third argument which allows to specify a
+// class that generates custom test name suffixes based on the type. This should
+// be a class which has a static template function GetName(int index) returning
+// a string for each type. The provided integer index equals the index of the
+// type in the provided type list. In many cases the index can be ignored.
+//
+// For example:
+//   class MyTypeNames {
+//    public:
+//     template <typename T>
+//     static std::string GetName(int) {
+//       if (std::is_same<T, char>()) return "char";
+//       if (std::is_same<T, int>()) return "int";
+//       if (std::is_same<T, unsigned int>()) return "unsigned_int";
+//     }
+//   };
+//   TYPED_TEST_CASE(FooTest, MyTypes, MyTypeNames);
+
 #endif  // 0
 
 // Type-parameterized tests are abstract test patterns parameterized
@@ -144,6 +162,11 @@
 // If the type list contains only one type, you can write that type
 // directly without Types<...>:
 //   INSTANTIATE_TYPED_TEST_CASE_P(My, FooTest, int);
+//
+// Similar to the optional argument of TYPED_TEST_CASE above,
+// INSTANTIATE_TEST_CASE_P takes an optional fourth argument which allows to
+// generate custom names.
+//   INSTANTIATE_TYPED_TEST_CASE_P(My, FooTest, MyTypes, MyTypeNames);
 
 #endif  // 0
 
@@ -160,32 +183,45 @@
 // given test case.
 # define GTEST_TYPE_PARAMS_(TestCaseName) gtest_type_params_##TestCaseName##_
 
+// Expands to the name of the typedef for the NameGenerator, responsible for
+// creating the suffixes of the name.
+#define GTEST_NAME_GENERATOR_(TestCaseName) \
+  gtest_type_params_##TestCaseName##_NameGenerator
+
 // The 'Types' template argument below must have spaces around it
 // since some compilers may choke on '>>' when passing a template
 // instance (e.g. Types<int>)
-# define TYPED_TEST_CASE(CaseName, Types) \
-  typedef ::testing::internal::TypeList< Types >::type \
-      GTEST_TYPE_PARAMS_(CaseName)
+# define TYPED_TEST_CASE(CaseName, Types, ...)                             \
+  typedef ::testing::internal::TypeList< Types >::type GTEST_TYPE_PARAMS_( \
+      CaseName);                                                           \
+  typedef ::testing::internal::NameGeneratorSelector<__VA_ARGS__>::type    \
+      GTEST_NAME_GENERATOR_(CaseName)
 
-# define TYPED_TEST(CaseName, TestName) \
-  template <typename gtest_TypeParam_> \
-  class GTEST_TEST_CLASS_NAME_(CaseName, TestName) \
-      : public CaseName<gtest_TypeParam_> { \
-   private: \
-    typedef CaseName<gtest_TypeParam_> TestFixture; \
-    typedef gtest_TypeParam_ TypeParam; \
-    virtual void TestBody(); \
-  }; \
-  bool gtest_##CaseName##_##TestName##_registered_ GTEST_ATTRIBUTE_UNUSED_ = \
-      ::testing::internal::TypeParameterizedTest< \
-          CaseName, \
-          ::testing::internal::TemplateSel< \
-              GTEST_TEST_CLASS_NAME_(CaseName, TestName)>, \
-          GTEST_TYPE_PARAMS_(CaseName)>::Register(\
-              "", ::testing::internal::CodeLocation(__FILE__, __LINE__), \
-              #CaseName, #TestName, 0); \
-  template <typename gtest_TypeParam_> \
-  void GTEST_TEST_CLASS_NAME_(CaseName, TestName)<gtest_TypeParam_>::TestBody()
+# define TYPED_TEST(CaseName, TestName)                                       \
+  template <typename gtest_TypeParam_>                                        \
+  class GTEST_TEST_CLASS_NAME_(CaseName, TestName)                            \
+      : public CaseName<gtest_TypeParam_> {                                   \
+   private:                                                                   \
+    typedef CaseName<gtest_TypeParam_> TestFixture;                           \
+    typedef gtest_TypeParam_ TypeParam;                                       \
+    virtual void TestBody();                                                  \
+  };                                                                          \
+  bool gtest_##CaseName##_##TestName##_registered_ GTEST_ATTRIBUTE_UNUSED_ =  \
+      ::testing::internal::TypeParameterizedTest<                             \
+          CaseName,                                                           \
+          ::testing::internal::TemplateSel<GTEST_TEST_CLASS_NAME_(CaseName,   \
+                                                                  TestName)>, \
+          GTEST_TYPE_PARAMS_(                                                 \
+              CaseName)>::Register("",                                        \
+                                   ::testing::internal::CodeLocation(         \
+                                       __FILE__, __LINE__),                   \
+                                   #CaseName, #TestName, 0,                   \
+                                   ::testing::internal::GenerateNames<        \
+                                       GTEST_NAME_GENERATOR_(CaseName),       \
+                                       GTEST_TYPE_PARAMS_(CaseName)>());      \
+  template <typename gtest_TypeParam_>                                        \
+  void GTEST_TEST_CLASS_NAME_(CaseName,                                       \
+                              TestName)<gtest_TypeParam_>::TestBody()
 
 #endif  // GTEST_HAS_TYPED_TEST
 
@@ -250,15 +286,19 @@
 // The 'Types' template argument below must have spaces around it
 // since some compilers may choke on '>>' when passing a template
 // instance (e.g. Types<int>)
-# define INSTANTIATE_TYPED_TEST_CASE_P(Prefix, CaseName, Types) \
-  bool gtest_##Prefix##_##CaseName GTEST_ATTRIBUTE_UNUSED_ = \
-      ::testing::internal::TypeParameterizedTestCase<CaseName, \
-          GTEST_CASE_NAMESPACE_(CaseName)::gtest_AllTests_, \
-          ::testing::internal::TypeList< Types >::type>::Register(\
-              #Prefix, \
-              ::testing::internal::CodeLocation(__FILE__, __LINE__), \
-              &GTEST_TYPED_TEST_CASE_P_STATE_(CaseName), \
-              #CaseName, GTEST_REGISTERED_TEST_NAMES_(CaseName))
+# define INSTANTIATE_TYPED_TEST_CASE_P(Prefix, CaseName, Types, ...)      \
+  bool gtest_##Prefix##_##CaseName GTEST_ATTRIBUTE_UNUSED_ =              \
+      ::testing::internal::TypeParameterizedTestCase<                     \
+          CaseName, GTEST_CASE_NAMESPACE_(CaseName)::gtest_AllTests_,     \
+          ::testing::internal::TypeList< Types >::type>::                 \
+          Register(#Prefix,                                               \
+                   ::testing::internal::CodeLocation(__FILE__, __LINE__), \
+                   &GTEST_TYPED_TEST_CASE_P_STATE_(CaseName), #CaseName,  \
+                   GTEST_REGISTERED_TEST_NAMES_(CaseName),                \
+                   ::testing::internal::GenerateNames<                    \
+                       ::testing::internal::NameGeneratorSelector<        \
+                           __VA_ARGS__>::type,                            \
+                       ::testing::internal::TypeList< Types >::type>())
 
 #endif  // GTEST_HAS_TYPED_TEST_P
 
diff --git a/googletest/include/gtest/internal/gtest-internal.h b/googletest/include/gtest/internal/gtest-internal.h
index 9593a45..b762f61 100644
--- a/googletest/include/gtest/internal/gtest-internal.h
+++ b/googletest/include/gtest/internal/gtest-internal.h
@@ -606,6 +606,37 @@
 void SplitString(const ::std::string& str, char delimiter,
                  ::std::vector< ::std::string>* dest);
 
+// The default argument to the template below for the case when the user does
+// not provide a name generator.
+struct DefaultNameGenerator {
+  template <typename T>
+  static std::string GetName(int i) {
+    return StreamableToString(i);
+  }
+};
+
+template <typename Provided = DefaultNameGenerator>
+struct NameGeneratorSelector {
+  typedef Provided type;
+};
+
+template <typename NameGenerator>
+void GenerateNamesRecursively(Types0, std::vector<std::string>*, int) {}
+
+template <typename NameGenerator, typename Types>
+void GenerateNamesRecursively(Types, std::vector<std::string>* result, int i) {
+  result->push_back(NameGenerator::template GetName<typename Types::Head>(i));
+  GenerateNamesRecursively<NameGenerator>(typename Types::Tail(), result,
+                                          i + 1);
+}
+
+template <typename NameGenerator, typename Types>
+std::vector<std::string> GenerateNames() {
+  std::vector<std::string> result;
+  GenerateNamesRecursively<NameGenerator>(Types(), &result, 0);
+  return result;
+}
+
 // TypeParameterizedTest<Fixture, TestSel, Types>::Register()
 // registers a list of type-parameterized tests with Google Test.  The
 // return value is insignificant - we just need to return something
@@ -620,10 +651,10 @@
   // specified in INSTANTIATE_TYPED_TEST_CASE_P(Prefix, TestCase,
   // Types).  Valid values for 'index' are [0, N - 1] where N is the
   // length of Types.
-  static bool Register(const char* prefix,
-                       const CodeLocation& code_location,
-                       const char* case_name, const char* test_names,
-                       int index) {
+  static bool Register(const char* prefix, const CodeLocation& code_location,
+                       const char* case_name, const char* test_names, int index,
+                       const std::vector<std::string>& type_names =
+                           GenerateNames<DefaultNameGenerator, Types>()) {
     typedef typename Types::Head Type;
     typedef Fixture<Type> FixtureClass;
     typedef typename GTEST_BIND_(TestSel, Type) TestClass;
@@ -631,20 +662,23 @@
     // First, registers the first type-parameterized test in the type
     // list.
     MakeAndRegisterTestInfo(
-        (std::string(prefix) + (prefix[0] == '\0' ? "" : "/") + case_name + "/"
-         + StreamableToString(index)).c_str(),
+        (std::string(prefix) + (prefix[0] == '\0' ? "" : "/") + case_name +
+         "/" + type_names[index])
+            .c_str(),
         StripTrailingSpaces(GetPrefixUntilComma(test_names)).c_str(),
         GetTypeName<Type>().c_str(),
         NULL,  // No value parameter.
-        code_location,
-        GetTypeId<FixtureClass>(),
-        TestClass::SetUpTestCase,
-        TestClass::TearDownTestCase,
-        new TestFactoryImpl<TestClass>);
+        code_location, GetTypeId<FixtureClass>(), TestClass::SetUpTestCase,
+        TestClass::TearDownTestCase, new TestFactoryImpl<TestClass>);
 
     // Next, recurses (at compile time) with the tail of the type list.
-    return TypeParameterizedTest<Fixture, TestSel, typename Types::Tail>
-        ::Register(prefix, code_location, case_name, test_names, index + 1);
+    return TypeParameterizedTest<Fixture, TestSel,
+                                 typename Types::Tail>::Register(prefix,
+                                                                 code_location,
+                                                                 case_name,
+                                                                 test_names,
+                                                                 index + 1,
+                                                                 type_names);
   }
 };
 
@@ -654,7 +688,9 @@
  public:
   static bool Register(const char* /*prefix*/, const CodeLocation&,
                        const char* /*case_name*/, const char* /*test_names*/,
-                       int /*index*/) {
+                       int /*index*/,
+                       const std::vector<std::string>& =
+                           std::vector<std::string>() /*type_names*/) {
     return true;
   }
 };
@@ -667,8 +703,10 @@
 class TypeParameterizedTestCase {
  public:
   static bool Register(const char* prefix, CodeLocation code_location,
-                       const TypedTestCasePState* state,
-                       const char* case_name, const char* test_names) {
+                       const TypedTestCasePState* state, const char* case_name,
+                       const char* test_names,
+                       const std::vector<std::string>& type_names =
+                           GenerateNames<DefaultNameGenerator, Types>()) {
     std::string test_name = StripTrailingSpaces(
         GetPrefixUntilComma(test_names));
     if (!state->TestExists(test_name)) {
@@ -685,12 +723,14 @@
 
     // First, register the first test in 'Test' for each type in 'Types'.
     TypeParameterizedTest<Fixture, Head, Types>::Register(
-        prefix, test_location, case_name, test_names, 0);
+        prefix, test_location, case_name, test_names, 0, type_names);
 
     // Next, recurses (at compile time) with the tail of the test list.
-    return TypeParameterizedTestCase<Fixture, typename Tests::Tail, Types>
-        ::Register(prefix, code_location, state,
-                   case_name, SkipComma(test_names));
+    return TypeParameterizedTestCase<Fixture, typename Tests::Tail,
+                                     Types>::Register(prefix, code_location,
+                                                      state, case_name,
+                                                      SkipComma(test_names),
+                                                      type_names);
   }
 };
 
@@ -700,7 +740,9 @@
  public:
   static bool Register(const char* /*prefix*/, const CodeLocation&,
                        const TypedTestCasePState* /*state*/,
-                       const char* /*case_name*/, const char* /*test_names*/) {
+                       const char* /*case_name*/, const char* /*test_names*/,
+                       const std::vector<std::string>& =
+                           std::vector<std::string>() /*type_names*/) {
     return true;
   }
 };
diff --git a/googletest/src/gtest.cc b/googletest/src/gtest.cc
index f476044..9796637 100644
--- a/googletest/src/gtest.cc
+++ b/googletest/src/gtest.cc
@@ -459,8 +459,6 @@
 // Returns the output format, or "" for normal printed output.
 std::string UnitTestOptions::GetOutputFormat() {
   const char* const gtest_output_flag = GTEST_FLAG(output).c_str();
-  if (gtest_output_flag == NULL) return std::string("");
-
   const char* const colon = strchr(gtest_output_flag, ':');
   return (colon == NULL) ?
       std::string(gtest_output_flag) :
@@ -469,11 +467,8 @@
 
 // Returns the name of the requested output file, or the default if none
 // was explicitly specified.
-// FIXME Remove GetAbsolutePathToOutputFile checking gtest_output_flag == NULL
 std::string UnitTestOptions::GetAbsolutePathToOutputFile() {
   const char* const gtest_output_flag = GTEST_FLAG(output).c_str();
-  if (gtest_output_flag == NULL)
-    return "";
 
   std::string format = GetOutputFormat();
   if (format.empty())
@@ -3505,7 +3500,7 @@
 // Creates a new XmlUnitTestResultPrinter.
 XmlUnitTestResultPrinter::XmlUnitTestResultPrinter(const char* output_file)
     : output_file_(output_file) {
-  if (output_file_.c_str() == NULL || output_file_.empty()) {
+  if (output_file_.empty()) {
     GTEST_LOG_(FATAL) << "XML output file may not be null";
   }
 }
diff --git a/googletest/test/googletest-output-test-golden-lin.txt b/googletest/test/googletest-output-test-golden-lin.txt
index b0c5189..7711cdc 100644
--- a/googletest/test/googletest-output-test-golden-lin.txt
+++ b/googletest/test/googletest-output-test-golden-lin.txt
@@ -12,7 +12,7 @@
   3
 Stack trace: (omitted)
 
-[==========] Running 68 tests from 30 test cases.
+[==========] Running 76 tests from 34 test cases.
 [----------] Global test environment set-up.
 FooEnvironment::SetUp() called.
 BarEnvironment::SetUp() called.
@@ -606,6 +606,24 @@
 Stack trace: (omitted)
 
 [  FAILED  ] TypedTest/0.Failure, where TypeParam = int
+[----------] 2 tests from TypedTestWithNames/char_0, where TypeParam = char
+[ RUN      ] TypedTestWithNames/char_0.Success
+[       OK ] TypedTestWithNames/char_0.Success
+[ RUN      ] TypedTestWithNames/char_0.Failure
+googletest-output-test_.cc:#: Failure
+Failed
+Stack trace: (omitted)
+
+[  FAILED  ] TypedTestWithNames/char_0.Failure, where TypeParam = char
+[----------] 2 tests from TypedTestWithNames/int_1, where TypeParam = int
+[ RUN      ] TypedTestWithNames/int_1.Success
+[       OK ] TypedTestWithNames/int_1.Success
+[ RUN      ] TypedTestWithNames/int_1.Failure
+googletest-output-test_.cc:#: Failure
+Failed
+Stack trace: (omitted)
+
+[  FAILED  ] TypedTestWithNames/int_1.Failure, where TypeParam = int
 [----------] 2 tests from Unsigned/TypedTestP/0, where TypeParam = unsigned char
 [ RUN      ] Unsigned/TypedTestP/0.Success
 [       OK ] Unsigned/TypedTestP/0.Success
@@ -634,6 +652,34 @@
 Stack trace: (omitted)
 
 [  FAILED  ] Unsigned/TypedTestP/1.Failure, where TypeParam = unsigned int
+[----------] 2 tests from UnsignedCustomName/TypedTestP/unsigned_char_0, where TypeParam = unsigned char
+[ RUN      ] UnsignedCustomName/TypedTestP/unsigned_char_0.Success
+[       OK ] UnsignedCustomName/TypedTestP/unsigned_char_0.Success
+[ RUN      ] UnsignedCustomName/TypedTestP/unsigned_char_0.Failure
+googletest-output-test_.cc:#: Failure
+Expected equality of these values:
+  1U
+    Which is: 1
+  TypeParam()
+    Which is: '\0'
+Expected failure
+Stack trace: (omitted)
+
+[  FAILED  ] UnsignedCustomName/TypedTestP/unsigned_char_0.Failure, where TypeParam = unsigned char
+[----------] 2 tests from UnsignedCustomName/TypedTestP/unsigned_int_1, where TypeParam = unsigned int
+[ RUN      ] UnsignedCustomName/TypedTestP/unsigned_int_1.Success
+[       OK ] UnsignedCustomName/TypedTestP/unsigned_int_1.Success
+[ RUN      ] UnsignedCustomName/TypedTestP/unsigned_int_1.Failure
+googletest-output-test_.cc:#: Failure
+Expected equality of these values:
+  1U
+    Which is: 1
+  TypeParam()
+    Which is: 0
+Expected failure
+Stack trace: (omitted)
+
+[  FAILED  ] UnsignedCustomName/TypedTestP/unsigned_int_1.Failure, where TypeParam = unsigned int
 [----------] 4 tests from ExpectFailureTest
 [ RUN      ] ExpectFailureTest.ExpectFatalFailure
 (expecting 1 failure)
@@ -860,9 +906,9 @@
 Expected fatal failure.
 Stack trace: (omitted)
 
-[==========] 68 tests from 30 test cases ran.
-[  PASSED  ] 22 tests.
-[  FAILED  ] 46 tests, listed below:
+[==========] 76 tests from 34 test cases ran.
+[  PASSED  ] 26 tests.
+[  FAILED  ] 50 tests, listed below:
 [  FAILED  ] NonfatalFailureTest.EscapesStringOperands
 [  FAILED  ] NonfatalFailureTest.DiffForLongStrings
 [  FAILED  ] FatalFailureTest.FatalFailureInSubroutine
@@ -898,8 +944,12 @@
 [  FAILED  ] ExpectFatalFailureTest.FailsWhenStatementReturns
 [  FAILED  ] ExpectFatalFailureTest.FailsWhenStatementThrows
 [  FAILED  ] TypedTest/0.Failure, where TypeParam = int
+[  FAILED  ] TypedTestWithNames/char_0.Failure, where TypeParam = char
+[  FAILED  ] TypedTestWithNames/int_1.Failure, where TypeParam = int
 [  FAILED  ] Unsigned/TypedTestP/0.Failure, where TypeParam = unsigned char
 [  FAILED  ] Unsigned/TypedTestP/1.Failure, where TypeParam = unsigned int
+[  FAILED  ] UnsignedCustomName/TypedTestP/unsigned_char_0.Failure, where TypeParam = unsigned char
+[  FAILED  ] UnsignedCustomName/TypedTestP/unsigned_int_1.Failure, where TypeParam = unsigned int
 [  FAILED  ] ExpectFailureTest.ExpectFatalFailure
 [  FAILED  ] ExpectFailureTest.ExpectNonFatalFailure
 [  FAILED  ] ExpectFailureTest.ExpectFatalFailureOnAllThreads
@@ -910,7 +960,7 @@
 [  FAILED  ] PrintingFailingParams/FailingParamTest.Fails/0, where GetParam() = 2
 [  FAILED  ] PrintingStrings/ParamTest.Failure/a, where GetParam() = "a"
 
-46 FAILED TESTS
+50 FAILED TESTS
   YOU HAVE 1 DISABLED TEST
 
 Note: Google Test filter = FatalFailureTest.*:LoggingTest.*
diff --git a/googletest/test/googletest-output-test_.cc b/googletest/test/googletest-output-test_.cc
index 3860cf4..180630e 100644
--- a/googletest/test/googletest-output-test_.cc
+++ b/googletest/test/googletest-output-test_.cc
@@ -39,6 +39,10 @@
 
 #include <stdlib.h>
 
+#if _MSC_VER
+  GTEST_DISABLE_MSC_WARNINGS_PUSH_(4127 /* conditional expression is constant */)
+#endif  // . _MSC_VER    
+
 #if GTEST_IS_THREADSAFE
 using testing::ScopedFakeTestPartResultReporter;
 using testing::TestPartResultArray;
@@ -801,6 +805,28 @@
   EXPECT_EQ(1, TypeParam()) << "Expected failure";
 }
 
+typedef testing::Types<char, int> TypesForTestWithNames;
+
+template <typename T>
+class TypedTestWithNames : public testing::Test {};
+
+class TypedTestNames {
+ public:
+  template <typename T>
+  static std::string GetName(int i) {
+    if (testing::internal::IsSame<T, char>::value)
+      return std::string("char_") + ::testing::PrintToString(i);
+    if (testing::internal::IsSame<T, int>::value)
+      return std::string("int_") + ::testing::PrintToString(i);
+  }
+};
+
+TYPED_TEST_CASE(TypedTestWithNames, TypesForTestWithNames, TypedTestNames);
+
+TYPED_TEST(TypedTestWithNames, Success) {}
+
+TYPED_TEST(TypedTestWithNames, Failure) { FAIL(); }
+
 #endif  // GTEST_HAS_TYPED_TEST
 
 // This #ifdef block tests the output of type-parameterized tests.
@@ -825,6 +851,22 @@
 typedef testing::Types<unsigned char, unsigned int> UnsignedTypes;
 INSTANTIATE_TYPED_TEST_CASE_P(Unsigned, TypedTestP, UnsignedTypes);
 
+class TypedTestPNames {
+ public:
+  template <typename T>
+  static std::string GetName(int i) {
+    if (testing::internal::IsSame<T, unsigned char>::value) {
+      return std::string("unsigned_char_") + ::testing::PrintToString(i);
+    }
+    if (testing::internal::IsSame<T, unsigned int>::value) {
+      return std::string("unsigned_int_") + ::testing::PrintToString(i);
+    }
+  }
+};
+
+INSTANTIATE_TYPED_TEST_CASE_P(UnsignedCustomName, TypedTestP, UnsignedTypes,
+                              TypedTestPNames);
+
 #endif  // GTEST_HAS_TYPED_TEST_P
 
 #if GTEST_HAS_DEATH_TEST
@@ -1060,6 +1102,8 @@
   // are registered, and torn down in the reverse order.
   testing::AddGlobalTestEnvironment(new FooEnvironment);
   testing::AddGlobalTestEnvironment(new BarEnvironment);
-
+#if _MSC_VER
+  GTEST_DISABLE_MSC_WARNINGS_POP_()  //  4127
+#endif  // . _MSC_VER    
   return RunAllTests();
 }
diff --git a/googletest/test/gtest-typed-test_test.cc b/googletest/test/gtest-typed-test_test.cc
index eddb52b..c38bb94 100644
--- a/googletest/test/gtest-typed-test_test.cc
+++ b/googletest/test/gtest-typed-test_test.cc
@@ -35,6 +35,10 @@
 
 #include "gtest/gtest.h"
 
+#if _MSC_VER
+GTEST_DISABLE_MSC_WARNINGS_PUSH_(4127 /* conditional expression is constant */)
+#endif  //  _MSC_VER
+
 using testing::Test;
 
 // Used for testing that SetUpTestCase()/TearDownTestCase(), fixture
@@ -165,6 +169,40 @@
 
 }  // namespace library1
 
+// Tests that custom names work.
+template <typename T>
+class TypedTestWithNames : public Test {};
+
+class TypedTestNames {
+ public:
+  template <typename T>
+  static std::string GetName(int i) {
+    if (testing::internal::IsSame<T, char>::value) {
+      return std::string("char_") + ::testing::PrintToString(i);
+    }
+    if (testing::internal::IsSame<T, int>::value) {
+      return std::string("int_") + ::testing::PrintToString(i);
+    }
+  }
+};
+
+TYPED_TEST_CASE(TypedTestWithNames, TwoTypes, TypedTestNames);
+
+TYPED_TEST(TypedTestWithNames, TestCaseName) {
+  if (testing::internal::IsSame<TypeParam, char>::value) {
+    EXPECT_STREQ(::testing::UnitTest::GetInstance()
+                     ->current_test_info()
+                     ->test_case_name(),
+                 "TypedTestWithNames/char_0");
+  }
+  if (testing::internal::IsSame<TypeParam, int>::value) {
+    EXPECT_STREQ(::testing::UnitTest::GetInstance()
+                     ->current_test_info()
+                     ->test_case_name(),
+                 "TypedTestWithNames/int_1");
+  }
+}
+
 #endif  // GTEST_HAS_TYPED_TEST
 
 // This #ifdef block tests type-parameterized tests.
@@ -265,6 +303,46 @@
 typedef Types<short, long> MyTwoTypes;
 INSTANTIATE_TYPED_TEST_CASE_P(My, DerivedTest, MyTwoTypes);
 
+// Tests that custom names work with type parametrized tests. We reuse the
+// TwoTypes from above here.
+template <typename T>
+class TypeParametrizedTestWithNames : public Test {};
+
+TYPED_TEST_CASE_P(TypeParametrizedTestWithNames);
+
+TYPED_TEST_P(TypeParametrizedTestWithNames, TestCaseName) {
+  if (testing::internal::IsSame<TypeParam, char>::value) {
+    EXPECT_STREQ(::testing::UnitTest::GetInstance()
+                     ->current_test_info()
+                     ->test_case_name(),
+                 "CustomName/TypeParametrizedTestWithNames/p_char_0");
+  }
+  if (testing::internal::IsSame<TypeParam, int>::value) {
+    EXPECT_STREQ(::testing::UnitTest::GetInstance()
+                     ->current_test_info()
+                     ->test_case_name(),
+                 "CustomName/TypeParametrizedTestWithNames/p_int_1");
+  }
+}
+
+REGISTER_TYPED_TEST_CASE_P(TypeParametrizedTestWithNames, TestCaseName);
+
+class TypeParametrizedTestNames {
+ public:
+  template <typename T>
+  static std::string GetName(int i) {
+    if (testing::internal::IsSame<T, char>::value) {
+      return std::string("p_char_") + ::testing::PrintToString(i);
+    }
+    if (testing::internal::IsSame<T, int>::value) {
+      return std::string("p_int_") + ::testing::PrintToString(i);
+    }
+  }
+};
+
+INSTANTIATE_TYPED_TEST_CASE_P(CustomName, TypeParametrizedTestWithNames,
+                              TwoTypes, TypeParametrizedTestNames);
+
 // Tests that multiple TYPED_TEST_CASE_P's can be defined in the same
 // translation unit.
 
@@ -376,4 +454,8 @@
 // must be defined). This dummy test keeps gtest_main linked in.
 TEST(DummyTest, TypedTestsAreNotSupportedOnThisPlatform) {}
 
+#if _MSC_VER
+GTEST_DISABLE_MSC_WARNINGS_POP_()  //  4127
+#endif                             //  _MSC_VER
+
 #endif  // #if !defined(GTEST_HAS_TYPED_TEST) && !defined(GTEST_HAS_TYPED_TEST_P)