/// checkCallees -- Verify callees for the given function /// Returns true iff the user specified anything for this option /// /// checks that the first function calls the rest of the /// functions in the list static bool checkCallees(llvm::raw_ostream &O, const Module *M, const DataStructures *DS) { //Mangled names must be provided for C++ cl::list<std::string>::iterator I = CheckCallees.begin(), E = CheckCallees.end(); // User didn't specify this option, bail. if (I == E) return false; std::string &func = *(I); Function *caller = M->getFunction(func); assert(caller && "Function not found in module"); FuncSetTy expectedCallees; while (++I != E) { std::string &func = *(I); const Function *callee = M->getFunction(func); assert(callee && "Specified callee function not found in module!"); expectedCallees.insert(callee); } const DSCallGraph callgraph = DS->getCallGraph(); FuncSetTy analysisCallees = getCalleesFor(caller, callgraph); if (!std::includes(analysisCallees.begin(), analysisCallees.end(), expectedCallees.begin(), expectedCallees.end())) { FuncSetTy missing; std::set_difference(expectedCallees.begin(), expectedCallees.end(), analysisCallees.begin(), analysisCallees.end(), std::inserter(missing, missing.begin())); errs() << "ERROR: Callgraph check failed for: \t" << caller->getName() << "\n"; errs() << " Analysis says calls: \t"; printCallees(analysisCallees, errs()); errs() << "\n"; errs() << " Testing to make sure calls: \t"; printCallees(expectedCallees, errs()); errs() << "\n"; errs() << " *** Missing: \t"; printCallees(missing, errs()); errs() << "\n"; llvm_unreachable("Analysis didn't contain the specified callees!"); } return true; }
/// checkNotCallees -- Verify non-callees for the given function /// Returns true iff the user specified anything for this option /// /// checks that the first function does not callsthe rest of the /// functions in the list static bool checkNotCallees(llvm::raw_ostream &O, const Module *M, const DataStructures *DS) { //Mangled names must be provided for C++ cl::list<std::string>::iterator I = CheckNotCallees.begin(), E = CheckNotCallees.end(); // User didn't specify this option, bail. if (I == E) return false; std::string &func = *(I); Function *caller = M->getFunction(func); assert(caller && "Function not found in module"); FuncSetTy notCallees; while (++I != E) { std::string &func = *(I); const Function *callee = M->getFunction(func); assert(callee && "Specified callee function not found in module!"); notCallees.insert(callee); } const DSCallGraph callgraph = DS->getCallGraph(); FuncSetTy analysisCallees = getCalleesFor(caller, callgraph); if (std::includes(analysisCallees.begin(), analysisCallees.end(), notCallees.begin(), notCallees.end())) { FuncSetTy invalid; std::set_intersection(analysisCallees.begin(), analysisCallees.end(), notCallees.begin(), notCallees.end(), std::inserter(invalid, invalid.begin())); errs() << "ERROR: Callgraph check failed for: \t" << caller->getName() << "\n"; errs() << " Analysis says calls: \t"; printCallees(analysisCallees, errs()); errs() << "\n"; errs() << " Testing to not call: \t"; printCallees(notCallees, errs()); errs() << "\n"; errs() << " *** Overlap: \t"; printCallees(invalid, errs()); errs() << "\n"; assert(0 && "Analysis contained the specified callees!"); } return true; }
static void printCallees(FuncSetTy & Funcs, raw_ostream & O) { FuncSetTy::iterator I = Funcs.begin(), E = Funcs.end(); if (I != E) { O << (*I)->getName(); while(++I != E) O << ", " << (*I)->getName(); } }