Fix a bug in my previous patch by restoring the behavior that the fatal
authorChandler Carruth <chandlerc@gmail.com>
Fri, 27 Jun 2014 16:37:27 +0000 (16:37 +0000)
committerChandler Carruth <chandlerc@gmail.com>
Fri, 27 Jun 2014 16:37:27 +0000 (16:37 +0000)
error handler is only registered once.

To avoid the use of std::call_once (the obvious way to do this) I've
wrapped everything up into a managed static and done the work in
a constructor. Silly, but it should be effective.

Some out-of-tree libclang users reported this to me, and I've asked them
to put together a test case which exhibits this behavior, but I wanted
to fix things ASAP since the nature of the fix is straight forward.

llvm-svn: 211905

clang/tools/libclang/CIndex.cpp

index 1d6258b..fdd6334 100644 (file)
@@ -2600,6 +2600,16 @@ static void fatal_error_handler(void *user_data, const std::string& reason,
   ::abort();
 }
 
+namespace {
+struct RegisterFatalErrorHandler {
+  RegisterFatalErrorHandler() {
+    llvm::install_fatal_error_handler(fatal_error_handler, nullptr);
+  }
+};
+}
+
+static llvm::ManagedStatic<RegisterFatalErrorHandler> RegisterFatalErrorHandlerOnce;
+
 extern "C" {
 CXIndex clang_createIndex(int excludeDeclarationsFromPCH,
                           int displayDiagnostics) {
@@ -2608,7 +2618,10 @@ CXIndex clang_createIndex(int excludeDeclarationsFromPCH,
   if (!getenv("LIBCLANG_DISABLE_CRASH_RECOVERY"))
     llvm::CrashRecoveryContext::Enable();
 
-  llvm::install_fatal_error_handler(fatal_error_handler, nullptr);
+  // Look through the managed static to trigger construction of the managed
+  // static which registers our fatal error handler. This ensures it is only
+  // registered once.
+  (void)*RegisterFatalErrorHandlerOnce;
 
   CIndexer *CIdxr = new CIndexer();
   if (excludeDeclarationsFromPCH)