Static Value-Flow Analysis
MTAResultValidator.cpp
Go to the documentation of this file.
1 /*
2  * MTAResultValidator.cpp
3  *
4  * Created on: 29/06/2015
5  * Author: Peng Di
6  */
7 
8 #include "Util/Options.h"
9 #include <string>
10 #include <sstream>
11 
12 #include "MTAResultValidator.h"
13 #include "SVF-LLVM/LLVMModule.h"
14 
15 using namespace SVF;
16 using namespace SVFUtil;
17 
18 namespace SVF
19 {
20 
21 // Subclassing RCResultValidator to define the abstract methods.
23 {
24 public:
25  MHPValidator(MHP *mhp) :mhp(mhp)
26  {
27  }
28  bool mayHappenInParallel(const Instruction* I1, const Instruction* I2)
29  {
32  return mhp->mayHappenInParallel(inst1, inst2);
33  }
34 private:
35  MHP *mhp;
36 };
37 
38 } // End namespace SVF
39 
41 {
42 
43  // Initialize the validator and perform validation.
44  MHPValidator validator(mhp);
45  validator.init(mhp->getTCT()->getSVFModule());
46  validator.analyze();
47 
48 
49  std::string errstring;
50  if (!collectCallsiteTargets())
51  return;
52  if (!collectCxtThreadTargets())
53  return;
54 
55  errstring = getOutput("Validate CxtThread:", validateCxtThread());
56  outs() << "======" << errstring << "======\n";
57 
58  if (!collectTCTTargets())
59  return;
60  errstring = getOutput("Validate TCT: ", validateTCT());
61  outs() << "======" << errstring << "======\n";
62 
63  if (!collectInterleavingTargets())
64  return;
65  errstring = getOutputforInterlevAnalysis("Validate Interleaving:", validateInterleaving());
66  outs() << "======" << errstring << "======\n";
67 }
68 
69 std::vector<std::string> &MTAResultValidator::split(const std::string &s, char delim, std::vector<std::string> &elems)
70 {
71  std::stringstream ss(s);
73  while (std::getline(ss, item, delim))
74  {
75  elems.push_back(item);
76  }
77  return elems;
78 }
79 
80 std::vector<std::string> MTAResultValidator::split(const std::string &s, char delim)
81 {
82  std::vector<std::string> elems;
83  split(s, delim, elems);
84  return elems;
85 }
87 {
88  assert(LLVMUtil::isCallSite(inst) && "getFirstIntArg: inst is not a callinst");
89  const CallBase* cs = LLVMUtil::getLLVMCallSite(inst);
90  const ConstantInt* x = SVFUtil::dyn_cast<ConstantInt>(cs->getArgOperand(arg_num));
91  assert((arg_num < cs->arg_size()) && "Does not has this argument");
92  return (NodeID) x->getSExtValue();
93 }
94 
95 std::vector<std::string> MTAResultValidator::getStringArg(const Instruction* inst, unsigned int arg_num)
96 {
97  assert(LLVMUtil::isCallSite(inst) && "getFirstIntArg: inst is not a callinst");
98  const CallBase* cs = LLVMUtil::getLLVMCallSite(inst);
99  assert((arg_num < cs->arg_size()) && "Does not has this argument");
100  const Constant* arrayinst = SVFUtil::dyn_cast<Constant>(cs->getArgOperand(arg_num));
101  if(const GetElementPtrInst* gepinst = SVFUtil::dyn_cast<GetElementPtrInst>(cs->getArgOperand(arg_num)))
102  {
103  arrayinst = SVFUtil::dyn_cast<Constant>(gepinst->getOperand(0));
104  }
105  const ConstantDataArray* cxtarray = SVFUtil::dyn_cast<ConstantDataArray>(arrayinst->getOperand(0));
106  if (!cxtarray)
107  {
108  std::vector<std::string> strvec;
109  return strvec;
110  }
111  const std::string vthdcxtstring = cxtarray->getAsCString().str();
112  return split(vthdcxtstring, ',');
113 }
114 
115 CallStrCxt MTAResultValidator::getCxtArg(const Instruction* inst, unsigned int arg_num)
116 {
117  std::vector<std::string> x = getStringArg(inst, arg_num);
118  CallStrCxt cxt;
119  if (0 == x.size())
120  return cxt;
121  // Deal with the second argument that records all callsites
122  for (std::vector<std::string>::iterator i = x.begin(); i != x.end(); i++)
123  {
124  std::vector<std::string> y = split((*i), '.');
125  y[0].erase(y[0].find("cs"), 2);
126 
127  const SVFFunction* callee = mod->getSVFFunction(y[1]);
128  const SVFInstruction* svfInst = csnumToInstMap[atoi(y[0].c_str())];
129  assert(callee && "callee error");
130  CallICFGNode* cbn = mhp->getTCT()->getCallICFGNode(svfInst);
131  CallSiteID csId = tcg->getCallSiteID(cbn, callee);
132  cxt.push_back(csId);
133  }
134  return cxt;
135 }
136 
138 {
139  I = I->getPrevNode();
140  while (I)
141  {
142  if (SVFUtil::isa<LoadInst>(I) || SVFUtil::isa<StoreInst>(I))
143  return I;
144  I = I->getPrevNode();
145  }
146  return nullptr;
147 }
148 
149 inline std::string MTAResultValidator::getOutput(const char *scenario, bool analysisRes)
150 {
151  std::string ret(scenario);
152  ret += "\t";
153 
154  if (analysisRes)
155  ret += SVFUtil::sucMsg("SUCCESS");
156  else
157  ret += SVFUtil::errMsg("FAILURE");
158  return ret;
159 }
160 
162 {
163  std::string ret(scenario);
164  ret += "\t";
165  switch (analysisRes)
166  {
167  case INTERLEV_TRUE:
168  ret += SVFUtil::sucMsg("SUCCESS");
169  break;
170  case INTERLEV_UNSOUND:
171  ret += SVFUtil::bugMsg2("UNSOUND");
172  break;
173  case INTERLEV_IMPRECISE:
174  ret += SVFUtil::bugMsg1("IMPRECISE");
175  break;
176  default:
177  ret += SVFUtil::errMsg("FAILURE");
178  }
179  return ret;
180 }
181 
182 bool MTAResultValidator::matchCxt(const CallStrCxt cxt1, const CallStrCxt cxt2) const
183 {
184  if (cxt1.size() != cxt2.size())
185  return false;
186  return std::equal(cxt1.begin(), cxt1.end(), cxt2.begin());
187 }
188 
190 {
191  std::string str;
192  std::stringstream rawstr(str);
193  rawstr << "[:";
194  for (CallStrCxt::const_iterator it = cxt.begin(), eit = cxt.end(); it != eit; ++it)
195  {
196  rawstr << " ' " << *it << " ' ";
197  rawstr << tcg->getCallSite(*it)->getCallSite()->toString();
198  rawstr << " call " << tcg->getCallSite(*it)->getCaller()->getName() << "-->" << tcg->getCalleeOfCallSite(*it)->getName() << ", \n";
199  }
200  rawstr << " ]";
201  outs() << "max cxt = " << cxt.size() << rawstr.str() << "\n";
202 }
203 
205 {
206  outs() << " [ ";
207  for (NodeBS::iterator it = lev.begin(), eit = lev.end(); it != eit; it++)
208  {
209  NodeID id = *it;
210  outs() << rthdTovthd[id] << ", ";
211  }
212  outs() << "]\n";
213 }
214 
216 {
217  for (Module& M : LLVMModuleSet::getLLVMModuleSet()->getLLVMModules())
218  {
219  for (Module::const_iterator F = M.begin(), E = M.end(); F != E; ++F)
220  {
221  for (Function::const_iterator bi = (*F).begin(), ebi = (*F).end(); bi != ebi; ++bi)
222  {
223  const BasicBlock* bb = &*bi;
224  if (!bb->getName().str().compare(0, 2, "cs"))
225  {
226  NodeID csnum = atoi(bb->getName().str().substr(2).c_str());
227  const Instruction* inst = &bb->front();
228  while (1)
229  {
230  if (SVFUtil::isa<CallInst>(inst))
231  {
232  break;
233  }
234  inst = inst->getNextNode();
235  assert(inst && "Wrong cs label, cannot find callsite");
236  }
238  csnumToInstMap[csnum] = svfInst;
239  }
240  }
241  }
242  }
243  return !csnumToInstMap.empty();
244 }
245 
247 {
248  const Function* F = nullptr;
249  for (Module &M : LLVMModuleSet::getLLVMModuleSet()->getLLVMModules())
250  {
251  for(auto it = M.begin(); it != M.end(); it++)
252  {
253  const std::string fName = (*it).getName().str();
254  if(fName.find(CXT_THREAD) != std::string::npos)
255  {
256  F = &(*it);
257  break;
258  }
259  }
260  }
261  if (!F)
262  return false;
263 
264  // Push main thread into vthdToCxt;
265  CallStrCxt main_cxt;
266  vthdToCxt[0] = main_cxt;
267 
268  // Collect call sites of all CXT_THREAD function calls.
269 
270  for (Value::const_use_iterator it = F->use_begin(), ie = F->use_end(); it != ie; ++it)
271  {
272  const Use *u = &*it;
273  const Value* user = u->getUser();
274  const Instruction* inst = SVFUtil::dyn_cast<Instruction>(user);
275 
276  NodeID vthdnum = getIntArg(inst, 0);
277  CallStrCxt cxt = getCxtArg(inst, 1);
278 
279  vthdToCxt[vthdnum] = cxt;
280  }
281  return true;
282 }
283 
285 {
286 
287  // Collect call sites of all TCT_ACCESS function calls.
288  const Function* F = nullptr;
289  for (Module &M : LLVMModuleSet::getLLVMModuleSet()->getLLVMModules())
290  {
291  for(auto it = M.begin(); it != M.end(); it++)
292  {
293  const std::string fName = (*it).getName().str();
294  if(fName.find(TCT_ACCESS) != std::string::npos)
295  {
296  F = &(*it);
297  break;
298  }
299  }
300  }
301  if (!F)
302  return false;
303 
304  for (Value::const_use_iterator it = F->use_begin(), ie = F->use_end(); it != ie; ++it)
305  {
306  const Use *u = &*it;
307  const Value* user = u->getUser();
308  const Instruction* inst = SVFUtil::dyn_cast<Instruction>(user);
309 
310  NodeID vthdnum = getIntArg(inst, 0);
311  NodeID rthdnum = vthdTorthd[vthdnum];
312  std::vector<std::string> x = getStringArg(inst, 1);
313 
314  for (std::vector<std::string>::iterator i = x.begin(); i != x.end(); i++)
315  {
316  rthdToChildren[rthdnum].insert(vthdTorthd[atoi((*i).c_str())]);
317  }
318  }
319  return true;
320 }
321 
323 {
324 
325  // Collect call sites of all INTERLEV_ACCESS function calls.
326  const Function* F = nullptr;
327  for (Module &M : LLVMModuleSet::getLLVMModuleSet()->getLLVMModules())
328  {
329  for(auto it = M.begin(); it != M.end(); it++)
330  {
331  const std::string fName = (*it).getName().str();
332  if(fName.find(INTERLEV_ACCESS) != std::string::npos)
333  {
334  F = &(*it);
335  break;
336  }
337  }
338  }
339  if (!F)
340  return false;
341 
342  for (Value::const_use_iterator it = F->use_begin(), ie = F->use_end(); it != ie; ++it)
343  {
344  const Use *u = &*it;
345  const Value* user = u->getUser();
346  const Instruction* inst = SVFUtil::dyn_cast<Instruction>(user);
347 
348  NodeID vthdnum = getIntArg(inst, 0);
349  NodeID rthdnum = vthdTorthd[vthdnum];
350  CallStrCxt x = getCxtArg(inst, 1);
351  std::vector<std::string> y = getStringArg(inst, 2);
352 
353  // Record given interleaving
354  NodeBS lev;
355  // Push thread itself into interleaving set
356  lev.set(rthdnum);
357  // Find rthd of given vthd and push it into interleaving set
358  for (std::vector<std::string>::iterator i = y.begin(); i != y.end(); i++)
359  {
360  lev.set(vthdTorthd[atoi((*i).c_str())]);
361  }
362 
363  const Instruction* memInst = getPreviousMemoryAccessInst(inst);
364  const SVFInstruction* svfMemInst = LLVMModuleSet::getLLVMModuleSet()->getSVFInstruction(memInst);
365  CxtThreadStmt cts(rthdnum, x, svfMemInst);
366  instToTSMap[svfMemInst].insert(cts);
367  threadStmtToInterLeaving[cts] = lev;
368  }
369  return true;
370 }
371 
373 {
374 
375  bool res = true;
376  TCT* tct = mhp->getTCT();
377  if (tct->getTCTNodeNum() != vthdToCxt.size())
378  {
379  res = false;
381  {
382  outs() << errMsg("\nValidate CxtThread: The number of CxtThread is different from given result!!!\n");
383  outs() << "Given threads:\t" << vthdToCxt.size() << "\nAnalysis result:\t" << tct->getTCTNodeNum() << "\n";
384  assert(false && "test case failed!");
385  }
386  }
387 
388  Set<int> visitedvthd;
389 
390  for (NodeID i = 0; i < tct->getTCTNodeNum(); i++)
391  {
392  const CxtThread rthd = tct->getTCTNode(i)->getCxtThread();
393  bool matched = false;
394  for (Map<NodeID, CallStrCxt>::iterator j = vthdToCxt.begin(), ej = vthdToCxt.end(); j != ej; j++)
395  {
396  NodeID vthdid = (*j).first;
397  if (matchCxt(rthd.getContext(), vthdToCxt[vthdid]))
398  {
399  if (visitedvthd.find(vthdid) != visitedvthd.end())
400  {
401  res = false;
403  {
404  outs() << "\nValidate CxtThread: Repeat real CxtThread !!!\n";
405  rthd.dump();
406  tct->getTCTNode(vthdTorthd[vthdid])->getCxtThread().dump();
407  }
408  }
409  vthdTorthd[vthdid] = i;
410  rthdTovthd[i] = vthdid;
411  visitedvthd.insert(vthdid);
412  matched = true;
413  break;
414  }
415  }
416  if (!matched)
417  {
418  res = false;
420  {
421  SVFUtil::errs() << errMsg("\nValidate CxtThread: Cannot match real CxtThread !!!\n");
422  rthd.dump();
423  assert(false && "test case failed!");
424  }
425  }
426  }
427  if (visitedvthd.size() != vthdToCxt.size())
428  {
429  res = false;
431  {
432  SVFUtil::errs() << errMsg("\nValidate CxtThread: Some given CxtThreads cannot be found !!!\n");
433  assert(false && "test case failed!");
434  for (Map<NodeID, CallStrCxt>::iterator j = vthdToCxt.begin(), ej = vthdToCxt.end(); j != ej; j++)
435  {
436  NodeID vthdid = (*j).first;
437  if (visitedvthd.find(vthdid) == visitedvthd.end())
438  {
439  dumpCxt(vthdToCxt[vthdid]);
440  }
441  }
442  }
443  }
444  return res;
445 }
446 
448 {
449  bool res = true;
450 
451  TCT* tct = mhp->getTCT();
452  for (NodeID i = 0; i < tct->getTCTNodeNum(); i++)
453  {
454  bool res_node = true;
455  TCTNode* pnode = tct->getTCTNode(i);
456  for (TCT::ThreadCreateEdgeSet::const_iterator ci = tct->getChildrenBegin(pnode), cei = tct->getChildrenEnd(pnode); ci != cei;
457  ci++)
458  {
459  NodeID tid = (*ci)->getDstID();
460  if (rthdToChildren[i].find(tid) == rthdToChildren[i].end())
461  {
462  res = false;
463  res_node = false;
464  }
465  }
466 
467  for (Set<NodeID>::iterator j = rthdToChildren[i].begin(), ej = rthdToChildren[i].end(); j != ej; j++)
468  {
469  NodeID gid = *j;
470  if (!tct->hasGraphEdge(pnode, tct->getTCTNode(gid), TCTEdge::ThreadCreateEdge))
471  {
472  res = false;
473  res_node = false;
474  }
475  }
476  if ((!res_node) && Options::PrintValidRes())
477  {
478  outs() << errMsg("\nValidate TCT: Wrong at TID ") << rthdTovthd[i] << "\n";
479  outs() << "Given children: \t";
480  for (Set<NodeID>::iterator j = rthdToChildren[i].begin(), ej = rthdToChildren[i].end(); j != ej; j++)
481  {
482  NodeID gid = *j;
483  outs() << rthdTovthd[gid] << ", ";
484  }
485  outs() << "\nAnalysis children:\t";
486  for (TCT::ThreadCreateEdgeSet::const_iterator ci = tct->getChildrenBegin(pnode), cei = tct->getChildrenEnd(pnode); ci != cei;
487  ci++)
488  {
489  NodeID tid = (*ci)->getDstID();
490  outs() << rthdTovthd[tid] << ", ";
491  }
492  outs() << "\n";
493  }
494  }
495  return res;
496 }
497 
499 {
501 
502  for (MHP::InstToThreadStmtSetMap::iterator seti = instToTSMap.begin(), eseti = instToTSMap.end(); seti != eseti; ++seti)
503  {
504  const SVFInstruction* inst = (*seti).first;
505 
506  const MHP::CxtThreadStmtSet& tsSet = mhp->getThreadStmtSet(inst);
507 
508  if ((*seti).second.size() != tsSet.size())
509  {
511  {
512  outs() << errMsg("\n Validate Interleaving: Wrong at : ") << inst->getSourceLoc() << "\n";
513  outs() << "Reason: The number of thread running on stmt is wrong\n";
514  outs() << "\n----Given threads:\n";
515  for (MHP::CxtThreadStmtSet::iterator thdlevi = (*seti).second.begin(), ethdlevi = (*seti).second.end(); thdlevi != ethdlevi;
516  ++thdlevi)
517  {
518  outs() << "TID " << rthdTovthd[(*thdlevi).getTid()] << ": ";
519  dumpCxt((*thdlevi).getContext());
520  }
521  outs() << "\n----Analysis threads:\n";
522  for (MHP::CxtThreadStmtSet::const_iterator it = tsSet.begin(), eit = tsSet.end(); it != eit; ++it)
523  {
524  outs() << "TID " << rthdTovthd[(*it).getTid()] << ": ";
525  dumpCxt((*it).getContext());
526  }
527  outs() << "\n";
528  }
530  }
531 
532  for (MHP::CxtThreadStmtSet::const_iterator it = tsSet.begin(), eit = tsSet.end(); it != eit; ++it)
533  {
534  const CxtThreadStmt& ts = *it;
535  bool matched = false;
536  for (MHP::CxtThreadStmtSet::iterator it2 = (*seti).second.begin(), eit2 = (*seti).second.end(); it2 != eit2; ++it2)
537  {
538  const CxtThreadStmt& ts2 = *it2;
539 
540  if (ts2.getTid() == ts.getTid() && matchCxt(ts2.getContext(), ts.getContext()))
541  {
542  matched = true;
543  NodeBS lev = mhp->getInterleavingThreads(ts);
544  NodeBS lev2 = threadStmtToInterLeaving[ts2];
545  if (lev != lev2)
546  {
548  {
549  outs() << errMsg("\nValidate Interleaving: Wrong at: ") << inst->getSourceLoc() << "\n";
550  outs() << "Reason: thread interleaving on stmt is wrong\n";
551  dumpCxt(ts.getContext());
552  outs() << "Given result: \tTID " << rthdTovthd[ts.getTid()];
553  dumpInterlev(lev2);
554  outs() << "Analysis result: \tTID " << rthdTovthd[ts.getTid()];
555  dumpInterlev(lev);
556  }
557 
560 
561  if (lev.count() >= lev2.count())
562  {
563  bool findeveryelement = true;
564  for (NodeBS::iterator it = lev2.begin(), eit = lev2.end(); it != eit; it++)
565  {
566  if (!lev.test(*it))
567  {
568  findeveryelement = false;
569  break;
570  }
571  }
572  if (!findeveryelement)
574  }
575  else
577  }
578  }
579  }
580 
581  if (!matched)
582  {
584  {
585  outs() << errMsg("\nValidate Interleaving: Wrong at:") << inst->getSourceLoc() << "\n";
586  outs() << "Reason: analysis thread cxt is not matched by given thread cxt\n";
587  dumpCxt(ts.getContext());
588  NodeBS lev = mhp->getInterleavingThreads(ts);
589 
590  outs() << "Analysis result: \tTID " << rthdTovthd[ts.getTid()];
591  dumpInterlev(lev);
592  }
594  }
595  }
596  }
597  return res;
598 }
599 
601 {
602  // Collect call sites of all RC_ACCESS function calls.
603  std::vector<const CallBase*> csInsts;
604  const Function* F = nullptr;
605  for (Module &M : LLVMModuleSet::getLLVMModuleSet()->getLLVMModules())
606  {
607  for(auto it = M.begin(); it != M.end(); it++)
608  {
609  const std::string fName = (*it).getName().str();
610  if(fName.find(RC_ACCESS) != std::string::npos)
611  {
612  F = &(*it);
613  break;
614  }
615  }
616  }
617  if (!F) return;
618 
619  for (Value::const_use_iterator it = F->use_begin(), ie =
620  F->use_end(); it != ie; ++it)
621  {
622  const Use *u = &*it;
623  const Value *user = u->getUser();
624  if(LLVMUtil::isCallSite(user))
625  {
626  const CallBase* csInst = LLVMUtil::getLLVMCallSite(user);
627  csInsts.push_back(csInst);
628  }
629  }
630  assert(csInsts.size() % 2 == 0 && "We should have RC_ACCESS called in pairs.");
631 
632  // Sort the validation sites according to their ids.
633  std::sort(csInsts.begin(), csInsts.end(), compare);
634 
635  // Generate access pairs.
636  for (int i = 0, e = csInsts.size(); i != e;)
637  {
638  const CallBase* CI1 = csInsts[i++];
639  const CallBase* CI2 = csInsts[i++];
640  const ConstantInt* C = SVFUtil::dyn_cast<ConstantInt>(CI1->getArgOperand(1));
641  assert(C);
642  const Instruction* I1 = getPreviousMemoryAccessInst(CI1);
643  const Instruction* I2 = getPreviousMemoryAccessInst(CI2);
644  assert(I1 && I2 && "RC_ACCESS should be placed immediately after the target memory access.");
645  RC_FLAG flags = C->getZExtValue();
646  accessPairs.push_back(AccessPair(I1, I2, flags));
647  }
648 }
649 
651 {
652  SVFUtil::outs() << SVFUtil::pasMsg(" --- Analysis Result Validation ---\n");
653 
654  // Iterate every memory access pair to perform the validation.
655  for (int i = 0, e = accessPairs.size(); i != e; ++i)
656  {
657  const AccessPair &ap = accessPairs[i];
658  const Instruction* I1 = ap.getInstruction1();
659  const Instruction* I2 = ap.getInstruction2();
660 
661  bool mhp = mayHappenInParallel(I1, I2);
662  bool alias = mayAccessAliases(I1, I2);
663  bool protect = protectedByCommonLocks(I1, I2);
664  bool racy = mayHaveDataRace(I1, I2);
665 
666  SVFUtil::outs() << "For the memory access pair at ("
669  if (selectedValidationScenarios & RC_ALIASES)
670  {
671  SVFUtil::outs() << "\t"
672  << getOutput("ALIASES", alias, ap.isFlaged(RC_ALIASES))
673  << "\n";
674  }
675  if (selectedValidationScenarios & RC_MHP)
676  {
677  SVFUtil::outs() << "\t"
678  << getOutput("MHP", mhp, ap.isFlaged(RC_MHP)) << "\n";
679  }
680  if (selectedValidationScenarios & RC_PROTECTED)
681  {
682  SVFUtil::outs() << "\t"
683  << getOutput("PROTECT", protect,
684  ap.isFlaged(RC_PROTECTED)) << "\n";
685  }
686  if (selectedValidationScenarios & RC_RACE)
687  {
688  SVFUtil::outs() << "\t"
689  << getOutput("RACE", racy, ap.isFlaged(RC_RACE))
690  << "\n";
691  }
692  }
693 
694  SVFUtil::outs() << "\n";
695 }
696 
698 {
699  I = I->getPrevNode();
700  while (I)
701  {
702  if (SVFUtil::isa<LoadInst>(I) || SVFUtil::isa<StoreInst>(I))
703  return I;
704 
706 
707  if (const SVFFunction *callee = SVFUtil::getCallee(inst))
708  {
709  if (callee->getName().find("llvm.memset") != std::string::npos)
710  return I;
711 
712  }
713  I = I->getPrevNode();
714  }
715  return nullptr;
716 }
#define F(f)
cJSON * item
Definition: cJSON.h:222
const char *const string
Definition: cJSON.h:172
const CallStrCxt & getContext() const
Return current context.
Definition: CxtStmt.h:57
NodeID getTid() const
Return current context.
Definition: CxtStmt.h:139
void dump() const
Dump CxtThread.
Definition: CxtStmt.h:278
const CallStrCxt & getContext() const
Return context of the thread.
Definition: CxtStmt.h:205
static LLVMModuleSet * getLLVMModuleSet()
Definition: LLVMModule.h:105
SVFInstruction * getSVFInstruction(const Instruction *inst) const
Definition: LLVMModule.h:224
SVFValue * getSVFValue(const Value *value)
bool mayHappenInParallel(const Instruction *I1, const Instruction *I2)
Definition: MHP.h:46
Set< CxtThreadStmt > CxtThreadStmtSet
Definition: MHP.h:53
static const INTERLEV_FLAG INTERLEV_UNSOUND
std::vector< std::string > getStringArg(const Instruction *inst, unsigned int arg_num)
void dumpInterlev(NodeBS &lev)
INTERLEV_FLAG validateInterleaving()
static const INTERLEV_FLAG INTERLEV_TRUE
Constant INTERLEV_FLAG values.
bool matchCxt(const CallStrCxt cxt1, const CallStrCxt cxt2) const
std::vector< std::string > & split(const std::string &s, char delim, std::vector< std::string > &elems)
static const INTERLEV_FLAG INTERLEV_IMPRECISE
std::string getOutput(const char *scenario, bool analysisRes)
const Instruction * getPreviousMemoryAccessInst(const Instruction *I)
std::string getOutputforInterlevAnalysis(const char *scenario, INTERLEV_FLAG analysisRes)
NodeID getIntArg(const Instruction *inst, unsigned int arg_num)
void dumpCxt(const CallStrCxt &cxt) const
CallStrCxt getCxtArg(const Instruction *inst, unsigned int arg_num)
static const Option< bool > PrintValidRes
Definition: Options.h:175
bool isFlaged(const RC_FLAG flag) const
Class member access.
const Instruction * getInstruction1() const
const Instruction * getInstruction2() const
Validate the result of concurrent analysis.
void validateAll()
Perform validation for all targets.
const Instruction * getPreviousMemoryAccessInst(const Instruction *I)
void init(SVFModule *M)
Initialization.
virtual const std::string getSourceLoc() const
Definition: SVFValue.h:280
bool test(unsigned Idx) const
iterator end() const
void set(unsigned Idx)
unsigned count() const
iterator begin() const
@ ThreadCreateEdge
Definition: TCT.h:55
const CxtThread & getCxtThread() const
Get CxtThread.
Definition: TCT.h:101
Definition: TCT.h:136
ThreadCreateEdgeSet::const_iterator getChildrenBegin(const TCTNode *node) const
Get children and parent nodes.
Definition: TCT.h:203
TCTNode * getTCTNode(NodeID id) const
Get TCT node.
Definition: TCT.h:192
TCTEdge * hasGraphEdge(TCTNode *src, TCTNode *dst, TCTEdge::CEDGEK kind) const
Whether we have already created this call graph edge.
Definition: TCT.cpp:533
u32_t getTCTNodeNum() const
Get Statistics.
Definition: TCT.h:235
ThreadCreateEdgeSet::const_iterator getChildrenEnd(const TCTNode *node) const
Definition: TCT.h:207
const CallBase * getLLVMCallSite(const Value *value)
Return LLVM callsite given a value.
Definition: LLVMUtil.h:59
bool isCallSite(const Instruction *inst)
Whether an instruction is a call or invoke instruction.
Definition: LLVMUtil.h:45
std::string sucMsg(const std::string &msg)
Returns successful message by converting a string into green string output.
Definition: SVFUtil.cpp:53
std::string bugMsg1(const std::string &msg)
Definition: SVFUtil.cpp:81
const SVFFunction * getCallee(const CallSite cs)
Return callee of a callsite. Return null if this is an indirect call.
Definition: SVFUtil.h:241
std::string pasMsg(const std::string &msg)
Print each pass/phase message by converting a string into blue string output.
Definition: SVFUtil.cpp:99
std::string errMsg(const std::string &msg)
Print error message by converting a string into red string output.
Definition: SVFUtil.cpp:76
std::ostream & errs()
Overwrite llvm::errs()
Definition: SVFUtil.h:56
std::string bugMsg2(const std::string &msg)
Definition: SVFUtil.cpp:86
std::vector< std::string > split(const std::string &s, char separator)
Split into two substrings around the first occurrence of a separator string.
Definition: SVFUtil.h:218
std::ostream & outs()
Overwrite llvm::outs()
Definition: SVFUtil.h:50
for isBitcode
Definition: BasicTypes.h:68
unsigned CallSiteID
Definition: GeneralType.h:58
llvm::CallBase CallBase
Definition: BasicTypes.h:146
llvm::BasicBlock BasicBlock
Definition: BasicTypes.h:86
llvm::Use Use
Definition: BasicTypes.h:72
unsigned NodeID
llvm::Function Function
Definition: BasicTypes.h:85
llvm::Instruction Instruction
Definition: BasicTypes.h:87
llvm::Constant Constant
Definition: BasicTypes.h:124
std::unordered_map< Key, Value, Hash, KeyEqual, Allocator > Map
Definition: GeneralType.h:101
llvm::Value Value
LLVM Basic classes.
Definition: BasicTypes.h:82
llvm::Module Module
Definition: BasicTypes.h:84
std::vector< u32_t > CallStrCxt
Definition: GeneralType.h:122
llvm::GetElementPtrInst GetElementPtrInst
Definition: BasicTypes.h:162
unsigned u32_t
Definition: GeneralType.h:46
llvm::ConstantDataArray ConstantDataArray
Definition: BasicTypes.h:121
llvm::ConstantInt ConstantInt
Definition: BasicTypes.h:125
std::unordered_set< Key, Hash, KeyEqual, Allocator > Set
Definition: GeneralType.h:96