Esempio n. 1
0
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();
  }
}
Esempio n. 2
0
FuncSetTy
getCalleesFor(const Function * caller, const DSCallGraph & cg)
{
  FuncSetTy callees;

  Function const*leader = cg.sccLeader(&*caller);

  // Add all methods in same SCC as caller...
  for(DSCallGraph::scc_iterator sccii = cg.scc_begin(leader),
      sccee = cg.scc_end(leader); sccii != sccee; ++sccii)
    callees.insert(*sccii);

  // And all methods in the SCC's called by the caller
  for(DSCallGraph::flat_iterator CI = cg.flat_callee_begin(caller);
      CI != cg.flat_callee_end(caller); CI ++) {
    callees.insert(*CI);
    for(DSCallGraph::scc_iterator sccii = cg.scc_begin(*CI),
        sccee = cg.scc_end(*CI); sccii != sccee; ++sccii)
      callees.insert(*sccii);
  }

  return callees;
}
Esempio n. 3
0
/// 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;
}
Esempio n. 4
0
/// 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;
}