components/llvm/patches/003-solaris-LLVM-ADT.patch
author Mike Sullivan <Mike.Sullivan@Oracle.COM>
Thu, 25 Aug 2016 23:02:28 -0700
changeset 6703 b41bd36a76a5
parent 6512 92717ce71105
permissions -rw-r--r--
Added tag s12-107 for changeset 140c4300a556

# 24312028 llvm::Twine needs copy constructors and assignment operators
# 3.9.X for upstream.
--- include/llvm/ADT/DenseMap.h	2015-10-01 20:46:33.000000000 -0400
+++ include/llvm/ADT/DenseMap.h	2016-05-08 23:19:20.512430267 -0400
@@ -854,7 +854,8 @@
 
       // First move the inline buckets into a temporary storage.
       AlignedCharArrayUnion<BucketT[InlineBuckets]> TmpStorage;
-      BucketT *TmpBegin = reinterpret_cast<BucketT *>(TmpStorage.buffer);
+      BucketT *TmpBegin =
+        reinterpret_cast<BucketT*>(reinterpret_cast<void*>(TmpStorage.buffer));
       BucketT *TmpEnd = TmpBegin;
 
       // Loop over the buckets, moving non-empty, non-tombstones into the
@@ -938,7 +939,8 @@
     // Note that this cast does not violate aliasing rules as we assert that
     // the memory's dynamic type is the small, inline bucket buffer, and the
     // 'storage.buffer' static type is 'char *'.
