Skip to content

Commit

Permalink
AK: Fix "assignment from temporary" check of Optional::operator=
Browse files Browse the repository at this point in the history
There was an existing check to ensure that `U` was an lvalue reference,
but when this check fails, overload resolution will just move right on
to the copy asignment operator, which will cause the temporary to be
assigned anyway.

Disallowing `Optional<T&>`s to be created from temporaries entirely
would be undesired, since existing code has valid reasons for creating
`Optional<T&>`s from temporaries, such as for function call arguments.

This fix explicitly deletes the `Optional::operator=(U&&)` operator,
so overload resolution stops.
  • Loading branch information
yyny committed Nov 24, 2024
1 parent 4913dac commit 850e53a
Showing 1 changed file with 9 additions and 3 deletions.
12 changes: 9 additions & 3 deletions AK/Optional.h
Original file line number Diff line number Diff line change
Expand Up @@ -446,16 +446,22 @@ requires(IsLvalueReference<T>) class [[nodiscard]] Optional<T> {
return *this;
}

// Note: Disallows assignment from a temporary as this does not do any lifetime extension.
template<typename U>
requires(!IsSame<OptionalNone, RemoveCVReference<U>>)
ALWAYS_INLINE Optional& operator=(U&& value)
requires(CanBePlacedInOptional<U> && IsLvalueReference<U>)
ALWAYS_INLINE Optional& operator=(U& value)
requires(CanBePlacedInOptional<U>)
{
m_pointer = &value;
return *this;
}

// Note: Disallows assignment from a temporary as this does not do any lifetime extension.
template<typename U>
requires(!IsSame<OptionalNone, RemoveCVReference<U>>)
ALWAYS_INLINE consteval Optional& operator=(RemoveReference<U> const&& value)
requires(CanBePlacedInOptional<U>)
= delete;

ALWAYS_INLINE void clear()
{
m_pointer = nullptr;
Expand Down

0 comments on commit 850e53a

Please sign in to comment.