forked from OSchip/llvm-project
[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:
parent
5e4df288e2
commit
6b5c300327
|
@ -23,6 +23,7 @@
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <new>
|
#include <new>
|
||||||
|
#include <cstring>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
namespace llvm {
|
namespace llvm {
|
||||||
|
@ -117,10 +118,16 @@ template <typename T> struct OptionalStorage<T, true> {
|
||||||
|
|
||||||
OptionalStorage() = default;
|
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) {
|
OptionalStorage &operator=(const T &y) {
|
||||||
new (storage.buffer) T(y);
|
|
||||||
hasVal = true;
|
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;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue