From 86d2eeb1120a330cec8396aee97914dae909e237 Mon Sep 17 00:00:00 2001 From: "zhanyong.wan" Date: Wed, 16 Mar 2011 17:10:39 +0000 Subject: [PATCH] Prevents ADL in AllOf() and AnyOf() (by Manuel Klimek). --- include/gmock/gmock-generated-matchers.h | 39 ++++++++++--------- include/gmock/gmock-generated-matchers.h.pump | 8 ++-- test/gmock-generated-matchers_test.cc | 29 ++++++++++++++ 3 files changed, 54 insertions(+), 22 deletions(-) diff --git a/include/gmock/gmock-generated-matchers.h b/include/gmock/gmock-generated-matchers.h index 68af306b..6feaf1a2 100644 --- a/include/gmock/gmock-generated-matchers.h +++ b/include/gmock/gmock-generated-matchers.h @@ -850,7 +850,7 @@ ElementsAreArray(const T (&array)[N]) { } // AllOf(m1, m2, ..., mk) matches any value that matches all of the given -// sub-matchers. +// sub-matchers. AllOf is called fully qualified to prevent ADL from firing. template inline internal::BothOfMatcher @@ -862,7 +862,7 @@ template inline internal::BothOfMatcher > AllOf(Matcher1 m1, Matcher2 m2, Matcher3 m3) { - return AllOf(m1, AllOf(m2, m3)); + return ::testing::AllOf(m1, ::testing::AllOf(m2, m3)); } template > > AllOf(Matcher1 m1, Matcher2 m2, Matcher3 m3, Matcher4 m4) { - return AllOf(m1, AllOf(m2, m3, m4)); + return ::testing::AllOf(m1, ::testing::AllOf(m2, m3, m4)); } template > > > AllOf(Matcher1 m1, Matcher2 m2, Matcher3 m3, Matcher4 m4, Matcher5 m5) { - return AllOf(m1, AllOf(m2, m3, m4, m5)); + return ::testing::AllOf(m1, ::testing::AllOf(m2, m3, m4, m5)); } template > > > > AllOf(Matcher1 m1, Matcher2 m2, Matcher3 m3, Matcher4 m4, Matcher5 m5, Matcher6 m6) { - return AllOf(m1, AllOf(m2, m3, m4, m5, m6)); + return ::testing::AllOf(m1, ::testing::AllOf(m2, m3, m4, m5, m6)); } template > > > > > AllOf(Matcher1 m1, Matcher2 m2, Matcher3 m3, Matcher4 m4, Matcher5 m5, Matcher6 m6, Matcher7 m7) { - return AllOf(m1, AllOf(m2, m3, m4, m5, m6, m7)); + return ::testing::AllOf(m1, ::testing::AllOf(m2, m3, m4, m5, m6, m7)); } template > > > > > > AllOf(Matcher1 m1, Matcher2 m2, Matcher3 m3, Matcher4 m4, Matcher5 m5, Matcher6 m6, Matcher7 m7, Matcher8 m8) { - return AllOf(m1, AllOf(m2, m3, m4, m5, m6, m7, m8)); + return ::testing::AllOf(m1, ::testing::AllOf(m2, m3, m4, m5, m6, m7, m8)); } template > > > > > > > AllOf(Matcher1 m1, Matcher2 m2, Matcher3 m3, Matcher4 m4, Matcher5 m5, Matcher6 m6, Matcher7 m7, Matcher8 m8, Matcher9 m9) { - return AllOf(m1, AllOf(m2, m3, m4, m5, m6, m7, m8, m9)); + return ::testing::AllOf(m1, ::testing::AllOf(m2, m3, m4, m5, m6, m7, m8, m9)); } template > > > > > > > > AllOf(Matcher1 m1, Matcher2 m2, Matcher3 m3, Matcher4 m4, Matcher5 m5, Matcher6 m6, Matcher7 m7, Matcher8 m8, Matcher9 m9, Matcher10 m10) { - return AllOf(m1, AllOf(m2, m3, m4, m5, m6, m7, m8, m9, m10)); + return ::testing::AllOf(m1, ::testing::AllOf(m2, m3, m4, m5, m6, m7, m8, m9, + m10)); } // AnyOf(m1, m2, ..., mk) matches any value that matches any of the given -// sub-matchers. +// sub-matchers. AnyOf is called fully qualified to prevent ADL from firing. template inline internal::EitherOfMatcher @@ -954,7 +955,7 @@ template inline internal::EitherOfMatcher > AnyOf(Matcher1 m1, Matcher2 m2, Matcher3 m3) { - return AnyOf(m1, AnyOf(m2, m3)); + return ::testing::AnyOf(m1, ::testing::AnyOf(m2, m3)); } template > > AnyOf(Matcher1 m1, Matcher2 m2, Matcher3 m3, Matcher4 m4) { - return AnyOf(m1, AnyOf(m2, m3, m4)); + return ::testing::AnyOf(m1, ::testing::AnyOf(m2, m3, m4)); } template > > > AnyOf(Matcher1 m1, Matcher2 m2, Matcher3 m3, Matcher4 m4, Matcher5 m5) { - return AnyOf(m1, AnyOf(m2, m3, m4, m5)); + return ::testing::AnyOf(m1, ::testing::AnyOf(m2, m3, m4, m5)); } template > > > > AnyOf(Matcher1 m1, Matcher2 m2, Matcher3 m3, Matcher4 m4, Matcher5 m5, Matcher6 m6) { - return AnyOf(m1, AnyOf(m2, m3, m4, m5, m6)); + return ::testing::AnyOf(m1, ::testing::AnyOf(m2, m3, m4, m5, m6)); } template > > > > > AnyOf(Matcher1 m1, Matcher2 m2, Matcher3 m3, Matcher4 m4, Matcher5 m5, Matcher6 m6, Matcher7 m7) { - return AnyOf(m1, AnyOf(m2, m3, m4, m5, m6, m7)); + return ::testing::AnyOf(m1, ::testing::AnyOf(m2, m3, m4, m5, m6, m7)); } template > > > > > > AnyOf(Matcher1 m1, Matcher2 m2, Matcher3 m3, Matcher4 m4, Matcher5 m5, Matcher6 m6, Matcher7 m7, Matcher8 m8) { - return AnyOf(m1, AnyOf(m2, m3, m4, m5, m6, m7, m8)); + return ::testing::AnyOf(m1, ::testing::AnyOf(m2, m3, m4, m5, m6, m7, m8)); } template > > > > > > > AnyOf(Matcher1 m1, Matcher2 m2, Matcher3 m3, Matcher4 m4, Matcher5 m5, Matcher6 m6, Matcher7 m7, Matcher8 m8, Matcher9 m9) { - return AnyOf(m1, AnyOf(m2, m3, m4, m5, m6, m7, m8, m9)); + return ::testing::AnyOf(m1, ::testing::AnyOf(m2, m3, m4, m5, m6, m7, m8, m9)); } template > > > > > > > > AnyOf(Matcher1 m1, Matcher2 m2, Matcher3 m3, Matcher4 m4, Matcher5 m5, Matcher6 m6, Matcher7 m7, Matcher8 m8, Matcher9 m9, Matcher10 m10) { - return AnyOf(m1, AnyOf(m2, m3, m4, m5, m6, m7, m8, m9, m10)); + return ::testing::AnyOf(m1, ::testing::AnyOf(m2, m3, m4, m5, m6, m7, m8, m9, + m10)); } } // namespace testing + // The MATCHER* family of macros can be used in a namespace scope to // define custom matchers easily. // diff --git a/include/gmock/gmock-generated-matchers.h.pump b/include/gmock/gmock-generated-matchers.h.pump index cebdd0e6..8c09444c 100644 --- a/include/gmock/gmock-generated-matchers.h.pump +++ b/include/gmock/gmock-generated-matchers.h.pump @@ -303,7 +303,7 @@ ElementsAreArray(const T (&array)[N]) { } // AllOf(m1, m2, ..., mk) matches any value that matches all of the given -// sub-matchers. +// sub-matchers. AllOf is called fully qualified to prevent ADL from firing. $range i 2..n $for i [[ @@ -318,7 +318,7 @@ AllOf($for j, [[Matcher$j m$j]]) { $if i == 2 [[ return internal::BothOfMatcher(m1, m2); ]] $else [[ - return AllOf(m1, AllOf($for k, [[m$(k + 1)]])); + return ::testing::AllOf(m1, ::testing::AllOf($for k, [[m$(k + 1)]])); ]] } @@ -326,7 +326,7 @@ $if i == 2 [[ ]] // AnyOf(m1, m2, ..., mk) matches any value that matches any of the given -// sub-matchers. +// sub-matchers. AnyOf is called fully qualified to prevent ADL from firing. $range i 2..n $for i [[ @@ -341,7 +341,7 @@ AnyOf($for j, [[Matcher$j m$j]]) { $if i == 2 [[ return internal::EitherOfMatcher(m1, m2); ]] $else [[ - return AnyOf(m1, AnyOf($for k, [[m$(k + 1)]])); + return ::testing::AnyOf(m1, ::testing::AnyOf($for k, [[m$(k + 1)]])); ]] } diff --git a/test/gmock-generated-matchers_test.cc b/test/gmock-generated-matchers_test.cc index 5e18471d..819f1a83 100644 --- a/test/gmock-generated-matchers_test.cc +++ b/test/gmock-generated-matchers_test.cc @@ -1091,6 +1091,35 @@ TEST(ContainsTest, WorksForTwoDimensionalNativeArray) { EXPECT_THAT(a, Contains(Not(Contains(5)))); } +namespace adl_test { + +// Verifies that the implementation of ::testing::AllOf and ::testing::AnyOf +// don't issue unqualified recursive calls. If they do, the argument dependent +// name lookup will cause AllOf/AnyOf in the 'adl_test' namespace to be found +// as a candidate and the compilation will break due to an ambiguous overload. + +// The matcher must be in the same namespace as AllOf/AnyOf to make argument +// dependent lookup find those. +MATCHER(M, "") { return true; } + +template +bool AllOf(const T1& t1, const T2& t2) { return true; } + +TEST(AllOfTest, DoesNotCallAllOfUnqualified) { + EXPECT_THAT(42, testing::AllOf( + M(), M(), M(), M(), M(), M(), M(), M(), M(), M())); +} + +template bool +AnyOf(const T1& t1, const T2& t2) { return true; } + +TEST(AnyOfTest, DoesNotCallAnyOfUnqualified) { + EXPECT_THAT(42, testing::AnyOf( + M(), M(), M(), M(), M(), M(), M(), M(), M(), M())); +} + +} // namespace adl_test + #ifdef _MSC_VER # pragma warning(pop) #endif