This patch addresses discussion in
https://bugs.llvm.org/show_bug.cgi?id=35978
and the email thread
https://lists.llvm.org/pipermail/llvm-commits/Week-of-Mon-20180122/519188.html
Compiling LLVM with either clang or gcc and a dependant project which
uses the opposite compiler results in an ABI incompatibility in Optional
due to the trivially copyable optimisation in the OptionalStorage type
being enabled when compiling with clang and disabled when GCC.
Additionally, this patch removes undefined behavior in the copy assignment
operator of OptionalStorage. When OptionalStorage does not hold a
valid object and the copy assignment operator is invoked, the object
being copied must be copy constructed in the uninitialized storage.buffer.
In the scenario of installing LLVM from the apt packages and a
downstream project choosing to use a different compiler the resulting
application will exhibit runtime failures such as segmentation faults
when calling LLVM functions with an Optional parameter crossing which
cross the ABI boundary.
I believe this is a serious bug and if this patch is accepted should
also be backported to the 7.0 release branch as this has been a latent
issue since late January 2018.
I did not have enough information to be able to reproduce the
"miscompiles" mentioned on the bug tracker so am unable to verify if
those have been fixed this with patch, it is my hope that fixing the
undefined behavior should resolve these issues.
When the type is *actually* trivially-copyable (and not just isPodLike, which lies), we could just store it directly: union { T storage; };