Convert more mallocs/frees to news/deletes (#2157)

This change replaces more malloc/calloc/realloc/free calls to new/delete. This creates several new out of memory exception paths (especially due to changing MallocAllocator) which exposed many memory mismanagement bugs that I found using the OOM test. Hence this grew to be a pretty big change.
This commit is contained in:
Tristan Labelle 2019-05-07 07:46:09 -07:00 коммит произвёл GitHub
Родитель 893d340c4f
Коммит e4ceb30434
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
32 изменённых файлов: 207 добавлений и 80 удалений

Просмотреть файл

@ -190,7 +190,7 @@ public:
SparseMultiSet()
: Sparse(nullptr), Universe(0), FreelistIdx(SMSNode::INVALID), NumFree(0) {}
~SparseMultiSet() { free(Sparse); }
~SparseMultiSet() { delete[] Sparse; } // HLSL Change: Use overridable operator new
/// Set the universe size which determines the largest key the set can hold.
/// The universe must be sized before any elements can be added.
@ -204,11 +204,14 @@ public:
// Hysteresis prevents needless reallocations.
if (U >= Universe/4 && U <= Universe)
return;
free(Sparse);
// HLSL Change Begin: Use overridable operator new/delete
delete[] Sparse;
// The Sparse array doesn't actually need to be initialized, so malloc
// would be enough here, but that will cause tools like valgrind to
// complain about branching on uninitialized data.
Sparse = reinterpret_cast<SparseT*>(calloc(U, sizeof(SparseT)));
Sparse = new SparseT[U];
std::memset(Sparse, 0, U * sizeof(SparseT));
// HLSL Change End
Universe = U;
}

Просмотреть файл

@ -144,7 +144,7 @@ public:
typedef const ValueT *const_pointer;
SparseSet() : Sparse(nullptr), Universe(0) {}
~SparseSet() { free(Sparse); }
~SparseSet() { delete[] Sparse; } // HLSL Change Begin: Use overridable operator delete
/// setUniverse - Set the universe size which determines the largest key the
/// set can hold. The universe must be sized before any elements can be
@ -159,11 +159,14 @@ public:
// Hysteresis prevents needless reallocations.
if (U >= Universe/4 && U <= Universe)
return;
free(Sparse);
// HLSL Change Begin: Use overridable operator new/delete
delete[] Sparse;
// The Sparse array doesn't actually need to be initialized, so malloc
// would be enough here, but that will cause tools like valgrind to
// complain about branching on uninitialized data.
Sparse = reinterpret_cast<SparseT*>(calloc(U, sizeof(SparseT)));
Sparse = new SparseT[U];
std::memset(Sparse, 0, U * sizeof(SparseT));
// HLSL Change End
Universe = U;
}

Просмотреть файл

@ -382,7 +382,7 @@ public:
}
}
}
free(TheTable);
::operator delete(TheTable); // HLSL Change Begin: Use overridable operator delete
}
};

Просмотреть файл

@ -420,7 +420,21 @@ public:
Head = New;
this->setPrev(CurNode, New);
this->addNodeToList(New); // Notify traits that we added a node...
// HLSL Change Begin: Undo insertion if exception
try {
this->addNodeToList(New); // Notify traits that we added a node...
} catch (...) {
// Undo insertion
if (New == Head)
Head = CurNode;
else
this->setNext(PrevNode, CurNode);
this->setPrev(CurNode, PrevNode);
this->setPrev(New, nullptr);
this->setNext(New, nullptr);
throw;
}
// HLSL Change End
return New;
}

Просмотреть файл

