-
Notifications
You must be signed in to change notification settings - Fork 1.6k
Description
Found by std/ranges/range.factories/range.repeat.view/iterator/minus.pass.cpp in the upcoming libcxx update.
D:\GitHub\STL\out\x64>type meow.cpp
#include <cassert>
#include <iostream>
#include <ranges>
using namespace std;
int main() {
auto rv = views::repeat(1729, 20u);
auto first = rv.begin();
auto last = rv.end();
assert(last - first == 20);
first += 2;
last -= 3;
assert(last - first == 15);
}D:\GitHub\STL\out\x64>cl /EHsc /nologo /W4 /std:c++latest /MTd /Od meow.cpp && meow
meow.cpp
D:\GitHub\STL\out\x64\out\inc\ranges(1574): warning C4244: '-=': conversion from '__int64' to 'unsigned int', possible loss of data
D:\GitHub\STL\out\x64\out\inc\ranges(1574): note: the template instantiation context (the oldest one first) is
D:\GitHub\STL\out\x64\out\inc\ranges(1484): note: while compiling class 'std::ranges::repeat_view<_Ty,unsigned int>::_Iterator'
with
[
_Ty=int
]
D:\GitHub\STL\out\x64\out\inc\ranges(1560): note: while compiling class template member function 'std::ranges::repeat_view<_Ty,unsigned int>::_Iterator &std::ranges::repeat_view<_Ty,unsigned int>::_Iterator::operator -=(__int64) noexcept'
with
[
_Ty=int
]
meow.cpp(12): note: see the first reference to 'std::ranges::repeat_view<_Ty,unsigned int>::_Iterator::operator -=' in 'main'
with
[
_Ty=int
]
D:\GitHub\STL\out\x64\out\inc\ranges(1557): warning C4244: '+=': conversion from '__int64' to 'unsigned int', possible loss of data
D:\GitHub\STL\out\x64\out\inc\ranges(1557): note: the template instantiation context (the oldest one first) is
D:\GitHub\STL\out\x64\out\inc\ranges(1543): note: while compiling class template member function 'std::ranges::repeat_view<_Ty,unsigned int>::_Iterator &std::ranges::repeat_view<_Ty,unsigned int>::_Iterator::operator +=(__int64) noexcept'
with
[
_Ty=int
]
meow.cpp(11): note: see the first reference to 'std::ranges::repeat_view<_Ty,unsigned int>::_Iterator::operator +=' in 'main'
with
[
_Ty=int
]
At first glance, it doesn't seem that the user code is provoking these warnings, instead it's how the STL widens and narrows types.
In our implementation, I see that we have:
Line 1490 in cf1313c
| /* [[no_unique_address]] */ _Index_type _Current{}; |
and then we're performing debug checks with static_cast<_Index_type>(_Off) and finally saying _Current += _Off;:
Lines 1543 to 1559 in cf1313c
| constexpr _Iterator& operator+=(difference_type _Off) noexcept /* strengthened */ { | |
| #if _CONTAINER_DEBUG_LEVEL > 0 | |
| if (_Off > 0) { | |
| _STL_VERIFY(_Current <= (numeric_limits<_Index_type>::max)() - static_cast<_Index_type>(_Off), | |
| "cannot advance repeat_view iterator past end (integer overflow)"); | |
| } else { | |
| _STL_VERIFY(_Current >= (numeric_limits<_Index_type>::min)() - static_cast<_Index_type>(_Off), | |
| "cannot advance repeat_view iterator before begin (integer overflow)"); | |
| } | |
| if constexpr (!is_same_v<_Bo, unreachable_sentinel_t>) { | |
| _STL_VERIFY(_Current + _Off >= 0, "cannot subtract below 0"); | |
| } | |
| #endif // _CONTAINER_DEBUG_LEVEL > 0 | |
| _Current += _Off; | |
| return *this; | |
| } |
My vague guess is that after the debug checks, we should be able to use static_cast<_Index_type>(_Off) to avoid the warning. However, I'm not sure if we should be checking that difference_type _Off can be losslessly static_cast<_Index_type>(_Off) in the first place, which is why I'm filing this issue instead of just changing the implementation.