//===----------------------------------------------------------------------===//
#include "BugDriver.h"
-#include "ToolRunner.h"
#include "ListReducer.h"
-#include "llvm/Constants.h"
-#include "llvm/DerivedTypes.h"
-#include "llvm/Instructions.h"
-#include "llvm/Module.h"
+#include "ToolRunner.h"
+#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/IR/CFG.h"
+#include "llvm/IR/Constants.h"
+#include "llvm/IR/DerivedTypes.h"
+#include "llvm/IR/Instructions.h"
+#include "llvm/IR/Module.h"
+#include "llvm/IR/ValueSymbolTable.h"
+#include "llvm/IR/Verifier.h"
#include "llvm/Pass.h"
#include "llvm/PassManager.h"
-#include "llvm/ValueSymbolTable.h"
-#include "llvm/ADT/SmallPtrSet.h"
-#include "llvm/Analysis/Verifier.h"
-#include "llvm/Support/CFG.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/FileUtilities.h"
#include "llvm/Transforms/Scalar.h"
#include "llvm/Transforms/Utils/Cloning.h"
-#include "llvm/Support/FileUtilities.h"
-#include "llvm/Support/CommandLine.h"
#include <set>
using namespace llvm;
// running the "Kept" passes fail when run on the output of the "removed"
// passes. If we return true, we update the current module of bugpoint.
//
- virtual TestResult doTest(std::vector<std::string> &Removed,
- std::vector<std::string> &Kept,
- std::string &Error);
+ TestResult doTest(std::vector<std::string> &Removed,
+ std::vector<std::string> &Kept,
+ std::string &Error) override;
};
}
ReducePassList::doTest(std::vector<std::string> &Prefix,
std::vector<std::string> &Suffix,
std::string &Error) {
- sys::Path PrefixOutput;
- Module *OrigProgram = 0;
+ std::string PrefixOutput;
+ Module *OrigProgram = nullptr;
if (!Prefix.empty()) {
outs() << "Checking to see if these passes crash: "
<< getPassesString(Prefix) << ": ";
- std::string PfxOutput;
- if (BD.runPasses(BD.getProgram(), Prefix, PfxOutput))
+ if (BD.runPasses(BD.getProgram(), Prefix, PrefixOutput))
return KeepPrefix;
- PrefixOutput.set(PfxOutput);
OrigProgram = BD.Program;
- BD.Program = ParseInputFile(PrefixOutput.str(), BD.getContext());
- if (BD.Program == 0) {
+ BD.Program = parseInputFile(PrefixOutput, BD.getContext()).release();
+ if (BD.Program == nullptr) {
errs() << BD.getToolName() << ": Error reading bitcode file '"
- << PrefixOutput.str() << "'!\n";
+ << PrefixOutput << "'!\n";
exit(1);
}
- PrefixOutput.eraseFromDisk();
+ sys::fs::remove(PrefixOutput);
}
outs() << "Checking to see if these passes crash: "
bool (*testFn)(const BugDriver &, Module *))
: BD(bd), TestFn(testFn) {}
- virtual TestResult doTest(std::vector<GlobalVariable*> &Prefix,
- std::vector<GlobalVariable*> &Kept,
- std::string &Error) {
+ TestResult doTest(std::vector<GlobalVariable*> &Prefix,
+ std::vector<GlobalVariable*> &Kept,
+ std::string &Error) override {
if (!Kept.empty() && TestGlobalVariables(Kept))
return KeepSuffix;
if (!Prefix.empty() && TestGlobalVariables(Prefix))
for (Module::global_iterator I = M->global_begin(), E = M->global_end();
I != E; ++I)
if (I->hasInitializer() && !GVSet.count(I)) {
- I->setInitializer(0);
+ I->setInitializer(nullptr);
I->setLinkage(GlobalValue::ExternalLinkage);
}
return false;
}
-namespace llvm {
+namespace {
/// ReduceCrashingFunctions reducer - This works by removing functions and
/// seeing if the program still crashes. If it does, then keep the newer,
/// smaller program.
bool (*testFn)(const BugDriver &, Module *))
: BD(bd), TestFn(testFn) {}
- virtual TestResult doTest(std::vector<Function*> &Prefix,
- std::vector<Function*> &Kept,
- std::string &Error) {
+ TestResult doTest(std::vector<Function*> &Prefix,
+ std::vector<Function*> &Kept,
+ std::string &Error) override {
if (!Kept.empty() && TestFuncs(Kept))
return KeepSuffix;
if (!Prefix.empty() && TestFuncs(Prefix))
}
bool ReduceCrashingFunctions::TestFuncs(std::vector<Function*> &Funcs) {
-
- //if main isn't present, claim there is no problem
- if (KeepMain && find(Funcs.begin(), Funcs.end(),
- BD.getProgram()->getFunction("main")) == Funcs.end())
+ // If main isn't present, claim there is no problem.
+ if (KeepMain && std::find(Funcs.begin(), Funcs.end(),
+ BD.getProgram()->getFunction("main")) ==
+ Funcs.end())
return false;
// Clone the program to try hacking it apart...
bool (*testFn)(const BugDriver &, Module *))
: BD(bd), TestFn(testFn) {}
- virtual TestResult doTest(std::vector<const BasicBlock*> &Prefix,
- std::vector<const BasicBlock*> &Kept,
- std::string &Error) {
+ TestResult doTest(std::vector<const BasicBlock*> &Prefix,
+ std::vector<const BasicBlock*> &Kept,
+ std::string &Error) override {
if (!Kept.empty() && TestBlocks(Kept))
return KeepSuffix;
if (!Prefix.empty() && TestBlocks(Prefix))
// have to take.
std::vector<std::pair<std::string, std::string> > BlockInfo;
- for (SmallPtrSet<BasicBlock*, 8>::iterator I = Blocks.begin(),
- E = Blocks.end(); I != E; ++I)
- BlockInfo.push_back(std::make_pair((*I)->getParent()->getName(),
- (*I)->getName()));
+ for (BasicBlock *BB : Blocks)
+ BlockInfo.push_back(std::make_pair(BB->getParent()->getName(),
+ BB->getName()));
// Now run the CFG simplify pass on the function...
std::vector<std::string> Passes;
Passes.push_back("simplifycfg");
Passes.push_back("verify");
- Module *New = BD.runPassesOn(M, Passes);
+ std::unique_ptr<Module> New = BD.runPassesOn(M, Passes);
delete M;
if (!New) {
errs() << "simplifycfg failed!\n";
exit(1);
}
- M = New;
+ M = New.release();
// Try running on the hacked up program...
if (TestFn(BD, M)) {
bool (*testFn)(const BugDriver &, Module *))
: BD(bd), TestFn(testFn) {}
- virtual TestResult doTest(std::vector<const Instruction*> &Prefix,
- std::vector<const Instruction*> &Kept,
- std::string &Error) {
+ TestResult doTest(std::vector<const Instruction*> &Prefix,
+ std::vector<const Instruction*> &Kept,
+ std::string &Error) override {
if (!Kept.empty() && TestInsts(Kept))
return KeepSuffix;
if (!Prefix.empty() && TestInsts(Prefix))
// Verify that this is still valid.
PassManager Passes;
Passes.add(createVerifierPass());
+ Passes.add(createDebugInfoVerifierPass());
Passes.run(*M);
// Try running on the hacked up program...
// Make sure to use instruction pointers that point into the now-current
// module, and that they don't include any deleted blocks.
Insts.clear();
- for (SmallPtrSet<Instruction*, 64>::const_iterator I = Instructions.begin(),
- E = Instructions.end(); I != E; ++I)
- Insts.push_back(*I);
+ for (Instruction *Inst : Instructions)
+ Insts.push_back(Inst);
return true;
}
delete M; // It didn't crash, try something else.
for (Module::global_iterator I = M->global_begin(), E = M->global_end();
I != E; ++I)
if (I->hasInitializer()) {
- I->setInitializer(0);
+ I->setInitializer(nullptr);
I->setLinkage(GlobalValue::ExternalLinkage);
DeletedInit = true;
}
for (Function::const_iterator BI = FI->begin(), E = FI->end(); BI != E;
++BI)
for (BasicBlock::const_iterator I = BI->begin(), E = --BI->end();
- I != E; ++I, ++CurInstructionNum)
+ I != E; ++I, ++CurInstructionNum) {
if (InstructionsToSkipBeforeDeleting) {
--InstructionsToSkipBeforeDeleting;
} else {
continue;
outs() << "Checking instruction: " << *I;
- Module *M = BD.deleteInstructionFromProgram(I, Simplification);
+ std::unique_ptr<Module> M =
+ BD.deleteInstructionFromProgram(I, Simplification);
// Find out if the pass still crashes on this pass...
- if (TestFn(BD, M)) {
+ if (TestFn(BD, M.get())) {
// Yup, it does, we delete the old module, and continue trying
// to reduce the testcase...
- BD.setNewProgram(M);
+ BD.setNewProgram(M.release());
InstructionsToSkipBeforeDeleting = CurInstructionNum;
goto TryAgain; // I wish I had a multi-level break here!
}
-
- // This pass didn't crash without this instruction, try the next
- // one.
- delete M;
}
+ }
if (InstructionsToSkipBeforeDeleting) {
InstructionsToSkipBeforeDeleting = 0;
if (!BugpointIsInterrupted) {
outs() << "\n*** Attempting to perform final cleanups: ";
Module *M = CloneModule(BD.getProgram());
- M = BD.performFinalCleanups(M, true);
+ M = BD.performFinalCleanups(M, true).release();
// Find out if the pass still crashes on the cleaned up program...
if (TestFn(BD, M)) {