components/llvm/patches/007-TemplateBase.patch
changeset 5434 9f55c805ce9d
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/components/llvm/patches/007-TemplateBase.patch	Wed Feb 10 11:54:12 2016 -0800
@@ -0,0 +1,224 @@
+# 1. RAII - Resource Acquisition Is Initialization.
+# 2. Default bit-copying or assigning union member bitfields
+#    between unions of different types or size is undefined behavior.
+# 3. Default bit-copying or assigning unions of different types or
+#    size is undefined behavior.
+# 4. Default bit-copying or assigning nested unions is undefined behavior.
+# https://llvm.org/bugs/show_bug.cgi?id=24608
+--- tools/clang/include/clang/AST/TemplateBase.h	2015-07-17 16:43:46.506876445 -0700
++++ tools/clang/include/clang/AST/TemplateBase.h	2015-07-17 17:39:04.239131360 -0700
+@@ -22,6 +22,7 @@
+ #include "llvm/ADT/iterator_range.h"
+ #include "llvm/Support/Compiler.h"
+ #include "llvm/Support/ErrorHandling.h"
++#include <cstring>
+ 
+ namespace llvm {
+   class FoldingSetNodeID;
+@@ -84,8 +85,8 @@
+     // We store a decomposed APSInt with the data allocated by ASTContext if
+     // BitWidth > 64. The memory may be shared between multiple
+     // TemplateArgument instances.
+-    unsigned BitWidth : 31;
+-    unsigned IsUnsigned : 1;
++    unsigned BitWidth;
++    bool IsUnsigned;
+     union {
+       uint64_t VAL;          ///< Used to store the <= 64 bits integer value.
+       const uint64_t *pVal;  ///< Used to store the >64 bits integer value.
+@@ -112,6 +113,7 @@
+     struct A Args;
+     struct TA TemplateArg;
+     struct TV TypeOrValue;
++    uint64_t Buffer[8];
+   };
+ 
+   TemplateArgument(TemplateName, bool) LLVM_DELETED_FUNCTION;
+@@ -119,12 +121,27 @@
+ public:
+   /// \brief Construct an empty, invalid template argument.
+   TemplateArgument() {
++    (void) std::memset(Buffer, 0, sizeof(Buffer));
+     TypeOrValue.Kind = Null;
+     TypeOrValue.V = 0;
+   }
+ 
++  TemplateArgument(const TemplateArgument &RHS) {
++    (void) std::memset(Buffer, 0, sizeof(Buffer));
++    (void) std::memcpy(Buffer, RHS.Buffer, sizeof(Buffer));
++  }
++
++  TemplateArgument &operator=(const TemplateArgument &RHS) {
++    if (this != &RHS) {
++      (void) std::memset(Buffer, 0, sizeof(Buffer));
++      (void) std::memcpy(Buffer, RHS.Buffer, sizeof(Buffer));
++    }
++    return *this;
++  }
++
+   /// \brief Construct a template type argument.
+   TemplateArgument(QualType T, bool isNullPtr = false) {
++    (void) std::memset(Buffer, 0, sizeof(Buffer));
+     TypeOrValue.Kind = isNullPtr ? NullPtr : Type;
+     TypeOrValue.V = reinterpret_cast<uintptr_t>(T.getAsOpaquePtr());
+   }
+@@ -134,6 +151,7 @@
+   /// template declaration.
+   TemplateArgument(ValueDecl *D, QualType QT) {
+     assert(D && "Expected decl");
++    (void) std::memset(Buffer, 0, sizeof(Buffer));
+     DeclArg.Kind = Declaration;
+     DeclArg.QT = QT.getAsOpaquePtr();
+     DeclArg.D = D;
+@@ -146,6 +164,7 @@
+   /// \brief Construct an integral constant template argument with the same
+   /// value as Other but a different type.
+   TemplateArgument(const TemplateArgument &Other, QualType Type) {
++    (void) std::memset(Buffer, 0, sizeof(Buffer));
+     Integer = Other.Integer;
+     Integer.Type = Type.getAsOpaquePtr();
+   }
+@@ -159,6 +178,7 @@
+   ///
+   /// \param Name The template name.
+   TemplateArgument(TemplateName Name) {
++    (void) std::memset(Buffer, 0, sizeof(Buffer));
+     TemplateArg.Kind = Template;
+     TemplateArg.Name = Name.getAsVoidPointer();
+     TemplateArg.NumExpansions = 0;
+@@ -176,6 +196,7 @@
+   /// \param NumExpansions The number of expansions that will be generated by
+   /// instantiating
+   TemplateArgument(TemplateName Name, Optional<unsigned> NumExpansions) {
++    (void) std::memset(Buffer, 0, sizeof(Buffer));
+     TemplateArg.Kind = TemplateExpansion;
+     TemplateArg.Name = Name.getAsVoidPointer();
+     if (NumExpansions)
+@@ -190,6 +211,7 @@
+   /// lists used for dependent types and for expression; it will not
+   /// occur in a non-dependent, canonical template argument list.
+   TemplateArgument(Expr *E) {
++    (void) std::memset(Buffer, 0, sizeof(Buffer));
+     TypeOrValue.Kind = Expression;
+     TypeOrValue.V = reinterpret_cast<uintptr_t>(E);
+   }
+@@ -199,6 +221,7 @@
+   /// We assume that storage for the template arguments provided
+   /// outlives the TemplateArgument itself.
+   TemplateArgument(const TemplateArgument *Args, unsigned NumArgs) {
++    (void) std::memset(Buffer, 0, sizeof(Buffer));
+     this->Args.Kind = Pack;
+     this->Args.Args = Args;
+     this->Args.NumArgs = NumArgs;
+@@ -391,25 +414,55 @@
+     struct T Template;
+     Expr *Expression;
+     TypeSourceInfo *Declarator;
++    unsigned long Buffer[4];
+   };
+ 
+ public:
+   TemplateArgumentLocInfo();
+   
+-  TemplateArgumentLocInfo(TypeSourceInfo *TInfo) : Declarator(TInfo) {}
++  TemplateArgumentLocInfo(TypeSourceInfo *TInfo) {
++    (void) std::memset(Buffer, 0, sizeof(Buffer));
++    Declarator = TInfo;
++  }
+   
+-  TemplateArgumentLocInfo(Expr *E) : Expression(E) {}
++  TemplateArgumentLocInfo(Expr *E) {
++    (void) std::memset(Buffer, 0, sizeof(Buffer));
++    Expression = E;
++  }
+   
+   TemplateArgumentLocInfo(NestedNameSpecifierLoc QualifierLoc,
+                           SourceLocation TemplateNameLoc,
+-                          SourceLocation EllipsisLoc)
+-  {
++                          SourceLocation EllipsisLoc) {
++    (void) std::memset(Buffer, 0, sizeof(Buffer));
+     Template.Qualifier = QualifierLoc.getNestedNameSpecifier();
+     Template.QualifierLocData = QualifierLoc.getOpaqueData();
+     Template.TemplateNameLoc = TemplateNameLoc.getRawEncoding();
+     Template.EllipsisLoc = EllipsisLoc.getRawEncoding();
+   }
+ 
++  TemplateArgumentLocInfo(const TemplateArgumentLocInfo &RHS) {
++    (void) std::memset(Buffer, 0, sizeof(Buffer));
++    Template.Qualifier = RHS.Template.Qualifier;
++    Template.QualifierLocData = RHS.Template.QualifierLocData;
++    Template.TemplateNameLoc = RHS.Template.TemplateNameLoc;
++    Template.EllipsisLoc = RHS.Template.EllipsisLoc;
++    Expression = RHS.Expression;
++    Declarator = RHS.Declarator;
++  }
++
++  TemplateArgumentLocInfo &operator=(const TemplateArgumentLocInfo &RHS) {
++    if (this != &RHS) {
++      (void) std::memset(Buffer, 0, sizeof(Buffer));
++      Template.Qualifier = RHS.Template.Qualifier;
++      Template.QualifierLocData = RHS.Template.QualifierLocData;
++      Template.TemplateNameLoc = RHS.Template.TemplateNameLoc;
++      Template.EllipsisLoc = RHS.Template.EllipsisLoc;
++      Expression = RHS.Expression;
++      Declarator = RHS.Declarator;
++    }
++    return *this;
++  }
++
+   TypeSourceInfo *getAsTypeSourceInfo() const {
+     return Declarator;
+   }
+# 1. RAII - Resource Acquisition Is Initialization.
+# 2. Allocate memory with suitable alignment for uint64_t.
+# 3. reinterpret_cast<> from void* to <type*>.
+--- tools/clang/lib/AST/TemplateBase.cpp	2015-01-08 16:58:16.000000000 -0800
++++ tools/clang/lib/AST/TemplateBase.cpp	2015-07-17 17:42:51.744142395 -0700
+@@ -71,6 +71,7 @@
+ 
+ TemplateArgument::TemplateArgument(ASTContext &Ctx, const llvm::APSInt &Value,
+                                    QualType Type) {
++  (void) std::memset(Buffer, '\0', sizeof(Buffer));
+   Integer.Kind = Integral;
+   // Copy the APSInt value into our decomposed form.
+   Integer.BitWidth = Value.getBitWidth();
+@@ -78,9 +79,9 @@
+   // If the value is large, we have to get additional memory from the ASTContext
+   unsigned NumWords = Value.getNumWords();
+   if (NumWords > 1) {
+-    void *Mem = Ctx.Allocate(NumWords * sizeof(uint64_t));
+-    std::memcpy(Mem, Value.getRawData(), NumWords * sizeof(uint64_t));
+-    Integer.pVal = static_cast<uint64_t *>(Mem);
++    void *Mem = Ctx.Allocate(NumWords * sizeof(uint64_t), alignof(uint64_t));
++    (void) std::memcpy(Mem, Value.getRawData(), NumWords * sizeof(uint64_t));
++    Integer.pVal = reinterpret_cast<uint64_t *>(Mem);
+   } else {
+     Integer.VAL = Value.getZExtValue();
+   }
+@@ -422,7 +423,9 @@
+ //===----------------------------------------------------------------------===//
+ 
+ TemplateArgumentLocInfo::TemplateArgumentLocInfo() {
+-  memset((void*)this, 0, sizeof(TemplateArgumentLocInfo));
++  (void) std::memset(Buffer, 0, sizeof(Buffer));
++  Expression = nullptr;
++  Declarator = nullptr;
+ }
+ 
+ SourceRange TemplateArgumentLoc::getSourceRange() const {
+# 1. Pointer Arithmetic Paranoia.
+--- tools/clang/lib/AST/Type.cpp	2014-12-28 01:18:54.000000000 -0800
++++ tools/clang/lib/AST/Type.cpp	2015-07-17 17:43:57.848813992 -0700
+@@ -1464,7 +1464,10 @@
+     if (Args[I].containsUnexpandedParameterPack())
+       setContainsUnexpandedParameterPack();
+ 
+-    new (&getArgBuffer()[I]) TemplateArgument(Args[I]);
++    TemplateArgument *TA = getArgBuffer();
++    TA = &(TA[I]);
++    TA = new (TA) TemplateArgument();
++    *TA = Args[I];
+   }
+ }
+