#include "BugDriver.h"
#include "ListReducer.h"
#include "ToolRunner.h"
-#include "llvm/Analysis/Verifier.h"
#include "llvm/Config/config.h" // for HAVE_LINK_R
#include "llvm/IR/Constants.h"
#include "llvm/IR/DerivedTypes.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/Module.h"
-#include "llvm/Linker.h"
+#include "llvm/IR/Verifier.h"
+#include "llvm/Linker/Linker.h"
#include "llvm/Pass.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/FileUtilities.h"
public:
ReduceMiscompilingPasses(BugDriver &bd) : BD(bd) {}
- virtual TestResult doTest(std::vector<std::string> &Prefix,
- std::vector<std::string> &Suffix,
- std::string &Error);
+ TestResult doTest(std::vector<std::string> &Prefix,
+ std::vector<std::string> &Suffix,
+ std::string &Error) override;
};
}
// Ok, so now we know that the prefix passes work, try running the suffix
// passes on the result of the prefix passes.
//
- OwningPtr<Module> PrefixOutput(ParseInputFile(BitcodeResult,
- BD.getContext()));
+ std::unique_ptr<Module> PrefixOutput(
+ ParseInputFile(BitcodeResult, BD.getContext()));
if (!PrefixOutput) {
errs() << BD.getToolName() << ": Error reading bitcode file '"
<< BitcodeResult << "'!\n";
<< "' passes compile correctly after the '"
<< getPassesString(Prefix) << "' passes: ";
- OwningPtr<Module> OriginalInput(BD.swapProgramIn(PrefixOutput.take()));
+ std::unique_ptr<Module> OriginalInput(
+ BD.swapProgramIn(PrefixOutput.release()));
if (BD.runPasses(BD.getProgram(), Suffix, BitcodeResult, false/*delete*/,
true/*quiet*/)) {
errs() << " Error running this sequence of passes"
// Otherwise, we must not be running the bad pass anymore.
outs() << " yup.\n"; // No miscompilation!
// Restore orig program & free test.
- delete BD.swapProgramIn(OriginalInput.take());
+ delete BD.swapProgramIn(OriginalInput.release());
return NoFailure;
}
std::string &))
: BD(bd), TestFn(F) {}
- virtual TestResult doTest(std::vector<Function*> &Prefix,
- std::vector<Function*> &Suffix,
- std::string &Error) {
+ TestResult doTest(std::vector<Function*> &Prefix,
+ std::vector<Function*> &Suffix,
+ std::string &Error) override {
if (!Suffix.empty()) {
bool Ret = TestFuncs(Suffix, Error);
if (!Error.empty())
if (!Error.empty()) {
// Delete the linked module
delete M1;
- return NULL;
+ return nullptr;
}
return M1;
}
false, Error, Failure);
if (!New)
return false;
+
// Delete the original and set the new program.
- delete BD.swapProgramIn(New);
+ Module *Old = BD.swapProgramIn(New);
+ for (unsigned i = 0, e = MiscompiledFunctions.size(); i != e; ++i)
+ MiscompiledFunctions[i] = cast<Function>(VMap[MiscompiledFunctions[i]]);
+ delete Old;
+
if (Failure) {
BD.switchToInterpreter(AI);
outs() << " Testing after loop extraction:\n";
// Clone modules, the tester function will free them.
- Module *TOLEBackup = CloneModule(ToOptimizeLoopExtracted);
- Module *TNOBackup = CloneModule(ToNotOptimize);
+ Module *TOLEBackup = CloneModule(ToOptimizeLoopExtracted, VMap);
+ Module *TNOBackup = CloneModule(ToNotOptimize, VMap);
+
+ for (unsigned i = 0, e = MiscompiledFunctions.size(); i != e; ++i)
+ MiscompiledFunctions[i] = cast<Function>(VMap[MiscompiledFunctions[i]]);
+
Failure = TestFn(BD, ToOptimizeLoopExtracted, ToNotOptimize, Error);
if (!Error.empty())
return false;
+
+ ToOptimizeLoopExtracted = TOLEBackup;
+ ToNotOptimize = TNOBackup;
+
if (!Failure) {
outs() << "*** Loop extraction masked the problem. Undoing.\n";
// If the program is not still broken, then loop extraction did something
// that masked the error. Stop loop extraction now.
- delete TOLEBackup;
- delete TNOBackup;
+
+ std::vector<std::pair<std::string, FunctionType*> > MisCompFunctions;
+ for (unsigned i = 0, e = MiscompiledFunctions.size(); i != e; ++i) {
+ Function *F = MiscompiledFunctions[i];
+ MisCompFunctions.push_back(std::make_pair(F->getName(),
+ F->getFunctionType()));
+ }
+
+ std::string ErrorMsg;
+ if (Linker::LinkModules(ToNotOptimize, ToOptimizeLoopExtracted,
+ Linker::DestroySource, &ErrorMsg)){
+ errs() << BD.getToolName() << ": Error linking modules together:"
+ << ErrorMsg << '\n';
+ exit(1);
+ }
+
+ MiscompiledFunctions.clear();
+ for (unsigned i = 0, e = MisCompFunctions.size(); i != e; ++i) {
+ Function *NewF = ToNotOptimize->getFunction(MisCompFunctions[i].first);
+
+ assert(NewF && "Function not found??");
+ MiscompiledFunctions.push_back(NewF);
+ }
+
+ delete ToOptimizeLoopExtracted;
+ BD.setNewProgram(ToNotOptimize);
return MadeChange;
}
- ToOptimizeLoopExtracted = TOLEBackup;
- ToNotOptimize = TNOBackup;
outs() << "*** Loop extraction successful!\n";
const std::vector<Function*> &Fns)
: BD(bd), TestFn(F), FunctionsBeingTested(Fns) {}
- virtual TestResult doTest(std::vector<BasicBlock*> &Prefix,
- std::vector<BasicBlock*> &Suffix,
- std::string &Error) {
+ TestResult doTest(std::vector<BasicBlock*> &Prefix,
+ std::vector<BasicBlock*> &Suffix,
+ std::string &Error) override {
if (!Suffix.empty()) {
bool Ret = TestFuncs(Suffix, Error);
if (!Error.empty())
MiscompiledFunctions,
VMap);
Module *Extracted = BD.ExtractMappedBlocksFromModule(Blocks, ToExtract);
- if (Extracted == 0) {
+ if (!Extracted) {
// Weird, extraction should have worked.
errs() << "Nondeterministic problem extracting blocks??\n";
delete ProgClone;
Safe->getOrInsertFunction("getPointerToNamedFunction",
Type::getInt8PtrTy(Safe->getContext()),
Type::getInt8PtrTy(Safe->getContext()),
- (Type *)0);
+ (Type *)nullptr);
// Use the function we just added to get addresses of functions we need.
for (Module::iterator F = Safe->begin(), E = Safe->end(); F != E; ++F) {
SmallString<128> TestModuleBC;
int TestModuleFD;
- error_code EC = sys::fs::unique_file("bugpoint.test-%%%%%%%.bc", TestModuleFD,
- TestModuleBC);
+ error_code EC = sys::fs::createTemporaryFile("bugpoint.test", "bc",
+ TestModuleFD, TestModuleBC);
if (EC) {
errs() << BD.getToolName() << "Error making unique filename: "
<< EC.message() << "\n";
// Make the shared library
SmallString<128> SafeModuleBC;
int SafeModuleFD;
- EC = sys::fs::unique_file("bugpoint.safe-%%%%%%%.bc", SafeModuleFD,
- SafeModuleBC);
+ EC = sys::fs::createTemporaryFile("bugpoint.safe", "bc", SafeModuleFD,
+ SafeModuleBC);
if (EC) {
errs() << BD.getToolName() << "Error making unique filename: "
<< EC.message() << "\n";
SmallString<128> TestModuleBC;
int TestModuleFD;
- error_code EC = sys::fs::unique_file("bugpoint.test-%%%%%%%.bc", TestModuleFD,
- TestModuleBC);
+ error_code EC = sys::fs::createTemporaryFile("bugpoint.test", "bc",
+ TestModuleFD, TestModuleBC);
if (EC) {
errs() << getToolName() << "Error making unique filename: "
<< EC.message() << "\n";
// Make the shared library
SmallString<128> SafeModuleBC;
int SafeModuleFD;
- EC = sys::fs::unique_file("bugpoint.safe-%%%%%%%.bc", SafeModuleFD,
- SafeModuleBC);
+ EC = sys::fs::createTemporaryFile("bugpoint.safe", "bc", SafeModuleFD,
+ SafeModuleBC);
if (EC) {
errs() << getToolName() << "Error making unique filename: "
<< EC.message() << "\n";