Skip to content

Commit eb5557a

Browse files
committed
Fix CI
1 parent 9fc3169 commit eb5557a

File tree

2 files changed

+60
-20
lines changed

2 files changed

+60
-20
lines changed

clang/include/clang/Basic/AttrDocs.td

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -9312,12 +9312,12 @@ flow as):
93129312
}
93139313

93149314
The benefits of this attribute are:
9315-
- **Avoid heap allocations for coro frames**: Allocating short-circuiting
9316-
coros on the stack makes code more predictable under memory pressure.
9317-
Without this attribute, LLVM cannot elide heap allocation even when all
9318-
awaiters are short-circuiting.
9319-
- **Performance**: Significantly faster execution and smaller code size.
9320-
- **Build time**: Faster compilation due to less IR being generated.
9315+
- **Avoid heap allocations for coro frames**: Allocating short-circuiting
9316+
coros on the stack makes code more predictable under memory pressure.
9317+
Without this attribute, LLVM cannot elide heap allocation even when all
9318+
awaiters are short-circuiting.
9319+
- **Performance**: Significantly faster execution and smaller code size.
9320+
- **Build time**: Faster compilation due to less IR being generated.
93219321

93229322
Marking your ``await_suspend_destroy`` method as ``noexcept`` can sometimes
93239323
further improve optimization.
@@ -9343,16 +9343,16 @@ Here is a toy example of a portable short-circuiting awaiter:
93439343

93449344
If all suspension points use (i) trivial or (ii) short-circuiting awaiters,
93459345
then the coroutine optimizes more like a plain function, with 2 caveats:
9346-
- **Behavior:** The coroutine promise provides an implicit exception boundary
9347-
(as if wrapping the function in ``try {} catch { unhandled_exception(); }``).
9348-
This exception handling behavior is usually desirable in robust,
9349-
return-value-oriented programs that need short-circuiting coroutines.
9350-
Otherwise, the promise can always re-throw.
9351-
- **Speed:** As of 2025, there is still an optimization gap between a
9352-
realistic short-circuiting coro, and the equivalent (but much more verbose)
9353-
function. For a guesstimate, expect 4-5ns per call on x86. One idea for
9354-
improvement is to also elide trivial suspends like `std::suspend_never`, in
9355-
order to hit the `HasCoroSuspend` path in `CoroEarly.cpp`.
9346+
- **Behavior:** The coroutine promise provides an implicit exception boundary
9347+
(as if wrapping the function in ``try {} catch { unhandled_exception(); }``).
9348+
This exception handling behavior is usually desirable in robust,
9349+
return-value-oriented programs that need short-circuiting coroutines.
9350+
Otherwise, the promise can always re-throw.
9351+
- **Speed:** As of 2025, there is still an optimization gap between a
9352+
realistic short-circuiting coro, and the equivalent (but much more verbose)
9353+
function. For a guesstimate, expect 4-5ns per call on x86. One idea for
9354+
improvement is to also elide trivial suspends like `std::suspend_never`, in
9355+
order to hit the `HasCoroSuspend` path in `CoroEarly.cpp`.
93569356

93579357
}];
93589358
}

libcxx/test/std/language.support/support.coroutines/end.to.end/coro_await_suspend_destroy.pass.cpp

Lines changed: 44 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,14 @@
4040
#include <optional>
4141
#include <string>
4242

43+
#define DEBUG_LOG 0 // Logs break no-localization CI, set to 1 if needed
44+
45+
#ifndef TEST_HAS_NO_EXCEPTIONS
46+
# define THROW(_ex) throw _ex;
47+
#else
48+
# define THROW(_ex)
49+
#endif
50+
4351
struct my_err : std::exception {};
4452

