@@ -20,13 +20,14 @@ class BasicBlock;
20
20
21
21
bool User::replaceUsesOfWith (Value *From, Value *To) {
22
22
bool Changed = false ;
23
- if (From == To) return Changed; // Duh what?
23
+ if (From == To)
24
+ return Changed; // Duh what?
24
25
25
26
assert ((!isa<Constant>(this ) || isa<GlobalValue>(this )) &&
26
27
" Cannot call User::replaceUsesOfWith on a constant!" );
27
28
28
29
for (unsigned i = 0 , E = getNumOperands (); i != E; ++i)
29
- if (getOperand (i) == From) { // Is This operand is pointing to oldval?
30
+ if (getOperand (i) == From) { // Is This operand is pointing to oldval?
30
31
// The side effects of this setOperand call include linking to
31
32
// "To", adding "this" to the uses list of To, and
32
33
// most importantly, removing "this" from the use list of "From".
@@ -57,7 +58,7 @@ void User::allocHungoffUses(unsigned N, bool IsPhi) {
57
58
size_t size = N * sizeof (Use);
58
59
if (IsPhi)
59
60
size += N * sizeof (BasicBlock *);
60
- Use *Begin = static_cast <Use*>(::operator new (size));
61
+ Use *Begin = static_cast <Use *>(::operator new (size));
61
62
Use *End = Begin + N;
62
63
setOperandList (Begin);
63
64
for (; Begin != End; Begin++)
@@ -89,7 +90,6 @@ void User::growHungoffUses(unsigned NewNumUses, bool IsPhi) {
89
90
Use::zap (OldOps, OldOps + OldNumUses, true );
90
91
}
91
92
92
-
93
93
// This is a private struct used by `User` to track the co-allocated descriptor
94
94
// section.
95
95
struct DescriptorInfo {
@@ -191,28 +191,70 @@ void *User::operator new(size_t Size, HungOffOperandsAllocMarker) {
191
191
LLVM_NO_SANITIZE_MEMORY_ATTRIBUTE void User::operator delete (void *Usr) {
192
192
// Hung off uses use a single Use* before the User, while other subclasses
193
193
// use a Use[] allocated prior to the user.
194
- User *Obj = static_cast <User *>(Usr);
194
+ const auto *Obj = static_cast <User *>(Usr);
195
195
if (Obj->HasHungOffUses ) {
196
- assert (!Obj->HasDescriptor && " not supported!" );
197
-
198
- Use **HungOffOperandList = static_cast <Use **>(Usr) - 1 ;
199
- // drop the hung off uses.
200
- Use::zap (*HungOffOperandList, *HungOffOperandList + Obj->NumUserOperands ,
201
- /* Delete */ true );
202
- ::operator delete (HungOffOperandList);
196
+ const HungOffOperandsAllocMarker Marker{
197
+ Obj->NumUserOperands ,
198
+ };
199
+ operator delete (Usr, Marker);
203
200
} else if (Obj->HasDescriptor ) {
204
- Use *UseBegin = static_cast <Use *>(Usr) - Obj->NumUserOperands ;
205
- Use::zap (UseBegin, UseBegin + Obj->NumUserOperands , /* Delete */ false );
206
-
207
- auto *DI = reinterpret_cast <DescriptorInfo *>(UseBegin) - 1 ;
208
- uint8_t *Storage = reinterpret_cast <uint8_t *>(DI) - DI->SizeInBytes ;
209
- ::operator delete (Storage);
201
+ const IntrusiveOperandsAndDescriptorAllocMarker Marker{
202
+ Obj->NumUserOperands ,
203
+ Obj->HasDescriptor ,
204
+ };
205
+ operator delete (Usr, Marker);
210
206
} else {
211
- Use *Storage = static_cast <Use *>(Usr) - Obj-> NumUserOperands ;
212
- Use::zap (Storage, Storage + Obj->NumUserOperands ,
213
- /* Delete */ false ) ;
214
- :: operator delete (Storage );
207
+ const IntrusiveOperandsAllocMarker Marker{
208
+ Obj->NumUserOperands ,
209
+ } ;
210
+ operator delete (Usr, Marker );
215
211
}
216
212
}
217
213
214
+ // Repress memory sanitization, due to use-after-destroy by operator
215
+ // delete. Bug report 24578 identifies this issue.
216
+ LLVM_NO_SANITIZE_MEMORY_ATTRIBUTE void
217
+ User::operator delete (void *Usr, const HungOffOperandsAllocMarker Marker) {
218
+ // Note: If a subclass manipulates the information which is required to
219
+ // calculate the Usr memory pointer, e.g. NumUserOperands, the operator
220
+ // delete of that subclass has to restore the changed information to the
221
+ // original value, since the dtor of that class is not called if the ctor
222
+ // fails.
223
+ Use **HungOffOperandList = static_cast <Use **>(Usr) - 1 ;
224
+ // drop the hung off uses.
225
+ Use::zap (*HungOffOperandList, *HungOffOperandList + Marker.NumOps ,
226
+ /* Delete */ true );
227
+ ::operator delete (HungOffOperandList);
228
+ }
229
+
230
+ // Repress memory sanitization, due to use-after-destroy by operator
231
+ // delete. Bug report 24578 identifies this issue.
232
+ LLVM_NO_SANITIZE_MEMORY_ATTRIBUTE void
233
+ User::operator delete (void *Usr, const IntrusiveOperandsAllocMarker Marker) {
234
+ // Note: If a subclass manipulates the information which is required to
235
+ // calculate the Usr memory pointer, e.g. NumUserOperands, the operator delete
236
+ // of that subclass has to restore the changed information to the original
237
+ // value, since the dtor of that class is not called if the ctor fails.
238
+ Use *Storage = static_cast <Use *>(Usr) - Marker.NumOps ;
239
+ Use::zap (Storage, Storage + Marker.NumOps , /* Delete */ false );
240
+ ::operator delete (Storage);
241
+ }
242
+
243
+ // Repress memory sanitization, due to use-after-destroy by operator
244
+ // delete. Bug report 24578 identifies this issue.
245
+ LLVM_NO_SANITIZE_MEMORY_ATTRIBUTE void
246
+ User::operator delete (void *Usr,
247
+ const IntrusiveOperandsAndDescriptorAllocMarker Marker) {
248
+ // Note: If a subclass manipulates the information which is required to
249
+ // calculate the Usr memory pointer, e.g. NumUserOperands, the operator delete
250
+ // of that subclass has to restore the changed information to the original
251
+ // value, since the dtor of that class is not called if the ctor fails.
252
+ Use *UseBegin = static_cast <Use *>(Usr) - Marker.NumOps ;
253
+ Use::zap (UseBegin, UseBegin + Marker.NumOps , /* Delete */ false );
254
+
255
+ auto *DI = reinterpret_cast <DescriptorInfo *>(UseBegin) - 1 ;
256
+ uint8_t *Storage = reinterpret_cast <uint8_t *>(DI) - DI->SizeInBytes ;
257
+ ::operator delete (Storage);
258
+ }
259
+
218
260
} // namespace llvm
0 commit comments