diff options
-rw-r--r-- | googlemock/include/gmock/gmock-actions.h | 6 | ||||
-rw-r--r-- | googlemock/include/gmock/gmock-matchers.h | 56 | ||||
-rw-r--r-- | googlemock/include/gmock/internal/gmock-internal-utils.h | 14 | ||||
-rw-r--r-- | googlemock/src/gmock-internal-utils.cc | 5 | ||||
-rw-r--r-- | googletest/include/gtest/gtest-assertion-result.h | 2 | ||||
-rw-r--r-- | googletest/include/gtest/internal/gtest-internal.h | 54 | ||||
-rw-r--r-- | googletest/include/gtest/internal/gtest-param-util.h | 8 | ||||
-rw-r--r-- | googletest/include/gtest/internal/gtest-port-arch.h | 2 | ||||
-rw-r--r-- | googletest/include/gtest/internal/gtest-port.h | 13 | ||||
-rw-r--r-- | googletest/src/gtest-port.cc | 53 | ||||
-rw-r--r-- | googletest/src/gtest.cc | 20 | ||||
-rw-r--r-- | googletest/test/googletest-json-output-unittest.py | 9 | ||||
-rw-r--r-- | googletest/test/gtest_unittest.cc | 16 |
13 files changed, 114 insertions, 144 deletions
diff --git a/googlemock/include/gmock/gmock-actions.h b/googlemock/include/gmock/gmock-actions.h index fab99933..7e17b305 100644 --- a/googlemock/include/gmock/gmock-actions.h +++ b/googlemock/include/gmock/gmock-actions.h @@ -2135,13 +2135,13 @@ struct ActionImpl<R(Args...), Impl> : ImplBase<Impl>::type { R operator()(Args&&... arg) const { static constexpr size_t kMaxArgs = sizeof...(Args) <= 10 ? sizeof...(Args) : 10; - return Apply(MakeIndexSequence<kMaxArgs>{}, - MakeIndexSequence<10 - kMaxArgs>{}, + return Apply(std::make_index_sequence<kMaxArgs>{}, + std::make_index_sequence<10 - kMaxArgs>{}, args_type{std::forward<Args>(arg)...}); } template <std::size_t... arg_id, std::size_t... excess_id> - R Apply(IndexSequence<arg_id...>, IndexSequence<excess_id...>, + R Apply(std::index_sequence<arg_id...>, std::index_sequence<excess_id...>, const args_type& args) const { // Impl need not be specific to the signature of action being implemented; // only the implementing function body needs to have all of the specific diff --git a/googlemock/include/gmock/gmock-matchers.h b/googlemock/include/gmock/gmock-matchers.h index c4149f2e..6b6b4371 100644 --- a/googlemock/include/gmock/gmock-matchers.h +++ b/googlemock/include/gmock/gmock-matchers.h @@ -490,12 +490,12 @@ class MatcherBaseImpl<Derived<Ts...>> { template <typename F> operator ::testing::Matcher<F>() const { // NOLINT(runtime/explicit) - return Apply<F>(MakeIndexSequence<sizeof...(Ts)>{}); + return Apply<F>(std::make_index_sequence<sizeof...(Ts)>{}); } private: template <typename F, std::size_t... tuple_ids> - ::testing::Matcher<F> Apply(IndexSequence<tuple_ids...>) const { + ::testing::Matcher<F> Apply(std::index_sequence<tuple_ids...>) const { return ::testing::Matcher<F>( new typename Derived<Ts...>::template gmock_Impl<F>( std::get<tuple_ids>(params_)...)); @@ -3152,8 +3152,8 @@ class PairMatcher { }; template <typename T, size_t... I> -auto UnpackStructImpl(const T& t, IndexSequence<I...>, int) - -> decltype(std::tie(get<I>(t)...)) { +auto UnpackStructImpl(const T& t, std::index_sequence<I...>, + int) -> decltype(std::tie(get<I>(t)...)) { static_assert(std::tuple_size<T>::value == sizeof...(I), "Number of arguments doesn't match the number of fields."); return std::tie(get<I>(t)...); @@ -3161,97 +3161,97 @@ auto UnpackStructImpl(const T& t, IndexSequence<I...>, int) #if defined(__cpp_structured_bindings) && __cpp_structured_bindings >= 201606 template <typename T> -auto UnpackStructImpl(const T& t, MakeIndexSequence<1>, char) { +auto UnpackStructImpl(const T& t, std::make_index_sequence<1>, char) { const auto& [a] = t; return std::tie(a); } template <typename T> -auto UnpackStructImpl(const T& t, MakeIndexSequence<2>, char) { +auto UnpackStructImpl(const T& t, std::make_index_sequence<2>, char) { const auto& [a, b] = t; return std::tie(a, b); } template <typename T> -auto UnpackStructImpl(const T& t, MakeIndexSequence<3>, char) { +auto UnpackStructImpl(const T& t, std::make_index_sequence<3>, char) { const auto& [a, b, c] = t; return std::tie(a, b, c); } template <typename T> -auto UnpackStructImpl(const T& t, MakeIndexSequence<4>, char) { +auto UnpackStructImpl(const T& t, std::make_index_sequence<4>, char) { const auto& [a, b, c, d] = t; return std::tie(a, b, c, d); } template <typename T> -auto UnpackStructImpl(const T& t, MakeIndexSequence<5>, char) { +auto UnpackStructImpl(const T& t, std::make_index_sequence<5>, char) { const auto& [a, b, c, d, e] = t; return std::tie(a, b, c, d, e); } template <typename T> -auto UnpackStructImpl(const T& t, MakeIndexSequence<6>, char) { +auto UnpackStructImpl(const T& t, std::make_index_sequence<6>, char) { const auto& [a, b, c, d, e, f] = t; return std::tie(a, b, c, d, e, f); } template <typename T> -auto UnpackStructImpl(const T& t, MakeIndexSequence<7>, char) { +auto UnpackStructImpl(const T& t, std::make_index_sequence<7>, char) { const auto& [a, b, c, d, e, f, g] = t; return std::tie(a, b, c, d, e, f, g); } template <typename T> -auto UnpackStructImpl(const T& t, MakeIndexSequence<8>, char) { +auto UnpackStructImpl(const T& t, std::make_index_sequence<8>, char) { const auto& [a, b, c, d, e, f, g, h] = t; return std::tie(a, b, c, d, e, f, g, h); } template <typename T> -auto UnpackStructImpl(const T& t, MakeIndexSequence<9>, char) { +auto UnpackStructImpl(const T& t, std::make_index_sequence<9>, char) { const auto& [a, b, c, d, e, f, g, h, i] = t; return std::tie(a, b, c, d, e, f, g, h, i); } template <typename T> -auto UnpackStructImpl(const T& t, MakeIndexSequence<10>, char) { +auto UnpackStructImpl(const T& t, std::make_index_sequence<10>, char) { const auto& [a, b, c, d, e, f, g, h, i, j] = t; return std::tie(a, b, c, d, e, f, g, h, i, j); } template <typename T> -auto UnpackStructImpl(const T& t, MakeIndexSequence<11>, char) { +auto UnpackStructImpl(const T& t, std::make_index_sequence<11>, char) { const auto& [a, b, c, d, e, f, g, h, i, j, k] = t; return std::tie(a, b, c, d, e, f, g, h, i, j, k); } template <typename T> -auto UnpackStructImpl(const T& t, MakeIndexSequence<12>, char) { +auto UnpackStructImpl(const T& t, std::make_index_sequence<12>, char) { const auto& [a, b, c, d, e, f, g, h, i, j, k, l] = t; return std::tie(a, b, c, d, e, f, g, h, i, j, k, l); } template <typename T> -auto UnpackStructImpl(const T& t, MakeIndexSequence<13>, char) { +auto UnpackStructImpl(const T& t, std::make_index_sequence<13>, char) { const auto& [a, b, c, d, e, f, g, h, i, j, k, l, m] = t; return std::tie(a, b, c, d, e, f, g, h, i, j, k, l, m); } template <typename T> -auto UnpackStructImpl(const T& t, MakeIndexSequence<14>, char) { +auto UnpackStructImpl(const T& t, std::make_index_sequence<14>, char) { const auto& [a, b, c, d, e, f, g, h, i, j, k, l, m, n] = t; return std::tie(a, b, c, d, e, f, g, h, i, j, k, l, m, n); } template <typename T> -auto UnpackStructImpl(const T& t, MakeIndexSequence<15>, char) { +auto UnpackStructImpl(const T& t, std::make_index_sequence<15>, char) { const auto& [a, b, c, d, e, f, g, h, i, j, k, l, m, n, o] = t; return std::tie(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o); } template <typename T> -auto UnpackStructImpl(const T& t, MakeIndexSequence<16>, char) { +auto UnpackStructImpl(const T& t, std::make_index_sequence<16>, char) { const auto& [a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p] = t; return std::tie(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p); } template <typename T> -auto UnpackStructImpl(const T& t, MakeIndexSequence<17>, char) { +auto UnpackStructImpl(const T& t, std::make_index_sequence<17>, char) { const auto& [a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q] = t; return std::tie(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q); } template <typename T> -auto UnpackStructImpl(const T& t, MakeIndexSequence<18>, char) { +auto UnpackStructImpl(const T& t, std::make_index_sequence<18>, char) { const auto& [a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r] = t; return std::tie(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r); } template <typename T> -auto UnpackStructImpl(const T& t, MakeIndexSequence<19>, char) { +auto UnpackStructImpl(const T& t, std::make_index_sequence<19>, char) { const auto& [a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s] = t; return std::tie(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s); } @@ -3259,8 +3259,8 @@ auto UnpackStructImpl(const T& t, MakeIndexSequence<19>, char) { template <size_t I, typename T> auto UnpackStruct(const T& t) - -> decltype((UnpackStructImpl)(t, MakeIndexSequence<I>{}, 0)) { - return (UnpackStructImpl)(t, MakeIndexSequence<I>{}, 0); + -> decltype((UnpackStructImpl)(t, std::make_index_sequence<I>{}, 0)) { + return (UnpackStructImpl)(t, std::make_index_sequence<I>{}, 0); } // Helper function to do comma folding in C++11. @@ -3273,7 +3273,7 @@ template <typename Struct, typename StructSize> class FieldsAreMatcherImpl; template <typename Struct, size_t... I> -class FieldsAreMatcherImpl<Struct, IndexSequence<I...>> +class FieldsAreMatcherImpl<Struct, std::index_sequence<I...>> : public MatcherInterface<Struct> { using UnpackedType = decltype(UnpackStruct<sizeof...(I)>(std::declval<const Struct&>())); @@ -3355,8 +3355,8 @@ class FieldsAreMatcher { template <typename Struct> operator Matcher<Struct>() const { // NOLINT return Matcher<Struct>( - new FieldsAreMatcherImpl<const Struct&, IndexSequenceFor<Inner...>>( - matchers_)); + new FieldsAreMatcherImpl<const Struct&, + std::index_sequence_for<Inner...>>(matchers_)); } private: diff --git a/googlemock/include/gmock/internal/gmock-internal-utils.h b/googlemock/include/gmock/internal/gmock-internal-utils.h index ead6d7c8..b7685f57 100644 --- a/googlemock/include/gmock/internal/gmock-internal-utils.h +++ b/googlemock/include/gmock/internal/gmock-internal-utils.h @@ -44,6 +44,7 @@ #include <ostream> // NOLINT #include <string> #include <type_traits> +#include <utility> #include <vector> #include "gmock/internal/gmock-port.h" @@ -420,7 +421,7 @@ struct RemoveConstFromKey<std::pair<const K, V> > { GTEST_API_ void IllegalDoDefault(const char* file, int line); template <typename F, typename Tuple, size_t... Idx> -auto ApplyImpl(F&& f, Tuple&& args, IndexSequence<Idx...>) +auto ApplyImpl(F&& f, Tuple&& args, std::index_sequence<Idx...>) -> decltype(std::forward<F>(f)( std::get<Idx>(std::forward<Tuple>(args))...)) { return std::forward<F>(f)(std::get<Idx>(std::forward<Tuple>(args))...); @@ -428,12 +429,13 @@ auto ApplyImpl(F&& f, Tuple&& args, IndexSequence<Idx...>) // Apply the function to a tuple of arguments. template <typename F, typename Tuple> -auto Apply(F&& f, Tuple&& args) -> decltype(ApplyImpl( - std::forward<F>(f), std::forward<Tuple>(args), - MakeIndexSequence<std::tuple_size< - typename std::remove_reference<Tuple>::type>::value>())) { +auto Apply(F&& f, Tuple&& args) + -> decltype(ApplyImpl( + std::forward<F>(f), std::forward<Tuple>(args), + std::make_index_sequence<std::tuple_size< + typename std::remove_reference<Tuple>::type>::value>())) { return ApplyImpl(std::forward<F>(f), std::forward<Tuple>(args), - MakeIndexSequence<std::tuple_size< + std::make_index_sequence<std::tuple_size< typename std::remove_reference<Tuple>::type>::value>()); } diff --git a/googlemock/src/gmock-internal-utils.cc b/googlemock/src/gmock-internal-utils.cc index 5c2ce0d5..96c7e306 100644 --- a/googlemock/src/gmock-internal-utils.cc +++ b/googlemock/src/gmock-internal-utils.cc @@ -44,6 +44,7 @@ #include <iostream> #include <ostream> // NOLINT #include <string> +#include <utility> #include <vector> #include "gmock/gmock.h" @@ -211,14 +212,14 @@ constexpr char UnBase64Impl(char c, const char* const base64, char carry) { } template <size_t... I> -constexpr std::array<char, 256> UnBase64Impl(IndexSequence<I...>, +constexpr std::array<char, 256> UnBase64Impl(std::index_sequence<I...>, const char* const base64) { return { {UnBase64Impl(UndoWebSafeEncoding(static_cast<char>(I)), base64, 0)...}}; } constexpr std::array<char, 256> UnBase64(const char* const base64) { - return UnBase64Impl(MakeIndexSequence<256>{}, base64); + return UnBase64Impl(std::make_index_sequence<256>{}, base64); } static constexpr char kBase64[] = diff --git a/googletest/include/gtest/gtest-assertion-result.h b/googletest/include/gtest/gtest-assertion-result.h index 56fe128f..74eb2b1f 100644 --- a/googletest/include/gtest/gtest-assertion-result.h +++ b/googletest/include/gtest/gtest-assertion-result.h @@ -129,7 +129,7 @@ namespace testing { // // Expected: Foo() is even // Actual: it's 5 -// + class GTEST_API_ AssertionResult { public: // Copy constructor. diff --git a/googletest/include/gtest/internal/gtest-internal.h b/googletest/include/gtest/internal/gtest-internal.h index 4661248f..cffb8e11 100644 --- a/googletest/include/gtest/internal/gtest-internal.h +++ b/googletest/include/gtest/internal/gtest-internal.h @@ -1137,40 +1137,6 @@ class NativeArray { void (NativeArray::*clone_)(const Element*, size_t); }; -// Backport of std::index_sequence. -template <size_t... Is> -struct IndexSequence { - using type = IndexSequence; -}; - -// Double the IndexSequence, and one if plus_one is true. -template <bool plus_one, typename T, size_t sizeofT> -struct DoubleSequence; -template <size_t... I, size_t sizeofT> -struct DoubleSequence<true, IndexSequence<I...>, sizeofT> { - using type = IndexSequence<I..., (sizeofT + I)..., 2 * sizeofT>; -}; -template <size_t... I, size_t sizeofT> -struct DoubleSequence<false, IndexSequence<I...>, sizeofT> { - using type = IndexSequence<I..., (sizeofT + I)...>; -}; - -// Backport of std::make_index_sequence. -// It uses O(ln(N)) instantiation depth. -template <size_t N> -struct MakeIndexSequenceImpl - : DoubleSequence<N % 2 == 1, typename MakeIndexSequenceImpl<N / 2>::type, - N / 2>::type {}; - -template <> -struct MakeIndexSequenceImpl<0> : IndexSequence<> {}; - -template <size_t N> -using MakeIndexSequence = typename MakeIndexSequenceImpl<N>::type; - -template <typename... T> -using IndexSequenceFor = typename MakeIndexSequence<sizeof...(T)>::type; - template <size_t> struct Ignore { Ignore(...); // NOLINT @@ -1179,7 +1145,7 @@ struct Ignore { template <typename> struct ElemFromListImpl; template <size_t... I> -struct ElemFromListImpl<IndexSequence<I...>> { +struct ElemFromListImpl<std::index_sequence<I...>> { // We make Ignore a template to solve a problem with MSVC. // A non-template Ignore would work fine with `decltype(Ignore(I))...`, but // MSVC doesn't understand how to deal with that pack expansion. @@ -1190,9 +1156,8 @@ struct ElemFromListImpl<IndexSequence<I...>> { template <size_t N, typename... T> struct ElemFromList { - using type = - decltype(ElemFromListImpl<typename MakeIndexSequence<N>::type>::Apply( - static_cast<T (*)()>(nullptr)...)); + using type = decltype(ElemFromListImpl<std::make_index_sequence<N>>::Apply( + static_cast<T (*)()>(nullptr)...)); }; struct FlatTupleConstructTag {}; @@ -1217,9 +1182,9 @@ template <typename Derived, typename Idx> struct FlatTupleBase; template <size_t... Idx, typename... T> -struct FlatTupleBase<FlatTuple<T...>, IndexSequence<Idx...>> +struct FlatTupleBase<FlatTuple<T...>, std::index_sequence<Idx...>> : FlatTupleElemBase<FlatTuple<T...>, Idx>... { - using Indices = IndexSequence<Idx...>; + using Indices = std::index_sequence<Idx...>; FlatTupleBase() = default; template <typename... Args> explicit FlatTupleBase(FlatTupleConstructTag, Args&&... args) @@ -1254,14 +1219,15 @@ struct FlatTupleBase<FlatTuple<T...>, IndexSequence<Idx...>> // implementations. // FlatTuple and ElemFromList are not recursive and have a fixed depth // regardless of T... -// MakeIndexSequence, on the other hand, it is recursive but with an +// std::make_index_sequence, on the other hand, it is recursive but with an // instantiation depth of O(ln(N)). template <typename... T> class FlatTuple : private FlatTupleBase<FlatTuple<T...>, - typename MakeIndexSequence<sizeof...(T)>::type> { - using Indices = typename FlatTupleBase< - FlatTuple<T...>, typename MakeIndexSequence<sizeof...(T)>::type>::Indices; + std::make_index_sequence<sizeof...(T)>> { + using Indices = + typename FlatTupleBase<FlatTuple<T...>, + std::make_index_sequence<sizeof...(T)>>::Indices; public: FlatTuple() = default; diff --git a/googletest/include/gtest/internal/gtest-param-util.h b/googletest/include/gtest/internal/gtest-param-util.h index 1fc500f9..cc7ea531 100644 --- a/googletest/include/gtest/internal/gtest-param-util.h +++ b/googletest/include/gtest/internal/gtest-param-util.h @@ -807,12 +807,12 @@ class ValueArray { template <typename T> operator ParamGenerator<T>() const { // NOLINT - return ValuesIn(MakeVector<T>(MakeIndexSequence<sizeof...(Ts)>())); + return ValuesIn(MakeVector<T>(std::make_index_sequence<sizeof...(Ts)>())); } private: template <typename T, size_t... I> - std::vector<T> MakeVector(IndexSequence<I...>) const { + std::vector<T> MakeVector(std::index_sequence<I...>) const { return std::vector<T>{static_cast<T>(v_.template Get<I>())...}; } @@ -842,7 +842,7 @@ class CartesianProductGenerator template <class I> class IteratorImpl; template <size_t... I> - class IteratorImpl<IndexSequence<I...>> + class IteratorImpl<std::index_sequence<I...>> : public ParamIteratorInterface<ParamType> { public: IteratorImpl(const ParamGeneratorInterface<ParamType>* base, @@ -933,7 +933,7 @@ class CartesianProductGenerator std::shared_ptr<ParamType> current_value_; }; - using Iterator = IteratorImpl<typename MakeIndexSequence<sizeof...(T)>::type>; + using Iterator = IteratorImpl<std::make_index_sequence<sizeof...(T)>>; std::tuple<ParamGenerator<T>...> generators_; }; diff --git a/googletest/include/gtest/internal/gtest-port-arch.h b/googletest/include/gtest/internal/gtest-port-arch.h index 3162f2b1..7ec968f3 100644 --- a/googletest/include/gtest/internal/gtest-port-arch.h +++ b/googletest/include/gtest/internal/gtest-port-arch.h @@ -56,6 +56,8 @@ #elif WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_TV_TITLE) #define GTEST_OS_WINDOWS_PHONE 1 #define GTEST_OS_WINDOWS_TV_TITLE 1 +#elif WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_GAMES) +#define GTEST_OS_WINDOWS_GAMES 1 #else // WINAPI_FAMILY defined but no known partition matched. // Default to desktop. diff --git a/googletest/include/gtest/internal/gtest-port.h b/googletest/include/gtest/internal/gtest-port.h index fa457b78..6c469e9b 100644 --- a/googletest/include/gtest/internal/gtest-port.h +++ b/googletest/include/gtest/internal/gtest-port.h @@ -340,8 +340,8 @@ #if defined(GTEST_HAS_ABSL) && !defined(GTEST_NO_ABSL_FLAGS) #define GTEST_INTERNAL_HAS_ABSL_FLAGS // Used only in this file. -#include "absl/flags/flag.h" #include "absl/flags/declare.h" +#include "absl/flags/flag.h" #include "absl/flags/reflection.h" #endif @@ -659,9 +659,9 @@ typedef struct _RTL_CRITICAL_SECTION GTEST_CRITICAL_SECTION; // platforms except known mobile / embedded ones. Also, if the port doesn't have // a file system, stream redirection is not supported. #if defined(GTEST_OS_WINDOWS_MOBILE) || defined(GTEST_OS_WINDOWS_PHONE) || \ - defined(GTEST_OS_WINDOWS_RT) || defined(GTEST_OS_ESP8266) || \ - defined(GTEST_OS_XTENSA) || defined(GTEST_OS_QURT) || \ - !GTEST_HAS_FILE_SYSTEM + defined(GTEST_OS_WINDOWS_RT) || defined(GTEST_OS_WINDOWS_GAMES) || \ + defined(GTEST_OS_ESP8266) || defined(GTEST_OS_XTENSA) || \ + defined(GTEST_OS_QURT) || !GTEST_HAS_FILE_SYSTEM #define GTEST_HAS_STREAM_REDIRECTION 0 #else #define GTEST_HAS_STREAM_REDIRECTION 1 @@ -2108,8 +2108,9 @@ GTEST_DISABLE_MSC_DEPRECATED_PUSH_() // defined there. #if GTEST_HAS_FILE_SYSTEM #if !defined(GTEST_OS_WINDOWS_MOBILE) && !defined(GTEST_OS_WINDOWS_PHONE) && \ - !defined(GTEST_OS_WINDOWS_RT) && !defined(GTEST_OS_ESP8266) && \ - !defined(GTEST_OS_XTENSA) && !defined(GTEST_OS_QURT) + !defined(GTEST_OS_WINDOWS_RT) && !defined(GTEST_OS_WINDOWS_GAMES) && \ + !defined(GTEST_OS_ESP8266) && !defined(GTEST_OS_XTENSA) && \ + !defined(GTEST_OS_QURT) inline int ChDir(const char* dir) { return chdir(dir); } #endif inline FILE* FOpen(const char* path, const char* mode) { diff --git a/googletest/src/gtest-port.cc b/googletest/src/gtest-port.cc index 3bb7dd45..1038ad7b 100644 --- a/googletest/src/gtest-port.cc +++ b/googletest/src/gtest-port.cc @@ -587,9 +587,11 @@ class ThreadLocalRegistryImpl { // thread's ID. typedef std::map<DWORD, ThreadLocalValues> ThreadIdToThreadLocals; - // Holds the thread id and thread handle that we pass from - // StartWatcherThreadFor to WatcherThreadFunc. - typedef std::pair<DWORD, HANDLE> ThreadIdAndHandle; + struct WatcherThreadParams { + DWORD thread_id; + HANDLE handle; + Notification has_initialized; + }; static void StartWatcherThreadFor(DWORD thread_id) { // The returned handle will be kept in thread_map and closed by @@ -597,15 +599,20 @@ class ThreadLocalRegistryImpl { HANDLE thread = ::OpenThread(SYNCHRONIZE | THREAD_QUERY_INFORMATION, FALSE, thread_id); GTEST_CHECK_(thread != nullptr); + + WatcherThreadParams* watcher_thread_params = new WatcherThreadParams; + watcher_thread_params->thread_id = thread_id; + watcher_thread_params->handle = thread; + // We need to pass a valid thread ID pointer into CreateThread for it // to work correctly under Win98. DWORD watcher_thread_id; - HANDLE watcher_thread = ::CreateThread( - nullptr, // Default security. - 0, // Default stack size - &ThreadLocalRegistryImpl::WatcherThreadFunc, - reinterpret_cast<LPVOID>(new ThreadIdAndHandle(thread_id, thread)), - CREATE_SUSPENDED, &watcher_thread_id); + HANDLE watcher_thread = + ::CreateThread(nullptr, // Default security. + 0, // Default stack size + &ThreadLocalRegistryImpl::WatcherThreadFunc, + reinterpret_cast<LPVOID>(watcher_thread_params), + CREATE_SUSPENDED, &watcher_thread_id); GTEST_CHECK_(watcher_thread != nullptr) << "CreateThread failed with error " << ::GetLastError() << "."; // Give the watcher thread the same priority as ours to avoid being @@ -614,17 +621,25 @@ class ThreadLocalRegistryImpl { ::GetThreadPriority(::GetCurrentThread())); ::ResumeThread(watcher_thread); ::CloseHandle(watcher_thread); + + // Wait for the watcher thread to start to avoid race conditions. + // One specific race condition that can happen is that we have returned + // from main and have started to tear down, the newly spawned watcher + // thread may access already-freed variables, like global shared_ptrs. + watcher_thread_params->has_initialized.WaitForNotification(); } // Monitors exit from a given thread and notifies those // ThreadIdToThreadLocals about thread termination. static DWORD WINAPI WatcherThreadFunc(LPVOID param) { - const ThreadIdAndHandle* tah = - reinterpret_cast<const ThreadIdAndHandle*>(param); - GTEST_CHECK_(::WaitForSingleObject(tah->second, INFINITE) == WAIT_OBJECT_0); - OnThreadExit(tah->first); - ::CloseHandle(tah->second); - delete tah; + WatcherThreadParams* watcher_thread_params = + reinterpret_cast<WatcherThreadParams*>(param); + watcher_thread_params->has_initialized.Notify(); + GTEST_CHECK_(::WaitForSingleObject(watcher_thread_params->handle, + INFINITE) == WAIT_OBJECT_0); + OnThreadExit(watcher_thread_params->thread_id); + ::CloseHandle(watcher_thread_params->handle); + delete watcher_thread_params; return 0; } @@ -1033,12 +1048,12 @@ GTestLog::~GTestLog() { } } +#if GTEST_HAS_STREAM_REDIRECTION + // Disable Microsoft deprecation warnings for POSIX functions called from // this class (creat, dup, dup2, and close) GTEST_DISABLE_MSC_DEPRECATED_PUSH_() -#if GTEST_HAS_STREAM_REDIRECTION - namespace { #if defined(GTEST_OS_LINUX_ANDROID) || defined(GTEST_OS_IOS) @@ -1333,8 +1348,8 @@ bool ParseInt32(const Message& src_text, const char* str, int32_t* value) { ) { Message msg; msg << "WARNING: " << src_text - << " is expected to be a 32-bit integer, but actually" - << " has value " << str << ", which overflows.\n"; + << " is expected to be a 32-bit integer, but actually" << " has value " + << str << ", which overflows.\n"; printf("%s", msg.GetString().c_str()); fflush(stdout); return false; diff --git a/googletest/src/gtest.cc b/googletest/src/gtest.cc index 2aac9591..d64c18d7 100644 --- a/googletest/src/gtest.cc +++ b/googletest/src/gtest.cc @@ -3184,9 +3184,9 @@ static void PrintTestPartResult(const TestPartResult& test_part_result) { } // class PrettyUnitTestResultPrinter -#if defined(GTEST_OS_WINDOWS) && !defined(GTEST_OS_WINDOWS_MOBILE) && \ - !defined(GTEST_OS_WINDOWS_PHONE) && !defined(GTEST_OS_WINDOWS_RT) && \ - !defined(GTEST_OS_WINDOWS_MINGW) +#if defined(GTEST_OS_WINDOWS) && !defined(GTEST_OS_WINDOWS_MOBILE) && \ + !defined(GTEST_OS_WINDOWS_GAMES) && !defined(GTEST_OS_WINDOWS_PHONE) && \ + !defined(GTEST_OS_WINDOWS_RT) && !defined(GTEST_OS_WINDOWS_MINGW) // Returns the character attribute for the given color. static WORD GetColorAttribute(GTestColor color) { @@ -3313,9 +3313,9 @@ static void ColoredPrintf(GTestColor color, const char* fmt, ...) { return; } -#if defined(GTEST_OS_WINDOWS) && !defined(GTEST_OS_WINDOWS_MOBILE) && \ - !defined(GTEST_OS_WINDOWS_PHONE) && !defined(GTEST_OS_WINDOWS_RT) && \ - !defined(GTEST_OS_WINDOWS_MINGW) +#if defined(GTEST_OS_WINDOWS) && !defined(GTEST_OS_WINDOWS_MOBILE) && \ + !defined(GTEST_OS_WINDOWS_GAMES) && !defined(GTEST_OS_WINDOWS_PHONE) && \ + !defined(GTEST_OS_WINDOWS_RT) && !defined(GTEST_OS_WINDOWS_MINGW) const HANDLE stdout_handle = GetStdHandle(STD_OUTPUT_HANDLE); // Gets the current text color. @@ -4755,7 +4755,8 @@ void JsonUnitTestResultPrinter::OutputJsonTestResult(::std::ostream* stream, const std::string location = internal::FormatCompilerIndependentFileLocation(part.file_name(), part.line_number()); - const std::string message = EscapeJson(location + "\n" + part.message()); + const std::string message = + EscapeJson(location + "\n" + part.message()); *stream << kIndent << " {\n" << kIndent << " \"failure\": \"" << message << "\",\n" << kIndent << " \"type\": \"\"\n" @@ -4778,7 +4779,8 @@ void JsonUnitTestResultPrinter::OutputJsonTestResult(::std::ostream* stream, const std::string location = internal::FormatCompilerIndependentFileLocation(part.file_name(), part.line_number()); - const std::string message = EscapeJson(location + "\n" + part.message()); + const std::string message = + EscapeJson(location + "\n" + part.message()); *stream << kIndent << " {\n" << kIndent << " \"message\": \"" << message << "\"\n" << kIndent << " }"; @@ -5498,7 +5500,7 @@ int UnitTest::Run() { // about crashes - they are expected. if (impl()->catch_exceptions() || in_death_test_child_process) { #if !defined(GTEST_OS_WINDOWS_MOBILE) && !defined(GTEST_OS_WINDOWS_PHONE) && \ - !defined(GTEST_OS_WINDOWS_RT) + !defined(GTEST_OS_WINDOWS_RT) && !defined(GTEST_OS_WINDOWS_GAMES) // SetErrorMode doesn't exist on CE. SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOALIGNMENTFAULTEXCEPT | SEM_NOGPFAULTERRORBOX | SEM_NOOPENFILEERRORBOX); diff --git a/googletest/test/googletest-json-output-unittest.py b/googletest/test/googletest-json-output-unittest.py index 323f4b3e..d3338e3d 100644 --- a/googletest/test/googletest-json-output-unittest.py +++ b/googletest/test/googletest-json-output-unittest.py @@ -150,12 +150,9 @@ EXPECTED_NON_EMPTY = { 'time': '*', 'timestamp': '*', 'classname': 'SkippedTest', - 'skipped': [{ - 'message': ( - 'gtest_xml_output_unittest_.cc:*\n' - '\n' - ) - }], + 'skipped': [ + {'message': 'gtest_xml_output_unittest_.cc:*\n\n'} + ], }, { 'name': 'SkippedWithMessage', diff --git a/googletest/test/gtest_unittest.cc b/googletest/test/gtest_unittest.cc index 5d7cfb09..edbe2ea2 100644 --- a/googletest/test/gtest_unittest.cc +++ b/googletest/test/gtest_unittest.cc @@ -7482,22 +7482,6 @@ TEST(NativeArrayTest, WorksForTwoDimensionalArray) { EXPECT_EQ(a, na.begin()); } -// IndexSequence -TEST(IndexSequence, MakeIndexSequence) { - using testing::internal::IndexSequence; - using testing::internal::MakeIndexSequence; - EXPECT_TRUE( - (std::is_same<IndexSequence<>, MakeIndexSequence<0>::type>::value)); - EXPECT_TRUE( - (std::is_same<IndexSequence<0>, MakeIndexSequence<1>::type>::value)); - EXPECT_TRUE( - (std::is_same<IndexSequence<0, 1>, MakeIndexSequence<2>::type>::value)); - EXPECT_TRUE(( - std::is_same<IndexSequence<0, 1, 2>, MakeIndexSequence<3>::type>::value)); - EXPECT_TRUE( - (std::is_base_of<IndexSequence<0, 1, 2>, MakeIndexSequence<3>>::value)); -} - // ElemFromList TEST(ElemFromList, Basic) { using testing::internal::ElemFromList; |