diff options
author | Benjamin Kramer <benny.kra@googlemail.com> | 2018-01-18 16:23:40 +0000 |
---|---|---|
committer | Benjamin Kramer <benny.kra@googlemail.com> | 2018-01-18 16:23:40 +0000 |
commit | 0a2193054b13b5c4cc89cc101cedc0b3f0240d4f (patch) | |
tree | ad52d80e4039eb9761f6d4bce089519ffaa5b35c | |
parent | 712cd41fa0b0f45a7bc589d89af273341be8c529 (diff) | |
download | bcm5719-llvm-0a2193054b13b5c4cc89cc101cedc0b3f0240d4f.tar.gz bcm5719-llvm-0a2193054b13b5c4cc89cc101cedc0b3f0240d4f.zip |
[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.
llvm-svn: 322862
-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( |