Skip to content

Commit 06a78fd

Browse files
committed
Don't leak EnumImplStrategy objects.
1 parent e8c1ad3 commit 06a78fd

File tree

2 files changed

+32
-23
lines changed

2 files changed

+32
-23
lines changed

lib/IRGen/GenEnum.cpp

Lines changed: 29 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -4670,10 +4670,8 @@ namespace {
46704670
};
46714671
} // end anonymous namespace
46724672

4673-
EnumImplStrategy *EnumImplStrategy::get(TypeConverter &TC,
4674-
SILType type,
4675-
EnumDecl *theEnum)
4676-
{
4673+
std::unique_ptr<EnumImplStrategy>
4674+
EnumImplStrategy::get(TypeConverter &TC, SILType type, EnumDecl *theEnum) {
46774675
unsigned numElements = 0;
46784676
TypeInfoKind tik = Loadable;
46794677
IsFixedSize_t alwaysFixedSize = IsFixedSize;
@@ -4779,43 +4777,49 @@ EnumImplStrategy *EnumImplStrategy::get(TypeConverter &TC,
47794777
&& "not all elements accounted for");
47804778

47814779
if (isResilient) {
4782-
return new ResilientEnumImplStrategy(TC.IGM,
4780+
return std::unique_ptr<EnumImplStrategy>(
4781+
new ResilientEnumImplStrategy(TC.IGM,
47834782
numElements,
47844783
std::move(elementsWithPayload),
4785-
std::move(elementsWithNoPayload));
4784+
std::move(elementsWithNoPayload)));
47864785
}
47874786

47884787
// Enums imported from Clang or marked with @objc use C-compatible layout.
47894788
if (theEnum->hasClangNode() || theEnum->isObjC()) {
47904789
assert(elementsWithPayload.size() == 0 && "C enum with payload?!");
47914790
assert(alwaysFixedSize == IsFixedSize && "C enum with resilient payload?!");
4792-
return new CCompatibleEnumImplStrategy(TC.IGM, tik, alwaysFixedSize,
4791+
return std::unique_ptr<EnumImplStrategy>(
4792+
new CCompatibleEnumImplStrategy(TC.IGM, tik, alwaysFixedSize,
47934793
numElements,
47944794
std::move(elementsWithPayload),
4795-
std::move(elementsWithNoPayload));
4795+
std::move(elementsWithNoPayload)));
47964796
}
47974797

47984798
if (numElements <= 1)
4799-
return new SingletonEnumImplStrategy(TC.IGM, tik, alwaysFixedSize,
4799+
return std::unique_ptr<EnumImplStrategy>(
4800+
new SingletonEnumImplStrategy(TC.IGM, tik, alwaysFixedSize,
48004801
numElements,
48014802
std::move(elementsWithPayload),
4802-
std::move(elementsWithNoPayload));
4803+
std::move(elementsWithNoPayload)));
48034804
if (elementsWithPayload.size() > 1)
4804-
return new MultiPayloadEnumImplStrategy(TC.IGM, tik, alwaysFixedSize,
4805+
return std::unique_ptr<EnumImplStrategy>(
4806+
new MultiPayloadEnumImplStrategy(TC.IGM, tik, alwaysFixedSize,
48054807
allowFixedLayoutOptimizations,
48064808
numElements,
48074809
std::move(elementsWithPayload),
4808-
std::move(elementsWithNoPayload));
4810+
std::move(elementsWithNoPayload)));
48094811
if (elementsWithPayload.size() == 1)
4810-
return new SinglePayloadEnumImplStrategy(TC.IGM, tik, alwaysFixedSize,
4812+
return std::unique_ptr<EnumImplStrategy>(
4813+
new SinglePayloadEnumImplStrategy(TC.IGM, tik, alwaysFixedSize,
48114814
numElements,
48124815
std::move(elementsWithPayload),
4813-
std::move(elementsWithNoPayload));
4816+
std::move(elementsWithNoPayload)));
48144817

4815-
return new NoPayloadEnumImplStrategy(TC.IGM, tik, alwaysFixedSize,
4818+
return std::unique_ptr<EnumImplStrategy>(
4819+
new NoPayloadEnumImplStrategy(TC.IGM, tik, alwaysFixedSize,
48164820
numElements,
48174821
std::move(elementsWithPayload),
4818-
std::move(elementsWithNoPayload));
4822+
std::move(elementsWithNoPayload)));
48194823
}
48204824

48214825
namespace {
@@ -4829,6 +4833,10 @@ namespace {
48294833
EnumTypeInfoBase(EnumImplStrategy &strategy, AA &&...args)
48304834
: BaseTypeInfo(std::forward<AA>(args)...), Strategy(strategy) {}
48314835

4836+
~EnumTypeInfoBase() {
4837+
delete &Strategy;
4838+
}
4839+
48324840
llvm::StructType *getStorageType() const {
48334841
return cast<llvm::StructType>(TypeInfo::getStorageType());
48344842
}
@@ -5502,11 +5510,12 @@ const TypeInfo *TypeConverter::convertEnumType(TypeBase *key, CanType type,
55025510
SILType loweredTy = SILType::getPrimitiveAddressType(type);
55035511

55045512
// Determine the implementation strategy.
5505-
EnumImplStrategy *strategy = EnumImplStrategy::get(*this, loweredTy, theEnum);
5513+
auto strategy = EnumImplStrategy::get(*this, loweredTy, theEnum).release();
5514+
5515+
// Create the TI. The TI will delete the strategy in its destructor.
5516+
auto *ti =
5517+
strategy->completeEnumTypeLayout(*this, loweredTy, theEnum, storageType);
55065518

5507-
// Create the TI.
5508-
auto *ti = strategy->completeEnumTypeLayout(*this, loweredTy,
5509-
theEnum, storageType);
55105519
// Assert that the layout query functions for fixed-layout enums work, for
55115520
// LLDB's sake.
55125521
#ifndef NDEBUG

lib/IRGen/GenEnum.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -165,9 +165,9 @@ class EnumImplStrategy {
165165
virtual ~EnumImplStrategy() { }
166166

167167
/// Construct a layout strategy appropriate to the enum type.
168-
static EnumImplStrategy *get(TypeConverter &TC,
169-
SILType Type,
170-
EnumDecl *theEnum);
168+
static std::unique_ptr<EnumImplStrategy> get(TypeConverter &TC,
169+
SILType Type,
170+
EnumDecl *theEnum);
171171

172172
/// Given an incomplete StructType for the enum, completes layout of the
173173
/// storage type, calculates its size and alignment, and produces the

0 commit comments

Comments
 (0)