diff options
| -rw-r--r-- | llvm/include/llvm/ADT/Optional.h | 13 | ||||
| -rw-r--r-- | llvm/unittests/ADT/OptionalTest.cpp | 3 |
2 files changed, 5 insertions, 11 deletions
diff --git a/llvm/include/llvm/ADT/Optional.h b/llvm/include/llvm/ADT/Optional.h index 2c2d2c639da..0f073fab2a9 100644 --- a/llvm/include/llvm/ADT/Optional.h +++ b/llvm/include/llvm/ADT/Optional.h @@ -23,7 +23,6 @@ #include <algorithm> #include <cassert> #include <new> -#include <cstring> #include <utility> namespace llvm { @@ -111,6 +110,7 @@ template <typename T, bool IsPodLike> struct OptionalStorage { } }; +#if !defined(__GNUC__) || defined(__clang__) // GCC up to GCC7 miscompiles this. /// Storage for trivially copyable types only. template <typename T> struct OptionalStorage<T, true> { AlignedCharArrayUnion<T> storage; @@ -118,21 +118,16 @@ template <typename T> struct OptionalStorage<T, true> { OptionalStorage() = default; - OptionalStorage(const T &y) : hasVal(true) { - // We use memmove here because we know that T is trivially copyable and GCC - // up to 7 miscompiles placement new. - std::memmove(storage.buffer, &y, sizeof(y)); - } + OptionalStorage(const T &y) : hasVal(true) { new (storage.buffer) T(y); } OptionalStorage &operator=(const T &y) { + *reinterpret_cast<T *>(storage.buffer) = y; hasVal = true; - // We use memmove here because we know that T is trivially copyable and GCC - // up to 7 miscompiles placement new. - std::memmove(storage.buffer, &y, sizeof(y)); return *this; } void reset() { hasVal = false; } }; +#endif } // namespace optional_detail template <typename T> class Optional { diff --git a/llvm/unittests/ADT/OptionalTest.cpp b/llvm/unittests/ADT/OptionalTest.cpp index a9a37bf820d..be49b85f486 100644 --- a/llvm/unittests/ADT/OptionalTest.cpp +++ b/llvm/unittests/ADT/OptionalTest.cpp @@ -518,8 +518,7 @@ TEST_F(OptionalTest, OperatorGreaterEqual) { CheckRelation<GreaterEqual>(InequalityLhs, InequalityRhs, !IsLess); } -#if (__has_feature(is_trivially_copyable) && defined(_LIBCPP_VERSION)) || \ - (defined(__GNUC__) && __GNUC__ >= 5) +#if __has_feature(is_trivially_copyable) && defined(_LIBCPP_VERSION) static_assert(std::is_trivially_copyable<Optional<int>>::value, "Should be trivially copyable"); static_assert( |

