Skip to content

Commit

Permalink
Keep operator= on FnRefs
Browse files Browse the repository at this point in the history
The assignment is fine if it's from an already created FnRef that
is coming in from a higher stack frame. It's the construction of
a FnRef outside of a function parameter (ie. not on a stack frame
boundary to keep any temporary alive) that is the problem.
  • Loading branch information
danakj committed Sep 8, 2023
1 parent 9f3c947 commit a3465c2
Show file tree
Hide file tree
Showing 2 changed files with 13 additions and 10 deletions.
21 changes: 12 additions & 9 deletions sus/fn/fn_ref.h
Original file line number Diff line number Diff line change
Expand Up @@ -96,9 +96,10 @@ class [[sus_trivial_abi]] FnRef<R(CallArgs...)> {
::sus::check(invoke_); // Catch use-after-move.
}
constexpr FnRef& operator=(FnRef&& o) noexcept {
// Assigning to an lvalue from a lambda would cause the lambda to be dropped
// but the FnRef would still hold a reference to it.
sus::unreachable();
storage_ = o.storage_;
invoke_ = ::sus::mem::replace(o.invoke_, nullptr);
::sus::check(invoke_); // Catch use-after-move.
return *this;
}

// Not copyable.
Expand Down Expand Up @@ -248,9 +249,10 @@ class [[sus_trivial_abi]] FnMutRef<R(CallArgs...)> {
::sus::check(invoke_); // Catch use-after-move.
}
constexpr FnMutRef& operator=(FnMutRef&& o) noexcept {
// Assigning to an lvalue from a lambda would cause the lambda to be dropped
// but the FnMutRef would still hold a reference to it.
sus::unreachable();
storage_ = o.storage_;
invoke_ = ::sus::mem::replace(o.invoke_, nullptr);
::sus::check(invoke_); // Catch use-after-move.
return *this;
}

// Not copyable.
Expand Down Expand Up @@ -409,9 +411,10 @@ class [[sus_trivial_abi]] FnOnceRef<R(CallArgs...)> {
::sus::check(invoke_); // Catch use-after-move.
}
constexpr FnOnceRef& operator=(FnOnceRef&& o) noexcept {
// Assigning to an lvalue from a lambda would cause the lambda to be dropped
// but the FnOnceRef would still hold a reference to it.
sus::unreachable();
storage_ = o.storage_;
invoke_ = ::sus::mem::replace(o.invoke_, nullptr);
::sus::check(invoke_); // Catch use-after-move.
return *this;
}

// Not copyable.
Expand Down
2 changes: 1 addition & 1 deletion tools/run_subdoc.sh
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,4 @@ out/subdoc/subdoc -p out --out docs \
--project-logo logo.png \
--project-name Subspace \
--ignore-bad-code-links \
i32_unittest compat_range boxed choice_unit
i8_unittest

0 comments on commit a3465c2

Please sign in to comment.