@ -146,7 +146,7 @@ class PressureDiffs {
unsigned Max;
public:
PressureDiffs(): PDiffArray(nullptr), Size(0), Max(0) {}
~PressureDiffs() { free(PDiffArray); }
~PressureDiffs() { delete[] PDiffArray; } // HLSL Change: Use overridable operator delete
void clear() { Size = 0; }

Просмотреть файл

@ -66,7 +66,7 @@ private:
// Important things that make up a function!
BasicBlockListType BasicBlocks; ///< The basic blocks
mutable ArgumentListType ArgumentList; ///< The formal arguments
ValueSymbolTable *SymTab; ///< Symbol table of args/instructions
std::unique_ptr<ValueSymbolTable> SymTab; ///< Symbol table of args/instructions // HLSL Change: use unique_ptr
AttributeSet AttributeSets; ///< Parameter attributes
FunctionType *Ty;

Просмотреть файл

@ -51,6 +51,12 @@ public:
return User::operator new(s, 1);
}
// HLSL Change Begin: Match operator new/delete
void operator delete(void* Ptr) {
User::operator delete(Ptr, 1);
}
// HLSL Change End
/// GlobalVariable ctor - If a parent module is specified, the global is
/// automatically inserted into the end of the specified modules global list.
GlobalVariable(Type *Ty, bool isConstant, LinkageTypes Linkage,

Просмотреть файл

@ -93,18 +93,14 @@ public:
_Ret_notnull_ // HLSL Change - SAL
LLVM_ATTRIBUTE_RETURNS_NONNULL void *Allocate(size_t Size,
size_t /*Alignment*/) {
// HLSL Change Starts - throw on OOM
void* result = malloc(Size);
if (result == nullptr) throw std::bad_alloc();
return result;
// HLSL Change Ends - throw on OOM
return ::operator new(Size); // HLSL Change: use overridable operator new and throw on OOM
}
// Pull in base class overloads.
using AllocatorBase<MallocAllocator>::Allocate;
void Deallocate(const void *Ptr, size_t /*Size*/) {
free(const_cast<void *>(Ptr));
::operator delete(const_cast<void*>(Ptr)); // HLSL Change: use overridable operator delete
}
// Pull in base class overloads.
@ -314,6 +310,7 @@ private:
void StartNewSlab() {
size_t AllocatedSlabSize = computeSlabSize(Slabs.size());
Slabs.reserve(Slabs.size() + 1); // HLSL Change: Prevent leak on push_back exception
void *NewSlab = Allocator.Allocate(AllocatedSlabSize, 0);
Slabs.push_back(NewSlab);
CurPtr = (char *)(NewSlab);

Просмотреть файл

@ -94,8 +94,10 @@ private:
/// \brief Resize the hash table, moving the old entries into the new buckets.
void resize(size_t NewSize) {
Bucket *NewBuckets = (Bucket *)std::calloc(NewSize, sizeof(Bucket));
if (NewBuckets == nullptr) throw std::bad_alloc(); // HLSL Change
// HLSL Change Begin: Use overridable operator new
Bucket* NewBuckets = new Bucket[NewSize];
std::memset(NewBuckets, 0, NewSize * sizeof(Bucket));
// HLSL Change End
// Populate NewBuckets with the old entries.
for (size_t I = 0; I < NumBuckets; ++I)
for (Item *E = Buckets[I].Head; E;) {
@ -105,7 +107,7 @@ private:
E = N;
}
free(Buckets);
delete[] Buckets; // HLSL Change: Use overridable operator delete
NumBuckets = NewSize;
Buckets = NewBuckets;
}
@ -188,11 +190,13 @@ public:
NumBuckets = 64;
// Note that we do not need to run the constructors of the individual
// Bucket objects since 'calloc' returns bytes that are all 0.
Buckets = (Bucket *)std::calloc(NumBuckets, sizeof(Bucket));
if (Buckets == nullptr) throw std::bad_alloc(); // HLSL Change
// HLSL Change Begin: Use overridable operator new
Buckets = new Bucket[NumBuckets];
std::memset(Buckets, 0, NumBuckets * sizeof(Bucket));
// HLSL Change End
}
~OnDiskChainedHashTableGenerator() { std::free(Buckets); }
~OnDiskChainedHashTableGenerator() { delete[] Buckets; } // HLSL Change: Use overridable operator delete
};
/// \brief Provides lookup on an on disk hash table.

