Index: include/llvm/ADT/Optional.h =================================================================== --- include/llvm/ADT/Optional.h +++ include/llvm/ADT/Optional.h @@ -108,7 +108,6 @@ } }; -#if !defined(__GNUC__) || defined(__clang__) // GCC up to GCC7 miscompiles this. /// Storage for trivially copyable types only. template struct OptionalStorage { AlignedCharArrayUnion storage; @@ -118,14 +117,20 @@ OptionalStorage(const T &y) : hasVal(true) { new (storage.buffer) T(y); } OptionalStorage &operator=(const T &y) { - *reinterpret_cast(storage.buffer) = y; - hasVal = true; + if (hasVal) { + // Use std::addressof to silence strict-aliasing warnings from gcc. + *reinterpret_cast(std::addressof(storage.buffer)) = y; + } else { + // Copy assignment to uninitialized storage is undefined behavior so copy + // construct with placement new when no value is held. + new (storage.buffer) T(y); + hasVal = true; + } return *this; } void reset() { hasVal = false; } }; -#endif } // namespace optional_detail template class Optional {