On Wed, 22 Sept 2021 at 20:49, Antony Polukhin <antosh...@gmail.com> wrote: > > ср, 22 сент. 2021 г. в 20:23, Ville Voutilainen <ville.voutilai...@gmail.com>: > > > > On Wed, 22 Sept 2021 at 20:09, Antony Polukhin via Libstdc++ > > <libstd...@gcc.gnu.org> wrote: > > > > > > std::unique_ptr allows construction from std::unique_ptr of derived > > > type as per [unique.ptr.single.asgn] and [unique.ptr.single.ctor]. If > > > std::default_delete is used with std::unique_ptr, then after such > > > construction a delete is called on a pointer to base. According to > > > [expr.delete] calling a delete on a non similar object without a > > > virtual destructor is an undefined behavior. > > > > > > This patch turns that undefined behavior into static assertions inside > > > std::unique_ptr. > > > > I don't understand the sizeof(_Tp) == sizeof(_Up) part in the > > static_assert. I fail to see how > > a same-size check suggests that the types are similar enough that a > > delete-expression works. > > I used the following logic: > [unique.ptr.single.*] sections have the constraint that > "unique_ptr<U, E>::pointer is implicitly convertible to pointer". > There's already a static assert that T in unique_ptr<T> is not void, > so U either has to be the same type T, or a type derived from T. If a > derived type adds members, then size changes and types are not similar > as the decompositions won't have the qualification-decompositions with > the same n.
Right, but the delete-expression on a non-polymorphic type where the static type and the dynamic type are different is UB regardless of whether the derived type adds members.