https://gcc.gnu.org/g:b3a3ecc460237948d924bca6cb8fe15622e5025b
commit r17-5268-gb3a3ecc460237948d924bca6cb8fe15622e5025b Author: Jesse Connell <[email protected]> Date: Fri Oct 16 13:17:19 2026 +0100 libstdc++: Use borrowed_iterator_t in ranges::mismatch [PR127918] We did not match the return type specified in the standard. I did not find any other cases where we failed to use borrowed_iterator_t. libstdc++-v3/ChangeLog: PR libstdc++/127918 * include/bits/ranges_util.h (__mismatch_fn::operator()): Use borrowed_iterator_t in return type. * testsuite/25_algorithms/mismatch/constrained.cc: Check that dangling results are correctly avoided. Co-authored-by: Jonathan Wakely <[email protected]> Diff: --- libstdc++-v3/include/bits/ranges_util.h | 3 ++- .../25_algorithms/mismatch/constrained.cc | 30 ++++++++++++++++++++++ 2 files changed, 32 insertions(+), 1 deletion(-) diff --git a/libstdc++-v3/include/bits/ranges_util.h b/libstdc++-v3/include/bits/ranges_util.h index c474e7f165ef..9e51aa53ec8b 100644 --- a/libstdc++-v3/include/bits/ranges_util.h +++ b/libstdc++-v3/include/bits/ranges_util.h @@ -656,7 +656,8 @@ namespace ranges requires indirectly_comparable<iterator_t<_Range1>, iterator_t<_Range2>, _Pred, _Proj1, _Proj2> [[nodiscard]] - constexpr mismatch_result<iterator_t<_Range1>, iterator_t<_Range2>> + constexpr mismatch_result<borrowed_iterator_t<_Range1>, + borrowed_iterator_t<_Range2>> operator()(_Range1&& __r1, _Range2&& __r2, _Pred __pred = {}, _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const { diff --git a/libstdc++-v3/testsuite/25_algorithms/mismatch/constrained.cc b/libstdc++-v3/testsuite/25_algorithms/mismatch/constrained.cc index 1ee68c852a75..5108ba8b1875 100644 --- a/libstdc++-v3/testsuite/25_algorithms/mismatch/constrained.cc +++ b/libstdc++-v3/testsuite/25_algorithms/mismatch/constrained.cc @@ -67,9 +67,39 @@ test02() static_assert(ranges::mismatch(ya, yb, {}, &Y::i, &Y::j).in2 == yb+2); } +void +test03() +{ + // Bug 127918 - ranges::mismatch fails to use borrowed_iterator_t + + int a[3] = {1, 2, 3}; + using RA = test_range<int, input_iterator_wrapper>; + short b[3] = {1, 2, 4}; + using RB = test_range<short, input_iterator_wrapper>; + + { + RA ra(a); + auto ret = ranges::mismatch(ra, RB(b)); + static_assert( std::is_same_v<decltype(ret.in1), ranges::iterator_t<RA>> ); + static_assert( std::is_same_v<decltype(ret.in2), ranges::dangling> ); + } + { + RB rb(b); + auto ret = ranges::mismatch(RA(a), rb); + static_assert( std::is_same_v<decltype(ret.in1), ranges::dangling> ); + static_assert( std::is_same_v<decltype(ret.in2), ranges::iterator_t<RB>> ); + } + { + auto ret = ranges::mismatch(RA(a), RB(b)); + static_assert( std::is_same_v<decltype(ret.in1), ranges::dangling> ); + static_assert( std::is_same_v<decltype(ret.in2), ranges::dangling> ); + } +} + int main() { test01(); test02(); + test03(); }
