-
Notifications
You must be signed in to change notification settings - Fork 7
Description
Full name of submitter (unless configured in github; will be published with the issue): Jiang An
Reference (section label): [except.throw], [except.handle], [propagation]
Link to reflector thread (if any):
Issue description: CWG1863 clarified that the type of an exception object must be copyable. However, such restriction seems overly strict. Some (but not all) mainstream implementations (perhaps all implementations using Itanium C++ ABI) can correctly support move-only exception objects, given the operand of throw
-expression is an rvalue and the exception is caught by reference, because exception objects are allocated on the heap, and no exception_ptr
-related mechanism needs to copy exception objects. On the other hand, CWG1863 predated the acception of P0135R1 (guaranteed RVO since C++17), and the aforementioned implementations seem even support non-movable exception objects in C++17 and later modes.
This issue is related LWG3688. For implementations supporting move-only exception objects, std::bad_expection_access<MoveOnly>
can be thrown correctly, see gcc bug 105146.
I think move-only exception object type should be made conditionally-supported to legitimize such existing implementation strategy. The term "thrown object" may be wrong or denote different objects (see editiorial issue 5238), perhaps it should be reworded.
Suggested resolution:
Change [except.throw]/5 as indicated:
When the thrown object is a class object, the constructor selected for the copy-initialization as well as the constructor selected for a copy-initialization considering the thrown object as an lvalue shall be non-deleted and accessible, even if the copy/move operation is elided (11.9.6 [class.copy.elision]).The copy-initialization of the exception object from the operand of the throw-expression shall be well-formed in the context of the throw-expression.TWhen the operand is of a class type, the destructor is potentially invoked (11.4.7 [class.dtor]). If the copy-initialization of an object of the same type of the exception object from an lvalue of that type would be ill-formed in any context, the throw-expression is conditionally-supported.
Add a bullet after [except.handle]/3:
If the handler is of type
cv
T
, whereT
is an object type, the copy-initialization of an object of typeT
from an lvalue of typeT
shall be well-formed in every possible context.
Change [propagation]/8 as indicated:
... If it is possible to copy the exception object,
Iit is unspecified whether the return values of two successive calls tocurrent_exception
refer to the same exception object.
Change [propagation]/10 as indicated:
... If it is possible to copy the exception object,
Iit is unspecified whether a copy is made, and memory for the copy is allocated in an unspecified way. ...