From 39c422da57c58900eb4346cd3f69bea3e20b3ce9 Mon Sep 17 00:00:00 2001 From: Zachary Turner Date: Thu, 12 Jun 2014 00:16:36 +0000 Subject: [PATCH] Do not register and de-register PassRegistrationListeners during construction and destruction. PassRegistrationListener is intended for use as a generic listener. In some cases, PassRegistrationListener-derived classes were being created, and automatically registered and de-registered in static constructors and destructors. Since ManagedStatics are destroyed prior to program shutdown, this leads to errors where an attempt is made to access a ManagedStatic that has already been destroyed. Reviewed by: rnk, dblaikie Differential Revision: http://reviews.llvm.org/D4106 llvm-svn: 210724 --- llvm/include/llvm/IR/LegacyPassNameParser.h | 2 +- llvm/include/llvm/PassSupport.h | 13 +++---------- llvm/lib/IR/Pass.cpp | 22 ++++++++++------------ 3 files changed, 14 insertions(+), 23 deletions(-) diff --git a/llvm/include/llvm/IR/LegacyPassNameParser.h b/llvm/include/llvm/IR/LegacyPassNameParser.h index b72fc4c..e2e4912 100644 --- a/llvm/include/llvm/IR/LegacyPassNameParser.h +++ b/llvm/include/llvm/IR/LegacyPassNameParser.h @@ -43,7 +43,7 @@ class PassNameParser : public PassRegistrationListener, public cl::parser { cl::Option *Opt; public: - PassNameParser() : Opt(nullptr) {} + PassNameParser(); virtual ~PassNameParser(); void initialize(cl::Option &O) { diff --git a/llvm/include/llvm/PassSupport.h b/llvm/include/llvm/PassSupport.h index 5b56975b..b8efbb2 100644 --- a/llvm/include/llvm/PassSupport.h +++ b/llvm/include/llvm/PassSupport.h @@ -337,19 +337,12 @@ struct RegisterAnalysisGroup : public RegisterAGBase { /// clients that are interested in which passes get registered and unregistered /// at runtime (which can be because of the RegisterPass constructors being run /// as the program starts up, or may be because a shared object just got -/// loaded). Deriving from the PassRegistrationListener class automatically -/// registers your object to receive callbacks indicating when passes are loaded -/// and removed. +/// loaded). /// struct PassRegistrationListener { - /// PassRegistrationListener ctor - Add the current object to the list of - /// PassRegistrationListeners... - PassRegistrationListener(); - - /// dtor - Remove object from list of listeners... - /// - virtual ~PassRegistrationListener(); + PassRegistrationListener() {} + virtual ~PassRegistrationListener() {} /// Callback functions - These functions are invoked whenever a pass is loaded /// or removed from the current executable. diff --git a/llvm/lib/IR/Pass.cpp b/llvm/lib/IR/Pass.cpp index bb55d2af..916d79b 100644 --- a/llvm/lib/IR/Pass.cpp +++ b/llvm/lib/IR/Pass.cpp @@ -224,17 +224,6 @@ RegisterAGBase::RegisterAGBase(const char *Name, const void *InterfaceID, // PassRegistrationListener implementation // -// PassRegistrationListener ctor - Add the current object to the list of -// PassRegistrationListeners... -PassRegistrationListener::PassRegistrationListener() { - PassRegistry::getPassRegistry()->addRegistrationListener(this); -} - -// dtor - Remove object from list of listeners... -PassRegistrationListener::~PassRegistrationListener() { - PassRegistry::getPassRegistry()->removeRegistrationListener(this); -} - // enumeratePasses - Iterate over the registered passes, calling the // passEnumerate callback on each PassInfo object. // @@ -242,7 +231,16 @@ void PassRegistrationListener::enumeratePasses() { PassRegistry::getPassRegistry()->enumerateWith(this); } -PassNameParser::~PassNameParser() {} +PassNameParser::PassNameParser() + : Opt(nullptr) { + PassRegistry::getPassRegistry()->addRegistrationListener(this); +} + +PassNameParser::~PassNameParser() { + // This only gets called during static destruction, in which case the + // PassRegistry will have already been destroyed by llvm_shutdown(). So + // attempting to remove the registration listener is an error. +} //===----------------------------------------------------------------------===// // AnalysisUsage Class Implementation -- 2.7.4