diff options
author | Justin Bogner <mail@justinbogner.com> | 2016-09-06 17:18:22 +0000 |
---|---|---|
committer | Justin Bogner <mail@justinbogner.com> | 2016-09-06 17:18:22 +0000 |
commit | 1c039155009c04f4efc37fd76ad75d1342edfccd (patch) | |
tree | 9038c8830ec86482c0142418b537d74f36015303 /llvm/tools/bugpoint/ExecutionDriver.cpp | |
parent | 18ea094df15dfb8b41d4798bb1cbb14c434fa98d (diff) | |
download | bcm5719-llvm-1c039155009c04f4efc37fd76ad75d1342edfccd.tar.gz bcm5719-llvm-1c039155009c04f4efc37fd76ad75d1342edfccd.zip |
bugpoint: Return Errors instead of passing around strings
This replaces the threading of `std::string &Error` through all of
these APIs with checked Error returns instead. There are very few
places here that actually emit any errors right now, but threading the
APIs through will allow us to replace a bunch of exit(1)'s that are
scattered through this code with proper error handling.
This is more or less NFC, but does move around where a couple of error
messages are printed out.
llvm-svn: 280720
Diffstat (limited to 'llvm/tools/bugpoint/ExecutionDriver.cpp')
-rw-r--r-- | llvm/tools/bugpoint/ExecutionDriver.cpp | 112 |
1 files changed, 58 insertions, 54 deletions
diff --git a/llvm/tools/bugpoint/ExecutionDriver.cpp b/llvm/tools/bugpoint/ExecutionDriver.cpp index 695461e2d50..b0f3880fa74 100644 --- a/llvm/tools/bugpoint/ExecutionDriver.cpp +++ b/llvm/tools/bugpoint/ExecutionDriver.cpp @@ -141,7 +141,7 @@ cl::list<std::string> CCToolArgv("gcc-tool-args", cl::Positional, /// initializeExecutionEnvironment - This method is used to set up the /// environment for executing LLVM programs. /// -bool BugDriver::initializeExecutionEnvironment() { +Error BugDriver::initializeExecutionEnvironment() { outs() << "Initializing execution environment: "; // Create an instance of the AbstractInterpreter interface as specified on @@ -261,14 +261,17 @@ bool BugDriver::initializeExecutionEnvironment() { } // If there was an error creating the selected interpreter, quit with error. - return Interpreter == nullptr; + if (Interpreter == nullptr) + return make_error<StringError>("Failed to init execution environment", + inconvertibleErrorCode()); + return Error::success(); } /// compileProgram - Try to compile the specified module, returning false and /// setting Error if an error occurs. This is used for code generation /// crash testing. /// -void BugDriver::compileProgram(Module *M, std::string *Error) const { +Error BugDriver::compileProgram(Module *M) const { // Emit the program to a bitcode file... SmallString<128> BitcodeFile; int BitcodeFD; @@ -289,17 +292,18 @@ void BugDriver::compileProgram(Module *M, std::string *Error) const { FileRemover BitcodeFileRemover(BitcodeFile.str(), !SaveTemps); // Actually compile the program! - Interpreter->compileProgram(BitcodeFile.str(), Error, Timeout, MemoryLimit); + return Interpreter->compileProgram(BitcodeFile.str(), Timeout, MemoryLimit); } /// executeProgram - This method runs "Program", capturing the output of the /// program to a file, returning the filename of the file. A recommended /// filename may be optionally specified. /// -std::string -BugDriver::executeProgram(const Module *Program, std::string OutputFile, - std::string BitcodeFile, const std::string &SharedObj, - AbstractInterpreter *AI, std::string *Error) const { +Expected<std::string> BugDriver::executeProgram(const Module *Program, + std::string OutputFile, + std::string BitcodeFile, + const std::string &SharedObj, + AbstractInterpreter *AI) const { if (!AI) AI = Interpreter; assert(AI && "Interpreter should have been created already!"); @@ -347,13 +351,13 @@ BugDriver::executeProgram(const Module *Program, std::string OutputFile, if (!SharedObj.empty()) SharedObjs.push_back(SharedObj); - int RetVal = AI->ExecuteProgram(BitcodeFile, InputArgv, InputFile, OutputFile, - Error, AdditionalLinkerArgs, SharedObjs, - Timeout, MemoryLimit); - if (!Error->empty()) - return OutputFile; + Expected<int> RetVal = AI->ExecuteProgram(BitcodeFile, InputArgv, InputFile, + OutputFile, AdditionalLinkerArgs, + SharedObjs, Timeout, MemoryLimit); + if (Error E = RetVal.takeError()) + return std::move(E); - if (RetVal == -1) { + if (*RetVal == -1) { errs() << "<timeout>"; static bool FirstTimeout = true; if (FirstTimeout) { @@ -372,7 +376,7 @@ BugDriver::executeProgram(const Module *Program, std::string OutputFile, if (AppendProgramExitCode) { std::ofstream outFile(OutputFile.c_str(), std::ios_base::app); - outFile << "exit " << RetVal << '\n'; + outFile << "exit " << *RetVal << '\n'; outFile.close(); } @@ -383,29 +387,27 @@ BugDriver::executeProgram(const Module *Program, std::string OutputFile, /// executeProgramSafely - Used to create reference output with the "safe" /// backend, if reference output is not provided. /// -std::string BugDriver::executeProgramSafely(const Module *Program, - const std::string &OutputFile, - std::string *Error) const { - return executeProgram(Program, OutputFile, "", "", SafeInterpreter, Error); +Expected<std::string> +BugDriver::executeProgramSafely(const Module *Program, + const std::string &OutputFile) const { + return executeProgram(Program, OutputFile, "", "", SafeInterpreter); } -std::string BugDriver::compileSharedObject(const std::string &BitcodeFile, - std::string &Error) { +Expected<std::string> +BugDriver::compileSharedObject(const std::string &BitcodeFile) { assert(Interpreter && "Interpreter should have been created already!"); std::string OutputFile; // Using the known-good backend. - CC::FileType FT = SafeInterpreter->OutputCode(BitcodeFile, OutputFile, Error); - if (!Error.empty()) - return ""; + Expected<CC::FileType> FT = + SafeInterpreter->OutputCode(BitcodeFile, OutputFile); + if (Error E = FT.takeError()) + return std::move(E); std::string SharedObjectFile; - bool Failure = cc->MakeSharedObject(OutputFile, FT, SharedObjectFile, - AdditionalLinkerArgs, Error); - if (!Error.empty()) - return ""; - if (Failure) - exit(1); + if (Error E = cc->MakeSharedObject(OutputFile, *FT, SharedObjectFile, + AdditionalLinkerArgs)) + return std::move(E); // Remove the intermediate C file sys::fs::remove(OutputFile); @@ -418,25 +420,27 @@ std::string BugDriver::compileSharedObject(const std::string &BitcodeFile, /// otherwise. Note: initializeExecutionEnvironment should be called BEFORE /// this function. /// -bool BugDriver::createReferenceFile(Module *M, const std::string &Filename) { - std::string Error; - compileProgram(Program, &Error); - if (!Error.empty()) - return false; +Error BugDriver::createReferenceFile(Module *M, const std::string &Filename) { + if (Error E = compileProgram(Program)) + return E; - ReferenceOutputFile = executeProgramSafely(Program, Filename, &Error); - if (!Error.empty()) { - errs() << Error; + Expected<std::string> Result = executeProgramSafely(Program, Filename); + if (Error E = Result.takeError()) { if (Interpreter != SafeInterpreter) { - errs() << "*** There is a bug running the \"safe\" backend. Either" - << " debug it (for example with the -run-jit bugpoint option," - << " if JIT is being used as the \"safe\" backend), or fix the" - << " error some other way.\n"; + E = joinErrors( + std::move(E), + make_error<StringError>( + "*** There is a bug running the \"safe\" backend. Either" + " debug it (for example with the -run-jit bugpoint option," + " if JIT is being used as the \"safe\" backend), or fix the" + " error some other way.\n", + inconvertibleErrorCode())); } - return false; + return E; } + ReferenceOutputFile = *Result; outs() << "\nReference output is: " << ReferenceOutputFile << "\n\n"; - return true; + return Error::success(); } /// diffProgram - This method executes the specified module and diffs the @@ -444,19 +448,19 @@ bool BugDriver::createReferenceFile(Module *M, const std::string &Filename) { /// is different, 1 is returned. If there is a problem with the code /// generator (e.g., llc crashes), this will set ErrMsg. /// -bool BugDriver::diffProgram(const Module *Program, - const std::string &BitcodeFile, - const std::string &SharedObject, bool RemoveBitcode, - std::string *ErrMsg) const { +Expected<bool> BugDriver::diffProgram(const Module *Program, + const std::string &BitcodeFile, + const std::string &SharedObject, + bool RemoveBitcode) const { // Execute the program, generating an output file... - std::string Output( - executeProgram(Program, "", BitcodeFile, SharedObject, nullptr, ErrMsg)); - if (!ErrMsg->empty()) - return false; + Expected<std::string> Output = + executeProgram(Program, "", BitcodeFile, SharedObject, nullptr); + if (Error E = Output.takeError()) + return std::move(E); std::string Error; bool FilesDifferent = false; - if (int Diff = DiffFilesWithTolerance(ReferenceOutputFile, Output, + if (int Diff = DiffFilesWithTolerance(ReferenceOutputFile, *Output, AbsTolerance, RelTolerance, &Error)) { if (Diff == 2) { errs() << "While diffing output: " << Error << '\n'; @@ -465,7 +469,7 @@ bool BugDriver::diffProgram(const Module *Program, FilesDifferent = true; } else { // Remove the generated output if there are no differences. - sys::fs::remove(Output); + sys::fs::remove(*Output); } // Remove the bitcode file if we are supposed to. |