Просмотреть файл

@ -34,11 +34,12 @@ const InterferenceCache::BlockInterference
// numbers of PhysRegs: in this case PhysRegEntries is freed and reinitialized.
void InterferenceCache::reinitPhysRegEntries() {
if (PhysRegEntriesCount == TRI->getNumRegs()) return;
free(PhysRegEntries);
delete[] PhysRegEntries; // HLSL Change: Use overridable operator delete
PhysRegEntriesCount = TRI->getNumRegs();
PhysRegEntries = (unsigned char*)
calloc(PhysRegEntriesCount, sizeof(unsigned char));
if (PhysRegEntries == nullptr) throw std::bad_alloc(); // HLSL Change
// HLSL Change Begin: Use overridable operator new
PhysRegEntries = new unsigned char[PhysRegEntriesCount];
std::memset(PhysRegEntries, 0, PhysRegEntriesCount);
// HLSL Change End
}
void InterferenceCache::init(MachineFunction *mf,

Просмотреть файл

@ -154,7 +154,7 @@ public:
PhysRegEntriesCount(0), RoundRobin(0) {}
~InterferenceCache() {
free(PhysRegEntries);
delete[] PhysRegEntries; // HLSL Change: Use overridable operator delete
}
void reinitPhysRegEntries();

Просмотреть файл

@ -388,9 +388,11 @@ void PressureDiffs::init(unsigned N) {
return;
}
Max = Size;
free(PDiffArray);
PDiffArray = reinterpret_cast<PressureDiff*>(calloc(N, sizeof(PressureDiff)));
if (PDiffArray == nullptr) throw std::bad_alloc(); // HLSL Change
// HLSL Change Begin: Use overridable operator new/delete
delete[] PDiffArray;
PDiffArray = new PressureDiff[N];
std::memset(PDiffArray, 0, N * sizeof(PressureDiff));
// HLSL Change End
}
/// Add a change in pressure to the pressure diff of a given instruction.

Просмотреть файл

