Skip to content

Commit 8c9bfeb

Browse files
committed
try to work around mysterious codegen issue in apple-clang
1 parent d44ca19 commit 8c9bfeb

3 files changed

Lines changed: 45 additions & 32 deletions

File tree

include/nvexec/stream/start_detached.cuh

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -121,14 +121,20 @@ namespace nvexec::_strm {
121121
void operator()(Sender&& sndr, Env&& env = {}) const noexcept(false) {
122122
using Op = _start_detached::operation<__cvref_id<Sender>, __id<__decay_t<Env>>>;
123123

124-
// NON-STANDARD
124+
#if !STDEXEC_APPLE_CLANG() // There seems to be a codegen bug in apple clang that causes
125+
// `start_detached` to segfault when the code path below is
126+
// taken.
127+
// BUGBUG NOT TO SPEC: the use of the non-standard `submit` algorithm here is a
128+
// conforming extension.
125129
if constexpr (
126130
__same_as<Env, __root_env>
127131
&& __same_as<void, submit_result_t<Sender, _start_detached::submit_receiver>>) {
128132
// If submit(sndr, rcvr) returns void, then no state needs to be kept alive
129133
// for the operation. We can just call submit and return.
130134
stdexec::submit(static_cast<Sender&&>(sndr), _start_detached::submit_receiver{});
131-
} else if constexpr (__callable<get_allocator_t, Env>) {
135+
} else
136+
#endif
137+
if constexpr (__callable<get_allocator_t, Env>) {
132138
// Use the provided allocator to allocate the operation state.
133139
auto alloc = get_allocator(env);
134140
using Alloc = decltype(alloc);

include/stdexec/__detail/__start_detached.hpp

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -145,14 +145,20 @@ namespace stdexec {
145145
void apply_sender(_Sender&& __sndr, _Env&& __env = {}) const noexcept(false) {
146146
using _Op = __operation<__cvref_id<_Sender>, __id<__decay_t<_Env>>>;
147147

148-
// NON-STANDARD
148+
#if !STDEXEC_APPLE_CLANG() // There seems to be a codegen bug in apple clang that causes
149+
// `start_detached` to segfault when the code path below is
150+
// taken.
151+
// BUGBUG NOT TO SPEC: the use of the non-standard `submit` algorithm here is a
152+
// conforming extension.
149153
if constexpr (
150154
__same_as<_Env, __root_env>
151155
&& __same_as<void, submit_result_t<_Sender, __submit_receiver>>) {
152156
// If submit(sndr, rcvr) returns void, then no state needs to be kept alive
153157
// for the operation. We can just call submit and return.
154158
stdexec::submit(static_cast<_Sender&&>(__sndr), __submit_receiver{});
155-
} else if constexpr (__callable<get_allocator_t, _Env>) {
159+
} else
160+
#endif
161+
if constexpr (__callable<get_allocator_t, _Env>) {
156162
// Use the provided allocator if any to allocate the operation state.
157163
auto __alloc = get_allocator(__env);
158164
using _Alloc = decltype(__alloc);

include/stdexec/__detail/__submit.hpp

Lines changed: 29 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -70,35 +70,36 @@ namespace stdexec {
7070
static_cast<_Sender&&>(__sndr), static_cast<_Receiver&&>(__rcvr)};
7171
}
7272

73-
// // This implementation is used if the sender has a non-static submit member function.
74-
// template <class _Sender, class _Receiver, class _Default = __void>
75-
// requires sender_to<_Sender, _Receiver> && __submit::__has_memfn<_Sender, _Receiver>
76-
// auto operator()(_Sender&& __sndr, _Receiver __rcvr, [[maybe_unused]] _Default __def = {}) const
77-
// noexcept(noexcept(static_cast<_Sender&&>(__sndr).submit(static_cast<_Receiver&&>(__rcvr)))) {
78-
// using __result_t =
79-
// decltype(static_cast<_Sender&&>(__sndr).submit(static_cast<_Receiver&&>(__rcvr)));
80-
// if constexpr (__same_as<__result_t, void> && !__same_as<_Default, __void>) {
81-
// static_cast<_Sender&&>(__sndr).submit(static_cast<_Receiver&&>(__rcvr));
82-
// return __def;
83-
// } else {
84-
// return static_cast<_Sender&&>(__sndr).submit(static_cast<_Receiver&&>(__rcvr));
85-
// }
86-
// }
73+
// This implementation is used if the sender has a non-static submit member function.
74+
template <class _Sender, class _Receiver, class _Default = __void>
75+
requires sender_to<_Sender, _Receiver> && __submit::__has_memfn<_Sender, _Receiver>
76+
auto operator()(_Sender&& __sndr, _Receiver __rcvr, [[maybe_unused]] _Default __def = {}) const
77+
noexcept(noexcept(static_cast<_Sender&&>(__sndr).submit(static_cast<_Receiver&&>(__rcvr)))) {
78+
using __result_t =
79+
decltype(static_cast<_Sender&&>(__sndr).submit(static_cast<_Receiver&&>(__rcvr)));
80+
if constexpr (__same_as<__result_t, void> && !__same_as<_Default, __void>) {
81+
static_cast<_Sender&&>(__sndr).submit(static_cast<_Receiver&&>(__rcvr));
82+
return __def;
83+
} else {
84+
return static_cast<_Sender&&>(__sndr).submit(static_cast<_Receiver&&>(__rcvr));
85+
}
86+
}
8787

88-
// // This implementation is used if the sender has a static submit member function.
89-
// template <class _Sender, class _Receiver, class _Default = __void>
90-
// requires sender_to<_Sender, _Receiver> && __submit::__has_static_memfn<_Sender, _Receiver>
91-
// auto operator()(_Sender&& __sndr, _Receiver __rcvr, [[maybe_unused]] _Default __def = {}) const
92-
// noexcept(noexcept(__sndr.submit(static_cast<_Sender&&>(__sndr), static_cast<_Receiver&&>(__rcvr)))) {
93-
// using __result_t =
94-
// decltype(__sndr.submit(static_cast<_Sender&&>(__sndr), static_cast<_Receiver&&>(__rcvr)));
95-
// if constexpr (__same_as<__result_t, void> && !__same_as<_Default, __void>) {
96-
// __sndr.submit(static_cast<_Sender&&>(__sndr), static_cast<_Receiver&&>(__rcvr));
97-
// return __def;
98-
// } else {
99-
// return __sndr.submit(static_cast<_Sender&&>(__sndr), static_cast<_Receiver&&>(__rcvr));
100-
// }
101-
// }
88+
// This implementation is used if the sender has a static submit member function.
89+
template <class _Sender, class _Receiver, class _Default = __void>
90+
requires sender_to<_Sender, _Receiver> && __submit::__has_static_memfn<_Sender, _Receiver>
91+
auto operator()(_Sender&& __sndr, _Receiver __rcvr, [[maybe_unused]] _Default __def = {}) const
92+
noexcept(
93+
noexcept(__sndr.submit(static_cast<_Sender&&>(__sndr), static_cast<_Receiver&&>(__rcvr)))) {
94+
using __result_t =
95+
decltype(__sndr.submit(static_cast<_Sender&&>(__sndr), static_cast<_Receiver&&>(__rcvr)));
96+
if constexpr (__same_as<__result_t, void> && !__same_as<_Default, __void>) {
97+
__sndr.submit(static_cast<_Sender&&>(__sndr), static_cast<_Receiver&&>(__rcvr));
98+
return __def;
99+
} else {
100+
return __sndr.submit(static_cast<_Sender&&>(__sndr), static_cast<_Receiver&&>(__rcvr));
101+
}
102+
}
102103
};
103104

104105
inline constexpr __submit_t submit{};

0 commit comments

Comments
 (0)