|
1 # 1. RAII - Resource Acquisition Is Initialization. |
|
2 # 2. Default bit-copying or assigning union member bitfields |
|
3 # between unions of different types or size is undefined behavior. |
|
4 # 3. Default bit-copying or assigning unions of different types or |
|
5 # size is undefined behavior. |
|
6 # 4. Default bit-copying or assigning nested unions is undefined behavior. |
|
7 # https://llvm.org/bugs/show_bug.cgi?id=24608 |
|
8 --- tools/clang/include/clang/AST/TemplateBase.h 2015-07-17 16:43:46.506876445 -0700 |
|
9 +++ tools/clang/include/clang/AST/TemplateBase.h 2015-07-17 17:39:04.239131360 -0700 |
|
10 @@ -22,6 +22,7 @@ |
|
11 #include "llvm/ADT/iterator_range.h" |
|
12 #include "llvm/Support/Compiler.h" |
|
13 #include "llvm/Support/ErrorHandling.h" |
|
14 +#include <cstring> |
|
15 |
|
16 namespace llvm { |
|
17 class FoldingSetNodeID; |
|
18 @@ -84,8 +85,8 @@ |
|
19 // We store a decomposed APSInt with the data allocated by ASTContext if |
|
20 // BitWidth > 64. The memory may be shared between multiple |
|
21 // TemplateArgument instances. |
|
22 - unsigned BitWidth : 31; |
|
23 - unsigned IsUnsigned : 1; |
|
24 + unsigned BitWidth; |
|
25 + bool IsUnsigned; |
|
26 union { |
|
27 uint64_t VAL; ///< Used to store the <= 64 bits integer value. |
|
28 const uint64_t *pVal; ///< Used to store the >64 bits integer value. |
|
29 @@ -112,6 +113,7 @@ |
|
30 struct A Args; |
|
31 struct TA TemplateArg; |
|
32 struct TV TypeOrValue; |
|
33 + uint64_t Buffer[8]; |
|
34 }; |
|
35 |
|
36 TemplateArgument(TemplateName, bool) LLVM_DELETED_FUNCTION; |
|
37 @@ -119,12 +121,27 @@ |
|
38 public: |
|
39 /// \brief Construct an empty, invalid template argument. |
|
40 TemplateArgument() { |
|
41 + (void) std::memset(Buffer, 0, sizeof(Buffer)); |
|
42 TypeOrValue.Kind = Null; |
|
43 TypeOrValue.V = 0; |
|
44 } |
|
45 |
|
46 + TemplateArgument(const TemplateArgument &RHS) { |
|
47 + (void) std::memset(Buffer, 0, sizeof(Buffer)); |
|
48 + (void) std::memcpy(Buffer, RHS.Buffer, sizeof(Buffer)); |
|
49 + } |
|
50 + |
|
51 + TemplateArgument &operator=(const TemplateArgument &RHS) { |
|
52 + if (this != &RHS) { |
|
53 + (void) std::memset(Buffer, 0, sizeof(Buffer)); |
|
54 + (void) std::memcpy(Buffer, RHS.Buffer, sizeof(Buffer)); |
|
55 + } |
|
56 + return *this; |
|
57 + } |
|
58 + |
|
59 /// \brief Construct a template type argument. |
|
60 TemplateArgument(QualType T, bool isNullPtr = false) { |
|
61 + (void) std::memset(Buffer, 0, sizeof(Buffer)); |
|
62 TypeOrValue.Kind = isNullPtr ? NullPtr : Type; |
|
63 TypeOrValue.V = reinterpret_cast<uintptr_t>(T.getAsOpaquePtr()); |
|
64 } |
|
65 @@ -134,6 +151,7 @@ |
|
66 /// template declaration. |
|
67 TemplateArgument(ValueDecl *D, QualType QT) { |
|
68 assert(D && "Expected decl"); |
|
69 + (void) std::memset(Buffer, 0, sizeof(Buffer)); |
|
70 DeclArg.Kind = Declaration; |
|
71 DeclArg.QT = QT.getAsOpaquePtr(); |
|
72 DeclArg.D = D; |
|
73 @@ -146,6 +164,7 @@ |
|
74 /// \brief Construct an integral constant template argument with the same |
|
75 /// value as Other but a different type. |
|
76 TemplateArgument(const TemplateArgument &Other, QualType Type) { |
|
77 + (void) std::memset(Buffer, 0, sizeof(Buffer)); |
|
78 Integer = Other.Integer; |
|
79 Integer.Type = Type.getAsOpaquePtr(); |
|
80 } |
|
81 @@ -159,6 +178,7 @@ |
|
82 /// |
|
83 /// \param Name The template name. |
|
84 TemplateArgument(TemplateName Name) { |
|
85 + (void) std::memset(Buffer, 0, sizeof(Buffer)); |
|
86 TemplateArg.Kind = Template; |
|
87 TemplateArg.Name = Name.getAsVoidPointer(); |
|
88 TemplateArg.NumExpansions = 0; |
|
89 @@ -176,6 +196,7 @@ |
|
90 /// \param NumExpansions The number of expansions that will be generated by |
|
91 /// instantiating |
|
92 TemplateArgument(TemplateName Name, Optional<unsigned> NumExpansions) { |
|
93 + (void) std::memset(Buffer, 0, sizeof(Buffer)); |
|
94 TemplateArg.Kind = TemplateExpansion; |
|
95 TemplateArg.Name = Name.getAsVoidPointer(); |
|
96 if (NumExpansions) |
|
97 @@ -190,6 +211,7 @@ |
|
98 /// lists used for dependent types and for expression; it will not |
|
99 /// occur in a non-dependent, canonical template argument list. |
|
100 TemplateArgument(Expr *E) { |
|
101 + (void) std::memset(Buffer, 0, sizeof(Buffer)); |
|
102 TypeOrValue.Kind = Expression; |
|
103 TypeOrValue.V = reinterpret_cast<uintptr_t>(E); |
|
104 } |
|
105 @@ -199,6 +221,7 @@ |
|
106 /// We assume that storage for the template arguments provided |
|
107 /// outlives the TemplateArgument itself. |
|
108 TemplateArgument(const TemplateArgument *Args, unsigned NumArgs) { |
|
109 + (void) std::memset(Buffer, 0, sizeof(Buffer)); |
|
110 this->Args.Kind = Pack; |
|
111 this->Args.Args = Args; |
|
112 this->Args.NumArgs = NumArgs; |
|
113 @@ -391,25 +414,55 @@ |
|
114 struct T Template; |
|
115 Expr *Expression; |
|
116 TypeSourceInfo *Declarator; |
|
117 + unsigned long Buffer[4]; |
|
118 }; |
|
119 |
|
120 public: |
|
121 TemplateArgumentLocInfo(); |
|
122 |
|
123 - TemplateArgumentLocInfo(TypeSourceInfo *TInfo) : Declarator(TInfo) {} |
|
124 + TemplateArgumentLocInfo(TypeSourceInfo *TInfo) { |
|
125 + (void) std::memset(Buffer, 0, sizeof(Buffer)); |
|
126 + Declarator = TInfo; |
|
127 + } |
|
128 |
|
129 - TemplateArgumentLocInfo(Expr *E) : Expression(E) {} |
|
130 + TemplateArgumentLocInfo(Expr *E) { |
|
131 + (void) std::memset(Buffer, 0, sizeof(Buffer)); |
|
132 + Expression = E; |
|
133 + } |
|
134 |
|
135 TemplateArgumentLocInfo(NestedNameSpecifierLoc QualifierLoc, |
|
136 SourceLocation TemplateNameLoc, |
|
137 - SourceLocation EllipsisLoc) |
|
138 - { |
|
139 + SourceLocation EllipsisLoc) { |
|
140 + (void) std::memset(Buffer, 0, sizeof(Buffer)); |
|
141 Template.Qualifier = QualifierLoc.getNestedNameSpecifier(); |
|
142 Template.QualifierLocData = QualifierLoc.getOpaqueData(); |
|
143 Template.TemplateNameLoc = TemplateNameLoc.getRawEncoding(); |
|
144 Template.EllipsisLoc = EllipsisLoc.getRawEncoding(); |
|
145 } |
|
146 |
|
147 + TemplateArgumentLocInfo(const TemplateArgumentLocInfo &RHS) { |
|
148 + (void) std::memset(Buffer, 0, sizeof(Buffer)); |
|
149 + Template.Qualifier = RHS.Template.Qualifier; |
|
150 + Template.QualifierLocData = RHS.Template.QualifierLocData; |
|
151 + Template.TemplateNameLoc = RHS.Template.TemplateNameLoc; |
|
152 + Template.EllipsisLoc = RHS.Template.EllipsisLoc; |
|
153 + Expression = RHS.Expression; |
|
154 + Declarator = RHS.Declarator; |
|
155 + } |
|
156 + |
|
157 + TemplateArgumentLocInfo &operator=(const TemplateArgumentLocInfo &RHS) { |
|
158 + if (this != &RHS) { |
|
159 + (void) std::memset(Buffer, 0, sizeof(Buffer)); |
|
160 + Template.Qualifier = RHS.Template.Qualifier; |
|
161 + Template.QualifierLocData = RHS.Template.QualifierLocData; |
|
162 + Template.TemplateNameLoc = RHS.Template.TemplateNameLoc; |
|
163 + Template.EllipsisLoc = RHS.Template.EllipsisLoc; |
|
164 + Expression = RHS.Expression; |
|
165 + Declarator = RHS.Declarator; |
|
166 + } |
|
167 + return *this; |
|
168 + } |
|
169 + |
|
170 TypeSourceInfo *getAsTypeSourceInfo() const { |
|
171 return Declarator; |
|
172 } |
|
173 # 1. RAII - Resource Acquisition Is Initialization. |
|
174 # 2. Allocate memory with suitable alignment for uint64_t. |
|
175 # 3. reinterpret_cast<> from void* to <type*>. |
|
176 --- tools/clang/lib/AST/TemplateBase.cpp 2015-01-08 16:58:16.000000000 -0800 |
|
177 +++ tools/clang/lib/AST/TemplateBase.cpp 2015-07-17 17:42:51.744142395 -0700 |
|
178 @@ -71,6 +71,7 @@ |
|
179 |
|
180 TemplateArgument::TemplateArgument(ASTContext &Ctx, const llvm::APSInt &Value, |
|
181 QualType Type) { |
|
182 + (void) std::memset(Buffer, '\0', sizeof(Buffer)); |
|
183 Integer.Kind = Integral; |
|
184 // Copy the APSInt value into our decomposed form. |
|
185 Integer.BitWidth = Value.getBitWidth(); |
|
186 @@ -78,9 +79,9 @@ |
|
187 // If the value is large, we have to get additional memory from the ASTContext |
|
188 unsigned NumWords = Value.getNumWords(); |
|
189 if (NumWords > 1) { |
|
190 - void *Mem = Ctx.Allocate(NumWords * sizeof(uint64_t)); |
|
191 - std::memcpy(Mem, Value.getRawData(), NumWords * sizeof(uint64_t)); |
|
192 - Integer.pVal = static_cast<uint64_t *>(Mem); |
|
193 + void *Mem = Ctx.Allocate(NumWords * sizeof(uint64_t), alignof(uint64_t)); |
|
194 + (void) std::memcpy(Mem, Value.getRawData(), NumWords * sizeof(uint64_t)); |
|
195 + Integer.pVal = reinterpret_cast<uint64_t *>(Mem); |
|
196 } else { |
|
197 Integer.VAL = Value.getZExtValue(); |
|
198 } |
|
199 @@ -422,7 +423,9 @@ |
|
200 //===----------------------------------------------------------------------===// |
|
201 |
|
202 TemplateArgumentLocInfo::TemplateArgumentLocInfo() { |
|
203 - memset((void*)this, 0, sizeof(TemplateArgumentLocInfo)); |
|
204 + (void) std::memset(Buffer, 0, sizeof(Buffer)); |
|
205 + Expression = nullptr; |
|
206 + Declarator = nullptr; |
|
207 } |
|
208 |
|
209 SourceRange TemplateArgumentLoc::getSourceRange() const { |
|
210 # 1. Pointer Arithmetic Paranoia. |
|
211 --- tools/clang/lib/AST/Type.cpp 2014-12-28 01:18:54.000000000 -0800 |
|
212 +++ tools/clang/lib/AST/Type.cpp 2015-07-17 17:43:57.848813992 -0700 |
|
213 @@ -1464,7 +1464,10 @@ |
|
214 if (Args[I].containsUnexpandedParameterPack()) |
|
215 setContainsUnexpandedParameterPack(); |
|
216 |
|
217 - new (&getArgBuffer()[I]) TemplateArgument(Args[I]); |
|
218 + TemplateArgument *TA = getArgBuffer(); |
|
219 + TA = &(TA[I]); |
|
220 + TA = new (TA) TemplateArgument(); |
|
221 + *TA = Args[I]; |
|
222 } |
|
223 } |
|
224 |