diff --git a/llvm/lib/IR/Verifier.cpp b/llvm/lib/IR/Verifier.cpp --- a/llvm/lib/IR/Verifier.cpp +++ b/llvm/lib/IR/Verifier.cpp @@ -5118,6 +5118,42 @@ "inconsistent use of embedded source"); } +static void report_broken(Module *M, Function *F) { + std::string message = F ? "Broken function found, compilation aborted!" + : "Broken module found, compilation aborted!"; + if (!M) { + M = new Module(F->getName(), F->getContext()); + M->getFunctionList().push_back(F); + } + int FD; + SmallString<128> GeneratedUniqPath; + // Create a template based on some characteristics of the failure, + // mangled and chopped to be safe for most file systems + std::string Pattern( + (F && F->hasName() ? F->getName() : M->getName()).slice(0, 32)); + auto isunsafe = [](unsigned char C) { + return !(('A' <= C && C <= 'Z') || ('a' <= C && C <= 'z') || + ('0' <= C && C <= '9') || C == '-' || C == '_'); + }; + std::replace_if(Pattern.begin(), Pattern.end(), isunsafe, '_'); + Pattern = "llvm-" + Pattern + "-%%%%%%.ll"; + if (!sys::fs::createUniqueFile(Pattern, FD, GeneratedUniqPath)) { + raw_fd_ostream OS(FD, true, false); + // We'd like to use this, but linking can't handle it, + // so instead, we'll use the text format. + // WriteBitcodeToFile(*M, OS); + M->print(OS, nullptr, true, true); + message += "\nBroken bitcode dumped to \""; + message += GeneratedUniqPath; + message += "\""; + } + report_fatal_error(message); +} + +static void report_broken(Function &F) { report_broken(F.getParent(), &F); } + +static void report_broken(Module &M) { report_broken(&M, nullptr); } + //===----------------------------------------------------------------------===// // Implement the public interfaces to this file... //===----------------------------------------------------------------------===// @@ -5175,8 +5211,8 @@ bool runOnFunction(Function &F) override { if (!V->verify(F) && FatalErrors) { - errs() << "in function " << F.getName() << '\n'; - report_fatal_error("Broken function found, compilation aborted!"); + errs() << "in function " << F.getName() << '\n'; + report_broken(F); } return false; } @@ -5189,7 +5225,7 @@ HasErrors |= !V->verify(); if (FatalErrors && (HasErrors || V->hasBrokenDebugInfo())) - report_fatal_error("Broken module found, compilation aborted!"); + report_broken(M); return false; } @@ -5569,7 +5605,7 @@ PreservedAnalyses VerifierPass::run(Module &M, ModuleAnalysisManager &AM) { auto Res = AM.getResult(M); if (FatalErrors && (Res.IRBroken || Res.DebugInfoBroken)) - report_fatal_error("Broken module found, compilation aborted!"); + report_broken(M); return PreservedAnalyses::all(); } @@ -5577,7 +5613,7 @@ PreservedAnalyses VerifierPass::run(Function &F, FunctionAnalysisManager &AM) { auto res = AM.getResult(F); if (res.IRBroken && FatalErrors) - report_fatal_error("Broken function found, compilation aborted!"); + report_broken(F); return PreservedAnalyses::all(); }