From fd2f93683cfe83d2e083b6f06b97db282a212cb7 Mon Sep 17 00:00:00 2001 From: greg Date: Tue, 31 Dec 2019 13:26:03 -0500 Subject: [PATCH] cleanup more warnings with MSVC --- parallel_hashmap/phmap.h | 54 ++++++----- parallel_hashmap/phmap_base.h | 171 ++++++--------------------------- parallel_hashmap/phmap_bits.h | 9 ++ parallel_hashmap/phmap_utils.h | 8 ++ 4 files changed, 78 insertions(+), 164 deletions(-) diff --git a/parallel_hashmap/phmap.h b/parallel_hashmap/phmap.h index b169c03..eb89ccd 100644 --- a/parallel_hashmap/phmap.h +++ b/parallel_hashmap/phmap.h @@ -57,8 +57,16 @@ #ifdef _MSC_VER #pragma warning(push) - // warning C4820: '6' bytes padding added after data member - #pragma warning(disable : 4820) + + #pragma warning(disable : 4127) // conditional expression is constant + #pragma warning(disable : 4514) // unreferenced inline function has been removed + #pragma warning(disable : 4623) // default constructor was implicitly defined as deleted + #pragma warning(disable : 4625) // copy constructor was implicitly defined as deleted + #pragma warning(disable : 4626) // assignment operator was implicitly defined as deleted + #pragma warning(disable : 4820) // '6' bytes padding added after data member + #pragma warning(disable : 4868) // compiler may not enforce left-to-right evaluation order in braced initializer list + #pragma warning(disable : 5027) // move assignment operator was implicitly defined as deleted + #pragma warning(disable : 5045) // Compiler will insert Spectre mitigation for memory load if /Qspectre switch specified #endif namespace phmap { @@ -283,6 +291,11 @@ inline bool IsEmptyOrDeleted(ctrl_t c) { return c < kSentinel; } #if PHMAP_HAVE_SSE2 +#ifdef _MSC_VER + #pragma warning(push) + #pragma warning(disable : 4365) // conversion from 'int' to 'T', signed/unsigned mismatch +#endif + // -------------------------------------------------------------------------- // https://github.com/abseil/abseil-cpp/issues/209 // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=87853 @@ -368,6 +381,11 @@ struct GroupSse2Impl __m128i ctrl; }; + +#ifdef _MSC_VER + #pragma warning(pop) +#endif + #endif // PHMAP_HAVE_SSE2 // -------------------------------------------------------------------------- @@ -467,12 +485,6 @@ inline size_t NormalizeCapacity(size_t n) return n ? ~size_t{} >> LeadingZeros(n) : 1; } -#ifdef _MSC_VER - #pragma warning(push) - // warning C4127: conditional expression is constant - #pragma warning(disable : 4127) -#endif - // -------------------------------------------------------------------------- // We use 7/8th as maximum load factor. // For 16-wide groups, that gives an average of two empty slots per group. @@ -502,10 +514,6 @@ inline size_t GrowthToLowerboundCapacity(size_t growth) return growth + static_cast((static_cast(growth) - 1) / 7); } -#ifdef _MSC_VER - #pragma warning(pop) -#endif - namespace hashtable_debug_internal { // If it is a map, call get<0>(). @@ -1550,11 +1558,11 @@ public: auto seq = probe(hash); while (true) { Group g{ctrl_ + seq.offset()}; - for (int i : g.Match(H2(hash))) { + for (int i : g.Match((h2_t)H2(hash))) { if (PHMAP_PREDICT_TRUE(PolicyTraits::apply( EqualElement{key, eq_ref()}, - PolicyTraits::element(slots_ + seq.offset(i))))) - return iterator_at(seq.offset(i)); + PolicyTraits::element(slots_ + seq.offset((size_t)i))))) + return iterator_at(seq.offset((size_t)i)); } if (PHMAP_PREDICT_TRUE(g.MatchEmpty())) return end(); @@ -1725,7 +1733,7 @@ private: void erase_meta_only(const_iterator it) { assert(IsFull(*it.inner_.ctrl_) && "erasing a dangling iterator"); --size_; - const size_t index = it.inner_.ctrl_ - ctrl_; + const size_t index = (size_t)(it.inner_.ctrl_ - ctrl_); const size_t index_before = (index - Group::kWidth) & capacity_; const auto empty_after = Group(it.inner_.ctrl_).MatchEmpty(); const auto empty_before = Group(ctrl_ + index_before).MatchEmpty(); @@ -1884,8 +1892,8 @@ private: auto seq = probe(hash); while (true) { Group g{ctrl_ + seq.offset()}; - for (int i : g.Match(H2(hash))) { - if (PHMAP_PREDICT_TRUE(PolicyTraits::element(slots_ + seq.offset(i)) == + for (int i : g.Match((h2_t)H2(hash))) { + if (PHMAP_PREDICT_TRUE(PolicyTraits::element(slots_ + seq.offset((size_t)i)) == elem)) return true; } @@ -1921,7 +1929,7 @@ private: Group g{ctrl_ + seq.offset()}; auto mask = g.MatchEmptyOrDeleted(); if (mask) { - return {seq.offset(mask.LowestBitSet()), seq.index()}; + return {seq.offset((size_t)mask.LowestBitSet()), seq.index()}; } assert(seq.index() < capacity_ && "full table!"); seq.next(); @@ -1946,11 +1954,11 @@ protected: auto seq = probe(hash); while (true) { Group g{ctrl_ + seq.offset()}; - for (int i : g.Match(H2(hash))) { + for (int i : g.Match((h2_t)H2(hash))) { if (PHMAP_PREDICT_TRUE(PolicyTraits::apply( EqualElement{key, eq_ref()}, - PolicyTraits::element(slots_ + seq.offset(i))))) - return {seq.offset(i), false}; + PolicyTraits::element(slots_ + seq.offset((size_t)i))))) + return {seq.offset((size_t)i), false}; } if (PHMAP_PREDICT_TRUE(g.MatchEmpty())) break; seq.next(); @@ -3844,7 +3852,7 @@ struct HashtableDebugAccess> if (Traits::apply( typename Set::template EqualElement{ key, set.eq_ref()}, - Traits::element(set.slots_ + seq.offset(i)))) + Traits::element(set.slots_ + seq.offset((size_t)i)))) return num_probes; ++num_probes; } diff --git a/parallel_hashmap/phmap_base.h b/parallel_hashmap/phmap_base.h index 418a132..f6da6a3 100644 --- a/parallel_hashmap/phmap_base.h +++ b/parallel_hashmap/phmap_base.h @@ -54,6 +54,15 @@ #include // after "phmap_config.h" #endif +#ifdef _MSC_VER + #pragma warning(push) + #pragma warning(disable : 4514) // unreferenced inline function has been removed + #pragma warning(disable : 4582) // constructor is not implicitly called + #pragma warning(disable : 4625) // copy constructor was implicitly defined as deleted + #pragma warning(disable : 4626) // assignment operator was implicitly defined as deleted + #pragma warning(disable : 4820) // '6' bytes padding added after data member +#endif // _MSC_VER + namespace phmap { template using Allocator = typename std::allocator; @@ -213,166 +222,31 @@ struct disjunction : T {}; template <> struct disjunction<> : std::false_type {}; -// --------------------------------------------------------------------------- -// negation -// -// Performs a compile-time logical NOT operation on the passed type (which -// must have `::value` members convertible to `bool`. -// -// This metafunction is designed to be a drop-in replacement for the C++17 -// `std::negation` metafunction. -// --------------------------------------------------------------------------- template struct negation : std::integral_constant {}; -// --------------------------------------------------------------------------- -// is_trivially_destructible() -// -// Determines whether the passed type `T` is trivially destructable. -// -// This metafunction is designed to be a drop-in replacement for the C++11 -// `std::is_trivially_destructible()` metafunction for platforms that have -// incomplete C++11 support (such as libstdc++ 4.x). On any platforms that do -// fully support C++11, we check whether this yields the same result as the std -// implementation. -// -// NOTE: the extensions (__has_trivial_xxx) are implemented in gcc (version >= -// 4.3) and clang. Since we are supporting libstdc++ > 4.7, they should always -// be present. These extensions are documented at -// https://gcc.gnu.org/onlinedocs/gcc/Type-Traits.html#Type-Traits. -// --------------------------------------------------------------------------- template struct is_trivially_destructible : std::integral_constant::value> -{ -}; + std::is_destructible::value> {}; -// --------------------------------------------------------------------------- -// is_trivially_default_constructible() -// -// Determines whether the passed type `T` is trivially default constructible. -// -// This metafunction is designed to be a drop-in replacement for the C++11 -// `std::is_trivially_default_constructible()` metafunction for platforms that -// have incomplete C++11 support (such as libstdc++ 4.x). On any platforms that -// do fully support C++11, we check whether this yields the same result as the -// std implementation. -// -// NOTE: according to the C++ standard, Section: 20.15.4.3 [meta.unary.prop] -// "The predicate condition for a template specialization is_constructible shall be satisfied if and only if the following variable -// definition would be well-formed for some invented variable t: -// -// T t(declval()...); -// -// is_trivially_constructible additionally requires that the -// variable definition does not call any operation that is not trivial. -// For the purposes of this check, the call to std::declval is considered -// trivial." -// -// Notes from https://en.cppreference.com/w/cpp/types/is_constructible: -// In many implementations, is_nothrow_constructible also checks if the -// destructor throws because it is effectively noexcept(T(arg)). Same -// applies to is_trivially_constructible, which, in these implementations, also -// requires that the destructor is trivial. -// GCC bug 51452: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=51452 -// LWG issue 2116: http://cplusplus.github.io/LWG/lwg-active.html#2116. -// -// "T obj();" need to be well-formed and not call any nontrivial operation. -// Nontrivially destructible types will cause the expression to be nontrivial. -// --------------------------------------------------------------------------- template struct is_trivially_default_constructible : std::integral_constant::value && - is_trivially_destructible::value> -{ -#ifdef PHMAP_HAVE_STD_IS_TRIVIALLY_CONSTRUCTIBLE -private: - static constexpr bool compliant = - std::is_trivially_default_constructible::value == - is_trivially_default_constructible::value; - static_assert(compliant || std::is_trivially_default_constructible::value, - "Not compliant with std::is_trivially_default_constructible; " - "Standard: false, Implementation: true"); - static_assert(compliant || !std::is_trivially_default_constructible::value, - "Not compliant with std::is_trivially_default_constructible; " - "Standard: true, Implementation: false"); -#endif -}; + is_trivially_destructible::value> {}; -// --------------------------------------------------------------------------- -// is_trivially_copy_constructible() -// -// Determines whether the passed type `T` is trivially copy constructible. -// -// This metafunction is designed to be a drop-in replacement for the C++11 -// `std::is_trivially_copy_constructible()` metafunction for platforms that have -// incomplete C++11 support (such as libstdc++ 4.x). On any platforms that do -// fully support C++11, we check whether this yields the same result as the std -// implementation. -// -// NOTE: `T obj(declval());` needs to be well-formed and not call any -// nontrivial operation. Nontrivially destructible types will cause the -// expression to be nontrivial. -// --------------------------------------------------------------------------- template struct is_trivially_copy_constructible : std::integral_constant::value && - is_trivially_destructible::value> -{ -#ifdef PHMAP_HAVE_STD_IS_TRIVIALLY_CONSTRUCTIBLE -private: - static constexpr bool compliant = - std::is_trivially_copy_constructible::value == - is_trivially_copy_constructible::value; - static_assert(compliant || std::is_trivially_copy_constructible::value, - "Not compliant with std::is_trivially_copy_constructible; " - "Standard: false, Implementation: true"); - static_assert(compliant || !std::is_trivially_copy_constructible::value, - "Not compliant with std::is_trivially_copy_constructible; " - "Standard: true, Implementation: false"); -#endif -}; + is_trivially_destructible::value> {}; -// --------------------------------------------------------------------------- -// is_trivially_copy_assignable() -// -// Determines whether the passed type `T` is trivially copy assignable. -// -// This metafunction is designed to be a drop-in replacement for the C++11 -// `std::is_trivially_copy_assignable()` metafunction for platforms that have -// incomplete C++11 support (such as libstdc++ 4.x). On any platforms that do -// fully support C++11, we check whether this yields the same result as the std -// implementation. -// -// NOTE: `is_assignable::value` is `true` if the expression -// `declval() = declval()` is well-formed when treated as an unevaluated -// operand. `is_trivially_assignable` requires the assignment to call no -// operation that is not trivial. `is_trivially_copy_assignable` is simply -// `is_trivially_assignable`. -// --------------------------------------------------------------------------- template struct is_trivially_copy_assignable : std::integral_constant< bool, __has_trivial_assign(typename std::remove_reference::type) && - phmap::is_copy_assignable::value> -{ -#ifdef PHMAP_HAVE_STD_IS_TRIVIALLY_ASSIGNABLE -private: - static constexpr bool compliant = - std::is_trivially_copy_assignable::value == - is_trivially_copy_assignable::value; - static_assert(compliant || std::is_trivially_copy_assignable::value, - "Not compliant with std::is_trivially_copy_assignable; " - "Standard: false, Implementation: true"); - static_assert(compliant || !std::is_trivially_copy_assignable::value, - "Not compliant with std::is_trivially_copy_assignable; " - "Standard: true, Implementation: false"); -#endif -}; + phmap::is_copy_assignable::value> {}; // ----------------------------------------------------------------------------- // C++14 "_t" trait aliases @@ -1216,6 +1090,11 @@ auto apply(Functor&& functor, Tuple&& t) typename std::remove_reference::type>::value>{}); } +#ifdef _MSC_VER + #pragma warning(push) + #pragma warning(disable : 4365) // '=': conversion from 'T' to 'T', signed/unsigned mismatch +#endif // _MSC_VER + // exchange // // Replaces the value of `obj` with `new_value` and returns the old value of @@ -1237,6 +1116,11 @@ T exchange(T& obj, U&& new_value) return old_value; } +#ifdef _MSC_VER + #pragma warning(pop) +#endif // _MSC_VER + + } // namespace phmap // ----------------------------------------------------------------------------- @@ -2895,8 +2779,8 @@ protected: PolicyTraits::transfer(alloc(), slot(), s); } - node_handle_base(const node_handle_base&) = delete; - node_handle_base& operator=(const node_handle_base&) = delete; + //node_handle_base(const node_handle_base&) = delete; + //node_handle_base& operator=(const node_handle_base&) = delete; void destroy() { if (!empty()) { @@ -5264,4 +5148,9 @@ public: } // phmap +#ifdef _MSC_VER + #pragma warning(pop) +#endif + + #endif // phmap_base_h_guard_ diff --git a/parallel_hashmap/phmap_bits.h b/parallel_hashmap/phmap_bits.h index f28e686..7933d8c 100644 --- a/parallel_hashmap/phmap_bits.h +++ b/parallel_hashmap/phmap_bits.h @@ -50,6 +50,11 @@ #include #include "phmap_config.h" +#ifdef _MSC_VER + #pragma warning(push) + #pragma warning(disable : 4514) // unreferenced inline function has been removed +#endif + // ----------------------------------------------------------------------------- // unaligned APIs // ----------------------------------------------------------------------------- @@ -651,4 +656,8 @@ inline void Store64(void *p, uint64_t v) { } // namespace phmap +#ifdef _MSC_VER + #pragma warning(pop) +#endif + #endif // phmap_bits_h_guard_ diff --git a/parallel_hashmap/phmap_utils.h b/parallel_hashmap/phmap_utils.h index 3ffa2ec..6151ba2 100644 --- a/parallel_hashmap/phmap_utils.h +++ b/parallel_hashmap/phmap_utils.h @@ -26,6 +26,11 @@ #include #include "phmap_bits.h" +#ifdef _MSC_VER + #pragma warning(push) + #pragma warning(disable : 4514) // unreferenced inline function has been removed +#endif + namespace phmap { @@ -356,5 +361,8 @@ private: } // namespace phmap +#ifdef _MSC_VER + #pragma warning(pop) +#endif #endif // phmap_utils_h_guard_