From 6b5c3003279f46aba39e88a1dc88edf7ac7ce9a8 Mon Sep 17 00:00:00 2001 From: Benjamin Kramer Date: Thu, 18 Jan 2018 15:47:59 +0000 Subject: [PATCH] [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 --- llvm/include/llvm/ADT/Optional.h | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/llvm/include/llvm/ADT/Optional.h b/llvm/include/llvm/ADT/Optional.h index 54dc5744ad4b..2c2d2c639dae 100644 --- a/llvm/include/llvm/ADT/Optional.h +++ b/llvm/include/llvm/ADT/Optional.h @@ -23,6 +23,7 @@ #include #include #include +#include #include namespace llvm { @@ -117,10 +118,16 @@ template struct OptionalStorage { 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; }