The third issue we're having is with our aligned_storage. Its address() member function doesn't return the address of the unsigned char[] array, but the address of the aligned_storage object itself (or rather, to its aligned_storage_impl base, which contains the char array as its first member. Inside a union.)
This means that we aren't in the clear with respect to the "provides storage" wording in https://eel.is/c++draft/basic.memobj#intro.object-3. I'm not entirely sure that what we're doing is undefined, but it looks like we can avoid this issue by just returning the address of the char array in address().
Note that this potential source of UB can't be fixed with launder.
Actually, Boost.Optional uses its own aligned_storage: https://github.com/boostorg/optional/blob/develop/include/boost/optional/det... which does return the address of the char[] buffer, but only if the compiler doesn't have the may_alias attribute, in which case the address of the union is returned, but the union is marked with may_alias. What effect this has is anyone's guess. I suppose it's effectively equivalent to laundering the address each time, but as the attribute is nonstandard, there's no way to know.