@ -42,13 +42,19 @@ BasicBlock::BasicBlock(LLVMContext &C, const Twine &Name, Function *NewParent,
BasicBlock *InsertBefore)
: Value(Type::getLabelTy(C), Value::BasicBlockVal), Parent(nullptr) {
// HLSL Change Begin
// Do everything that can throw before inserting into the
// linked list, which takes ownership of this object on success.
setName(Name);
// HLSL Change End
if (NewParent)
insertInto(NewParent, InsertBefore);
else
assert(!InsertBefore &&
"Cannot insert block before another block with no function!");
setName(Name);
// setName(Name); // HLSL Change: moved above
}
void BasicBlock::insertInto(Function *NewParent, BasicBlock *InsertBefore) {

Просмотреть файл

@ -525,7 +525,7 @@ public:
for (const auto &I : LayoutInfo) {
StructLayout *Value = I.second;
Value->~StructLayout();
free(Value);
::operator delete(Value); // HLSL Change: Use overridable operator delete
}
}
@ -560,7 +560,7 @@ const StructLayout *DataLayout::getStructLayout(StructType *Ty) const {
// malloc it, then use placement new.
int NumElts = Ty->getNumElements();
StructLayout *L =
(StructLayout *)malloc(sizeof(StructLayout)+(NumElts-1) * sizeof(uint64_t));
(StructLayout *)::operator new(sizeof(StructLayout)+(NumElts-1) * sizeof(uint64_t)); // HLSL Change: Use overridable operator new
// Set SL before calling StructLayout's ctor. The ctor could cause other
// entries to be added to TheMap, invalidating our reference.

Просмотреть файл

@ -256,7 +256,7 @@ Function::Function(FunctionType *Ty, LinkageTypes Linkage, const Twine &name,
assert(FunctionType::isValidReturnType(getReturnType()) &&
"invalid return type");
setGlobalObjectSubClassData(0);
SymTab = new ValueSymbolTable();
SymTab.reset(new ValueSymbolTable()); // HLSL Change: use unique_ptr
// If the function has arguments, mark them as lazily built.
if (Ty->getNumParams())
@ -277,7 +277,7 @@ Function::~Function() {
// Delete all of the method arguments and unlink from symbol table...
ArgumentList.clear();
delete SymTab;
SymTab.reset(); // HLSL Change: use unique_ptr
// Remove the function from the on-the-side GC table.
clearGC();

Просмотреть файл

@ -32,6 +32,7 @@ LLVMContext& llvm::getGlobalContext() {
}
LLVMContext::LLVMContext() : pImpl(new LLVMContextImpl(*this)) {
std::unique_ptr<LLVMContextImpl> implPtrGuard(pImpl); // HLSL Change: Don't leak if constructor throws.
// Create the fixed metadata kinds. This is done in the same order as the
// MD_* enum values so that they correspond.
@ -104,6 +105,8 @@ LLVMContext::LLVMContext() : pImpl(new LLVMContextImpl(*this)) {
assert(DereferenceableOrNullID == MD_dereferenceable_or_null &&
"dereferenceable_or_null kind id drifted");
(void)DereferenceableOrNullID;
implPtrGuard.release(); // HLSL Change: Destructor now on the hook for destruction
}
LLVMContext::~LLVMContext() { delete pImpl; }

Просмотреть файл

@ -365,9 +365,17 @@ MDString *MDString::get(LLVMContext &Context, StringRef Str) {
auto *Entry =
StringMapEntry<MDString>::Create(Str, Store.getAllocator(), MDString());
// HLSL Change Begin: Don't leak on insertion failure
try {
bool WasInserted = Store.insert(Entry);
(void)WasInserted;
assert(WasInserted && "Expected entry to be inserted");
}
catch (...) {
Entry->Destroy();
throw;
}
// HLSL Change End
Entry->second.Entry = Entry;
return &Entry->second;
}

Просмотреть файл

@ -181,7 +181,15 @@ void Value::setValueName(ValueName *VN) {
return;
}
// HLSL Change Begin: try/catch to not leak VN on exceptions
try {
Ctx.pImpl->ValueNames[this] = VN;
}
catch (...) {
VN->Destroy();
throw;
}
// HLSL Change End
HasName = true; // HLSL Change - only set this to true after assignment
}

Просмотреть файл

@ -105,6 +105,7 @@ add_llvm_library(LLVMSupport
regexec.c
regfree.c
regstrlcpy.c
regmalloc.cpp # HLSL Change
# System
assert.cpp # HLSL Change

Просмотреть файл

@ -40,10 +40,14 @@ void StringMapImpl::init(unsigned InitSize) {
NumItems = 0;
NumTombstones = 0;
TheTable = (StringMapEntryBase **)calloc(NumBuckets+1,
sizeof(StringMapEntryBase **) +
sizeof(unsigned));
if (TheTable == nullptr) throw std::bad_alloc(); // HLSL Change
// HLSL Change Begin: Use overridable operator new
unsigned NewNumBuckets = NumBuckets;
NumBuckets = 0; // If allocation fails, we should have zero buckets.
size_t TableSize = (NewNumBuckets + 1) * (sizeof(StringMapEntryBase *) + sizeof(unsigned));
TheTable = (StringMapEntryBase **)::operator new(TableSize);
std::memset(TheTable, 0, TableSize);
NumBuckets = NewNumBuckets;
// HLSL Change End
// Allocate one extra bucket, set it to look filled so the iterators stop at
// end.
@ -201,10 +205,11 @@ unsigned StringMapImpl::RehashTable(unsigned BucketNo) {
unsigned NewBucketNo = BucketNo;
// Allocate one extra bucket which will always be non-empty. This allows the
// iterators to stop at end.
StringMapEntryBase **NewTableArray =
(StringMapEntryBase **)calloc(NewSize+1, sizeof(StringMapEntryBase *) +
sizeof(unsigned));
if (NewTableArray == nullptr) throw std::bad_alloc(); // HLSL Change
// HLSL Change Begin: Use overridable operator new
size_t NewTableSize = (NewSize + 1) * (sizeof(StringMapEntryBase*) + sizeof(unsigned));
StringMapEntryBase **NewTableArray = (StringMapEntryBase **)::operator new(NewTableSize);
std::memset(NewTableArray, 0, NewTableSize);
// HLSL Change End
unsigned *NewHashArray = (unsigned *)(NewTableArray + NewSize + 1);
NewTableArray[NewSize] = (StringMapEntryBase*)2;
@ -238,7 +243,7 @@ unsigned StringMapImpl::RehashTable(unsigned BucketNo) {
}
}
free(TheTable);
::operator delete(TheTable); // HLSL Change: Use overridable operator delete
TheTable = NewTableArray;
NumBuckets = NewSize;

Просмотреть файл

@ -187,15 +187,15 @@ llvm_regcomp(llvm_regex_t *preg, const char *pattern, int cflags)
len = strlen((const char *)pattern);
/* do the mallocs early so failure handling is easy */
g = (struct re_guts *)malloc(sizeof(struct re_guts) +
g = (struct re_guts *)regex_malloc(sizeof(struct re_guts) + // HLSL Change: Use custom allocator
(NC-1)*sizeof(cat_t));
if (g == NULL)
return(REG_ESPACE);
p->ssize = len/(size_t)2*(size_t)3 + (size_t)1; /* ugh */
p->strip = (sop *)calloc(p->ssize, sizeof(sop));
p->strip = (sop *)regex_calloc(p->ssize, sizeof(sop)); // HLSL Change: Use custom allocator
p->slen = 0;
if (p->strip == NULL) {
free((char *)g);
regex_free((char *)g); // HLSL Change: Use custom allocator
return(REG_ESPACE);
}
@ -1082,12 +1082,12 @@ allocset(struct parse *p)
assert(nc % CHAR_BIT == 0);
nbytes = nc / CHAR_BIT * css;
ptr = (cset *)realloc((char *)p->g->sets, nc * sizeof(cset));
ptr = (cset *)regex_realloc((char *)p->g->sets, no * sizeof(cset), nc * sizeof(cset)); // HLSL Change: Use custom allocator
if (ptr == NULL)
goto nomem;
p->g->sets = ptr;
ptr = (uch *)realloc((char *)p->g->setbits, nbytes);
ptr = (uch *)regex_realloc((char *)p->g->setbits, no / CHAR_BIT * css, nbytes); // HLSL Change: Use custom allocator
if (ptr == NULL)
goto nomem;
p->g->setbits = ptr;
@ -1113,9 +1113,9 @@ allocset(struct parse *p)
return(cs);
nomem:
free(p->g->sets);
regex_free(p->g->sets); // HLSL Change: Use custom allocator
p->g->sets = NULL;
free(p->g->setbits);
regex_free(p->g->setbits); // HLSL Change: Use custom allocator
p->g->setbits = NULL;
SETERROR(REG_ESPACE);
@ -1218,10 +1218,10 @@ mcadd( struct parse *p, cset *cs, const char *cp)
void *np;
cs->smultis += strlen(cp) + 1;
np = realloc(cs->multis, cs->smultis);
np = regex_realloc(cs->multis, oldend, cs->smultis); // HLSL Change: Use custom allocator
if (np == NULL) {
if (cs->multis)
free(cs->multis);
regex_free(cs->multis); // HLSL Change: Use custom allocator
cs->multis = NULL;
SETERROR(REG_ESPACE);
return;
@ -1430,7 +1430,7 @@ enlarge(struct parse *p, sopno size)
return;
}
sp = (sop *)realloc(p->strip, size*sizeof(sop));
sp = (sop *)regex_realloc(p->strip, p->ssize*sizeof(sop), size*sizeof(sop)); // HLSL Change: Use custom allocator
if (sp == NULL) {
SETERROR(REG_ESPACE);
return;
@ -1452,7 +1452,7 @@ stripsnug(struct parse *p, struct re_guts *g)
return;
}
g->strip = (sop *)realloc((char *)p->strip, p->slen * sizeof(sop));
g->strip = (sop *)regex_realloc((char *)p->strip, p->slen * sizeof(sop), p->slen * sizeof(sop)); // HLSL Change: Use custom allocator
if (g->strip == NULL) {
SETERROR(REG_ESPACE);
g->strip = p->strip;
@ -1526,7 +1526,7 @@ findmust(struct parse *p, struct re_guts *g)
return;
/* turn it into a character string */
g->must = malloc((size_t)g->mlen + 1);
g->must = regex_malloc((size_t)g->mlen + 1); // HLSL Change: Use custom allocator
if (g->must == NULL) { /* argh; just forget it */
g->mlen = 0;
return;

Просмотреть файл

@ -184,8 +184,8 @@ matcher(struct re_guts *g, const char *string, size_t nmatch,
for (;;) {
endp = fast(m, start, stop, gf, gl);
if (endp == NULL) { /* a miss */
free(m->pmatch);
free((void*)m->lastpos);
regex_free(m->pmatch); // HLSL Change: Use custom allocator
regex_free((void*)m->lastpos); // HLSL Change: Use custom allocator
STATETEARDOWN(m);
return(REG_NOMATCH);
}
@ -207,7 +207,7 @@ matcher(struct re_guts *g, const char *string, size_t nmatch,
/* oh my, they want the subexpressions... */
if (m->pmatch == NULL)
m->pmatch = (llvm_regmatch_t *)malloc((m->g->nsub + 1) *
m->pmatch = (llvm_regmatch_t *)regex_malloc((m->g->nsub + 1) * // HLSL Change: Use custom allocator
sizeof(llvm_regmatch_t));
if (m->pmatch == NULL) {
STATETEARDOWN(m);
@ -220,10 +220,10 @@ matcher(struct re_guts *g, const char *string, size_t nmatch,
dp = dissect(m, m->coldp, endp, gf, gl);
} else {
if (g->nplus > 0 && m->lastpos == NULL)
m->lastpos = (const char **)malloc((g->nplus+1) *
m->lastpos = (const char **)regex_malloc((g->nplus+1) * // HLSL Change: Use custom allocator
sizeof(char *));
if (g->nplus > 0 && m->lastpos == NULL) {
free(m->pmatch);
regex_free(m->pmatch); // HLSL Change: Use custom allocator
STATETEARDOWN(m);
return(REG_ESPACE);
}
@ -281,9 +281,9 @@ matcher(struct re_guts *g, const char *string, size_t nmatch,
}
if (m->pmatch != NULL)
free((char *)m->pmatch);
regex_free((char *)m->pmatch); // HLSL Change: Use custom allocator
if (m->lastpos != NULL)
free((char *)m->lastpos);
regex_free((char *)m->lastpos); // HLSL Change: Use custom allocator
STATETEARDOWN(m);
return(0);
}

Просмотреть файл

@ -112,10 +112,12 @@
#define ASSIGN(d, s) memmove(d, s, m->g->nstates)
#define EQ(a, b) (memcmp(a, b, m->g->nstates) == 0)
#define STATEVARS long vn; char *space
#define STATESETUP(m, nv) { (m)->space = malloc((nv)*(m)->g->nstates); \
// HLSL Change Begin: Use custom allocator
#define STATESETUP(m, nv) { (m)->space = regex_malloc((nv)*(m)->g->nstates); \
if ((m)->space == NULL) return(REG_ESPACE); \
(m)->vn = 0; }
#define STATETEARDOWN(m) { free((m)->space); }
#define STATETEARDOWN(m) { regex_free((m)->space); }
// HLSL Change End
#define SETUP(v) ((v) = &m->space[m->vn++ * m->g->nstates])
#define onestate long
#define INIT(o, n) ((o) = (n))

36
lib/Support/regmalloc.cpp Normal file
Просмотреть файл

@ -0,0 +1,36 @@
//===-- regmalloc.cpp - Memory allocation for regex implementation --------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
// Support operator new/delete overriding for regex memory allocations.
//===----------------------------------------------------------------------===//
#include "regutils.h"
#include <algorithm>
#include <new>
#include <cstring>
extern "C" {
void *regex_malloc(size_t size) {
return ::operator new(size, std::nothrow);
}
void *regex_calloc(size_t num, size_t size) {
void* ptr = regex_malloc(num * size);
if (ptr) std::memset(ptr, 0, num * size);
return ptr;
}
void* regex_realloc(void* ptr, size_t oldsize, size_t newsize) {
void* newptr = regex_malloc(newsize);
if (newptr == nullptr) return nullptr;
std::memcpy(newptr, ptr, std::min(oldsize, newsize));
regex_free(ptr);
return newptr;
}
void regex_free(void *ptr) {
return ::operator delete(ptr);
}
}

Просмотреть файл

@ -38,6 +38,8 @@
#ifndef LLVM_SUPPORT_REGUTILS_H
#define LLVM_SUPPORT_REGUTILS_H
#include <stdlib.h>
/* utility definitions */
#define NC (CHAR_MAX - CHAR_MIN + 1)
typedef unsigned char uch;
@ -55,4 +57,18 @@ typedef unsigned char uch;
#define memmove(d, s, c) bcopy(s, d, c)
#endif
// HLSL Change Begin: Use custom allocators
#ifdef __cplusplus
extern "C" {
#endif
void* regex_malloc(size_t size);
void* regex_calloc(size_t num, size_t size);
// Realloc diverges from standard because we can't implement it in terms of new[]/delete[]
void* regex_realloc(void* ptr, size_t oldsize, size_t newsize);
void regex_free(void* ptr);
#ifdef __cplusplus
}
#endif
// HLSL Change Ends
#endif

Просмотреть файл

@ -368,7 +368,7 @@ public:
~NestedNameSpecifierLocBuilder() {
if (BufferCapacity)
free(Buffer);
delete[] Buffer;
}
/// \brief Retrieve the representation of the nested-name-specifier.

Просмотреть файл

@ -184,8 +184,8 @@ namespace clang {
static TemplateIdAnnotation *
Allocate(unsigned NumArgs, SmallVectorImpl<TemplateIdAnnotation*> &List) {
TemplateIdAnnotation *TemplateId
= (TemplateIdAnnotation *)std::malloc(sizeof(TemplateIdAnnotation) +
sizeof(ParsedTemplateArgument) * NumArgs);
= (TemplateIdAnnotation *)::operator new(sizeof(TemplateIdAnnotation) +
sizeof(ParsedTemplateArgument) * NumArgs); // HLSL Change: Use overridable operator new
TemplateId->NumArgs = NumArgs;
// Default-construct nested-name-specifier.
@ -202,7 +202,7 @@ namespace clang {
void Destroy() {
SS.~CXXScopeSpec();
free(this);
::operator delete(this); // HLSL Change: Use overridable operator delete
}
};

Просмотреть файл

@ -1117,8 +1117,16 @@ DiagnosticsEngine &ASTContext::getDiagnostics() const {
AttrVec& ASTContext::getDeclAttrs(const Decl *D) {
AttrVec *&Result = DeclAttrs[D];
if (!Result) {
try { // HLSL Change
void *Mem = Allocate(sizeof(AttrVec));
Result = new (Mem) AttrVec;
// HLSL Change Begin: Don't leave empty entry on exception
}
catch (...) {
DeclAttrs.erase(D);
throw;
}
// HLSL Change End
}
return *Result;

Просмотреть файл

@ -445,10 +445,10 @@ namespace {
unsigned NewCapacity = std::max(
(unsigned)(BufferCapacity ? BufferCapacity * 2 : sizeof(void *) * 2),
(unsigned)(BufferSize + (End - Start)));
char *NewBuffer = static_cast<char *>(malloc(NewCapacity));
char *NewBuffer = new char[NewCapacity]; // HLSL Change: Use overridable operator new
if (BufferCapacity) {
memcpy(NewBuffer, Buffer, BufferSize);
free(Buffer);
delete[] Buffer; // HLSL Change: Use overridable operator delete
}
Buffer = NewBuffer;
BufferCapacity = NewCapacity;

Просмотреть файл

@ -88,8 +88,8 @@ void HTMLPrinter::HandleTranslationUnit(ASTContext &Ctx) {
// Emit the HTML.
const RewriteBuffer &RewriteBuf = R.getEditBuffer(FID);
char *Buffer = (char*)malloc(RewriteBuf.size());
char *Buffer = new char[RewriteBuf.size()]; // HLSL Change: Use overridable operator new
std::copy(RewriteBuf.begin(), RewriteBuf.end(), Buffer);
Out->write(Buffer, RewriteBuf.size());
free(Buffer);
delete[] Buffer; // HLSL Change: Use overridable operator delete
}

Просмотреть файл

@ -64,9 +64,13 @@ PragmaHandler *PragmaNamespace::FindHandler(StringRef Name,
}
void PragmaNamespace::AddPragma(PragmaHandler *Handler) {
// HLSL Change Begins: Don't leak on exceptions
std::unique_ptr<PragmaHandler> HandlerPtr(Handler);
assert(!Handlers.lookup(Handler->getName()) &&
"A handler with this name is already registered in this namespace");
Handlers[Handler->getName()] = Handler;
PragmaHandler*& MapHandler = Handlers[Handler->getName()];
MapHandler = HandlerPtr.release();
// HLSL Change Ends
}
void PragmaNamespace::RemovePragmaHandler(PragmaHandler *Handler) {
@ -724,6 +728,7 @@ void Preprocessor::HandlePragmaIncludeAlias(Token &Tok) {
/// pragma line before the pragma string starts, e.g. "STDC" or "GCC".
void Preprocessor::AddPragmaHandler(StringRef Namespace,
PragmaHandler *Handler) {
std::unique_ptr<PragmaHandler> HandlerPtr(Handler); // HLSL Change: Don't leak on exceptions
PragmaNamespace *InsertNS = PragmaHandlers.get();
// If this is specified to be in a namespace, step down into it.
@ -746,7 +751,7 @@ void Preprocessor::AddPragmaHandler(StringRef Namespace,
// Check to make sure we don't already have a pragma for this identifier.
assert(!InsertNS->FindHandler(Handler->getName()) &&
"Pragma handler already exists for this identifier!");
InsertNS->AddPragma(Handler);
InsertNS->AddPragma(HandlerPtr.release()); // HLSL Change: Don't leak on exceptions
}
/// RemovePragmaHandler - Remove the specific pragma handler from the

Просмотреть файл

@ -251,11 +251,10 @@ void Parser::initializePragmaHandlers() {
} // HLSL Change, matching HLSL check to remove pragma processing
else {
// HLSL Change Begin - packmatrix.
// The pointer ownership goes to PP, which deletes it in its destructor
// unless it is removed & deleted via resetPragmaHandlers
std::unique_ptr<PragmaHandler> pHandler(new PragmaPackMatrixHandler(Actions));
PP.AddPragmaHandler(pHandler.get());
pPackMatrixHandler = pHandler.release();
// The pointer ownership goes to PP as soon as we do the call,
// which deletes it in its destructor unless it is removed & deleted via resetPragmaHandlers
pPackMatrixHandler = new PragmaPackMatrixHandler(Actions);
PP.AddPragmaHandler(pPackMatrixHandler);
// HLSL Change End.
}
}