-    return reinterpret_cast<const BucketT *>(storage.buffer);
+    return reinterpret_cast<const BucketT*>(
+      reinterpret_cast<const void*>(storage.buffer));
   }
   BucketT *getInlineBuckets() {
     return const_cast<BucketT *>(
@@ -947,8 +949,10 @@
   const LargeRep *getLargeRep() const {
     assert(!Small);
     // Note, same rule about aliasing as with getInlineBuckets.
-    return reinterpret_cast<const LargeRep *>(storage.buffer);
+    return reinterpret_cast<const LargeRep*>(
+      reinterpret_cast<const void*>(storage.buffer));
   }
+
   LargeRep *getLargeRep() {
     return const_cast<LargeRep *>(
       const_cast<const SmallDenseMap *>(this)->getLargeRep());
--- include/llvm/ADT/Optional.h	2015-08-19 19:07:27.000000000 -0400
+++ include/llvm/ADT/Optional.h	2016-05-08 23:19:20.513430291 -0400
@@ -116,17 +116,39 @@
     reset();
   }
 
-  const T* getPointer() const { assert(hasVal); return reinterpret_cast<const T*>(storage.buffer); }
-  T* getPointer() { assert(hasVal); return reinterpret_cast<T*>(storage.buffer); }
-  const T& getValue() const LLVM_LVALUE_FUNCTION { assert(hasVal); return *getPointer(); }
-  T& getValue() LLVM_LVALUE_FUNCTION { assert(hasVal); return *getPointer(); }
+  const T* getPointer() const {
+    assert(hasVal);
+    return reinterpret_cast<const T*>(storage.buffer);
+  }
+
+  T* getPointer() {
+    assert(hasVal);
+    return reinterpret_cast<T*>(storage.buffer);
+  }
+
+  const T& getValue() const LLVM_LVALUE_FUNCTION {
+    assert(hasVal);
+    return *getPointer();
+  }
+
+  T& getValue() LLVM_LVALUE_FUNCTION {
+    assert(hasVal);
+    return *getPointer();
+  }
 
   explicit operator bool() const { return hasVal; }
   bool hasValue() const { return hasVal; }
   const T* operator->() const { return getPointer(); }
   T* operator->() { return getPointer(); }
-  const T& operator*() const LLVM_LVALUE_FUNCTION { assert(hasVal); return *getPointer(); }
-  T& operator*() LLVM_LVALUE_FUNCTION { assert(hasVal); return *getPointer(); }
+  const T& operator*() const LLVM_LVALUE_FUNCTION {
+    assert(hasVal);
+    return *getPointer();
+  }
+
+  T& operator*() LLVM_LVALUE_FUNCTION {
+    assert(hasVal);
+    return *getPointer();
+  }
 
   template <typename U>
   LLVM_CONSTEXPR T getValueOr(U &&value) const LLVM_LVALUE_FUNCTION {
--- include/llvm/ADT/Triple.h	2015-12-01 02:33:56.000000000 -0800
+++ include/llvm/ADT/Triple.h	2016-05-09 07:12:20.705509490 -0700
@@ -127,6 +127,7 @@
     MipsTechnologies,
     NVIDIA,
     CSR,
+    Sun,
     Myriad,
     LastVendorType = Myriad
   };
####
--- include/llvm/ADT/SmallVector.h	2015-09-10 02:46:47.000000000 -0700
+++ include/llvm/ADT/SmallVector.h	2016-05-28 15:24:24.738410753 -0700
@@ -19,6 +19,7 @@
 #include "llvm/Support/Compiler.h"
 #include "llvm/Support/MathExtras.h"
 #include "llvm/Support/type_traits.h"
+
 #include <algorithm>
 #include <cassert>
 #include <cstddef>
@@ -27,6 +28,9 @@
 #include <initializer_list>
 #include <iterator>
 #include <memory>
+#include <cstdio>
+#include <type_traits>
+#include <typeinfo>
 
 namespace llvm {
 
@@ -251,11 +255,27 @@
 void SmallVectorTemplateBase<T, isPodLike>::grow(size_t MinSize) {
   size_t CurCapacity = this->capacity();
   size_t CurSize = this->size();
+
   // Always grow, even from zero.
   size_t NewCapacity = size_t(NextPowerOf2(CurCapacity+2));
   if (NewCapacity < MinSize)
     NewCapacity = MinSize;
+
+  NewCapacity = llvm::RoundUpToAlignment(NewCapacity,
+                                         llvm::alignOf<uint64_t>());
+
+#if defined(HAVE_POSIX_MEMALIGN)
+  T *NewElts;
+  size_t Alignment =
+    std::max<size_t>(llvm::AlignOf<uint64_t>::Alignment,
+                     llvm::AlignOf<T>::Alignment);
+  size_t Size = NewCapacity * sizeof(T);
+  int R = posix_memalign((void**) &NewElts, Alignment, Size);
+  assert((R == 0) && "posix_memalign failed!");
+  (void) std::memset(NewElts, 0, Size);
+#else
   T *NewElts = static_cast<T*>(malloc(NewCapacity*sizeof(T)));
+#endif
 
   // Move the elements over.
   this->uninitialized_move(this->begin(), this->end(), NewElts);
@@ -410,10 +430,44 @@
       this->grow(N);
   }
 
+  // This function is evil.
+  // Be very careful here with move vs. copy semantics.
   T LLVM_ATTRIBUTE_UNUSED_RESULT pop_back_val() {
-    T Result = ::std::move(this->back());
-    this->pop_back();
-    return Result;
+    if (std::is_move_constructible<T>::value &&
+        std::is_move_assignable<T>::value) {
+      T Result = std::move(this->back());
+      this->pop_back();
+      return Result;
+    } else if (std::is_copy_constructible<T>::value &&
+               std::is_copy_assignable<T>::value) {
+      T Result = this->back();
+      this->pop_back();
+      return Result;
+    }
+
+    // We can't use llvm::errs() because it has a circular
+    // dependency on llvm::SmallVector<T>.
+    if (!std::is_copy_constructible<T>::value) {
+      std::fprintf(stderr,
+                   "%s: Type %s is not copy-constructible!\n",
+                   __PRETTY_FUNCTION__, typeid(T).name());
+      abort();
+    } else if (!std::is_copy_assignable<T>::value) {
+      std::fprintf(stderr,
+                   "%s: Type %s is not copy-assignable!\n",
+                   __PRETTY_FUNCTION__, typeid(T).name());
+      abort();
+    } else if (!std::is_move_constructible<T>::value) {
+      std::fprintf(stderr,
+                   "%s: Type %s is not move-constructible!\n",
+                   __PRETTY_FUNCTION__, typeid(T).name());
+      abort();
+    } else if (!std::is_move_assignable<T>::value) {
+      std::fprintf(stderr,
+                   "%s: Type %s is not move-assignable!\n",
+                   __PRETTY_FUNCTION__, typeid(T).name());
+      abort();
+    }
   }
 
   void swap(SmallVectorImpl &RHS);
###
--- include/llvm/ADT/Twine.h	2016-01-10 00:27:13.000000000 -0800
+++ include/llvm/ADT/Twine.h	2016-07-16 22:13:18.628217595 -0700
@@ -129,8 +129,7 @@
       UHexKind
     };
 
-    union Child
-    {
+    union Child {
       const Twine *twine;
       const char *cString;
       const std::string *stdString;
@@ -144,6 +143,7 @@
       const unsigned long long *decULL;
       const long long *decLL;
       const uint64_t *uHex;
+      uint64_t buffer[1];
     };
 
   private:
@@ -161,28 +161,32 @@
   private:
     /// Construct a nullary twine; the kind must be NullKind or EmptyKind.
     explicit Twine(NodeKind Kind)
-      : LHSKind(Kind), RHSKind(EmptyKind) {
+      : LHS(), RHS(), LHSKind(Kind), RHSKind(EmptyKind) {
       assert(isNullary() && "Invalid kind!");
+      (void) memset(LHS.buffer, 0, sizeof(LHS.buffer));
+      (void) memset(RHS.buffer, 0, sizeof(RHS.buffer));
+      LHS.twine = 0L;
+      RHS.twine = 0L;
     }
 
     /// Construct a binary twine.
-    explicit Twine(const Twine &LHS, const Twine &RHS)
-        : LHSKind(TwineKind), RHSKind(TwineKind) {
-      this->LHS.twine = &LHS;
-      this->RHS.twine = &RHS;
-      assert(isValid() && "Invalid twine!");
+    explicit Twine(const Twine &TLHS, const Twine &TRHS)
+      : LHSKind(TwineKind), RHSKind(TwineKind) {
+        (void) memset(LHS.buffer, 0, sizeof(LHS.buffer));
+        (void) memset(RHS.buffer, 0, sizeof(RHS.buffer));
+        this->LHS.twine = &TLHS;
+        this->RHS.twine = &TRHS;
+        assert(isValid() && "Invalid twine!");
     }
 
     /// Construct a twine from explicit values.
-    explicit Twine(Child LHS, NodeKind LHSKind, Child RHS, NodeKind RHSKind)
-        : LHS(LHS), RHS(RHS), LHSKind(LHSKind), RHSKind(RHSKind) {
+    explicit Twine(Child CLHS, NodeKind LHSKind, Child CRHS, NodeKind RHSKind)
+        : LHS(CLHS), RHS(CRHS), LHSKind(LHSKind), RHSKind(RHSKind) {
       assert(isValid() && "Invalid twine!");
+      (void) memcpy(LHS.buffer, CLHS.buffer, sizeof(LHS.buffer));
+      (void) memcpy(RHS.buffer, CRHS.buffer, sizeof(RHS.buffer));
     }
 
-    /// Since the intended use of twines is as temporary objects, assignments
-    /// when concatenating might cause undefined behavior or stack corruptions
-    Twine &operator=(const Twine &Other) = delete;
-
     /// Check for the null twine.
     bool isNull() const {
       return getLHSKind() == NullKind;
@@ -252,11 +256,25 @@
     /// @{
 
     /// Construct from an empty string.
-    /*implicit*/ Twine() : LHSKind(EmptyKind), RHSKind(EmptyKind) {
+    /*implicit*/ Twine()
+    : LHS(), RHS(), LHSKind(EmptyKind), RHSKind(EmptyKind) {
+      (void) memset(LHS.buffer, 0, sizeof(LHS.buffer));
+      (void) memset(RHS.buffer, 0, sizeof(RHS.buffer));
+
       assert(isValid() && "Invalid twine!");
     }
 
-    Twine(const Twine &) = default;
+    Twine(const Twine &RHST)
+    : LHS(), RHS(), LHSKind(RHST.LHSKind), RHSKind(RHST.RHSKind) {
+      (void) memcpy(LHS.buffer, RHST.LHS.buffer, sizeof(LHS.buffer));
+      (void) memcpy(RHS.buffer, RHST.RHS.buffer, sizeof(RHS.buffer));
+    }
+
+    Twine(Twine &&RHST)
+    : LHS(), RHS(), LHSKind(RHST.LHSKind), RHSKind(RHST.RHSKind) {
+      (void) memcpy(LHS.buffer, RHST.LHS.buffer, sizeof(LHS.buffer));
+      (void) memcpy(RHS.buffer, RHST.RHS.buffer, sizeof(RHS.buffer));
+    }
 
     /// Construct from a C string.
     ///
@@ -264,7 +282,10 @@
     /// optimized out for string constants. This allows Twine arguments have
     /// default "" values, without introducing unnecessary string constants.
     /*implicit*/ Twine(const char *Str)
-      : RHSKind(EmptyKind) {
+      : LHS(), RHS(), LHSKind(EmptyKind), RHSKind(EmptyKind) {
+      (void) memset(LHS.buffer, 0, sizeof(LHS.buffer));
+      (void) memset(RHS.buffer, 0, sizeof(RHS.buffer));
+
       if (Str[0] != '\0') {
         LHS.cString = Str;
         LHSKind = CStringKind;
@@ -276,76 +297,113 @@
 
     /// Construct from an std::string.
     /*implicit*/ Twine(const std::string &Str)
-      : LHSKind(StdStringKind), RHSKind(EmptyKind) {
+      : LHS(), RHS(), LHSKind(StdStringKind), RHSKind(EmptyKind) {
+      (void) memset(LHS.buffer, 0, sizeof(LHS.buffer));
+      (void) memset(RHS.buffer, 0, sizeof(RHS.buffer));
+
       LHS.stdString = &Str;
       assert(isValid() && "Invalid twine!");
     }
 
     /// Construct from a StringRef.
     /*implicit*/ Twine(const StringRef &Str)
-      : LHSKind(StringRefKind), RHSKind(EmptyKind) {
+      : LHS(), RHS(), LHSKind(StringRefKind), RHSKind(EmptyKind) {
+      (void) memset(LHS.buffer, 0, sizeof(LHS.buffer));
+      (void) memset(RHS.buffer, 0, sizeof(RHS.buffer));
+
       LHS.stringRef = &Str;
       assert(isValid() && "Invalid twine!");
     }
 
     /// Construct from a SmallString.
     /*implicit*/ Twine(const SmallVectorImpl<char> &Str)
-      : LHSKind(SmallStringKind), RHSKind(EmptyKind) {
+      : LHS(), RHS(), LHSKind(SmallStringKind), RHSKind(EmptyKind) {
+      (void) memset(LHS.buffer, 0, sizeof(LHS.buffer));
+      (void) memset(RHS.buffer, 0, sizeof(RHS.buffer));
+
       LHS.smallString = &Str;
       assert(isValid() && "Invalid twine!");
     }
 
     /// Construct from a char.
     explicit Twine(char Val)
-      : LHSKind(CharKind), RHSKind(EmptyKind) {
+      : LHS(), RHS(), LHSKind(CharKind), RHSKind(EmptyKind) {
+      (void) memset(LHS.buffer, 0, sizeof(LHS.buffer));
+      (void) memset(RHS.buffer, 0, sizeof(RHS.buffer));
+
       LHS.character = Val;
     }
 
     /// Construct from a signed char.
     explicit Twine(signed char Val)
-      : LHSKind(CharKind), RHSKind(EmptyKind) {
+      : LHS(), RHS(), LHSKind(CharKind), RHSKind(EmptyKind) {
+      (void) memset(LHS.buffer, 0, sizeof(LHS.buffer));
+      (void) memset(RHS.buffer, 0, sizeof(RHS.buffer));
+
+      LHS.character = Val;
       LHS.character = static_cast<char>(Val);
     }
 
     /// Construct from an unsigned char.
     explicit Twine(unsigned char Val)
-      : LHSKind(CharKind), RHSKind(EmptyKind) {
+      : LHS(), RHS(), LHSKind(CharKind), RHSKind(EmptyKind) {
+      (void) memset(LHS.buffer, 0, sizeof(LHS.buffer));
+      (void) memset(RHS.buffer, 0, sizeof(RHS.buffer));
+
       LHS.character = static_cast<char>(Val);
     }
 
     /// Construct a twine to print \p Val as an unsigned decimal integer.
     explicit Twine(unsigned Val)
-      : LHSKind(DecUIKind), RHSKind(EmptyKind) {
+      : LHS(), RHS(), LHSKind(DecUIKind), RHSKind(EmptyKind) {
+      (void) memset(LHS.buffer, 0, sizeof(LHS.buffer));
+      (void) memset(RHS.buffer, 0, sizeof(RHS.buffer));
+
       LHS.decUI = Val;
     }
 
     /// Construct a twine to print \p Val as a signed decimal integer.
     explicit Twine(int Val)
-      : LHSKind(DecIKind), RHSKind(EmptyKind) {
+      : LHS(), RHS(), LHSKind(DecIKind), RHSKind(EmptyKind) {
+      (void) memset(LHS.buffer, 0, sizeof(LHS.buffer));
+      (void) memset(RHS.buffer, 0, sizeof(RHS.buffer));
+
       LHS.decI = Val;
     }
 
     /// Construct a twine to print \p Val as an unsigned decimal integer.
     explicit Twine(const unsigned long &Val)
-      : LHSKind(DecULKind), RHSKind(EmptyKind) {
+      : LHS(), RHS(), LHSKind(DecULKind), RHSKind(EmptyKind) {
+      (void) memset(LHS.buffer, 0, sizeof(LHS.buffer));
+      (void) memset(RHS.buffer, 0, sizeof(RHS.buffer));
+
       LHS.decUL = &Val;
     }
 
     /// Construct a twine to print \p Val as a signed decimal integer.
     explicit Twine(const long &Val)
-      : LHSKind(DecLKind), RHSKind(EmptyKind) {
+      : LHS(), RHS(), LHSKind(DecLKind), RHSKind(EmptyKind) {
+      (void) memset(LHS.buffer, 0, sizeof(LHS.buffer));
+      (void) memset(RHS.buffer, 0, sizeof(RHS.buffer));
+
       LHS.decL = &Val;
     }
 
     /// Construct a twine to print \p Val as an unsigned decimal integer.
     explicit Twine(const unsigned long long &Val)
-      : LHSKind(DecULLKind), RHSKind(EmptyKind) {
+      : LHS(), RHS(), LHSKind(DecULLKind), RHSKind(EmptyKind) {
+      (void) memset(LHS.buffer, 0, sizeof(LHS.buffer));
+      (void) memset(RHS.buffer, 0, sizeof(RHS.buffer));
+
       LHS.decULL = &Val;
     }
 
     /// Construct a twine to print \p Val as a signed decimal integer.
     explicit Twine(const long long &Val)
-      : LHSKind(DecLLKind), RHSKind(EmptyKind) {
+      : LHS(), RHS(), LHSKind(DecLLKind), RHSKind(EmptyKind) {
+      (void) memset(LHS.buffer, 0, sizeof(LHS.buffer));
+      (void) memset(RHS.buffer, 0, sizeof(RHS.buffer));
+
       LHS.decLL = &Val;
     }
 
@@ -355,27 +413,62 @@
     // right thing. Yet.
 
     /// Construct as the concatenation of a C string and a StringRef.
-    /*implicit*/ Twine(const char *LHS, const StringRef &RHS)
-        : LHSKind(CStringKind), RHSKind(StringRefKind) {
-      this->LHS.cString = LHS;
-      this->RHS.stringRef = &RHS;
+    /*implicit*/ explicit Twine(const char *CLHS, const StringRef &SRHS)
+        : LHS(), RHS(), LHSKind(CStringKind), RHSKind(StringRefKind) {
+      (void) memset(LHS.buffer, 0, sizeof(LHS.buffer));
+      (void) memset(RHS.buffer, 0, sizeof(RHS.buffer));
+
+      this->LHS.cString = CLHS;
+      this->RHS.stringRef = &SRHS;
       assert(isValid() && "Invalid twine!");
     }
 
     /// Construct as the concatenation of a StringRef and a C string.
-    /*implicit*/ Twine(const StringRef &LHS, const char *RHS)
-        : LHSKind(StringRefKind), RHSKind(CStringKind) {
-      this->LHS.stringRef = &LHS;
-      this->RHS.cString = RHS;
+    /*implicit*/ explicit Twine(const StringRef &SLHS, const char *CRHS)
+        : LHS(), RHS(), LHSKind(StringRefKind), RHSKind(CStringKind) {
+      (void) memset(LHS.buffer, 0, sizeof(LHS.buffer));
+      (void) memset(RHS.buffer, 0, sizeof(RHS.buffer));
+
+      this->LHS.stringRef = &SLHS;
+      this->RHS.cString = CRHS;
       assert(isValid() && "Invalid twine!");
     }
 
+    /// Assignment operators.
+    Twine &operator=(const Twine &TRHS) {
+      if (this != &TRHS) {
+        (void) memset(LHS.buffer, 0, sizeof(LHS.buffer));
+        (void) memset(RHS.buffer, 0, sizeof(RHS.buffer));
+        (void) memcpy(LHS.buffer, TRHS.LHS.buffer, sizeof(LHS.buffer));
+        (void) memcpy(RHS.buffer, TRHS.RHS.buffer, sizeof(RHS.buffer));
+      }
+
+      return *this;
+    }
+
+    const Twine &operator=(Twine &&TRHS) {
+      if (this != &TRHS) {
+        (void) memset(LHS.buffer, 0, sizeof(LHS.buffer));
+        (void) memset(RHS.buffer, 0, sizeof(RHS.buffer));
+        (void) memcpy(LHS.buffer, TRHS.LHS.buffer, sizeof(LHS.buffer));
+        (void) memcpy(RHS.buffer, TRHS.RHS.buffer, sizeof(RHS.buffer));
+      }
+
+      return *this;
+    }
+
     /// Create a 'null' string, which is an empty string that always
     /// concatenates to form another empty string.
     static Twine createNull() {
       return Twine(NullKind);
     }
 
+    /// Create an empty string, which is an empty string that always
+    /// concatenates to form another empty string.
+    static Twine createEmpty() {
+      return Twine(EmptyKind);
+    }
+
     /// @}
     /// @name Numeric Conversions
     /// @{