Skip to content

Commit e9a00cf

Browse files
snarkmastermeta-codesync[bot]
authored andcommitted
Fix GCC -Werror=terminate in WithAsyncStack await_suspend
Summary: In D90950367, I added conditional `noexcept` to `await_suspend`. The function became `noexcept(true)` when the inner awaiter's `await_suspend` is noexcept. GCC warns that `throw;` in a `noexcept` function will always call `terminate` (`-Werror=terminate`). Unfortunately, GCC's warning analysis wasn't smart enough to realize that the `throw` is unreachable, so certain build configurations broke due to this warning. The workaround is to make the `try-catch` conditional on `noexcept`. This seems cleaner than just suppressing the warning. Reviewed By: ispeters Differential Revision: D91366908 fbshipit-source-id: cd59c77723f583d9716f3a8336b6f473c508a843
1 parent ea24fa5 commit e9a00cf

File tree

1 file changed

+19
-8
lines changed

1 file changed

+19
-8
lines changed

folly/coro/WithAsyncStack.h

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,10 @@ template <typename Awaitable>
116116
class WithAsyncStackAwaiter {
117117
using Awaiter = awaiter_type_t<Awaitable>;
118118

119+
static constexpr bool kSuspendIsNoexcept =
120+
noexcept(FOLLY_DECLVAL(Awaiter&).await_suspend(FOLLY_DECLVAL(
121+
coroutine_handle<WithAsyncStackCoroutine::promise_type>)));
122+
119123
public:
120124
explicit WithAsyncStackAwaiter(Awaitable&& awaitable)
121125
: awaiter_(get_awaiter(static_cast<Awaitable&&>(awaitable))),
@@ -130,8 +134,7 @@ class WithAsyncStackAwaiter {
130134
// tracing
131135
template <typename Promise>
132136
FOLLY_NOINLINE auto await_suspend(coroutine_handle<Promise> h) noexcept(
133-
noexcept(FOLLY_DECLVAL(Awaiter&).await_suspend(FOLLY_DECLVAL(
134-
coroutine_handle<WithAsyncStackCoroutine::promise_type>)))) {
137+
kSuspendIsNoexcept) {
135138
AsyncStackFrame& callerFrame = h.promise().getAsyncFrame();
136139
AsyncStackRoot* stackRoot = callerFrame.getStackRoot();
137140
assert(stackRoot != nullptr);
@@ -145,8 +148,7 @@ class WithAsyncStackAwaiter {
145148
using await_suspend_result_t =
146149
decltype(awaiter_.await_suspend(wrapperHandle));
147150

148-
// Restore async stack state on exception, then rethrow.
149-
try {
151+
auto doSuspend = [&]() {
150152
if constexpr (std::is_same_v<await_suspend_result_t, bool>) {
151153
if (!awaiter_.await_suspend(wrapperHandle)) {
152154
folly::activateAsyncStackFrame(*stackRoot, callerFrame);
@@ -157,10 +159,19 @@ class WithAsyncStackAwaiter {
157159
} else {
158160
return awaiter_.await_suspend(wrapperHandle);
159161
}
160-
} catch (...) {
161-
folly::activateAsyncStackFrame(*stackRoot, callerFrame);
162-
folly::deactivateSuspendedLeaf(coroWrapper_.getLeafFrame());
163-
throw;
162+
};
163+
164+
if constexpr (kSuspendIsNoexcept) {
165+
return doSuspend();
166+
} else {
167+
// Restore async stack state on exception, then rethrow.
168+
try {
169+
return doSuspend();
170+
} catch (...) {
171+
folly::activateAsyncStackFrame(*stackRoot, callerFrame);
172+
folly::deactivateSuspendedLeaf(coroWrapper_.getLeafFrame());
173+
throw;
174+
}
164175
}
165176
}
166177

0 commit comments

Comments
 (0)