From 76b3bc528c5587bacc432142425c528f7e6cb7de Mon Sep 17 00:00:00 2001 From: Serge Guelton Date: Sun, 17 Feb 2019 14:59:21 +0000 Subject: [PATCH] Revert [NFC] Better encapsulation of llvm::Optional Storage I'm getting the feealing that current Optional implementation is full of UB :-/ git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@354217 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/ADT/Optional.h | 30 ++++++++++++++---------------- 1 file changed, 14 insertions(+), 16 deletions(-) diff --git a/include/llvm/ADT/Optional.h b/include/llvm/ADT/Optional.h index 09a26b65c70..25a3185064f 100644 --- a/include/llvm/ADT/Optional.h +++ b/include/llvm/ADT/Optional.h @@ -30,12 +30,10 @@ class raw_ostream; namespace optional_detail { /// Storage for any type. -template ::value> -class OptionalStorage { +template ::value> struct OptionalStorage { AlignedCharArrayUnion storage; bool hasVal = false; -public: OptionalStorage() = default; OptionalStorage(const T &y) : hasVal(true) { new (storage.buffer) T(y); } @@ -109,14 +107,6 @@ public: assert(hasVal); return reinterpret_cast(storage.buffer); } - - template void emplace(ArgTypes &&... Args) { - reset(); - hasVal = true; - new (storage.buffer) T(std::forward(Args)...); - } - - bool hasValue() const { return hasVal; } }; } // namespace optional_detail @@ -144,7 +134,9 @@ public: /// Create a new object by constructing it in place with the given arguments. template void emplace(ArgTypes &&... Args) { - Storage.emplace(std::forward(Args)...); + reset(); + Storage.hasVal = true; + new (getPointer()) T(std::forward(Args)...); } static inline Optional create(const T *y) { @@ -159,13 +151,19 @@ public: void reset() { Storage.reset(); } - const T *getPointer() const { return Storage.getPointer(); } - T *getPointer() { return Storage.getPointer(); } + const T *getPointer() const { + assert(Storage.hasVal); + return reinterpret_cast(Storage.storage.buffer); + } + T *getPointer() { + assert(Storage.hasVal); + return reinterpret_cast(Storage.storage.buffer); + } const T &getValue() const LLVM_LVALUE_FUNCTION { return *getPointer(); } T &getValue() LLVM_LVALUE_FUNCTION { return *getPointer(); } - explicit operator bool() const { return hasValue(); } - bool hasValue() const { return Storage.hasValue(); } + explicit operator bool() const { return Storage.hasVal; } + bool hasValue() const { return Storage.hasVal; } const T *operator->() const { return getPointer(); } T *operator->() { return getPointer(); } const T &operator*() const LLVM_LVALUE_FUNCTION { return *getPointer(); } -- 2.11.0