4553
enum test_toggles {
@@ -110,7 +118,7 @@ struct optional_wrapper {
110118
operator std::optional<T>() {
111119
if (driver_.toggles(test_toggles::throw_in_convert_optional_wrapper)) {
112120
driver_.log(test_event::throw_convert_optional_wrapper);
113-
throw my_err();
121+
THROW(my_err());
114122
}
115123
driver_.log(test_event::convert_optional_wrapper);
116124
return std::move(storage_);
@@ -143,7 +151,7 @@ struct std::coroutine_traits<std::optional<T>, test_driver&, Args...> {
143151
driver_.log(test_event::return_value, value);
144152
if (driver_.toggles(test_toggles::throw_in_return_value)) {
145153
driver_.log(test_event::throw_return_value);
146-
throw my_err();
154+
THROW(my_err());
147155
}
148156
*storagePtr_ = std::move(value);
149157
}
@@ -169,7 +177,7 @@ struct base_optional_awaitable {
169177
T await_resume() {
170178
if (driver_.toggles(test_toggles::throw_in_await_resume)) {
171179
driver_.log(test_event::throw_await_resume, id_);
172-
throw my_err();
180+
THROW(my_err());
173181
}
174182
driver_.log(test_event::await_resume, id_);
175183
return std::move(opt_).value();
@@ -184,7 +192,7 @@ struct base_optional_awaitable {
184192
assert(promise.storagePtr_);
185193
if (driver_.toggles(test_toggles::throw_in_await_suspend_destroy)) {
186194
driver_.log(test_event::throw_await_suspend_destroy, id_);
187-
throw my_err();
195+
THROW(my_err());
188196
}
189197
driver_.log(test_event::await_suspend_destroy, id_);
190198
}
@@ -218,20 +226,29 @@ void check_coro_with_driver_for(auto coro_fn) {
218226
auto old_driver = driver;
219227
std::optional<T> old_res;
220228
bool old_threw = false;
229+
#ifndef TEST_HAS_NO_EXCEPTIONS
221230
try {
231+
#endif
222232
old_res = coro_fn.template operator()<old_optional_awaitable<T>, T>(old_driver);
233+
#ifndef TEST_HAS_NO_EXCEPTIONS
223234
} catch (const my_err&) {
224235
old_threw = true;
225236
}
237+
#endif
226238
auto new_driver = driver;
227239
std::optional<T> new_res;
228240
bool new_threw = false;
241+
#ifndef TEST_HAS_NO_EXCEPTIONS
229242
try {
243+
#endif
230244
new_res = coro_fn.template operator()<new_optional_awaitable<T>, T>(new_driver);
245+
#ifndef TEST_HAS_NO_EXCEPTIONS
231246
} catch (const my_err&) {
232247
new_threw = true;
233248
}
249+
#endif
234250

251+
#if DEBUG_LOG
235252
// Print toggle values for debugging
236253
std::string toggle_info = "Toggles: ";
237254
for (int i = 0; i <= test_toggles::largest; ++i) {
@@ -241,6 +258,7 @@ void check_coro_with_driver_for(auto coro_fn) {
241258
}
242259
toggle_info += "\n";
243260
std::cerr << toggle_info.c_str() << std::endl;
261+
#endif
244262

245263
assert(old_threw == new_threw);
246264
assert(old_res == new_res);
@@ -282,7 +300,9 @@ std::optional<T> coro_shortcircuits_to_empty(test_driver& driver) {
282300
}
283301

284302
void test_coro_shortcircuits_to_empty() {
303+
#if DEBUG_LOG
285304
std::cerr << "test_coro_shortcircuits_to_empty" << std::endl;
305+
#endif
286306
check_coro_with_driver([]<typename Awaitable, typename T>(test_driver& driver) {
287307
return coro_shortcircuits_to_empty<Awaitable, T>(driver);
288308
});
@@ -295,7 +315,9 @@ std::optional<T> coro_simple_await(test_driver& driver) {
295315
}
296316

297317
void test_coro_simple_await() {
318+
#if DEBUG_LOG
298319
std::cerr << "test_coro_simple_await" << std::endl;
320+
#endif
299321
check_coro_with_driver([]<typename Awaitable, typename T>(test_driver& driver) {
300322
return coro_simple_await<Awaitable, T>(driver);
301323
});
@@ -306,37 +328,49 @@ void test_coro_simple_await() {
306328

307329
template <typename Awaitable, typename T>
308330
std::optional<T> coro_catching_shortcircuits_to_empty(test_driver& driver) {
331+
#ifndef TEST_HAS_NO_EXCEPTIONS
309332
try {
333+
#endif
310334
T n = co_await Awaitable{driver, 1, std::optional<T>{11}};
311335
co_await Awaitable{driver, 2, std::optional<T>{}}; // return early!
312336
co_return n + co_await Awaitable{driver, 3, std::optional<T>{22}};
337+
#ifndef TEST_HAS_NO_EXCEPTIONS
313338
} catch (...) {
314339
driver.log(test_event::coro_catch);
315340
throw;
316341
}
342+
#endif
317343
}
318344

319345
void test_coro_catching_shortcircuits_to_empty() {
346+
#if DEBUG_LOG
320347
std::cerr << "test_coro_catching_shortcircuits_to_empty" << std::endl;
348+
#endif
321349
check_coro_with_driver([]<typename Awaitable, typename T>(test_driver& driver) {
322350
return coro_catching_shortcircuits_to_empty<Awaitable, T>(driver);
323351
});
324352
}
325353

326354
template <typename Awaitable, typename T>
327355
std::optional<T> coro_catching_simple_await(test_driver& driver) {
356+
#ifndef TEST_HAS_NO_EXCEPTIONS
328357
try {
358+
#endif
329359
co_return co_await Awaitable{driver, 1, std::optional<T>{11}} +
330360
co_await Awaitable{
331361
driver, 2, driver.toggles(dynamic_short_circuit) ? std::optional<T>{} : std::optional<T>{22}};
362+
#ifndef TEST_HAS_NO_EXCEPTIONS
332363
} catch (...) {
333364
driver.log(test_event::coro_catch);
334365
throw;
335366
}
367+
#endif
336368
}
337369

338370
void test_coro_catching_simple_await() {
371+
#if DEBUG_LOG
339372
std::cerr << "test_coro_catching_simple_await" << std::endl;
373+
#endif
340374
check_coro_with_driver([]<typename Awaitable, typename T>(test_driver& driver) {
341375
return coro_catching_simple_await<Awaitable, T>(driver);
342376
});
@@ -354,7 +388,9 @@ std::optional<T> noneliding_coro_shortcircuits_to_empty(test_driver& driver) {
354388
}
355389

356390
void test_noneliding_coro_shortcircuits_to_empty() {
391+
#if DEBUG_LOG
357392
std::cerr << "test_noneliding_coro_shortcircuits_to_empty" << std::endl;
393+
#endif
358394
check_coro_with_driver([]<typename Awaitable, typename T>(test_driver& driver) {
359395
return noneliding_coro_shortcircuits_to_empty<Awaitable, T>(driver);
360396
});
@@ -368,7 +404,9 @@ std::optional<T> noneliding_coro_simple_await(test_driver& driver) {
368404
}
369405

370406
void test_noneliding_coro_simple_await() {
407+
#if DEBUG_LOG
371408
std::cerr << "test_noneliding_coro_simple_await" << std::endl;
409+
#endif
372410
check_coro_with_driver([]<typename Awaitable, typename T>(test_driver& driver) {
373411
return noneliding_coro_simple_await<Awaitable, T>(driver);
374412
});
@@ -391,7 +429,9 @@ std::optional<T> outer_coro(test_driver& driver) {
391429
}
392430

393431
void test_nested_coroutines() {
432+
#if DEBUG_LOG
394433
std::cerr << "test_nested_coroutines" << std::endl;
434+
#endif
395435
check_coro_with_driver([]<typename Awaitable, typename T>(test_driver& driver) {
396436
return outer_coro<Awaitable, T>(driver);
397437
});

0 commit comments

Comments
 (0)