From 4f002f1e236c1a0e7bdb096cd845f1a9c6c129c6 Mon Sep 17 00:00:00 2001 From: Arthur O'Dwyer Date: Thu, 16 Apr 2020 16:34:13 -0400 Subject: VariadicMatcher needs a non-defaulted move constructor for compile-time performance. We are about to remove all uses of GTEST_DISALLOW_ASSIGN_ in favor of using the Rule of Zero everywhere. Unfortunately, if we use the Rule of Zero here, then when the compiler needs to figure out if VariadicMatcher is move-constructible, it will recurse down into `tuple`, which on libstdc++ recurses too deeply. In file included from googlemock/test/gmock-matchers_test.cc:43: In file included from googlemock/include/gmock/gmock-matchers.h:258: In file included from /usr/include/c++/5.5.0/algorithm:60: In file included from /usr/include/c++/5.5.0/utility:70: In file included from /usr/include/c++/5.5.0/bits/stl_pair.h:59: In file included from /usr/include/c++/5.5.0/bits/move.h:57: /usr/bin/include/c++/5.5.0/type_traits:115:26: fatal error: recursive template instantiation exceeded maximum depth of 256 : public conditional<_B1::value, _B1, _B2>::type ^ The move constructor is the only problematic case, for some unknown reason. With GTEST_DISALLOW_ASSIGN_, the presence of a copy assignment operator causes the move constructor to be non-declared, thus non-defaulted, thus non-problematic. Without GTEST_DISALLOW_ASSIGN_, we have to do one of the following: - Default the copy constructor, so that the move constructor will be non-declared. - Define our own non-defaulted move constructor. ...except that doing the latter STILL did not work! Fortunately, the former (default the copy constructor, don't provide any move constructor) both works in practice and is semantically equivalent to the old code. --- googlemock/include/gmock/gmock-matchers.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/googlemock/include/gmock/gmock-matchers.h b/googlemock/include/gmock/gmock-matchers.h index fe88a7c7..b5b662d4 100644 --- a/googlemock/include/gmock/gmock-matchers.h +++ b/googlemock/include/gmock/gmock-matchers.h @@ -1333,6 +1333,9 @@ class VariadicMatcher { static_assert(sizeof...(Args) > 0, "Must have at least one matcher."); } + VariadicMatcher(const VariadicMatcher&) = default; + VariadicMatcher& operator=(const VariadicMatcher&) = delete; + // This template type conversion operator allows an // VariadicMatcher object to match any type that // all of the provided matchers (Matcher1, Matcher2, ...) can match. @@ -1357,8 +1360,6 @@ class VariadicMatcher { std::integral_constant) const {} std::tuple matchers_; - - GTEST_DISALLOW_ASSIGN_(VariadicMatcher); }; template -- cgit v1.2.3