diff --git a/include/llvm/Support/CrashRecoveryContext.h b/include/llvm/Support/CrashRecoveryContext.h index 40b5286d901..6e975fe3a1c 100644 --- a/include/llvm/Support/CrashRecoveryContext.h +++ b/include/llvm/Support/CrashRecoveryContext.h @@ -95,10 +95,16 @@ public: class CrashRecoveryContextCleanup { public: + bool cleanupFired; + enum ProvidedCleanups { DeleteCleanup, DestructorCleanup }; + + CrashRecoveryContextCleanup() : cleanupFired(false) {} virtual ~CrashRecoveryContextCleanup(); virtual void recoverResources() = 0; - template static CrashRecoveryContextCleanup *create(T *); + template static CrashRecoveryContextCleanup *create(T *, + ProvidedCleanups cleanupKind = + CrashRecoveryContextCleanup::DeleteCleanup); private: friend class CrashRecoveryContext; @@ -131,15 +137,25 @@ public: template struct CrashRecoveryContextTrait { - static inline CrashRecoveryContextCleanup *createCleanup(T *resource) { - return new CrashRecoveryContextDeleteCleanup(resource); + static inline CrashRecoveryContextCleanup * + createCleanup(T *resource, + CrashRecoveryContextCleanup::ProvidedCleanups cleanup) { + switch (cleanup) { + case CrashRecoveryContextCleanup::DeleteCleanup: + return new CrashRecoveryContextDeleteCleanup(resource); + case CrashRecoveryContextCleanup::DestructorCleanup: + return new CrashRecoveryContextDestructorCleanup(resource); + } + return 0; } }; template -inline CrashRecoveryContextCleanup* CrashRecoveryContextCleanup::create(T *x) { +inline CrashRecoveryContextCleanup* +CrashRecoveryContextCleanup::create(T *x, + CrashRecoveryContextCleanup::ProvidedCleanups cleanupKind) { return CrashRecoveryContext::GetCurrent() ? - CrashRecoveryContextTrait::createCleanup(x) : + CrashRecoveryContextTrait::createCleanup(x, cleanupKind) : 0; } @@ -155,7 +171,7 @@ public: context->registerCleanup(cleanup); } ~CrashRecoveryContextCleanupRegistrar() { - if (cleanup) { + if (cleanup && !cleanup->cleanupFired) { if (context) context->unregisterCleanup(cleanup); else diff --git a/lib/Support/CrashRecoveryContext.cpp b/lib/Support/CrashRecoveryContext.cpp index d4e21a3a826..e558662611f 100644 --- a/lib/Support/CrashRecoveryContext.cpp +++ b/lib/Support/CrashRecoveryContext.cpp @@ -65,6 +65,7 @@ CrashRecoveryContext::~CrashRecoveryContext() { while (i) { CrashRecoveryContextCleanup *tmp = i; i = tmp->next; + tmp->cleanupFired = true; tmp->recoverResources(); delete tmp; }