[PATCH] libstdc++: avoid ill-formed nested generator

Jonathan Wakely jwakely@redhat.com
Fri Jun 5 10:18:32 GMT 2026


On Fri, 05 Jun 2026 at 01:03 +0800, Yuao Ma wrote:
>Hi!
>
>This patch resolves the LWG 4119 issue.
>Tested on x86_64-linux. OK for trunk?
>
>Thanks,
>Yuao

>From f87ecb025bef05c1c401c9c632dc43047ea05ae1 Mon Sep 17 00:00:00 2001
>From: Yuao Ma <c8ef@outlook.com>
>Date: Fri, 5 Jun 2026 00:52:56 +0800
>Subject: [PATCH] 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.
>---
> libstdc++-v3/include/std/generator                 |  6 +++++-
> .../24_iterators/range_generators/lwg4119.cc       | 14 ++++++++++++++
> 2 files changed, 19 insertions(+), 1 deletion(-)
> create mode 100644 libstdc++-v3/testsuite/24_iterators/range_generators/lwg4119.cc
>
>diff --git a/libstdc++-v3/include/std/generator b/libstdc++-v3/include/std/generator
>index 88651dd6f76..55a8ef9f629 100644
>--- a/libstdc++-v3/include/std/generator
>+++ b/libstdc++-v3/include/std/generator
>@@ -163,6 +163,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
> 	  noexcept
> 	{ return _Recursive_awaiter { std::move(__r.range) }; }
>
>+	// _GLIBCXX_RESOLVE_LIB_DEFECTS
>+	// 4119.
>+	// generator::promise_type::yield_value(ranges::elements_of<R, Alloc>)'s
>+	// nested generator may be ill-formed


I'd be tempted to abbreviate the issue title by removing "ranges::"

	// _GLIBCXX_RESOLVE_LIB_DEFECTS
	// 4119. generator::promise_type::yield_value(elements_of<R, Alloc>)'s
         // nested generator may be ill-formed

But it doesn't matter.

OK for trunk, thanks.

> 	template<ranges::input_range _R, typename _Alloc>
> 	requires convertible_to<ranges::range_reference_t<_R>, _Yielded>
> 	auto
>@@ -171,7 +175,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 00000000000..383c9074345
>--- /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);
>+}
>-- 
>2.53.0
>



More information about the Libstdc++ mailing list