diff --git a/libcxx/include/__functional/hash.h b/libcxx/include/__functional/hash.h --- a/libcxx/include/__functional/hash.h +++ b/libcxx/include/__functional/hash.h @@ -75,10 +75,10 @@ switch (__len) { case 3: - __h ^= __data[2] << 16; + __h ^= static_cast<_Size>(__data[2] << 16); _LIBCPP_FALLTHROUGH(); case 2: - __h ^= __data[1] << 8; + __h ^= static_cast<_Size>(__data[1] << 8); _LIBCPP_FALLTHROUGH(); case 1: __h ^= __data[0]; @@ -140,9 +140,9 @@ return __hash_len_16(__len + (__a << 3), __b); } if (__len > 0) { - const unsigned char __a = __s[0]; - const unsigned char __b = __s[__len >> 1]; - const unsigned char __c = __s[__len - 1]; + const unsigned char __a = static_cast(__s[0]); + const unsigned char __b = static_cast(__s[__len >> 1]); + const unsigned char __c = static_cast(__s[__len - 1]); const uint32_t __y = static_cast(__a) + (static_cast(__b) << 8); const uint32_t __z = __len + (static_cast(__c) << 2); diff --git a/libcxx/include/__iterator/advance.h b/libcxx/include/__iterator/advance.h --- a/libcxx/include/__iterator/advance.h +++ b/libcxx/include/__iterator/advance.h @@ -32,15 +32,15 @@ _LIBCPP_BEGIN_NAMESPACE_STD template -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 void -__advance(_InputIter& __i, typename iterator_traits<_InputIter>::difference_type __n, input_iterator_tag) { +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX14 +void __advance(_InputIter& __i, typename iterator_traits<_InputIter>::difference_type __n, input_iterator_tag) { for (; __n > 0; --__n) ++__i; } template -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 void -__advance(_BiDirIter& __i, typename iterator_traits<_BiDirIter>::difference_type __n, bidirectional_iterator_tag) { +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX14 +void __advance(_BiDirIter& __i, typename iterator_traits<_BiDirIter>::difference_type __n, bidirectional_iterator_tag) { if (__n >= 0) for (; __n > 0; --__n) ++__i; @@ -50,17 +50,19 @@ } template -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 void -__advance(_RandIter& __i, typename iterator_traits<_RandIter>::difference_type __n, random_access_iterator_tag) { +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX14 +void __advance(_RandIter& __i, typename iterator_traits<_RandIter>::difference_type __n, random_access_iterator_tag) { __i += __n; } template < class _InputIter, class _Distance, - class = typename enable_if()))>::value>::type> -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 void advance(_InputIter& __i, _Distance __orig_n) { - typedef decltype(_VSTD::__convert_to_integral(__orig_n)) _IntegralSize; - _IntegralSize __n = __orig_n; + class _IntegralDistance = decltype(_VSTD::__convert_to_integral(declval<_Distance>())), + class = _EnableIf::value> > +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX14 +void advance(_InputIter& __i, _Distance __orig_n) { + typedef typename iterator_traits<_InputIter>::difference_type _Difference; + _Difference __n = static_cast<_Difference>(_VSTD::__convert_to_integral(__orig_n)); _LIBCPP_ASSERT(__n >= 0 || __is_cpp17_bidirectional_iterator<_InputIter>::value, "Attempt to advance(it, n) with negative n on a non-bidirectional iterator"); _VSTD::__advance(__i, __n, typename iterator_traits<_InputIter>::iterator_category()); diff --git a/libcxx/include/tuple b/libcxx/include/tuple --- a/libcxx/include/tuple +++ b/libcxx/include/tuple @@ -1165,7 +1165,7 @@ namespace __find_detail { -static constexpr size_t __not_found = -1; +static constexpr size_t __not_found = static_cast(-1); static constexpr size_t __ambiguous = __not_found - 1; inline _LIBCPP_INLINE_VISIBILITY diff --git a/libcxx/test/std/iterators/iterator.primitives/iterator.operations/advance.pass.cpp b/libcxx/test/std/iterators/iterator.primitives/iterator.operations/advance.pass.cpp --- a/libcxx/test/std/iterators/iterator.primitives/iterator.operations/advance.pass.cpp +++ b/libcxx/test/std/iterators/iterator.primitives/iterator.operations/advance.pass.cpp @@ -20,7 +20,7 @@ // constexpr void advance(Iter& i, Distance n); // Make sure we catch forced conversions to the difference_type if they happen. -// ADDITIONAL_COMPILER_FLAGS: -Wsign-conversion +// ADDITIONAL_COMPILE_FLAGS: -Wsign-conversion #include #include @@ -42,21 +42,37 @@ TEST_CONSTEXPR_CXX17 bool tests() { const char* s = "1234567890"; - typedef std::iterator_traits::difference_type Distance; - check_advance(cpp17_input_iterator(s), 10, cpp17_input_iterator(s+10)); - check_advance(forward_iterator(s), 10, forward_iterator(s+10)); - check_advance(bidirectional_iterator(s+5), 5, bidirectional_iterator(s+10)); - check_advance(bidirectional_iterator(s+5), -5, bidirectional_iterator(s)); - check_advance(random_access_iterator(s+5), 5, random_access_iterator(s+10)); - check_advance(random_access_iterator(s+5), -5, random_access_iterator(s)); - check_advance(s+5, 5, s+10); - check_advance(s+5, -5, s); + + // Check with iterator_traits::difference_type + { + typedef std::iterator_traits::difference_type Distance; + check_advance(cpp17_input_iterator(s), 10, cpp17_input_iterator(s+10)); + check_advance(forward_iterator(s), 10, forward_iterator(s+10)); + check_advance(bidirectional_iterator(s+5), 5, bidirectional_iterator(s+10)); + check_advance(bidirectional_iterator(s+5), -5, bidirectional_iterator(s)); + check_advance(random_access_iterator(s+5), 5, random_access_iterator(s+10)); + check_advance(random_access_iterator(s+5), -5, random_access_iterator(s)); + check_advance(s+5, 5, s+10); + check_advance(s+5, -5, s); + } // Also check with other distance types - check_advance(cpp17_input_iterator(s), 10u, cpp17_input_iterator(s+10)); - check_advance(forward_iterator(s), 10u, forward_iterator(s+10)); - check_advance(bidirectional_iterator(s), 10u, bidirectional_iterator(s+10)); - check_advance(random_access_iterator(s), 10u, random_access_iterator(s+10)); + { + typedef int Distance; + check_advance(cpp17_input_iterator(s), 10, cpp17_input_iterator(s+10)); + check_advance(forward_iterator(s), 10, forward_iterator(s+10)); + check_advance(bidirectional_iterator(s), 10, bidirectional_iterator(s+10)); + check_advance(random_access_iterator(s), 10, random_access_iterator(s+10)); + } + + // Check with unsigned distance types to catch signedness-change issues + { + typedef std::size_t Distance; + check_advance(cpp17_input_iterator(s), 10u, cpp17_input_iterator(s+10)); + check_advance(forward_iterator(s), 10u, forward_iterator(s+10)); + check_advance(bidirectional_iterator(s), 10u, bidirectional_iterator(s+10)); + check_advance(random_access_iterator(s), 10u, random_access_iterator(s+10)); + } return true; }