From 933d1a7b93303c063ebf5e65e3aa0aae351ec8ee Mon Sep 17 00:00:00 2001 From: Benjamin Kramer Date: Thu, 18 Jan 2018 16:23:40 +0000 Subject: [PATCH] [ADT] Just give up on GCC, I can't fix this. While the memmove workaround fixed it for GCC 6.3. GCC 4.8 and GCC 7.1 are still broken. I have no clue what's going on, just blacklist GCC for now. Needless to say this code is ubsan, asan and msan-clean. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@322862 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/ADT/Optional.h | 13 ++++--------- unittests/ADT/OptionalTest.cpp | 3 +-- 2 files changed, 5 insertions(+), 11 deletions(-) diff --git a/include/llvm/ADT/Optional.h b/include/llvm/ADT/Optional.h index 2c2d2c639dae6d..0f073fab2a9640 100644 --- a/include/llvm/ADT/Optional.h +++ b/include/llvm/ADT/Optional.h @@ -23,7 +23,6 @@ #include #include #include -#include #include namespace llvm { @@ -111,6 +110,7 @@ template struct OptionalStorage { } }; +#if !defined(__GNUC__) || defined(__clang__) // GCC up to GCC7 miscompiles this. /// Storage for trivially copyable types only. template struct OptionalStorage { AlignedCharArrayUnion storage; @@ -118,21 +118,16 @@ template struct OptionalStorage { 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(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 class Optional { diff --git a/unittests/ADT/OptionalTest.cpp b/unittests/ADT/OptionalTest.cpp index a9a37bf820d002..be49b85f4860d9 100644 --- a/unittests/ADT/OptionalTest.cpp +++ b/unittests/ADT/OptionalTest.cpp @@ -518,8 +518,7 @@ TEST_F(OptionalTest, OperatorGreaterEqual) { CheckRelation(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>::value, "Should be trivially copyable"); static_assert(