Skip to content

Commit

Permalink
<optional>: Fix exception specification for optional's transform-…
Browse files Browse the repository at this point in the history
…construction (#3668)

Co-authored-by: S. B. Tam <cpplearner@outlook.com>
Co-authored-by: Stephan T. Lavavej <stl@nuwen.net>
  • Loading branch information
3 people authored Apr 28, 2023
1 parent 3e75f32 commit c5a5efa
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 3 deletions.
6 changes: 3 additions & 3 deletions stl/inc/optional
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ struct _Optional_destruct_base { // either contains a value of _Ty or is empty (
#if _HAS_CXX23
template <class _Fn, class _Ux>
constexpr _Optional_destruct_base(_Construct_from_invoke_result_tag, _Fn&& _Func, _Ux&& _Arg) noexcept(
is_nothrow_constructible_v<_Ty, invoke_result_t<_Fn, _Ux>>)
noexcept(static_cast<_Ty>(_STD invoke(_STD forward<_Fn>(_Func), _STD forward<_Ux>(_Arg)))))
: _Value(_STD invoke(_STD forward<_Fn>(_Func), _STD forward<_Ux>(_Arg))), _Has_value{true} {}
#endif // _HAS_CXX23

Expand Down Expand Up @@ -118,7 +118,7 @@ struct _Optional_destruct_base<_Ty, false> { // either contains a value of _Ty o
#if _HAS_CXX23
template <class _Fn, class _Ux>
constexpr _Optional_destruct_base(_Construct_from_invoke_result_tag, _Fn&& _Func, _Ux&& _Arg) noexcept(
is_nothrow_constructible_v<_Ty, invoke_result_t<_Fn, _Ux>>)
noexcept(static_cast<_Ty>(_STD invoke(_STD forward<_Fn>(_Func), _STD forward<_Ux>(_Arg)))))
: _Value(_STD invoke(_STD forward<_Fn>(_Func), _STD forward<_Ux>(_Arg))), _Has_value{true} {}
#endif // _HAS_CXX23

Expand Down Expand Up @@ -277,7 +277,7 @@ public:
#if _HAS_CXX23
template <class _Fn, class _Ux>
constexpr optional(_Construct_from_invoke_result_tag _Tag, _Fn&& _Func, _Ux&& _Arg) noexcept(
is_nothrow_constructible_v<_Ty, invoke_result_t<_Fn, _Ux>>)
noexcept(static_cast<_Ty>(_STD invoke(_STD forward<_Fn>(_Func), _STD forward<_Ux>(_Arg)))))
: _Mybase(_Tag, _STD forward<_Fn>(_Func), _STD forward<_Ux>(_Arg)) {}
#endif // _HAS_CXX23

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception

#include <cassert>
#include <exception>
#include <optional>
#include <string>
#include <type_traits>
#include <utility>

Expand Down Expand Up @@ -109,7 +111,26 @@ constexpr bool test() {
return true;
}

template <class T>
void test_gh_3667() {
// GH-3667 <optional>: Throwing transformers will cause the program to terminate
class unique_exception : public exception {};

try {
optional<T> opt(in_place);
opt.transform([](const T&) -> T { throw unique_exception{}; });
} catch (const unique_exception&) {
return;
} catch (...) {
assert(false); // shouldn't terminate or reach here
}
assert(false); // shouldn't terminate or reach here
}

int main() {
test();
static_assert(test());

test_gh_3667<int>(); // trivial destructor
test_gh_3667<string>(); // non-trivial destructor
}

0 comments on commit c5a5efa

Please sign in to comment.