This is an unofficial snapshot of the ISO/IEC JTC1 SC22 WG21 Core Issues List revision 113d. See http://www.open-std.org/jtc1/sc22/wg21/ for the official list.

2024-04-05


2486. Call to noexcept function via noexcept(false) pointer/lvalue

Section: 7.6.1.3  [expr.call]     Status: CD6     Submitter: Jiang An     Date: 2021-03-27

[Accepted as a DR at the October, 2021 meeting.]

According to 7.6.1.3 [expr.call] paragraph 6,

Calling a function through an expression whose function type is different from the function type of the called function's definition results in undefined behavior.

This restriction should exempt calling a noexcept function where the function type of the expression is identical except that it is noexcept(false).

In addition, 7.6.1.9 [expr.static.cast] paragraph 7 currently forbids static_cast from converting a function pointer or member function pointer from noexcept(false) to noexcept:

The inverse of any standard conversion sequence (7.3 [conv]) not containing an lvalue-to-rvalue (7.3.2 [conv.lval]), array-to-pointer (7.3.3 [conv.array]), function-to-pointer (7.3.4 [conv.func]), null pointer (7.3.12 [conv.ptr]), null member pointer (7.3.13 [conv.mem]), boolean (7.3.15 [conv.bool]), or function pointer (7.3.14 [conv.fctptr]) conversion, can be performed explicitly using static_cast.

This restriction should also be relaxed, allowing binding a constexpr reference to the result of the reversed conversion.

Notes from the August, 2021 teleconference:

CWG agreed that it should be permitted to call a noexcept function via an expression that is noexcept(false); since the implicit conversion is allowed, the failure to allow the call is clearly just an oversight. The question of whether to allow the static_cast in the inverse direction, as well as whether to allow calling a noexcept(false) function via a noexcept expression (which would result in undefined behavior only if the function actually threw an exception) was deemed to be a matter for EWG and was thus split off into issue 2500.

Proposed resolution (September, 2021):

Change 7.6.1.3 [expr.call] paragraph 6 as follows:

Calling a function through an expression whose function type E is different from the function type F of the called function's definition results in undefined behavior unless the type “pointer to F” can be converted to the type “pointer to E” via a function pointer conversion (7.3.14 [conv.fctptr]). [Note: The exception applies when the expression has the type of a potentially-throwing function, but the called function has a non-throwing exception specification, and the function types are otherwise the same. —end note]