diff --git a/include/gmock/gmock-matchers.h b/include/gmock/gmock-matchers.h index 44055c93..979b0e85 100644 --- a/include/gmock/gmock-matchers.h +++ b/include/gmock/gmock-matchers.h @@ -489,7 +489,7 @@ namespace internal { template class MatcherCastImpl { public: - static Matcher Cast(M polymorphic_matcher_or_value) { + static Matcher Cast(const M& polymorphic_matcher_or_value) { // M can be a polymorhic matcher, in which case we want to use // its conversion operator to create Matcher. Or it can be a value // that should be passed to the Matcher's constructor. @@ -510,14 +510,14 @@ class MatcherCastImpl { } private: - static Matcher CastImpl(M value, BooleanConstant) { + static Matcher CastImpl(const M& value, BooleanConstant) { // M can't be implicitly converted to Matcher, so M isn't a polymorphic // matcher. It must be a value then. Use direct initialization to create // a matcher. return Matcher(ImplicitCast_(value)); } - static Matcher CastImpl(M polymorphic_matcher_or_value, + static Matcher CastImpl(const M& polymorphic_matcher_or_value, BooleanConstant) { // M is implicitly convertible to Matcher, which means that either // M is a polymorhpic matcher or Matcher has an implicit constructor @@ -582,7 +582,7 @@ class MatcherCastImpl > { // matcher m and returns a Matcher. It compiles only when T can be // statically converted to the argument type of m. template -inline Matcher MatcherCast(M matcher) { +inline Matcher MatcherCast(const M& matcher) { return internal::MatcherCastImpl::Cast(matcher); } @@ -599,7 +599,7 @@ class SafeMatcherCastImpl { // This overload handles polymorphic matchers and values only since // monomorphic matchers are handled by the next one. template - static inline Matcher Cast(M polymorphic_matcher_or_value) { + static inline Matcher Cast(const M& polymorphic_matcher_or_value) { return internal::MatcherCastImpl::Cast(polymorphic_matcher_or_value); } diff --git a/test/gmock-matchers_test.cc b/test/gmock-matchers_test.cc index 4ce1e4a5..5de45c78 100644 --- a/test/gmock-matchers_test.cc +++ b/test/gmock-matchers_test.cc @@ -636,6 +636,22 @@ TEST(MatcherCastTest, FromConvertibleFromAny) { EXPECT_FALSE(m.Matches(ConvertibleFromAny(2))); } +struct IntReferenceWrapper { + IntReferenceWrapper(const int& a_value) : value(&a_value) {} + const int* value; +}; + +bool operator==(const IntReferenceWrapper& a, const IntReferenceWrapper& b) { + return a.value == b.value; +} + +TEST(MatcherCastTest, ValueIsNotCopied) { + int n = 42; + Matcher m = MatcherCast(n); + // Verify that the matcher holds a reference to n, not to its temporary copy. + EXPECT_TRUE(m.Matches(n)); +} + class Base {}; class Derived : public Base {}; @@ -724,6 +740,13 @@ TEST(SafeMatcherCastTest, FromConvertibleFromAny) { EXPECT_FALSE(m.Matches(ConvertibleFromAny(2))); } +TEST(SafeMatcherCastTest, ValueIsNotCopied) { + int n = 42; + Matcher m = SafeMatcherCast(n); + // Verify that the matcher holds a reference to n, not to its temporary copy. + EXPECT_TRUE(m.Matches(n)); +} + // Tests that A() matches any value of type T. TEST(ATest, MatchesAnyValue) { // Tests a matcher for a value type.