Skip to content

Commit 19d4204

Browse files
committed
make the try/catch portability macros safer
1 parent f8131ab commit 19d4204

10 files changed

Lines changed: 40 additions & 20 deletions

File tree

.clang-format

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ EmptyLineBeforeAccessModifier: Leave
7272
ExperimentalAutoDetectBinPacking: true
7373
FixNamespaceComments: true
7474
IfMacros: [
75-
STDEXEC_CATCH'
75+
'STDEXEC_CATCH'
7676
]
7777
IncludeBlocks: Preserve
7878
IndentAccessModifiers: false
@@ -88,6 +88,7 @@ KeepEmptyLinesAtTheStartOfBlocks: true
8888
LambdaBodyIndentation: Signature
8989
LineEnding: LF
9090
Macros: [
91+
'STDEXEC_CATCH_FALLTHROUGH= ',
9192
'STDEXEC_MEMFN_DECL(...)=__VA_ARGS__',
9293
'STDEXEC_ATTRIBUTE(...)=__attribute__((__VA_ARGS__))',
9394
'STDEXEC_IMMOVABLE_NO_UNIQUE_ADDRESS=[[no_unique_address]]',

.clangd

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ CompileFlags:
5353
- "-ftemplate-backtrace-limit=0"
5454
- "-std=gnu++20"
5555
- "-DSTDEXEC_CLANGD_INVOKED"
56+
- "-stdlib=libc++"
5657
Remove:
5758
- "-stdpar*"
5859
# strip CUDA fatbin args

examples/hello_coro.cpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,11 @@ auto main() -> int {
4646
auto [i] = stdexec::sync_wait(async_answer2(just(42), just())).value();
4747
std::cout << "The answer is " << i.value() << '\n';
4848
}
49-
STDEXEC_CATCH(const std::exception& e) {
50-
std::cout << e.what() << '\n';
49+
STDEXEC_CATCH(std::exception& e) {
50+
std::cerr << "error: " << e.what() << '\n';
51+
}
52+
STDEXEC_CATCH_ALL {
53+
std::cerr << "unknown error\n";
5154
}
5255
}
5356
#else

include/exec/__detail/__system_context_default_impl.hpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -249,7 +249,7 @@ namespace exec::__system_context_default_impl {
249249
__schedule_operation_t::__construct_maybe_alloc(__storage, &__r, std::move(__sndr));
250250
__os->start();
251251
}
252-
STDEXEC_CATCH(std::exception & __e) {
252+
STDEXEC_CATCH_ALL {
253253
__r.set_error(std::current_exception());
254254
}
255255
}
@@ -278,7 +278,7 @@ namespace exec::__system_context_default_impl {
278278
__storage, &__r, std::move(__sndr));
279279
__os->start();
280280
}
281-
STDEXEC_CATCH(std::exception & __e) {
281+
STDEXEC_CATCH_ALL {
282282
__r.set_error(std::current_exception());
283283
}
284284
}
@@ -297,7 +297,7 @@ namespace exec::__system_context_default_impl {
297297
__storage, &__r, std::move(__sndr));
298298
__os->start();
299299
}
300-
STDEXEC_CATCH(std::exception & __e) {
300+
STDEXEC_CATCH_ALL {
301301
__r.set_error(std::current_exception());
302302
}
303303
}

