Skip to content

potential dangling reference returned from transform_sender #343

@ericniebler

Description

@ericniebler

quoting from an email i received from Trevor Gray:

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...);

dom is the default_domain
sndr is starts_on

Execution flow:

  • dom.transform_sender(std::forward<Sndr>(sndr), env...) uses default_domain to invoke start_on's transform_sender. The return type is T (where T is a let_value sender)
  • transform_sender(dom, declval<T>(), env...) is then run which uses default_domain to just return std::forward<T>(t).

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

Discussion

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

Change [exec.domain.default]/p2 should be changed from:

  1. Let e be the expression tag_of_t<Sndr>().transform_sender(std::forward<Sndr>(sndr), env...)
    if that expression is well-formed; otherwise, std​::​forward<Sndr>(sndr).

to:

  1. 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)).

Metadata

Metadata

Assignees

No one assigned

    Labels

    P0bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions