This is an unofficial snapshot of the ISO/IEC JTC1 SC22 WG21 Core Issues List revision 115d. See http://www.open-std.org/jtc1/sc22/wg21/ for the official list.
2024-10-26
[Accepted as a DR at the November, 2022 meeting.]
According to 9.5.4 [dcl.fct.def.coroutine] paragraph 14,
If the evaluation of the expression promise.unhandled_exception() exits via an exception, the coroutine is considered suspended at the final suspend point.
However, the “final suspend point” is defined as being “the await-expression containing the call to final_suspend” (bullet 5.2), and it is not desired to evaluate the final_suspend expression in this case.
Suggested resolution [SUPERSEDED]:
Change 9.5.4 [dcl.fct.def.coroutine] paragraph 5 as follows:
...where
the await-expression containing the call to initial_suspend is the initial
suspend pointawait expression, andthe await-expression containing the call to final_suspend is the final
suspend pointawait expression, andinitial-await-resume-called is initially false and is set to true immediately before the evaluation of the await-resume expression (7.6.2.4 [expr.await]) of the initial
suspend pointawait expression, and...
promise-constructor-arguments is determined as follows: overload resolution is performed on a promise constructor call created by assembling an argument list with lvalues p1 ... pn. If a viable constructor is found (12.2.3 [over.match.viable]), then promise-constructor-arguments is (p1, ..., pn), otherwise promise-constructor-arguments is empty
., andA coroutine is suspended at a final suspend point if it is suspended
at a final await expression or
due to an exception exiting from unhandled_exception()
Change bullet 3.2 of 7.6.2.4 [expr.await] as follows:
Evaluation of an await-expression involves the following auxiliary types, expressions, and objects:
...
a is the cast-expression if the await-expression was implicitly produced by a yield-expression (7.6.17 [expr.yield]), an initial
suspend pointawait expression, or a finalsuspend pointawait expression (9.5.4 [dcl.fct.def.coroutine]). Otherwise...
If needed, change 9.5.4 [dcl.fct.def.coroutine] paragraph 14 as follows:
If the evaluation of the expression promise.unhandled_exception() exits via an exception, the coroutine is considered suspended at the final suspend point and the exception propagates to the caller or resumer.
Notes from the August, 2020 teleconference [SUPERSEDED]:
CWG expressed some concern about the lack of a precise definition of “suspend point”. Gor Nishanov suggests the following change, in 7.6.2.4 [expr.await] bullet 5.1:
If the evaluation of await-suspend exits via an exception, the exception is caught, the coroutine is resumed, and the exception is immediately re-thrown (14.2 [except.throw]). Otherwise, control flow returns to the current coroutine caller or resumer (9.5.4 [dcl.fct.def.coroutine]) without exiting any scopes (8.7 [stmt.jump]). The point in the coroutine immediately prior to control returning to its caller or resumer is a coroutine suspend point.
Proposed resolution (approved by CWG 2022-11-10):
Change in 7.6.2.4 [expr.await] bullet 3.2 as follows:
Evaluation of an await-expression involves the following auxiliary types, expressions, and objects:
...
a is the cast-expression if the await-expression was implicitly produced by a yield-expression (7.6.17 [expr.yield]), an initial
suspend pointawait expression, or a finalsuspend pointawait expression (9.5.4 [dcl.fct.def.coroutine]). Otherwise...
Change in 7.6.2.4 [expr.await] bullet 5.1 as follows:
If the evaluation of await-suspend exits via an exception, the exception is caught, the coroutine is resumed, and the exception is immediately re-thrown (14.2 [except.throw]). Otherwise, control flow returns to the current coroutine caller or resumer (9.5.4 [dcl.fct.def.coroutine]) without exiting any scopes (8.7 [stmt.jump]). The point in the coroutine immediately prior to control returning to its caller or resumer is a coroutine suspend point.
Change in 9.5.4 [dcl.fct.def.coroutine] paragraph 5 as follows:
...where
the await-expression containing the call to initial_suspend is the initial
suspend pointawait expression, andthe await-expression containing the call to final_suspend is the final
suspend pointawait expression, andinitial-await-resume-called is initially false and is set to true immediately before the evaluation of the await-resume expression (7.6.2.4 [expr.await]) of the initial
suspend pointawait expression, and...
promise-constructor-arguments is determined as follows: overload resolution is performed on a promise constructor call created by assembling an argument list with lvalues p1 ... pn. If a viable constructor is found (12.2.3 [over.match.viable]), then promise-constructor-arguments is (p1, ..., pn), otherwise promise-constructor-arguments is empty
., and- a coroutine is suspended at the initial suspend point if it is suspended at the initial await expression, and
a coroutine is suspended at a final suspend point if it is suspended
at a final await expression or
due to an exception exiting from unhandled_exception()
Change 9.5.4 [dcl.fct.def.coroutine] paragraph 14 as follows:
If the evaluation of the expression promise.unhandled_exception() exits via an exception, the coroutine is considered suspended at the final suspend point and the exception propagates to the caller or resumer.