diff --git a/libstdc++-v3/include/bits/ranges_algo.h b/libstdc++-v3/include/bits/ranges_algo.h index df92598f51a17054a92f61debbfcdb2fd45e2ccd..a72eab582be007bb29b846a83cb857ccd8bc0484 100644 --- a/libstdc++-v3/include/bits/ranges_algo.h +++ b/libstdc++-v3/include/bits/ranges_algo.h @@ -567,9 +567,12 @@ namespace ranges for (auto __scan = __first1; __scan != __last1; ++__scan) { - auto&& __proj_scan = std::__invoke(__proj1, *__scan); + auto&& __scan_deref = *__scan; + auto&& __proj_scan = + std::__invoke(__proj1, std::forward<decltype(__scan_deref)>(__scan_deref)); auto __comp_scan = [&] <typename _Tp> (_Tp&& __arg) -> bool { - return std::__invoke(__pred, __proj_scan, + return std::__invoke(__pred, + std::forward<decltype(__proj_scan)>(__proj_scan), std::forward<_Tp>(__arg)); }; if (__scan != ranges::find_if(__first1, __scan, diff --git a/libstdc++-v3/testsuite/25_algorithms/is_permutation/constrained.cc b/libstdc++-v3/testsuite/25_algorithms/is_permutation/constrained.cc index cd4b3fe8c32f7223bd9370a6fe63e4097151a4db..c96d7c568ead5c93495e5b32a99a9d7f980979a0 100644 --- a/libstdc++-v3/testsuite/25_algorithms/is_permutation/constrained.cc +++ b/libstdc++-v3/testsuite/25_algorithms/is_permutation/constrained.cc @@ -19,6 +19,7 @@ #include <algorithm> #include <iterator> +#include <ranges> #include <testsuite_hooks.h> #include <testsuite_iterators.h> @@ -76,10 +77,22 @@ test03() while (std::next_permutation(std::begin(cx), std::end(cx))); } +constexpr +bool +test04() // PR118160, do not create dangling references +{ + int x[] = { 4, 3, 2, 1 }; + auto y = std::views::iota(1, 5); + return ranges::is_permutation(x, y) && ranges::is_permutation(y, x); +} + +static_assert(test04()); + int main() { test01(); test02(); test03(); + VERIFY( test04() ); }