From a9653c401e799933be77ee9dfa4aa0c378031b1d Mon Sep 17 00:00:00 2001 From: Scott Graham Date: Wed, 2 May 2018 11:14:39 -0700 Subject: Fix gmock not building when -fno-rtti Fixes issue #1554. This is internal cl/195020996. --- googlemock/include/gmock/gmock-matchers.h | 8 ++++---- googlemock/test/gmock-matchers_test.cc | 6 ++---- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/googlemock/include/gmock/gmock-matchers.h b/googlemock/include/gmock/gmock-matchers.h index e0a78646..c94f5826 100644 --- a/googlemock/include/gmock/gmock-matchers.h +++ b/googlemock/include/gmock/gmock-matchers.h @@ -2371,6 +2371,7 @@ class PointeeMatcher { GTEST_DISALLOW_ASSIGN_(PointeeMatcher); }; +#if GTEST_HAS_RTTI // Implements the WhenDynamicCastTo(m) matcher that matches a pointer or // reference that matches inner_matcher when dynamic_cast is applied. // The result of dynamic_cast is forwarded to the inner matcher. @@ -2397,11 +2398,7 @@ class WhenDynamicCastToMatcherBase { const Matcher matcher_; static std::string GetToName() { -#if GTEST_HAS_RTTI return GetTypeName(); -#else // GTEST_HAS_RTTI - return "the target type"; -#endif // GTEST_HAS_RTTI } private: @@ -2447,6 +2444,7 @@ class WhenDynamicCastToMatcher : public WhenDynamicCastToMatcherBase { return MatchPrintAndExplain(*to, this->matcher_, listener); } }; +#endif // GTEST_HAS_RTTI // Implements the Field() matcher for matching a field (i.e. member // variable) of an object. @@ -4441,6 +4439,7 @@ inline internal::PointeeMatcher Pointee( return internal::PointeeMatcher(inner_matcher); } +#if GTEST_HAS_RTTI // Creates a matcher that matches a pointer or reference that matches // inner_matcher when dynamic_cast is applied. // The result of dynamic_cast is forwarded to the inner matcher. @@ -4453,6 +4452,7 @@ WhenDynamicCastTo(const Matcher& inner_matcher) { return MakePolymorphicMatcher( internal::WhenDynamicCastToMatcher(inner_matcher)); } +#endif // GTEST_HAS_RTTI // Creates a matcher that matches an object whose given field matches // 'matcher'. For example, diff --git a/googlemock/test/gmock-matchers_test.cc b/googlemock/test/gmock-matchers_test.cc index b4224651..87b2ad5c 100644 --- a/googlemock/test/gmock-matchers_test.cc +++ b/googlemock/test/gmock-matchers_test.cc @@ -3704,6 +3704,7 @@ MATCHER_P(FieldIIs, inner_matcher, "") { return ExplainMatchResult(inner_matcher, arg.i, result_listener); } +#if GTEST_HAS_RTTI TEST(WhenDynamicCastToTest, SameType) { Derived derived; derived.i = 4; @@ -3761,12 +3762,8 @@ TEST(WhenDynamicCastToTest, AmbiguousCast) { TEST(WhenDynamicCastToTest, Describe) { Matcher matcher = WhenDynamicCastTo(Pointee(_)); -#if GTEST_HAS_RTTI const std::string prefix = "when dynamic_cast to " + internal::GetTypeName() + ", "; -#else // GTEST_HAS_RTTI - const std::string prefix = "when dynamic_cast, "; -#endif // GTEST_HAS_RTTI EXPECT_EQ(prefix + "points to a value that is anything", Describe(matcher)); EXPECT_EQ(prefix + "does not point to a value that is anything", DescribeNegation(matcher)); @@ -3799,6 +3796,7 @@ TEST(WhenDynamicCastToTest, BadReference) { Base& as_base_ref = derived; EXPECT_THAT(as_base_ref, Not(WhenDynamicCastTo(_))); } +#endif // GTEST_HAS_RTTI // Minimal const-propagating pointer. template -- cgit v1.2.3 From b8fa4d275441acae8d4e84f373940869436b1de1 Mon Sep 17 00:00:00 2001 From: James Dennett Date: Thu, 10 May 2018 22:33:29 -0700 Subject: Add unit test for CanonicalizeForStdLibVersioning. --- googletest/test/gtest_unittest.cc | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/googletest/test/gtest_unittest.cc b/googletest/test/gtest_unittest.cc index 58995a4f..2b5a7e11 100644 --- a/googletest/test/gtest_unittest.cc +++ b/googletest/test/gtest_unittest.cc @@ -380,6 +380,31 @@ TEST(GetTestTypeIdTest, ReturnsTheSameValueInsideOrOutsideOfGoogleTest) { EXPECT_EQ(kTestTypeIdInGoogleTest, GetTestTypeId()); } +// Tests CanonicalizeForStdLibVersioning. + +using ::testing::internal::CanonicalizeForStdLibVersioning; + +TEST(CanonicalizeForStdLibVersioning, LeavesUnversionedNamesUnchanged) { + EXPECT_EQ("std::bind", CanonicalizeForStdLibVersioning("std::bind")); + EXPECT_EQ("std::_", CanonicalizeForStdLibVersioning("std::_")); + EXPECT_EQ("std::__foo", CanonicalizeForStdLibVersioning("std::__foo")); + EXPECT_EQ("gtl::__1::x", CanonicalizeForStdLibVersioning("gtl::__1::x")); + EXPECT_EQ("__1::x", CanonicalizeForStdLibVersioning("__1::x")); + EXPECT_EQ("::__1::x", CanonicalizeForStdLibVersioning("::__1::x")); +} + +TEST(CanonicalizeForStdLibVersioning, ElidesDoubleUnderNames) { + EXPECT_EQ("std::bind", CanonicalizeForStdLibVersioning("std::__1::bind")); + EXPECT_EQ("std::_", CanonicalizeForStdLibVersioning("std::__1::_")); + + EXPECT_EQ("std::bind", CanonicalizeForStdLibVersioning("std::__g::bind")); + EXPECT_EQ("std::_", CanonicalizeForStdLibVersioning("std::__g::_")); + + EXPECT_EQ("std::bind", + CanonicalizeForStdLibVersioning("std::__google::bind")); + EXPECT_EQ("std::_", CanonicalizeForStdLibVersioning("std::__google::_")); +} + // Tests FormatTimeInMillisAsSeconds(). TEST(FormatTimeInMillisAsSecondsTest, FormatsZero) { -- cgit v1.2.3 From fc66ae45fc7f935eef23af27347761ba4050ad6e Mon Sep 17 00:00:00 2001 From: James Dennett Date: Thu, 10 May 2018 22:36:50 -0700 Subject: Update generated code. --- googletest/include/gtest/internal/gtest-type-util.h | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/googletest/include/gtest/internal/gtest-type-util.h b/googletest/include/gtest/internal/gtest-type-util.h index e46f7cfc..d0d83f53 100644 --- a/googletest/include/gtest/internal/gtest-type-util.h +++ b/googletest/include/gtest/internal/gtest-type-util.h @@ -56,6 +56,22 @@ namespace testing { namespace internal { + +// Canonicalizes a given name with respect to the Standard C++ Library. +// This handles removing the inline namespace within `std` that is +// used by various standard libraries (e.g., `std::__1`). Names outside +// of namespace std are returned unmodified. +inline std::string CanonicalizeForStdLibVersioning(std::string s) { + static constexpr char prefix[] = "std::__"; + if (s.compare(0, strlen(prefix), prefix) == 0) { + auto end = s.find("::", strlen(prefix)); + if (end != s.npos) { + // Erase the `::__` plus whatever was between that and the next `::`. + s.erase(strlen("std"), strlen("::__") + end - strlen(prefix)); + } + } + return s; +} // GetTypeName() returns a human-readable name of type T. // NB: This function is also used in Google Mock, so don't move it inside of @@ -73,9 +89,9 @@ std::string GetTypeName() { using abi::__cxa_demangle; # endif // GTEST_HAS_CXXABI_H_ char* const readable_name = __cxa_demangle(name, 0, 0, &status); - const std::string name_str(status == 0 ? readable_name : name); + std::string name_str(status == 0 ? readable_name : name); free(readable_name); - return name_str; + return CanonicalizeForStdLibVersioning(std::move(name_str)); # else return name; # endif // GTEST_HAS_CXXABI_H_ || __HP_aCC -- cgit v1.2.3 From 54e331b88bca8e9ab9de55153a3e6d295299aad0 Mon Sep 17 00:00:00 2001 From: James Dennett Date: Thu, 10 May 2018 22:39:19 -0700 Subject: Add support for versioned standard libraries. This canonicalizes demangled names by omitting a nested inline namespace within namespace std if the name of the nested namespace begins with a double underscore. This improves compatibility with libc++. --- .../include/gtest/internal/gtest-type-util.h.pump | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/googletest/include/gtest/internal/gtest-type-util.h.pump b/googletest/include/gtest/internal/gtest-type-util.h.pump index 251fdf02..61228623 100644 --- a/googletest/include/gtest/internal/gtest-type-util.h.pump +++ b/googletest/include/gtest/internal/gtest-type-util.h.pump @@ -54,6 +54,22 @@ $var n = 50 $$ Maximum length of type lists we want to support. namespace testing { namespace internal { + +// Canonicalizes a given name with respect to the Standard C++ Library. +// This handles removing the inline namespace within `std` that is +// used by various standard libraries (e.g., `std::__1`). Names outside +// of namespace std are returned unmodified. +inline std::string CanonicalizeForStdLibVersioning(std::string s) { + static constexpr char prefix[] = "std::__"; + if (s.compare(0, strlen(prefix), prefix) == 0) { + auto end = s.find("::", strlen(prefix)); + if (end != s.npos) { + // Erase the `::__` plus whatever was between that and the next `::`. + s.erase(strlen("std"), strlen("::__") + end - strlen(prefix)); + } + } + return s; +} // GetTypeName() returns a human-readable name of type T. // NB: This function is also used in Google Mock, so don't move it inside of @@ -71,9 +87,9 @@ std::string GetTypeName() { using abi::__cxa_demangle; # endif // GTEST_HAS_CXXABI_H_ char* const readable_name = __cxa_demangle(name, 0, 0, &status); - const std::string name_str(status == 0 ? readable_name : name); + std::string name_str(status == 0 ? readable_name : name); free(readable_name); - return name_str; + return CanonicalizeForStdLibVersioning(std::move(name_str)); # else return name; # endif // GTEST_HAS_CXXABI_H_ || __HP_aCC -- cgit v1.2.3 From ec2c911b3370f6536b90bf8de7be742ac191c25f Mon Sep 17 00:00:00 2001 From: James Dennett Date: Mon, 21 May 2018 10:59:24 -0700 Subject: Downgrade to C++98 code. Some users are not ready for C++11 yet. --- googletest/include/gtest/internal/gtest-type-util.h | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/googletest/include/gtest/internal/gtest-type-util.h b/googletest/include/gtest/internal/gtest-type-util.h index d0d83f53..d7781312 100644 --- a/googletest/include/gtest/internal/gtest-type-util.h +++ b/googletest/include/gtest/internal/gtest-type-util.h @@ -62,12 +62,12 @@ namespace internal { // used by various standard libraries (e.g., `std::__1`). Names outside // of namespace std are returned unmodified. inline std::string CanonicalizeForStdLibVersioning(std::string s) { - static constexpr char prefix[] = "std::__"; + static const char prefix[] = "std::__"; if (s.compare(0, strlen(prefix), prefix) == 0) { - auto end = s.find("::", strlen(prefix)); + std::string::size_type end = s.find("::", strlen(prefix)); if (end != s.npos) { - // Erase the `::__` plus whatever was between that and the next `::`. - s.erase(strlen("std"), strlen("::__") + end - strlen(prefix)); + // Erase everything between the initial `std` and the second `::`. + s.erase(strlen("std"), end - strlen("std")); } } return s; @@ -89,9 +89,9 @@ std::string GetTypeName() { using abi::__cxa_demangle; # endif // GTEST_HAS_CXXABI_H_ char* const readable_name = __cxa_demangle(name, 0, 0, &status); - std::string name_str(status == 0 ? readable_name : name); + const std::string name_str(status == 0 ? readable_name : name); free(readable_name); - return CanonicalizeForStdLibVersioning(std::move(name_str)); + return CanonicalizeForStdLibVersioning(name_str); # else return name; # endif // GTEST_HAS_CXXABI_H_ || __HP_aCC -- cgit v1.2.3 From 49ecebd1f25cdfb97462e81ada8662990e3d211d Mon Sep 17 00:00:00 2001 From: James Dennett Date: Mon, 21 May 2018 12:27:52 -0700 Subject: Downgrade to C++98. Some projects cannot handle C++11 yet. --- googletest/include/gtest/internal/gtest-type-util.h.pump | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/googletest/include/gtest/internal/gtest-type-util.h.pump b/googletest/include/gtest/internal/gtest-type-util.h.pump index 61228623..eb4df2c3 100644 --- a/googletest/include/gtest/internal/gtest-type-util.h.pump +++ b/googletest/include/gtest/internal/gtest-type-util.h.pump @@ -60,12 +60,12 @@ namespace internal { // used by various standard libraries (e.g., `std::__1`). Names outside // of namespace std are returned unmodified. inline std::string CanonicalizeForStdLibVersioning(std::string s) { - static constexpr char prefix[] = "std::__"; + static const char prefix[] = "std::__"; if (s.compare(0, strlen(prefix), prefix) == 0) { - auto end = s.find("::", strlen(prefix)); + std::string::size_type end = s.find("::", strlen(prefix)); if (end != s.npos) { - // Erase the `::__` plus whatever was between that and the next `::`. - s.erase(strlen("std"), strlen("::__") + end - strlen(prefix)); + // Erase everything between the initial `std` and the second `::`. + s.erase(strlen("std"), end - strlen("std")); } } return s; @@ -87,9 +87,9 @@ std::string GetTypeName() { using abi::__cxa_demangle; # endif // GTEST_HAS_CXXABI_H_ char* const readable_name = __cxa_demangle(name, 0, 0, &status); - std::string name_str(status == 0 ? readable_name : name); + const std::string name_str(status == 0 ? readable_name : name); free(readable_name); - return CanonicalizeForStdLibVersioning(std::move(name_str)); + return CanonicalizeForStdLibVersioning(name_str); # else return name; # endif // GTEST_HAS_CXXABI_H_ || __HP_aCC -- cgit v1.2.3