https://gcc.gnu.org/g:78090f55dbb896e57f14b3ab2c333d1f5adb4815
commit r17-1371-g78090f55dbb896e57f14b3ab2c333d1f5adb4815 Author: Yuao Ma <[email protected]> Date: Fri Jun 5 19:50:54 2026 +0800 libstdc++: avoid ill-formed nested generator This was approved as LWG 4119. libstdc++-v3/ChangeLog: * include/std/generator (generator::yield_value): Change the second template parameter from range_value_t<R> to void. * testsuite/24_iterators/range_generators/lwg4119.cc: New test. Diff: --- libstdc++-v3/include/std/generator | 5 ++++- .../testsuite/24_iterators/range_generators/lwg4119.cc | 14 ++++++++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/libstdc++-v3/include/std/generator b/libstdc++-v3/include/std/generator index 88651dd6f76a..87fe28766f09 100644 --- a/libstdc++-v3/include/std/generator +++ b/libstdc++-v3/include/std/generator @@ -163,6 +163,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION noexcept { return _Recursive_awaiter { std::move(__r.range) }; } + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 4119. generator::promise_type::yield_value(elements_of<R, Alloc>)'s + // nested generator may be ill-formed template<ranges::input_range _R, typename _Alloc> requires convertible_to<ranges::range_reference_t<_R>, _Yielded> auto @@ -171,7 +174,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION auto __n = [] (allocator_arg_t, _Alloc, ranges::iterator_t<_R> __i, ranges::sentinel_t<_R> __s) - -> generator<_Yielded, ranges::range_value_t<_R>, _Alloc> { + -> generator<_Yielded, void, _Alloc> { for (; __i != __s; ++__i) co_yield static_cast<_Yielded>(*__i); }; diff --git a/libstdc++-v3/testsuite/24_iterators/range_generators/lwg4119.cc b/libstdc++-v3/testsuite/24_iterators/range_generators/lwg4119.cc new file mode 100644 index 000000000000..383c9074345c --- /dev/null +++ b/libstdc++-v3/testsuite/24_iterators/range_generators/lwg4119.cc @@ -0,0 +1,14 @@ +// { dg-do compile { target c++23 } } + +#include <generator> +#include <vector> + +std::generator<std::span<int>> f() { + std::vector<int> v; + co_yield v; +} + +std::generator<std::span<int>> g() { + std::vector<std::vector<int>> v; + co_yield std::ranges::elements_of(v); +}
