This page is a snapshot from the LWG issues list, see the Library Active Issues List for more information and the meaning of New status.

4368. Potential dangling reference returned from transform_sender

Section: 33.9.5 [exec.domain.default] Status: New Submitter: Eric Niebler Opened: 2025-08-31 Last modified: 2025-09-15

Priority: Not Prioritized

View all other issues in [exec.domain.default].

View all issues with New status.

Discussion:

The following has been reported by Trevor Gray to me:

There is a potential stack-use-after-scope in execution::transform_sender with execution::default_domain::transform_sender.

I'll give an example of the problem using starts_on with the default_domain.

starts_on defines a transform_sender so execution::transform_sender will expand to:

return transform_sender(
    dom,
    dom.transform_sender(std::forward<Sndr>(sndr), env...),
    env...);

where dom is the default_domain and sndr is starts_on.

Execution flow:

This means the value returned from the entire expression is T&& which a reference to a temporary variable in the frame of transform_sender which is no longer valid after the return.

In the reference implementation, this scenario does not create a dangling reference because its implementation of default_domain::transform_sender does not conform to the spec. By default, it returns an rvalue sender as a prvalue instead of an xvalue as the spec requires.

The fix is for the spec to follow suit and return prvalues when an xvalue would otherwise be returned.

Proposed resolution:

This wording is relative to N5014.

  1. Modify 33.9.5 [exec.domain.default] as indicated:

    template<sender Sndr, queryable... Env>
      requires (sizeof...(Env) <= 1)
    constexpr sender decltype(auto) transform_sender(Sndr&& sndr, const Env&... env)
      noexcept(see below);
    

    -2- Let e be the expression

    tag_of_t<Sndr>().transform_sender(std::forward<Sndr>(sndr), env...)
    

    if that expression is well-formed; otherwise, static_cast<Sndr>(std::forward<Sndr>(sndr)).

    -3- Returns: e.

    -4- Remarks: The exception specification is equivalent to noexcept(e).