Merge pull request #2904 from AmatanHead:throw-matchers

PiperOrigin-RevId: 327294137
diff --git a/README.md b/README.md
index 1727866..e8eefe5 100644
--- a/README.md
+++ b/README.md
@@ -25,9 +25,6 @@
 projects. These were so closely related that it makes sense to maintain and
 release them together.
 
-Please subscribe to the mailing list at googletestframework@googlegroups.com for
-questions, discussions, and development.
-
 ### Getting started:
 
 The information for **Google Test** is available in the
@@ -76,8 +73,6 @@
 *   [Protocol Buffers](https://github.com/google/protobuf), Google's data
     interchange format.
 *   The [OpenCV](http://opencv.org/) computer vision library.
-*   [tiny-dnn](https://github.com/tiny-dnn/tiny-dnn): header only,
-    dependency-free deep learning framework in C++11.
 
 ## Related Open Source Projects
 
@@ -113,8 +108,9 @@
 
 Google Test is designed to have fairly minimal requirements to build and use
 with your projects, but there are some. If you notice any problems on your
-platform, please notify
-[googletestframework@googlegroups.com](https://groups.google.com/forum/#!forum/googletestframework).
+platform, please file an issue on the
+[GoogleTest GitHub Issue Tracker](https://github.com/google/googletest/issues).
+
 Patches for fixing them are welcome!
 
 ### Build Requirements
diff --git a/googlemock/docs/cheat_sheet.md b/googlemock/docs/cheat_sheet.md
index 85620f7..cc7e699 100644
--- a/googlemock/docs/cheat_sheet.md
+++ b/googlemock/docs/cheat_sheet.md
@@ -2,6 +2,8 @@
 
 <!-- GOOGLETEST_CM0019 DO NOT DELETE -->
 
+<!-- GOOGLETEST_CM0035 DO NOT DELETE -->
+
 <!-- GOOGLETEST_CM0033 DO NOT DELETE -->
 
 ## Defining a Mock Class
@@ -616,7 +618,7 @@
 <!-- mdformat off(no multiline tables) -->
 |                                |                                             |
 | :----------------------------- | :------------------------------------------ |
-| `DoAll(a1, a2, ..., an)`       | Do all actions `a1` to `an` and return the result of `an` in each invocation. The first `n - 1` sub-actions must return void. |
+| `DoAll(a1, a2, ..., an)`       | Do all actions `a1` to `an` and return the result of `an` in each invocation. The first `n - 1` sub-actions must return void and will receive a  readonly view of the arguments. |
 | `IgnoreResult(a)`              | Perform action `a` and ignore its result. `a` must not return void. |
 | `WithArg<N>(a)`                | Pass the `N`-th (0-based) argument of the mock function to action `a` and perform it. |
 | `WithArgs<N1, N2, ..., Nk>(a)` | Pass the selected (0-based) arguments of the mock function to action `a` and perform it. |
diff --git a/googlemock/docs/cook_book.md b/googlemock/docs/cook_book.md
index 3fc1198..d7cee69 100644
--- a/googlemock/docs/cook_book.md
+++ b/googlemock/docs/cook_book.md
@@ -10,6 +10,8 @@
 name `Foo` defined by gMock. We omit such `using` statements in this section for
 brevity, but you should do it in your own code.
 
+<!-- GOOGLETEST_CM0035 DO NOT DELETE -->
+
 ## Creating Mock Classes
 
 Mock classes are defined as normal classes, using the `MOCK_METHOD` macro to
diff --git a/googlemock/docs/for_dummies.md b/googlemock/docs/for_dummies.md
index 4ce7b94..a9c012b 100644
--- a/googlemock/docs/for_dummies.md
+++ b/googlemock/docs/for_dummies.md
@@ -2,6 +2,8 @@
 
 <!-- GOOGLETEST_CM0013 DO NOT DELETE -->
 
+<!-- GOOGLETEST_CM0035 DO NOT DELETE -->
+
 ## What Is gMock?
 
 When you write a prototype or test, often it's not feasible or wise to rely on
diff --git a/googlemock/docs/gmock_faq.md b/googlemock/docs/gmock_faq.md
index 7f8c647..14acae5 100644
--- a/googlemock/docs/gmock_faq.md
+++ b/googlemock/docs/gmock_faq.md
@@ -2,6 +2,8 @@
 
 <!-- GOOGLETEST_CM0021 DO NOT DELETE -->
 
+<!-- GOOGLETEST_CM0035 DO NOT DELETE -->
+
 ### When I call a method on my mock object, the method for the real object is invoked instead. What's the problem?
 
 In order for a method to be mocked, it must be *virtual*, unless you use the
diff --git a/googlemock/docs/pump_manual.md b/googlemock/docs/pump_manual.md
index cdf7c57..19f1a48 100644
--- a/googlemock/docs/pump_manual.md
+++ b/googlemock/docs/pump_manual.md
@@ -1,5 +1,7 @@
 <b>P</b>ump is <b>U</b>seful for <b>M</b>eta <b>P</b>rogramming.
 
+<!-- GOOGLETEST_CM0035 DO NOT DELETE -->
+
 # The Problem
 
 Template and macro libraries often need to define many classes, functions, or
diff --git a/googlemock/include/gmock/gmock-actions.h b/googlemock/include/gmock/gmock-actions.h
index 79054db..3aba9ec 100644
--- a/googlemock/include/gmock/gmock-actions.h
+++ b/googlemock/include/gmock/gmock-actions.h
@@ -1032,9 +1032,13 @@
 template <typename... Actions>
 struct DoAllAction {
  private:
-  template <typename... Args, size_t... I>
-  std::vector<Action<void(Args...)>> Convert(IndexSequence<I...>) const {
-    return {std::get<I>(actions)...};
+  template <typename T>
+  using NonFinalType =
+      typename std::conditional<std::is_scalar<T>::value, T, const T&>::type;
+
+  template <typename ActionT, size_t... I>
+  std::vector<ActionT> Convert(IndexSequence<I...>) const {
+    return {ActionT(std::get<I>(actions))...};
   }
 
  public:
@@ -1043,17 +1047,17 @@
   template <typename R, typename... Args>
   operator Action<R(Args...)>() const {  // NOLINT
     struct Op {
-      std::vector<Action<void(Args...)>> converted;
+      std::vector<Action<void(NonFinalType<Args>...)>> converted;
       Action<R(Args...)> last;
       R operator()(Args... args) const {
-        auto tuple_args = std::forward_as_tuple(std::forward<Args>(args)...);
         for (auto& a : converted) {
-          a.Perform(tuple_args);
+          a.Perform(std::forward_as_tuple(std::forward<Args>(args)...));
         }
-        return last.Perform(tuple_args);
+        return last.Perform(std::forward_as_tuple(std::forward<Args>(args)...));
       }
     };
-    return Op{Convert<Args...>(MakeIndexSequence<sizeof...(Actions) - 1>()),
+    return Op{Convert<Action<void(NonFinalType<Args>...)>>(
+                  MakeIndexSequence<sizeof...(Actions) - 1>()),
               std::get<sizeof...(Actions) - 1>(actions)};
   }
 };
@@ -1093,7 +1097,8 @@
 typedef internal::IgnoredValue Unused;
 
 // Creates an action that does actions a1, a2, ..., sequentially in
-// each invocation.
+// each invocation. All but the last action will have a readonly view of the
+// arguments.
 template <typename... Action>
 internal::DoAllAction<typename std::decay<Action>::type...> DoAll(
     Action&&... action) {
diff --git a/googlemock/include/gmock/gmock-matchers.h b/googlemock/include/gmock/gmock-matchers.h
index 59ef2f3..a897611 100644
--- a/googlemock/include/gmock/gmock-matchers.h
+++ b/googlemock/include/gmock/gmock-matchers.h
@@ -4725,13 +4725,42 @@
       internal::variant_matcher::VariantMatcher<T>(matcher));
 }
 
-
 #if GTEST_HAS_EXCEPTIONS
 
-// Anything inside the 'internal' namespace IS INTERNAL IMPLEMENTATION
-// and MUST NOT BE USED IN USER CODE!!!
+// Anything inside the `internal` namespace is internal to the implementation
+// and must not be used in user code!
 namespace internal {
 
+class WithWhatMatcherImpl {
+ public:
+  WithWhatMatcherImpl(Matcher<std::string> matcher)
+      : matcher_(std::move(matcher)) {}
+
+  void DescribeTo(std::ostream* os) const {
+    *os << "contains .what() that ";
+    matcher_.DescribeTo(os);
+  }
+
+  void DescribeNegationTo(std::ostream* os) const {
+    *os << "contains .what() that does not ";
+    matcher_.DescribeTo(os);
+  }
+
+  template <typename Err>
+  bool MatchAndExplain(const Err& err, MatchResultListener* listener) const {
+    *listener << "which contains .what() that ";
+    return matcher_.MatchAndExplain(err.what(), listener);
+  }
+
+ private:
+  const Matcher<std::string> matcher_;
+};
+
+inline PolymorphicMatcher<WithWhatMatcherImpl> WithWhat(
+    Matcher<std::string> m) {
+  return MakePolymorphicMatcher(WithWhatMatcherImpl(std::move(m)));
+}
+
 template <typename Err>
 class ExceptionMatcherImpl {
   class NeverThrown {
@@ -4763,12 +4792,10 @@
   //     catch (const std::exception&) { /* an expected exception */ }
   //     catch (const NeverThrown&) { /* exception of a wrong type */ }
   using DefaultExceptionType = typename std::conditional<
-      std::is_same<
-          typename std::remove_cv<
-              typename std::remove_reference<Err>::type>::type,
-          std::exception>::value,
-      const NeverThrown&,
-      const std::exception&>::type;
+      std::is_same<typename std::remove_cv<
+                       typename std::remove_reference<Err>::type>::type,
+                   std::exception>::value,
+      const NeverThrown&, const std::exception&>::type;
 
  public:
   ExceptionMatcherImpl(Matcher<const Err&> matcher)
@@ -4776,16 +4803,14 @@
 
   void DescribeTo(std::ostream* os) const {
     *os << "throws an exception which is a " << GetTypeName<Err>();
-    if (matcher_.GetDescriber() != nullptr) {
-      *os << " which ";
-      matcher_.DescribeTo(os);
-    }
+    *os << " which ";
+    matcher_.DescribeTo(os);
   }
 
   void DescribeNegationTo(std::ostream* os) const {
-    *os << "not (";
-    DescribeTo(os);
-    *os << ")";
+    *os << "throws an exception which is not a " << GetTypeName<Err>();
+    *os << " which ";
+    matcher_.DescribeNegationTo(os);
   }
 
   template <typename T>
@@ -4794,18 +4819,14 @@
       (void)(std::forward<T>(x)());
     } catch (const Err& err) {
       *listener << "throws an exception which is a " << GetTypeName<Err>();
-      if (matcher_.GetDescriber() != nullptr) {
-        *listener << " ";
-        return matcher_.MatchAndExplain(err, listener);
-      } else {
-        return true;
-      }
+      *listener << " ";
+      return matcher_.MatchAndExplain(err, listener);
     } catch (DefaultExceptionType err) {
 #if GTEST_HAS_RTTI
-      *listener << "throws an exception of type "
-          << GetTypeName(typeid(err)) << " ";
+      *listener << "throws an exception of type " << GetTypeName(typeid(err));
+      *listener << " ";
 #else
-      *listener << "throws an std::exception-derived error ";
+      *listener << "throws an std::exception-derived type ";
 #endif
       *listener << "with description \"" << err.what() << "\"";
       return false;
@@ -4813,6 +4834,7 @@
       *listener << "throws an exception of an unknown type";
       return false;
     }
+
     *listener << "does not throw any exception";
     return false;
   }
@@ -4846,36 +4868,28 @@
 //           Property(&std::runtime_error::what, HasSubstr("message"))));
 
 template <typename Err>
-PolymorphicMatcher<internal::ExceptionMatcherImpl<Err>>
-Throws() {
+PolymorphicMatcher<internal::ExceptionMatcherImpl<Err>> Throws() {
   return MakePolymorphicMatcher(
-      internal::ExceptionMatcherImpl<Err>{
-          Matcher<const Err&>{}});
+      internal::ExceptionMatcherImpl<Err>(A<const Err&>()));
 }
+
 template <typename Err, typename ExceptionMatcher>
-PolymorphicMatcher<internal::ExceptionMatcherImpl<Err>>
-Throws(const ExceptionMatcher& exceptionMatcher) {
+PolymorphicMatcher<internal::ExceptionMatcherImpl<Err>> Throws(
+    const ExceptionMatcher& exception_matcher) {
   // Using matcher cast allows users to pass a matcher of a more broad type.
   // For example user may want to pass Matcher<std::exception>
   // to Throws<std::runtime_error>, or Matcher<int64> to Throws<int32>.
-  return MakePolymorphicMatcher(
-      internal::ExceptionMatcherImpl<Err>{
-          SafeMatcherCast<const Err&>(exceptionMatcher)});
+  return MakePolymorphicMatcher(internal::ExceptionMatcherImpl<Err>(
+      SafeMatcherCast<const Err&>(exception_matcher)));
 }
+
 template <typename Err, typename MessageMatcher>
-PolymorphicMatcher<internal::ExceptionMatcherImpl<Err>>
-ThrowsMessage(const MessageMatcher& messageMatcher) {
-  static_assert(
-      std::is_base_of<std::exception, Err>::value,
-      "expected an std::exception-derived class");
-  // We cast matcher to std::string so that we have string semantics instead of
-  // pointer semantics. With this cast, we can accept matchers that match types
-  // that're constructible from strings. Also, we can accept raw string
-  // literals, e.g. ThrowsMessage("message").
-  return MakePolymorphicMatcher(
-      internal::ExceptionMatcherImpl<Err>{
-          Property("what", &std::exception::what,
-                   MatcherCast<std::string>(messageMatcher))});
+PolymorphicMatcher<internal::ExceptionMatcherImpl<Err>> ThrowsMessage(
+    MessageMatcher&& message_matcher) {
+  static_assert(std::is_base_of<std::exception, Err>::value,
+                "expected an std::exception-derived type");
+  return Throws<Err>(internal::WithWhat(
+      MatcherCast<std::string>(std::forward<MessageMatcher>(message_matcher))));
 }
 
 #endif  // GTEST_HAS_EXCEPTIONS
diff --git a/googlemock/src/gmock-spec-builders.cc b/googlemock/src/gmock-spec-builders.cc
index 346e680..05a50f6 100644
--- a/googlemock/src/gmock-spec-builders.cc
+++ b/googlemock/src/gmock-spec-builders.cc
@@ -433,10 +433,10 @@
 
   // The UntypedFindMatchingExpectation() function acquires and
   // releases g_gmock_mutex.
+
   const ExpectationBase* const untyped_expectation =
-      this->UntypedFindMatchingExpectation(
-          untyped_args, &untyped_action, &is_excessive,
-          &ss, &why);
+      this->UntypedFindMatchingExpectation(untyped_args, &untyped_action,
+                                           &is_excessive, &ss, &why);
   const bool found = untyped_expectation != nullptr;
 
   // True if and only if we need to print the call's arguments
@@ -461,26 +461,42 @@
     untyped_expectation->DescribeLocationTo(&loc);
   }
 
-  UntypedActionResultHolderBase* const result =
-      untyped_action == nullptr
-          ? this->UntypedPerformDefaultAction(untyped_args, ss.str())
-          : this->UntypedPerformAction(untyped_action, untyped_args);
-  if (result != nullptr) result->PrintAsActionResult(&ss);
-  ss << "\n" << why.str();
+  UntypedActionResultHolderBase* result = nullptr;
 
-  if (!found) {
-    // No expectation matches this call - reports a failure.
-    Expect(false, nullptr, -1, ss.str());
-  } else if (is_excessive) {
-    // We had an upper-bound violation and the failure message is in ss.
-    Expect(false, untyped_expectation->file(),
-           untyped_expectation->line(), ss.str());
-  } else {
-    // We had an expected call and the matching expectation is
-    // described in ss.
-    Log(kInfo, loc.str() + ss.str(), 2);
+  auto perform_action = [&] {
+    return untyped_action == nullptr
+               ? this->UntypedPerformDefaultAction(untyped_args, ss.str())
+               : this->UntypedPerformAction(untyped_action, untyped_args);
+  };
+  auto handle_failures = [&] {
+    ss << "\n" << why.str();
+
+    if (!found) {
+      // No expectation matches this call - reports a failure.
+      Expect(false, nullptr, -1, ss.str());
+    } else if (is_excessive) {
+      // We had an upper-bound violation and the failure message is in ss.
+      Expect(false, untyped_expectation->file(), untyped_expectation->line(),
+             ss.str());
+    } else {
+      // We had an expected call and the matching expectation is
+      // described in ss.
+      Log(kInfo, loc.str() + ss.str(), 2);
+    }
+  };
+#if GTEST_HAS_EXCEPTIONS
+  try {
+    result = perform_action();
+  } catch (...) {
+    handle_failures();
+    throw;
   }
+#else
+  result = perform_action();
+#endif
 
+  if (result != nullptr) result->PrintAsActionResult(&ss);
+  handle_failures();
   return result;
 }
 
diff --git a/googlemock/test/gmock-generated-actions_test.cc b/googlemock/test/gmock-generated-actions_test.cc
index ef39dff..6490616 100644
--- a/googlemock/test/gmock-generated-actions_test.cc
+++ b/googlemock/test/gmock-generated-actions_test.cc
@@ -422,6 +422,33 @@
   EXPECT_EQ('g', g);
 }
 
+TEST(DoAllTest, NoArgs) {
+  bool ran_first = false;
+  Action<bool()> a =
+      DoAll([&] { ran_first = true; }, [&] { return ran_first; });
+  EXPECT_TRUE(a.Perform({}));
+}
+
+TEST(DoAllTest, MoveOnlyArgs) {
+  bool ran_first = false;
+  Action<int(std::unique_ptr<int>)> a =
+      DoAll(InvokeWithoutArgs([&] { ran_first = true; }),
+            [](std::unique_ptr<int> p) { return *p; });
+  EXPECT_EQ(7, a.Perform(std::make_tuple(std::unique_ptr<int>(new int(7)))));
+  EXPECT_TRUE(ran_first);
+}
+
+TEST(DoAllTest, ImplicitlyConvertsActionArguments) {
+  bool ran_first = false;
+  // Action<void(std::vector<int>)> isn't an
+  // Action<void(const std::vector<int>&) but can be converted.
+  Action<void(std::vector<int>)> first = [&] { ran_first = true; };
+  Action<int(std::vector<int>)> a =
+      DoAll(first, [](std::vector<int> arg) { return arg.front(); });
+  EXPECT_EQ(7, a.Perform(std::make_tuple(std::vector<int>{7})));
+  EXPECT_TRUE(ran_first);
+}
+
 // The ACTION*() macros trigger warning C4100 (unreferenced formal
 // parameter) in MSVC with -W4.  Unfortunately they cannot be fixed in
 // the macro definition, as the warnings are generated when the macro
diff --git a/googlemock/test/gmock-matchers_test.cc b/googlemock/test/gmock-matchers_test.cc
index af3b02c..1cba156 100644
--- a/googlemock/test/gmock-matchers_test.cc
+++ b/googlemock/test/gmock-matchers_test.cc
@@ -8119,55 +8119,60 @@
 
 #if GTEST_HAS_EXCEPTIONS
 
+// std::function<void()> is used below for compatibility with older copies of
+// GCC. Normally, a raw lambda is all that is needed.
+
 // Test that examples from documentation compile
 TEST(ThrowsTest, Examples) {
   EXPECT_THAT(
-      []() { throw std::runtime_error("message"); },
+      std::function<void()>([]() { throw std::runtime_error("message"); }),
       Throws<std::runtime_error>());
 
   EXPECT_THAT(
-      []() { throw std::runtime_error("message"); },
+      std::function<void()>([]() { throw std::runtime_error("message"); }),
       ThrowsMessage<std::runtime_error>(HasSubstr("message")));
-
-  EXPECT_THAT(
-      []() { throw std::runtime_error("message"); },
-      Throws<std::runtime_error>(
-          Property(&std::runtime_error::what, HasSubstr("message"))));
 }
 
 TEST(ThrowsTest, DoesNotGenerateDuplicateCatchClauseWarning) {
-  EXPECT_THAT(
-      []() { throw std::exception(); },
-      Throws<std::exception>());
+  EXPECT_THAT(std::function<void()>([]() { throw std::exception(); }),
+              Throws<std::exception>());
 }
 
 TEST(ThrowsTest, CallableExecutedExactlyOnce) {
   size_t a = 0;
 
-  EXPECT_THAT(
-      [&a]() { a++; throw 10; },
-      Throws<int>());
+  EXPECT_THAT(std::function<void()>([&a]() {
+                a++;
+                throw 10;
+              }),
+              Throws<int>());
   EXPECT_EQ(a, 1u);
 
-  EXPECT_THAT(
-      [&a]() { a++; throw std::runtime_error("message"); },
-      Throws<std::runtime_error>());
+  EXPECT_THAT(std::function<void()>([&a]() {
+                a++;
+                throw std::runtime_error("message");
+              }),
+              Throws<std::runtime_error>());
   EXPECT_EQ(a, 2u);
 
-  EXPECT_THAT(
-      [&a]() { a++; throw std::runtime_error("message"); },
-      ThrowsMessage<std::runtime_error>(HasSubstr("message")));
+  EXPECT_THAT(std::function<void()>([&a]() {
+                a++;
+                throw std::runtime_error("message");
+              }),
+              ThrowsMessage<std::runtime_error>(HasSubstr("message")));
   EXPECT_EQ(a, 3u);
 
-  EXPECT_THAT(
-      [&a]() { a++; throw std::runtime_error("message"); },
-      Throws<std::runtime_error>(
-          Property(&std::runtime_error::what, HasSubstr("message"))));
+  EXPECT_THAT(std::function<void()>([&a]() {
+                a++;
+                throw std::runtime_error("message");
+              }),
+              Throws<std::runtime_error>(
+                  Property(&std::runtime_error::what, HasSubstr("message"))));
   EXPECT_EQ(a, 4u);
 }
 
 TEST(ThrowsTest, Describe) {
-  Matcher<void (*)()> matcher = Throws<std::runtime_error>();
+  Matcher<std::function<void()>> matcher = Throws<std::runtime_error>();
   std::stringstream ss;
   matcher.DescribeTo(&ss);
   auto explanation = ss.str();
@@ -8175,50 +8180,42 @@
 }
 
 TEST(ThrowsTest, Success) {
-  Matcher<void (*)()> matcher = Throws<std::runtime_error>();
+  Matcher<std::function<void()>> matcher = Throws<std::runtime_error>();
   StringMatchResultListener listener;
-  EXPECT_TRUE(
-      matcher.MatchAndExplain(
-          []() { throw std::runtime_error("error message"); }, &listener));
+  EXPECT_TRUE(matcher.MatchAndExplain(
+      []() { throw std::runtime_error("error message"); }, &listener));
   EXPECT_THAT(listener.str(), HasSubstr("std::runtime_error"));
 }
 
 TEST(ThrowsTest, FailWrongType) {
-  Matcher<void (*)()> matcher = Throws<std::runtime_error>();
+  Matcher<std::function<void()>> matcher = Throws<std::runtime_error>();
   StringMatchResultListener listener;
-  EXPECT_FALSE(
-      matcher.MatchAndExplain(
-          []() { throw std::logic_error("error message"); }, &listener));
+  EXPECT_FALSE(matcher.MatchAndExplain(
+      []() { throw std::logic_error("error message"); }, &listener));
   EXPECT_THAT(listener.str(), HasSubstr("std::logic_error"));
   EXPECT_THAT(listener.str(), HasSubstr("\"error message\""));
 }
 
 TEST(ThrowsTest, FailWrongTypeNonStd) {
-  Matcher<void (*)()> matcher = Throws<std::runtime_error>();
+  Matcher<std::function<void()>> matcher = Throws<std::runtime_error>();
   StringMatchResultListener listener;
-  EXPECT_FALSE(
-      matcher.MatchAndExplain(
-          []() { throw 10; }, &listener));
-  EXPECT_THAT(
-      listener.str(),
-      HasSubstr("throws an exception of an unknown type"));
+  EXPECT_FALSE(matcher.MatchAndExplain([]() { throw 10; }, &listener));
+  EXPECT_THAT(listener.str(),
+              HasSubstr("throws an exception of an unknown type"));
 }
 
 TEST(ThrowsTest, FailNoThrow) {
-  Matcher<void (*)()> matcher = Throws<std::runtime_error>();
+  Matcher<std::function<void()>> matcher = Throws<std::runtime_error>();
   StringMatchResultListener listener;
-  EXPECT_FALSE(
-      matcher.MatchAndExplain(
-          []() { (void)0; }, &listener));
-  EXPECT_THAT(
-      listener.str(),
-      HasSubstr("does not throw any exception"));
+  EXPECT_FALSE(matcher.MatchAndExplain([]() { (void)0; }, &listener));
+  EXPECT_THAT(listener.str(), HasSubstr("does not throw any exception"));
 }
 
-class ThrowsPredicateTest: public TestWithParam<Matcher<void (*)()>> {};
+class ThrowsPredicateTest
+    : public TestWithParam<Matcher<std::function<void()>>> {};
 
 TEST_P(ThrowsPredicateTest, Describe) {
-  Matcher<void (*)()> matcher = GetParam();
+  Matcher<std::function<void()>> matcher = GetParam();
   std::stringstream ss;
   matcher.DescribeTo(&ss);
   auto explanation = ss.str();
@@ -8227,70 +8224,56 @@
 }
 
 TEST_P(ThrowsPredicateTest, Success) {
-  Matcher<void (*)()> matcher = GetParam();
+  Matcher<std::function<void()>> matcher = GetParam();
   StringMatchResultListener listener;
-  EXPECT_TRUE(
-      matcher.MatchAndExplain(
-          []() { throw std::runtime_error("error message"); }, &listener));
+  EXPECT_TRUE(matcher.MatchAndExplain(
+      []() { throw std::runtime_error("error message"); }, &listener));
   EXPECT_THAT(listener.str(), HasSubstr("std::runtime_error"));
 }
 
 TEST_P(ThrowsPredicateTest, FailWrongType) {
-  Matcher<void (*)()> matcher = GetParam();
+  Matcher<std::function<void()>> matcher = GetParam();
   StringMatchResultListener listener;
-  EXPECT_FALSE(
-      matcher.MatchAndExplain(
-          []() { throw std::logic_error("error message"); }, &listener));
+  EXPECT_FALSE(matcher.MatchAndExplain(
+      []() { throw std::logic_error("error message"); }, &listener));
   EXPECT_THAT(listener.str(), HasSubstr("std::logic_error"));
   EXPECT_THAT(listener.str(), HasSubstr("\"error message\""));
 }
 
 TEST_P(ThrowsPredicateTest, FailWrongTypeNonStd) {
-  Matcher<void (*)()> matcher = GetParam();
+  Matcher<std::function<void()>> matcher = GetParam();
   StringMatchResultListener listener;
-  EXPECT_FALSE(
-      matcher.MatchAndExplain(
-          []() { throw 10; }, &listener));
-  EXPECT_THAT(
-      listener.str(),
-      HasSubstr("throws an exception of an unknown type"));
+  EXPECT_FALSE(matcher.MatchAndExplain([]() { throw 10; }, &listener));
+  EXPECT_THAT(listener.str(),
+              HasSubstr("throws an exception of an unknown type"));
 }
 
 TEST_P(ThrowsPredicateTest, FailWrongMessage) {
-  Matcher<void (*)()> matcher = GetParam();
+  Matcher<std::function<void()>> matcher = GetParam();
   StringMatchResultListener listener;
-  EXPECT_FALSE(
-      matcher.MatchAndExplain(
-          []() { throw std::runtime_error("wrong message"); }, &listener));
+  EXPECT_FALSE(matcher.MatchAndExplain(
+      []() { throw std::runtime_error("wrong message"); }, &listener));
   EXPECT_THAT(listener.str(), HasSubstr("std::runtime_error"));
-  EXPECT_THAT(listener.str(), HasSubstr("wrong message"));
+  EXPECT_THAT(listener.str(), Not(HasSubstr("wrong message")));
 }
 
 TEST_P(ThrowsPredicateTest, FailNoThrow) {
-  Matcher<void (*)()> matcher = GetParam();
+  Matcher<std::function<void()>> matcher = GetParam();
   StringMatchResultListener listener;
-  EXPECT_FALSE(
-      matcher.MatchAndExplain(
-          []() { (void)0; }, &listener));
-  EXPECT_THAT(
-      listener.str(),
-      HasSubstr("does not throw any exception"));
+  EXPECT_FALSE(matcher.MatchAndExplain([]() {}, &listener));
+  EXPECT_THAT(listener.str(), HasSubstr("does not throw any exception"));
 }
 
-INSTANTIATE_TEST_SUITE_P(AllMessagePredicates, ThrowsPredicateTest,
-    Values(
-        static_cast<Matcher<void (*)()>>(
-            Throws<std::runtime_error>(
-                Property(&std::exception::what, HasSubstr("error message")))),
-        static_cast<Matcher<void (*)()>>(
-            ThrowsMessage<std::runtime_error>(HasSubstr("error message")))));
+INSTANTIATE_TEST_SUITE_P(
+    AllMessagePredicates, ThrowsPredicateTest,
+    Values(Matcher<std::function<void()>>(
+        ThrowsMessage<std::runtime_error>(HasSubstr("error message")))));
 
 // Tests that Throws<E1>(Matcher<E2>{}) compiles even when E2 != const E1&.
 TEST(ThrowsPredicateCompilesTest, ExceptionMatcherAcceptsBroadType) {
   {
-    Matcher<std::exception> inner =
-        Property(&std::exception::what, HasSubstr("error message"));
-    Matcher<void (*)()> matcher = Throws<std::runtime_error>(inner);
+    Matcher<std::function<void()>> matcher =
+        ThrowsMessage<std::runtime_error>(HasSubstr("error message"));
     EXPECT_TRUE(
         matcher.Matches([]() { throw std::runtime_error("error message"); }));
     EXPECT_FALSE(
@@ -8299,25 +8282,21 @@
 
   {
     Matcher<uint64_t> inner = Eq(10);
-    Matcher<void (*)()> matcher = Throws<uint32_t>(inner);
-    EXPECT_TRUE(
-        matcher.Matches([]() { throw (uint32_t)10; }));
-    EXPECT_FALSE(
-        matcher.Matches([]() { throw (uint32_t)11; }));
+    Matcher<std::function<void()>> matcher = Throws<uint32_t>(inner);
+    EXPECT_TRUE(matcher.Matches([]() { throw(uint32_t) 10; }));
+    EXPECT_FALSE(matcher.Matches([]() { throw(uint32_t) 11; }));
   }
 }
 
 // Tests that ThrowsMessage("message") is equivalent
 // to ThrowsMessage(Eq<std::string>("message")).
 TEST(ThrowsPredicateCompilesTest, MessageMatcherAcceptsNonMatcher) {
-  Matcher<void (*)()> matcher = ThrowsMessage<std::runtime_error>(
-      "error message");
+  Matcher<std::function<void()>> matcher =
+      ThrowsMessage<std::runtime_error>("error message");
   EXPECT_TRUE(
-      matcher.Matches(
-          []() { throw std::runtime_error("error message"); }));
-  EXPECT_FALSE(
-      matcher.Matches(
-          []() { throw std::runtime_error("wrong error message"); }));
+      matcher.Matches([]() { throw std::runtime_error("error message"); }));
+  EXPECT_FALSE(matcher.Matches(
+      []() { throw std::runtime_error("wrong error message"); }));
 }
 
 #endif  // GTEST_HAS_EXCEPTIONS
diff --git a/googlemock/test/gmock-more-actions_test.cc b/googlemock/test/gmock-more-actions_test.cc
index 97ec5cf..d6a078b 100644
--- a/googlemock/test/gmock-more-actions_test.cc
+++ b/googlemock/test/gmock-more-actions_test.cc
@@ -38,7 +38,9 @@
 #include <memory>
 #include <sstream>
 #include <string>
+
 #include "gmock/gmock.h"
+#include "gtest/gtest-spi.h"
 #include "gtest/gtest.h"
 
 namespace testing {
@@ -604,6 +606,33 @@
   EXPECT_THROW(a.Perform(std::make_tuple()), MyException);
 }
 
+class Object {
+ public:
+  virtual ~Object() {}
+  virtual void Func() {}
+};
+
+class MockObject : public Object {
+ public:
+  ~MockObject() override {}
+  MOCK_METHOD(void, Func, (), (override));
+};
+
+TEST(ThrowActionTest, Times0) {
+  EXPECT_NONFATAL_FAILURE(
+      [] {
+        try {
+          MockObject m;
+          ON_CALL(m, Func()).WillByDefault([] { throw "something"; });
+          EXPECT_CALL(m, Func()).Times(0);
+          m.Func();
+        } catch (...) {
+          // Exception is caught but Times(0) still triggers a failure.
+        }
+      }(),
+      "");
+}
+
 #endif  // GTEST_HAS_EXCEPTIONS
 
 // Tests that SetArrayArgument<N>(first, last) sets the elements of the array
diff --git a/googletest/docs/advanced.md b/googletest/docs/advanced.md
index ade87e2..32819b6 100644
--- a/googletest/docs/advanced.md
+++ b/googletest/docs/advanced.md
@@ -2,6 +2,8 @@
 
 <!-- GOOGLETEST_CM0016 DO NOT DELETE -->
 
+<!-- GOOGLETEST_CM0035 DO NOT DELETE -->
+
 ## Introduction
 
 Now that you have read the [googletest Primer](primer.md) and learned how to
@@ -909,6 +911,12 @@
 
 ## Using Assertions in Sub-routines
 
+Note: If you want to put a series of test assertions in a subroutine to check
+for a complex condition, consider using
+[a custom GMock matcher](../../googlemock/docs/cook_book.md#NewMatchers)
+instead. This lets you provide a more readable error message in case of failure
+and avoid all of the issues described below.
+
 ### Adding Traces to Assertions
 
 If a test sub-routine is called from several places, when an assertion inside it
diff --git a/googletest/docs/faq.md b/googletest/docs/faq.md
index ebfecd3..f290f02 100644
--- a/googletest/docs/faq.md
+++ b/googletest/docs/faq.md
@@ -2,6 +2,8 @@
 
 <!-- GOOGLETEST_CM0014 DO NOT DELETE -->
 
+<!-- GOOGLETEST_CM0035 DO NOT DELETE -->
+
 ## Why should test suite names and test names not contain underscore?
 
 Underscore (`_`) is special, as C++ reserves the following to be used by the
diff --git a/googletest/docs/pkgconfig.md b/googletest/docs/pkgconfig.md
index b9bef3f..aed4ad4 100644
--- a/googletest/docs/pkgconfig.md
+++ b/googletest/docs/pkgconfig.md
@@ -1,5 +1,7 @@
 ## Using GoogleTest from various build systems
 
+<!-- GOOGLETEST_CM0035 DO NOT DELETE -->
+
 GoogleTest comes with pkg-config files that can be used to determine all
 necessary flags for compiling and linking to GoogleTest (and GoogleMock).
 Pkg-config is a standardised plain-text format containing
diff --git a/googletest/docs/primer.md b/googletest/docs/primer.md
index 2f459fd..ed44369 100644
--- a/googletest/docs/primer.md
+++ b/googletest/docs/primer.md
@@ -1,5 +1,7 @@
 # Googletest Primer
 
+<!-- GOOGLETEST_CM0035 DO NOT DELETE -->
+
 ## Introduction: Why googletest?
 
 *googletest* helps you write better C++ tests.
diff --git a/googletest/include/gtest/internal/gtest-internal.h b/googletest/include/gtest/internal/gtest-internal.h
index 288ff93..233724c 100644
--- a/googletest/include/gtest/internal/gtest-internal.h
+++ b/googletest/include/gtest/internal/gtest-internal.h
@@ -520,6 +520,7 @@
 
   static SetUpTearDownSuiteFuncType GetSetUpCaseOrSuite(const char* filename,
                                                         int line_num) {
+#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_
     SetUpTearDownSuiteFuncType test_case_fp =
         GetNotDefaultOrNull(&T::SetUpTestCase, &Test::SetUpTestCase);
     SetUpTearDownSuiteFuncType test_suite_fp =
@@ -531,10 +532,16 @@
         << filename << ":" << line_num;
 
     return test_case_fp != nullptr ? test_case_fp : test_suite_fp;
+#else
+    (void)(filename);
+    (void)(line_num);
+    return &T::SetUpTestSuite;
+#endif
   }
 
   static SetUpTearDownSuiteFuncType GetTearDownCaseOrSuite(const char* filename,
                                                            int line_num) {
+#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_
     SetUpTearDownSuiteFuncType test_case_fp =
         GetNotDefaultOrNull(&T::TearDownTestCase, &Test::TearDownTestCase);
     SetUpTearDownSuiteFuncType test_suite_fp =
@@ -546,6 +553,11 @@
         << filename << ":" << line_num;
 
     return test_case_fp != nullptr ? test_case_fp : test_suite_fp;
+#else
+    (void)(filename);
+    (void)(line_num);
+    return &T::TearDownTestSuite;
+#endif
   }
 };
 
diff --git a/googletest/src/gtest.cc b/googletest/src/gtest.cc
index 937556b..96150f1 100644
--- a/googletest/src/gtest.cc
+++ b/googletest/src/gtest.cc
@@ -3007,9 +3007,9 @@
   // Call both legacy and the new API
   repeater->OnTestSuiteStart(*this);
 //  Legacy API is deprecated but still available
-#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI
+#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_
   repeater->OnTestCaseStart(*this);
-#endif  //  GTEST_REMOVE_LEGACY_TEST_CASEAPI
+#endif  //  GTEST_REMOVE_LEGACY_TEST_CASEAPI_
 
   impl->os_stack_trace_getter()->UponLeavingGTest();
   internal::HandleExceptionsInMethodIfSupported(
@@ -3034,9 +3034,9 @@
   // Call both legacy and the new API
   repeater->OnTestSuiteEnd(*this);
 //  Legacy API is deprecated but still available
-#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI
+#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_
   repeater->OnTestCaseEnd(*this);
-#endif  //  GTEST_REMOVE_LEGACY_TEST_CASEAPI
+#endif  //  GTEST_REMOVE_LEGACY_TEST_CASEAPI_
 
   impl->set_current_test_suite(nullptr);
 }
@@ -3053,9 +3053,9 @@
   // Call both legacy and the new API
   repeater->OnTestSuiteStart(*this);
 //  Legacy API is deprecated but still available
-#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI
+#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_
   repeater->OnTestCaseStart(*this);
-#endif  //  GTEST_REMOVE_LEGACY_TEST_CASEAPI
+#endif  //  GTEST_REMOVE_LEGACY_TEST_CASEAPI_
 
   for (int i = 0; i < total_test_count(); i++) {
     GetMutableTestInfo(i)->Skip();
@@ -3064,9 +3064,9 @@
   // Call both legacy and the new API
   repeater->OnTestSuiteEnd(*this);
   // Legacy API is deprecated but still available
-#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI
+#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_
   repeater->OnTestCaseEnd(*this);
-#endif  //  GTEST_REMOVE_LEGACY_TEST_CASEAPI
+#endif  //  GTEST_REMOVE_LEGACY_TEST_CASEAPI_
 
   impl->set_current_test_suite(nullptr);
 }
diff --git a/googletest/test/googletest-shuffle-test_.cc b/googletest/test/googletest-shuffle-test_.cc
index c1fc106..4505663 100644
--- a/googletest/test/googletest-shuffle-test_.cc
+++ b/googletest/test/googletest-shuffle-test_.cc
@@ -82,7 +82,7 @@
   }
 
   void OnTestStart(const TestInfo& test_info) override {
-    printf("%s.%s\n", test_info.test_case_name(), test_info.name());
+    printf("%s.%s\n", test_info.test_suite_name(), test_info.name());
   }
 };
 
diff --git a/googletest/test/gtest-typed-test_test.cc b/googletest/test/gtest-typed-test_test.cc
index 0c1f660..de1db0c 100644
--- a/googletest/test/gtest-typed-test_test.cc
+++ b/googletest/test/gtest-typed-test_test.cc
@@ -193,13 +193,13 @@
   if (std::is_same<TypeParam, char>::value) {
     EXPECT_STREQ(::testing::UnitTest::GetInstance()
                      ->current_test_info()
-                     ->test_case_name(),
+                     ->test_suite_name(),
                  "TypedTestWithNames/char0");
   }
   if (std::is_same<TypeParam, int>::value) {
     EXPECT_STREQ(::testing::UnitTest::GetInstance()
                      ->current_test_info()
-                     ->test_case_name(),
+                     ->test_suite_name(),
                  "TypedTestWithNames/int1");
   }
 }
@@ -315,13 +315,13 @@
   if (std::is_same<TypeParam, char>::value) {
     EXPECT_STREQ(::testing::UnitTest::GetInstance()
                      ->current_test_info()
-                     ->test_case_name(),
+                     ->test_suite_name(),
                  "CustomName/TypeParametrizedTestWithNames/parChar0");
   }
   if (std::is_same<TypeParam, int>::value) {
     EXPECT_STREQ(::testing::UnitTest::GetInstance()
                      ->current_test_info()
-                     ->test_case_name(),
+                     ->test_suite_name(),
                  "CustomName/TypeParametrizedTestWithNames/parInt1");
   }
 }
diff --git a/googletest/test/gtest_unittest.cc b/googletest/test/gtest_unittest.cc
index c5e2def..d7fb048 100644
--- a/googletest/test/gtest_unittest.cc
+++ b/googletest/test/gtest_unittest.cc
@@ -218,17 +218,18 @@
 using testing::GTEST_FLAG(throw_on_failure);
 using testing::IsNotSubstring;
 using testing::IsSubstring;
+using testing::kMaxStackTraceDepth;
 using testing::Message;
 using testing::ScopedFakeTestPartResultReporter;
 using testing::StaticAssertTypeEq;
 using testing::Test;
-using testing::TestCase;
 using testing::TestEventListeners;
 using testing::TestInfo;
 using testing::TestPartResult;
 using testing::TestPartResultArray;
 using testing::TestProperty;
 using testing::TestResult;
+using testing::TestSuite;
 using testing::TimeInMillis;
 using testing::UnitTest;
 using testing::internal::AlwaysFalse;
@@ -244,7 +245,6 @@
 using testing::internal::ForEach;
 using testing::internal::FormatEpochTimeInMillisAsIso8601;
 using testing::internal::FormatTimeInMillisAsSeconds;
-using testing::internal::GTestFlagSaver;
 using testing::internal::GetCurrentOsStackTraceExceptTop;
 using testing::internal::GetElementOr;
 using testing::internal::GetNextRandomSeed;
@@ -253,11 +253,14 @@
 using testing::internal::GetTimeInMillis;
 using testing::internal::GetTypeId;
 using testing::internal::GetUnitTestImpl;
+using testing::internal::GTestFlagSaver;
 using testing::internal::Int32FromEnvOrDie;
 using testing::internal::IsAProtocolMessage;
 using testing::internal::IsContainer;
 using testing::internal::IsContainerTest;
 using testing::internal::IsNotContainer;
+using testing::internal::kMaxRandomSeed;
+using testing::internal::kTestTypeIdInGoogleTest;
 using testing::internal::NativeArray;
 using testing::internal::OsStackTraceGetter;
 using testing::internal::OsStackTraceGetterInterface;
@@ -279,9 +282,6 @@
 using testing::internal::edit_distance::CalculateOptimalEdits;
 using testing::internal::edit_distance::CreateUnifiedDiff;
 using testing::internal::edit_distance::EditType;
-using testing::internal::kMaxRandomSeed;
-using testing::internal::kTestTypeIdInGoogleTest;
-using testing::kMaxStackTraceDepth;
 
 #if GTEST_HAS_STREAM_REDIRECTION
 using testing::internal::CaptureStdout;
@@ -5339,7 +5339,7 @@
 TEST_F(TestInfoTest, Names) {
   const TestInfo* const test_info = GetTestInfo("Names");
 
-  ASSERT_STREQ("TestInfoTest", test_info->test_case_name());
+  ASSERT_STREQ("TestInfoTest", test_info->test_suite_name());
   ASSERT_STREQ("Names", test_info->name());
 }
 
@@ -5409,7 +5409,7 @@
 
 // Tests setting up and tearing down a test case.
 // Legacy API is deprecated but still available
-#ifndef REMOVE_LEGACY_TEST_CASEAPI
+#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_
 class SetUpTestCaseTest : public Test {
  protected:
   // This will be called once before the first test in this test case
@@ -5468,7 +5468,7 @@
 TEST_F(SetUpTestCaseTest, Test2) {
   EXPECT_STREQ("123", shared_resource_);
 }
-#endif  //  REMOVE_LEGACY_TEST_CASEAPI
+#endif  //  GTEST_REMOVE_LEGACY_TEST_CASEAPI_
 
 // Tests SetupTestSuite/TearDown TestSuite
 class SetUpTestSuiteTest : public Test {
@@ -6374,8 +6374,8 @@
     UnitTest::GetInstance()->current_test_info();
   ASSERT_TRUE(nullptr != test_info)
       << "There is a test running so we should have a valid TestInfo.";
-  EXPECT_STREQ("CurrentTestInfoTest", test_info->test_case_name())
-      << "Expected the name of the currently running test case.";
+  EXPECT_STREQ("CurrentTestInfoTest", test_info->test_suite_name())
+      << "Expected the name of the currently running test suite.";
   EXPECT_STREQ("WorksForFirstTestInATestSuite", test_info->name())
       << "Expected the name of the currently running test.";
 }
@@ -6389,8 +6389,8 @@
     UnitTest::GetInstance()->current_test_info();
   ASSERT_TRUE(nullptr != test_info)
       << "There is a test running so we should have a valid TestInfo.";
-  EXPECT_STREQ("CurrentTestInfoTest", test_info->test_case_name())
-      << "Expected the name of the currently running test case.";
+  EXPECT_STREQ("CurrentTestInfoTest", test_info->test_suite_name())
+      << "Expected the name of the currently running test suite.";
   EXPECT_STREQ("WorksForSecondTestInATestSuite", test_info->name())
       << "Expected the name of the currently running test.";
 }