Title
promise.unhandled_exception() and final suspend point
Status
c++23
Section
9.5.4 [dcl.fct.def.coroutine]
Submitter
Lewis Baker

Created on 2020-02-14.00:00:00 last changed 16 months ago

Messages

Date: 2022-11-10.22:02:22

Proposed resolution (approved by CWG 2022-11-10):

  1. 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 point await expression, or a final suspend point await expression (9.5.4 [dcl.fct.def.coroutine]). Otherwise

    • ...

  2. 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.

  3. 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 point await expression, and

    • the await-expression containing the call to final_suspend is the final suspend point await expression, and

    • initial-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 point await 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()

  4. 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.
Date: 2020-08-15.00:00:00

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.

Date: 2022-11-10.15:34:19

Suggested resolution [SUPERSEDED]:

  1. Change 9.5.4 [dcl.fct.def.coroutine] paragraph 5 as follows:

  2. ...where

    • the await-expression containing the call to initial_suspend is the initial suspend point await expression, and

    • the await-expression containing the call to final_suspend is the final suspend point await expression, and

    • initial-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 point await 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 a final suspend point if it is suspended

      • at a final await expression or

      • due to an exception exiting from unhandled_exception()

  3. Change bullet 3.2 of 7.6.2.4 [expr.await] as follows:

  4. 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 point await expression, or a final suspend point await expression (9.5.4 [dcl.fct.def.coroutine]). Otherwise

    • ...

  5. If needed, change 9.5.4 [dcl.fct.def.coroutine] paragraph 14 as follows:

  6. 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.
Date: 2022-11-15.00:00:00

[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.

History
Date User Action Args
2023-07-16 13:00:43adminsetstatus: open -> c++23
2023-07-16 13:00:43adminsetstatus: drwp -> open
2023-02-18 18:43:04adminsetstatus: dr -> drwp
2022-11-25 05:14:04adminsetstatus: ready -> dr
2022-11-10 22:02:22adminsetstatus: review -> ready
2022-11-10 22:02:22adminsetstatus: review -> review
2022-11-10 22:02:22adminsetstatus: review -> review
2022-11-10 22:02:22adminsetstatus: review -> review
2022-11-10 15:34:19adminsetstatus: ready -> review
2022-11-10 15:34:19adminsetstatus: ready -> ready
2022-11-10 15:34:19adminsetstatus: ready -> ready
2022-11-10 15:34:19adminsetmessages: + msg6997
2022-02-18 07:47:23adminsetmessages: + msg6719
2020-12-15 00:00:00adminsetmessages: + msg6224
2020-02-14 00:00:00admincreate