Skip to content

Commit 053d56f

Browse files
committed
IRGen: correct some type deletion
ASAN identified mismatched `operator new` and `operator delete` on these types. The reason for this is the sized allocation for the tail packing involved. Provide the associated `operator delete` that releases the memory. Note that the `operator delete` is static and does not have the implicit `this` pointer, and we cannot use the name `this` for the variable.
1 parent dcfc536 commit 053d56f

File tree

3 files changed

+25
-3
lines changed

3 files changed

+25
-3
lines changed

lib/IRGen/GenExistential.cpp

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,7 @@ namespace {
130130
class ExistentialTypeInfoBase : public Base,
131131
private llvm::TrailingObjects<Derived, const ProtocolDecl *> {
132132
friend class llvm::TrailingObjects<Derived, const ProtocolDecl *>;
133+
using Tail = llvm::TrailingObjects<Derived, const ProtocolDecl *>;
133134

134135
/// The number of non-trivial protocols for this existential.
135136
unsigned NumStoredProtocols;
@@ -157,12 +158,19 @@ namespace {
157158
create(ArrayRef<const ProtocolDecl *> protocols, As &&...args)
158159
{
159160
void *buffer = operator new(
160-
llvm::TrailingObjects<Derived, const ProtocolDecl *>::
161-
template totalSizeToAlloc<const ProtocolDecl *>(
162-
protocols.size()));
161+
Tail::template totalSizeToAlloc<const ProtocolDecl *>(
162+
protocols.size()));
163163
return new (buffer) Derived(protocols, std::forward<As>(args)...);
164164
}
165165

166+
void operator delete(void *ptr) {
167+
const auto *pThis = static_cast<ExistentialTypeInfoBase *>(ptr);
168+
const size_t count = pThis->NumStoredProtocols;
169+
const size_t size =
170+
Tail::template totalSizeToAlloc<const ProtocolDecl *>(count);
171+
::operator delete(ptr, size);
172+
}
173+
166174
/// Returns the number of protocol witness tables directly carried
167175
/// by values of this type.
168176
unsigned getNumStoredProtocols() const { return NumStoredProtocols; }

lib/IRGen/GenRecord.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,13 @@ class RecordTypeInfoImpl : public Base,
157157
return new(buffer) Impl(fields, std::forward<As>(args)...);
158158
}
159159

160+
void operator delete(void *ptr) {
161+
const auto *pThis = static_cast<RecordTypeInfoImpl *>(ptr);
162+
const size_t count = pThis->NumFields;
163+
const size_t size = Impl::template totalSizeToAlloc<FieldImpl>(count);
164+
::operator delete(ptr, size);
165+
}
166+
160167
bool areFieldsABIAccessible() const {
161168
return AreFieldsABIAccessible;
162169
}

lib/IRGen/ProtocolInfo.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -230,6 +230,13 @@ class ProtocolInfo final :
230230
ProtocolInfoKind kind);
231231

232232
public:
233+
void operator delete(void *ptr) {
234+
const auto *pThis = static_cast<ProtocolInfo *>(ptr);
235+
const size_t count = pThis->NumTableEntries;
236+
const size_t size = totalSizeToAlloc<WitnessTableEntry>(count);
237+
::operator delete(ptr, size);
238+
}
239+
233240
/// The number of witness slots in a conformance to this protocol;
234241
/// in other words, the size of the table in words.
235242
unsigned getNumWitnesses() const {

0 commit comments

Comments
 (0)