From b93d0f10d5a1bab088223a57420ef599b26a5e0f Mon Sep 17 00:00:00 2001 From: kosak Date: Mon, 13 Jan 2014 22:28:01 +0000 Subject: Make Google Mock build cleanly on Visual Studio 2010, 2012, 2013. --- CMakeLists.txt | 25 ++++++++++++++++++++----- include/gmock/gmock-more-actions.h | 24 +++++++++++++++++------- test/gmock-generated-function-mockers_test.cc | 11 +++++++++++ test/gmock-more-actions_test.cc | 22 +++++++++++----------- 4 files changed, 59 insertions(+), 23 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 572d0444..4cc66372 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -63,6 +63,16 @@ include_directories("${gmock_SOURCE_DIR}/include" # Test sources. "${gtest_SOURCE_DIR}") +# Summary of tuple support for Microsoft Visual Studio: +# Compiler version(MS) version(cmake) Support +# ---------- ----------- -------------- ----------------------------- +# <= VS 2010 <= 10 <= 1600 Use Google Tests's own tuple. +# VS 2012 11 1700 std::tr1::tuple + _VARIADIC_MAX=10 +# VS 2013 12 1800 std::tr1::tuple +if (MSVC AND MSVC_VERSION EQUAL 1700) + add_definitions(/D _VARIADIC_MAX=10) +endif() + ######################################################################## # # Defines the gmock & gmock_main libraries. User tests should link @@ -134,8 +144,16 @@ if (gmock_build_tests) cxx_library(gmock_main_no_rtti "${cxx_no_rtti}" "${gtest_dir}/src/gtest-all.cc" src/gmock-all.cc src/gmock_main.cc) - cxx_library(gmock_main_use_own_tuple "${cxx_use_own_tuple}" - "${gtest_dir}/src/gtest-all.cc" src/gmock-all.cc src/gmock_main.cc) + if (NOT MSVC OR MSVC_VERSION LESS 1600) # 1600 is Visual Studio 2010. + # Visual Studio 2010, 2012, and 2013 define symbols in std::tr1 that + # conflict with our own definitions. Therefore using our own tuple does not + # work on those compilers. + cxx_library(gmock_main_use_own_tuple "${cxx_use_own_tuple}" + "${gtest_dir}/src/gtest-all.cc" src/gmock-all.cc src/gmock_main.cc) + + cxx_test_with_flags(gmock_use_own_tuple_test "${cxx_use_own_tuple}" + gmock_main_use_own_tuple test/gmock-spec-builders_test.cc) + endif() cxx_test_with_flags(gmock-more-actions_no_exception_test "${cxx_no_exception}" gmock_main_no_exception test/gmock-more-actions_test.cc) @@ -143,9 +161,6 @@ if (gmock_build_tests) cxx_test_with_flags(gmock_no_rtti_test "${cxx_no_rtti}" gmock_main_no_rtti test/gmock-spec-builders_test.cc) - cxx_test_with_flags(gmock_use_own_tuple_test "${cxx_use_own_tuple}" - gmock_main_use_own_tuple test/gmock-spec-builders_test.cc) - cxx_shared_library(shared_gmock_main "${cxx_default}" "${gtest_dir}/src/gtest-all.cc" src/gmock-all.cc src/gmock_main.cc) diff --git a/include/gmock/gmock-more-actions.h b/include/gmock/gmock-more-actions.h index fc5e5ca8..73b9deae 100644 --- a/include/gmock/gmock-more-actions.h +++ b/include/gmock/gmock-more-actions.h @@ -87,6 +87,20 @@ class InvokeMethodAction { GTEST_DISALLOW_ASSIGN_(InvokeMethodAction); }; +// An internal replacement for std::copy which mimics its behavior. This is +// necessary because Visual Studio deprecates ::std::copy, issuing warning 4996. +// However Visual Studio 2010 and later do not honor #pragmas which disable that +// warning. +template +inline OutputIterator CopyElements(InputIterator first, + InputIterator last, + OutputIterator output) { + for (; first != last; ++first, ++output) { + *output = *first; + } + return output; +} + } // namespace internal // Various overloads for Invoke(). @@ -185,15 +199,11 @@ ACTION_TEMPLATE(SetArgReferee, ACTION_TEMPLATE(SetArrayArgument, HAS_1_TEMPLATE_PARAMS(int, k), AND_2_VALUE_PARAMS(first, last)) { - // Microsoft compiler deprecates ::std::copy, so we want to suppress warning - // 4996 (Function call with parameters that may be unsafe) there. + // Visual Studio deprecates ::std::copy, so we use our own copy in that case. #ifdef _MSC_VER -# pragma warning(push) // Saves the current warning state. -# pragma warning(disable:4996) // Temporarily disables warning 4996. -#endif + internal::CopyElements(first, last, ::std::tr1::get(args)); +#else ::std::copy(first, last, ::std::tr1::get(args)); -#ifdef _MSC_VER -# pragma warning(pop) // Restores the warning state. #endif } diff --git a/test/gmock-generated-function-mockers_test.cc b/test/gmock-generated-function-mockers_test.cc index ea49b9c1..169ed5a2 100644 --- a/test/gmock-generated-function-mockers_test.cc +++ b/test/gmock-generated-function-mockers_test.cc @@ -112,6 +112,14 @@ class FooInterface { #endif // GTEST_OS_WINDOWS }; +// Const qualifiers on arguments were once (incorrectly) considered +// significant in determining whether two virtual functions had the same +// signature. This was fixed in Visual Studio 2008. However, the compiler +// still emits a warning that alerts about this change in behavior. +#ifdef _MSC_VER +# pragma warning(push) +# pragma warning(disable : 4373) +#endif class MockFoo : public FooInterface { public: MockFoo() {} @@ -167,6 +175,9 @@ class MockFoo : public FooInterface { private: GTEST_DISALLOW_COPY_AND_ASSIGN_(MockFoo); }; +#ifdef _MSC_VER +# pragma warning(pop) +#endif class FunctionMockerTest : public testing::Test { protected: diff --git a/test/gmock-more-actions_test.cc b/test/gmock-more-actions_test.cc index 9dde5ebb..eb516d22 100644 --- a/test/gmock-more-actions_test.cc +++ b/test/gmock-more-actions_test.cc @@ -668,17 +668,17 @@ TEST(SetArrayArgumentTest, SetsTheNthArrayWithEmptyRange) { // Tests SetArrayArgument(first, last) where *first is convertible // (but not equal) to the argument type. TEST(SetArrayArgumentTest, SetsTheNthArrayWithConvertibleType) { - typedef void MyFunction(bool, char*); - int codes[] = { 97, 98, 99 }; - Action a = SetArrayArgument<1>(codes, codes + 3); - - char ch[4] = {}; - char* pch = ch; - a.Perform(make_tuple(true, pch)); - EXPECT_EQ('a', ch[0]); - EXPECT_EQ('b', ch[1]); - EXPECT_EQ('c', ch[2]); - EXPECT_EQ('\0', ch[3]); + typedef void MyFunction(bool, int*); + char chars[] = { 97, 98, 99 }; + Action a = SetArrayArgument<1>(chars, chars + 3); + + int codes[4] = { 111, 222, 333, 444 }; + int* pcodes = codes; + a.Perform(make_tuple(true, pcodes)); + EXPECT_EQ(97, codes[0]); + EXPECT_EQ(98, codes[1]); + EXPECT_EQ(99, codes[2]); + EXPECT_EQ(444, codes[3]); } // Test SetArrayArgument(first, last) with iterator as argument. -- cgit v1.2.3