Index: src/IceCompileServer.cpp |
diff --git a/src/IceCompileServer.cpp b/src/IceCompileServer.cpp |
index db0694b9556653f230c8af08b6271dd2baff9f69..e2d7e38bdfb1e19d11930d618d28302c325bd115 100644 |
--- a/src/IceCompileServer.cpp |
+++ b/src/IceCompileServer.cpp |
@@ -93,6 +93,33 @@ ErrorCodes getReturnValue(const Ice::ClFlagsExtra &Flags, ErrorCodes Val) { |
return Val; |
} |
+// Reports fatal error message, and then exits with success status 0. |
+void reportFatalErrorThenExitSuccess(void * UserData, |
+ const std::string &Reason, |
+ bool GenCrashDag) { |
+ (void)UserData; |
+ (void)GenCrashDag; |
+ |
+ // Note: This code is (mostly) copied from llvm/lib/Support/ErrorHandling.cpp |
+ |
+ // Blast the result out to stderr. We don't try hard to make sure this |
+ // succeeds (e.g. handling EINTR) and we can't use errs() here because |
+ // raw ostreams can call report_fatal_error. |
+ llvm::SmallVector<char, 64> Buffer; |
+ llvm::raw_svector_ostream OS(Buffer); |
+ OS << "LLVM ERROR: " << Reason << "\n"; |
+ llvm::StringRef MessageStr = OS.str(); |
+ ssize_t written = ::write(2, MessageStr.data(), MessageStr.size()); |
+ (void)written; // If something went wrong, we deliberately just give up. |
+ |
+ // If we reached here, we are failing ungracefully. Run the interrupt handlers |
+ // to make sure any special cleanups get done, in particular that we remove |
+ // files registered with RemoveFileOnSignal. |
+ llvm::sys::RunInterruptHandlers(); |
+ |
+ exit(0); |
+} |
+ |
} // end of anonymous namespace |
void CLCompileServer::run() { |
@@ -105,6 +132,10 @@ void CLCompileServer::run() { |
ClFlags::getParsedClFlags(Flags); |
ClFlags::getParsedClFlagsExtra(ExtraFlags); |
+ // Override report_fatal_error if we want to exit with 0 status. |
+ if (ExtraFlags.getAlwaysExitSuccess()) |
+ llvm::install_fatal_error_handler(reportFatalErrorThenExitSuccess, this); |
+ |
std::error_code EC; |
std::unique_ptr<Ostream> Ls = makeStream(ExtraFlags.getLogFilename(), EC); |
if (EC) { |