[ADT] Add a workaround for GCC miscompiling the trivially copyable Optional

I've seen random crashes with GCC 4.8, GCC 6.3 and GCC 7.3, triggered by
my Optional change. All of them affect a different set of targets. This
change fixes the instance of the problem I'm seeing on my local machine,
let's hope it's good enough for the other instances too.

llvm-svn: 322859
This commit is contained in:
Benjamin Kramer 2018-01-18 15:47:59 +00:00
parent 5e4df288e2
commit 6b5c300327
1 changed files with 9 additions and 2 deletions

View File

@ -23,6 +23,7 @@
#include <algorithm>
#include <cassert>
#include <new>
#include <cstring>
#include <utility>
namespace llvm {
@ -117,10 +118,16 @@ template <typename T> struct OptionalStorage<T, true> {
OptionalStorage() = default;
OptionalStorage(const T &y) : hasVal(true) { new (storage.buffer) T(y); }
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 &operator=(const T &y) {
new (storage.buffer) 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));
return *this;
}