--- /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];
+ }
+ }
+