Proposed resolution:
This wording is relative to N4529.
Change [memory.smartptr.shared.const] as indicated:
template<class Y> explicit shared_ptr(Y* p);[…]
-3- Effects: When T is not an array type, constructs a shared_ptr object that owns the pointer p. Otherwise, constructs a shared_ptr that owns p and a deleter of an unspecified type that calls delete[] p. If an exception is thrown, delete p is called when T is not an array type, delete[] p otherwise.
[…]
-6- Exception safety: If an exception is thrown, delete p is called when T is not an array type, delete[] p otherwise.template<class Y, class D> shared_ptr(Y* p, D d); template<class Y, class D, class A> shared_ptr(Y* p, D d, A a); template <class D> shared_ptr(nullptr_t p, D d); template <class D, class A> shared_ptr(nullptr_t p, D d, A a);[…]
-9- Effects: Constructs a shared_ptr object that owns the object p and the deleter d. The second and fourth constructors shall use a copy of a to allocate memory for internal use. If an exception is thrown, d(p) is called.
[…]
-12- Exception safety: If an exception is thrown, d(p) is called.[…]
template<class Y> explicit shared_ptr(const weak_ptr<Y>& r);[…]
-28- Effects: Constructs a shared_ptr object that shares ownership with r and stores a copy of the pointer stored in r. If an exception is thrown, the constructor has no effect.
[…]
-31- Exception safety: If an exception is thrown, the constructor has no effect.template <class Y, class D> shared_ptr(unique_ptr<Y, D>&& r);[…]
-34- Effects: Equivalent to shared_ptr(r.release(), r.get_deleter()) when D is not a reference type, otherwise shared_ptr(r.release(), ref(r.get_deleter())). If an exception is thrown, the constructor has no effect.
-35- Exception safety: If an exception is thrown, the constructor has no effect.