include/stdexec/__detail/__config.hpp

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -540,6 +540,8 @@ namespace stdexec {
540540
# include <cuda_runtime_api.h>
541541
#endif
542542

543+
// clang-format off
544+
543545
// The following macros are used to conditionally compile exception handling code. They
544546
// are used in the same way as `try` and `catch`, but they allow for different behavior
545547
// based on whether exceptions are enabled or not, and whether the code is being compiled
@@ -559,28 +561,28 @@ namespace stdexec {
559561
// printf("unknown error\n");
560562
// }
561563
#if STDEXEC_STD_NO_EXCEPTIONS()
562-
# define STDEXEC_TRY if constexpr (true)
563-
# define STDEXEC_CATCH(...) \
564-
else if constexpr ([[maybe_unused]] __VA_ARGS__ = ::stdexec::_catch_any_lvalue{}; false)
565-
# define STDEXEC_CATCH_ALL \
566-
else if constexpr (true) { \
567-
} \
568-
else
569-
# define STDEXEC_THROW(...) ::stdexec::__terminate()
564+
# define STDEXEC_TRY if constexpr (true) {
565+
# define STDEXEC_CATCH(...) } else if constexpr (__VA_ARGS__ = ::stdexec::__catch_any_lvalue; false) {
566+
# define STDEXEC_CATCH_ALL } else if constexpr (true) {} else
567+
# define STDEXEC_THROW(...) ::stdexec::__terminate()
568+
# define STDEXEC_CATCH_FALLTHROUGH } else {}
570569
#else
571-
# define STDEXEC_TRY try
572-
# define STDEXEC_CATCH catch
573-
# define STDEXEC_CATCH_ALL STDEXEC_CATCH(...)
574-
# define STDEXEC_THROW(...) throw __VA_ARGS__
570+
# define STDEXEC_TRY try
571+
# define STDEXEC_CATCH catch
572+
# define STDEXEC_CATCH_ALL catch(...)
573+
# define STDEXEC_THROW(...) throw __VA_ARGS__
574+
# define STDEXEC_CATCH_FALLTHROUGH
575575
#endif
576576

577+
// clang-format on
578+
577579
namespace stdexec {
578580
// Used by the STDEXEC_CATCH macro to provide a stub initialization of the exception object.
579-
struct _catch_any_lvalue {
581+
constexpr struct __catch_any_lvalue_t {
580582
template <class _Tp>
581583
STDEXEC_ATTRIBUTE(host, device)
582584
operator _Tp&() const noexcept;
583-
};
585+
} __catch_any_lvalue{};
584586

585587
STDEXEC_ATTRIBUTE(noreturn, host, device)
586588
inline void __terminate() noexcept {

test/exec/async_scope/test_spawn_future.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,9 @@ namespace {
165165
STDEXEC_CATCH(const std::logic_error& e) {
166166
SUCCEED("correct exception caught");
167167
}
168+
STDEXEC_CATCH_ALL {
169+
FAIL("invalid exception caught");
170+
}
168171
sync_wait(scope.on_empty());
169172
}
170173
#endif // !STDEXEC_STD_NO_EXCEPTIONS()

test/exec/test_libdispatch.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,5 +86,8 @@ namespace {
8686
STDEXEC_CATCH(int e) {
8787
CHECK(e == 999);
8888
}
89+
STDEXEC_CATCH_ALL {
90+
FAIL("invalid exception caught");
91+
}
8992
}
9093
} // namespace

test/rrd/async_scope.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,9 @@ struct async_scope_future_set_result : rl::test_suite<async_scope_future_set_res
7575
STDEXEC_CATCH(const std::logic_error&) {
7676
threw = true;
7777
}
78+
STDEXEC_CATCH_ALL {
79+
RL_ASSERT(false);
80+
}
7881
RL_ASSERT(threw);
7982
ex::sync_wait(scope.on_empty());
8083
}

test/stdexec/algos/adaptors/test_let_error.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,7 @@ namespace {
9595
STDEXEC_CATCH(const std::exception& e) {
9696
return ex::just(std::string{e.what()});
9797
}
98+
STDEXEC_CATCH_FALLTHROUGH
9899
});
99100
wait_for_value(std::move(snd), std::string{"error description"});
100101
(void) snd;

test/test_common/receivers.hpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -509,6 +509,9 @@ namespace {
509509
STDEXEC_CATCH(const std::exception& e) {
510510
FAIL("Exception thrown: " << e.what());
511511
}
512+
STDEXEC_CATCH_ALL {
513+
FAIL("Exception thrown");
514+
}
512515
}
513516
};
514517

0 commit comments

Comments
 (0)