Skip to content

Commit

Permalink
[ADT] Add a workaround for GCC miscompiling the trivially copyable Op…
Browse files Browse the repository at this point in the history
…tional

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.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@322859 91177308-0d34-0410-b5e6-96231b3b80d8
  • Loading branch information
d0k committed Jan 18, 2018
1 parent b5501c9 commit 8845432
Showing 1 changed file with 9 additions and 2 deletions.
11 changes: 9 additions & 2 deletions include/llvm/ADT/Optional.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
#include <algorithm>
#include <cassert>
#include <new>
#include <cstring>
#include <utility>

namespace llvm {
Expand Down Expand Up @@ -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;
}

Expand Down

0 comments on commit 8845432

Please sign in to comment.