Do not register and de-register PassRegistrationListeners during
authorZachary Turner <zturner@google.com>
Thu, 12 Jun 2014 00:16:36 +0000 (00:16 +0000)
committerZachary Turner <zturner@google.com>
Thu, 12 Jun 2014 00:16:36 +0000 (00:16 +0000)
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

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@210724 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/IR/LegacyPassNameParser.h
include/llvm/PassSupport.h
lib/IR/Pass.cpp

index b72fc4c1a11b10f0006585ef3646bd399cd67a39..e2e4912ef64e2eac70bbf16246abe4627d91b195 100644 (file)
@@ -43,7 +43,7 @@ class PassNameParser : public PassRegistrationListener,
                        public cl::parser<const PassInfo*> {
   cl::Option *Opt;
 public:
-  PassNameParser() : Opt(nullptr) {}
+  PassNameParser();
   virtual ~PassNameParser();
 
   void initialize(cl::Option &O) {
index 5b56975b331421d3944b0f3fa7e8bb33da43e0a2..b8efbb2835ad12f79cb79e62bb5a7590bbb58f53 100644 (file)
@@ -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.
index bb55d2af7cf8d5b5ac7e6ac151cfb537c3baac20..916d79b4cbbe612175f7e59b79d204c1085f8a3a 100644 (file)
@@ -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