Title
Strike out purposeless UB involving the deleter in members functions of unique_ptr
Status
nad
Section
[unique.ptr.single.general]
Submitter
Johel Ernesto Guerrero Peña

Created on 2021-09-07.00:00:00 last changed 30 months ago

Messages

Date: 2021-09-20.11:18:00

Proposed resolution:

This wording is relative to N4892.

  1. Modify [unique.ptr.single.ctor] as indicated:

    constexpr unique_ptr() noexcept;
    constexpr unique_ptr(nullptr_t) noexcept;
    

    -1- […]

    -2- Preconditions: D meets the Cpp17DefaultConstructible requirements (Table 27), and that construction does not throw an exception.

    […]

    explicit unique_ptr(pointer p) noexcept;
    

    -5- Constraints: […]

    -6- Mandates: […]

    -7- Preconditions: D meets the Cpp17DefaultConstructible requirements (Table 27), and that construction does not throw an exception.

    […]

    unique_ptr(pointer p, const D& d) noexcept;
    unique_ptr(pointer p, remove_reference_t<D>&& d) noexcept;
    

    -10- Constraints: […]

    -11- Mandates: […]

    -12- Preconditions: For the first constructor, if D is not a reference type, D meets the Cpp17CopyConstructible requirements and such construction does not exit via an exception. For the second constructor, if D is not a reference type, D meets the Cpp17MoveConstructible requirements and such construction does not exit via an exception.

    […]

    unique_ptr(unique_ptr&& u) noexcept;
    

    -17- Constraints: […]

    -18- Preconditions: If D is not a reference type, D meets the Cpp17MoveConstructible requirements (Table 28). Construction of the deleter from an rvalue of type D does not throw an exception.

    […]

    template<class U, class E> unique_ptr(unique_ptr<U, E>&& u) noexcept;
    

    -21- Constraints: […]

    -22- Preconditions: If E is not a reference type, construction of the deleter from an rvalue of type E is well-formed and does not throw an exception. Otherwise, E is a reference type and construction of the deleter from an lvalue of type E is well-formed and does not throw an exception.

    […]

  2. Modify [unique.ptr.single.dtor] as indicated:

    ~unique_ptr();
    

    -1- Preconditions: The expression get_deleter()(get()) is well-formed, and has well-defined behavior, and does not throw exceptions.

    […]

  3. Modify [unique.ptr.single.asgn] as indicated:

    unique_ptr& operator=(unique_ptr&& u) noexcept;
    

    -1- Constraints: […]

    -2- Preconditions: If D is not a reference type, D meets the Cpp17MoveAssignable requirements (Table 30) and assignment of the deleter from an rvalue of type D does not throw an exception. Otherwise, D is a reference type; remove_reference_t<D> meets the Cpp17CopyAssignable requirements and assignment of the deleter from an lvalue of type D does not throw an exception.

    […]

    template<class U, class E> unique_ptr& operator=(unique_ptr<U, E>&& u) noexcept;
    

    -6- Constraints: […]

    -7- Preconditions: If E is not a reference type, assignment of the deleter from an rvalue of type E is well-formed and does not throw an exception. Otherwise, E is a reference type and assignment of the deleter from an lvalue of type E is well-formed and does not throw an exception.

    […]

  4. Modify [unique.ptr.single.modifiers] as indicated:

    void reset(pointer p = pointer()) noexcept;
    

    -3- Preconditions: The expression get_deleter()(get()) is well-formed, and has well-defined behavior, and does not throw exceptions.

    […]

    void swap(unique_ptr& u) noexcept;
    

    -6- Preconditions: get_deleter() is swappable ([swappable.requirements]) and does not throw an exception under swap.

    […]

Date: 2021-09-20.00:00:00

[ 2021-09-20 Status changed: New → NAD. ]

The current specification allows the compiler to omit noexcept-enforcement.

Date: 2021-09-07.00:00:00

This originated from the editorial issues #4871 and #4872.

Several member functions of unique_ptr are noexcept, and yet, they have the precondition that an expression involving the deleter does not exit via an exception. There's nothing an implementation or user can take advantage of in presence of this UB. Since the behavior otherwise would be a call to std::terminate, these preconditions should be striked out.

Note that although ~unique_ptr() is not noexcept, [res.on.exception.handling] p3 specifies it to behave as if it were.

History
Date User Action Args
2021-09-20 11:18:00adminsetmessages: + msg12046
2021-09-20 11:18:00adminsetstatus: new -> nad
2021-09-11 13:30:19adminsetmessages: + msg12030
2021-09-07 00:00:00admincreate