]> granicus.if.org Git - llvm/commitdiff
Revert [NFC] Better encapsulation of llvm::Optional Storage
authorSerge Guelton <sguelton@redhat.com>
Sun, 17 Feb 2019 14:59:21 +0000 (14:59 +0000)
committerSerge Guelton <sguelton@redhat.com>
Sun, 17 Feb 2019 14:59:21 +0000 (14:59 +0000)
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

index 09a26b65c7018b770bc9e005f417f2a7b4570c00..25a3185064f413225f0c63db53ea87114657dd75 100644 (file)
@@ -30,12 +30,10 @@ class raw_ostream;
 
 namespace optional_detail {
 /// Storage for any type.
-template <typename T, bool = is_trivially_copyable<T>::value>
-class OptionalStorage {
+template <typename T, bool = is_trivially_copyable<T>::value> struct OptionalStorage {
   AlignedCharArrayUnion<T> 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<const T *>(storage.buffer);
   }
-
-  template <typename... ArgTypes> void emplace(ArgTypes &&... Args) {
-    reset();
-    hasVal = true;
-    new (storage.buffer) T(std::forward<ArgTypes>(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 <typename... ArgTypes> void emplace(ArgTypes &&... Args) {
-    Storage.emplace(std::forward<ArgTypes>(Args)...);
+    reset();
+    Storage.hasVal = true;
+    new (getPointer()) T(std::forward<ArgTypes>(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<const T *>(Storage.storage.buffer);
+  }
+  T *getPointer() {
+    assert(Storage.hasVal);
+    return reinterpret_cast<T *>(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(); }