Static Value-Flow Analysis
Namespaces | Classes | Functions
SVF::cppUtil Namespace Reference

Namespaces

 ctir
 

Classes

struct  DemangledName
 

Functions

struct DemangledName demangle (const std::string &name)
 
Set< std::stringgetClsNamesInBrackets (const std::string &name)
 
std::string getBeforeBrackets (const std::string &name)
 
std::string getClassNameFromVtblObj (const std::string &vtblName)
 
const ConstantStructgetVtblStruct (const GlobalValue *vtbl)
 
bool isValVtbl (const Value *val)
 
bool isVirtualCallSite (const CallBase *cs)
 
bool isConstructor (const Function *F)
 
bool isDestructor (const Function *F)
 
bool isCPPThunkFunction (const Function *F)
 
const FunctiongetThunkTarget (const Function *F)
 
const ArgumentgetConstructorThisPtr (const Function *fun)
 
const ValuegetVCallThisPtr (const CallBase *cs)
 
const ValuegetVCallVtblPtr (const CallBase *cs)
 
s32_t getVCallIdx (const CallBase *cs)
 
bool classTyHasVTable (const StructType *ty)
 
std::string getClassNameFromType (const StructType *ty)
 
Set< std::stringgetClassNameOfThisPtr (const CallBase *cs)
 
std::string getFunNameOfVCallSite (const CallBase *cs)
 
bool VCallInCtorOrDtor (const CallBase *cs)
 
bool isSameThisPtrInConstructor (const Argument *thisPtr1, const Value *thisPtr2)
 
Set< std::stringextractClsNamesFromFunc (const Function *foo)
 extract class name from the c++ function name, e.g., constructor/destructors More...
 
Set< std::stringextractClsNamesFromTemplate (const std::string &oname)
 extract class names from template functions More...
 
bool isClsNameSource (const Value *val)
 
bool matchesLabel (const std::string &foo, const std::string &label)
 whether foo matches the mangler label More...
 
bool isTemplateFunc (const Function *foo)
 whether foo is a cpp template function More...
 
bool isDynCast (const Function *foo)
 whether foo is a cpp dyncast function More...
 
std::string extractClsNameFromDynCast (const CallBase *callBase)
 extract class name from cpp dyncast function More...
 
const TypecppClsNameToType (const std::string &className)
 

Function Documentation

◆ classTyHasVTable()

bool SVF::cppUtil::classTyHasVTable ( const StructType ty)

Definition at line 569 of file CppUtil.cpp.

570 {
571  if(getClassNameFromType(ty).empty()==false)
572  {
573  for(auto it = ty->element_begin(); it!=ty->element_end(); it++)
574  {
575  const std::string& str = LLVMUtil::dumpType(*it);
576  if (str.find(vtableType) != std::string::npos)
577  return true;
578  }
579  }
580  return false;
581 }
const std::string vtableType
Definition: CppUtil.cpp:57
const char *const string
Definition: cJSON.h:172
std::string dumpType(const Type *type)
Definition: LLVMUtil.cpp:596
std::string getClassNameFromType(const StructType *ty)
Definition: CppUtil.cpp:583

◆ cppClsNameToType()

const Type * SVF::cppUtil::cppClsNameToType ( const std::string className)

Definition at line 937 of file CppUtil.cpp.

938 {
939  StructType *classTy = StructType::getTypeByName(LLVMModuleSet::getLLVMModuleSet()->getContext(),
940  clsName + className);
941  return classTy ? classTy : LLVMModuleSet::getLLVMModuleSet()->getTypeInference()->ptrType();
942 }
const std::string clsName
Definition: CppUtil.cpp:55
llvm::StructType StructType
LLVM types.
Definition: BasicTypes.h:94

◆ demangle()

struct cppUtil::DemangledName SVF::cppUtil::demangle ( const std::string name)

Definition at line 146 of file CppUtil.cpp.

196 {
197  struct cppUtil::DemangledName dname;
198  dname.isThunkFunc = false;
199 
200  s32_t status;
201  char* realname = abi::__cxa_demangle(name.c_str(), 0, 0, &status);
202  if (realname == nullptr)
203  {
204  dname.className = "";
205  dname.funcName = "";
206  }
207  else
208  {
209  std::string realnameStr = std::string(realname);
210  std::string beforeParenthesis = getBeforeParenthesis(realnameStr);
211  if (beforeParenthesis.find("::") == std::string::npos ||
212  isOperOverload(beforeParenthesis))
213  {
214  dname.className = "";
215  dname.funcName = "";
216  }
217  else
218  {
219  std::string beforeBracket = getBeforeBrackets(beforeParenthesis);
220  size_t colon = beforeBracket.rfind("::");
221  if (colon == std::string::npos)
222  {
223  dname.className = "";
224  dname.funcName = "";
225  }
226  else
227  {
228  dname.className = beforeParenthesis.substr(0, colon);
229  dname.funcName = beforeParenthesis.substr(colon + 2);
230  }
231  }
232  std::free(realname);
233  }
234 
235  handleThunkFunction(dname);
236 
237  return dname;
238 }
static void handleThunkFunction(cppUtil::DemangledName &dname)
Definition: CppUtil.cpp:146
static bool isOperOverload(const std::string &name)
Definition: CppUtil.cpp:84
static std::string getBeforeParenthesis(const std::string &name)
Definition: CppUtil.cpp:107
const char *const name
Definition: cJSON.h:264
std::string getBeforeBrackets(const std::string &name)
Definition: CppUtil.cpp:127
signed s32_t
Definition: GeneralType.h:47

◆ extractClsNameFromDynCast()

std::string SVF::cppUtil::extractClsNameFromDynCast ( const CallBase callBase)

extract class name from cpp dyncast function

extract class name from cpp dyncast function

Parameters
callBase
Returns

Definition at line 921 of file CppUtil.cpp.

922 {
923  Value *tgtCast = callBase->getArgOperand(2);
924  const std::string &valueStr = LLVMUtil::dumpValue(tgtCast);
925  u32_t leftPos = valueStr.find(ztilabel);
926  assert(leftPos != (u32_t) std::string::npos && "does not find ZTI for dyncast?");
927  u32_t rightPos = leftPos;
928  while (rightPos < valueStr.size() && valueStr[rightPos] != ' ') rightPos++;
929  const std::string &substr = valueStr.substr(leftPos, rightPos - leftPos);
930  std::string demangleName = llvm::demangle(substr);
931  const std::string &realName = demangleName.substr(ztiprefix.size(),
932  demangleName.size() - ztiprefix.size());
933  assert(realName != "" && "real name for dyncast empty?");
934  return realName;
935 }
unsigned u32_t
Definition: CommandLine.h:18
const std::string ztilabel
Definition: CppUtil.cpp:79
const std::string ztiprefix
Definition: CppUtil.cpp:80
std::string dumpValue(const Value *val)
Definition: LLVMUtil.cpp:585
struct DemangledName demangle(const std::string &name)
Definition: CppUtil.cpp:195
llvm::Value Value
LLVM Basic classes.
Definition: BasicTypes.h:82

◆ extractClsNamesFromFunc()

Set< std::string > SVF::cppUtil::extractClsNamesFromFunc ( const Function foo)

extract class name from the c++ function name, e.g., constructor/destructors

extract class name from the c++ function name, e.g., constructor/destructors

Parameters
foo
Returns

Definition at line 706 of file CppUtil.cpp.

707 {
708  assert(foo->hasName() && "foo does not have a name? possible indirect call");
709  const std::string &name = foo->getName().str();
710  if (isConstructor(foo) || isDestructor(foo))
711  {
712  // c++ constructor or destructor
713  DemangledName demangledName = cppUtil::demangle(name);
714  Set<std::string> clsNameInBrackets =
716  clsNameInBrackets.insert(demangledName.className);
717  return clsNameInBrackets;
718  }
719  else if (isTemplateFunc(foo))
720  {
721  // array index
723  assert(!classNames.empty() && "empty class names?");
724  return classNames;
725  }
726  return {};
727 }
bool isTemplateFunc(const Function *foo)
whether foo is a cpp template function
Definition: CppUtil.cpp:894
Set< std::string > getClsNamesInBrackets(const std::string &name)
Definition: CppUtil.cpp:242
Set< std::string > extractClsNamesFromTemplate(const std::string &oname)
extract class names from template functions
Definition: CppUtil.cpp:821
bool isConstructor(const Function *F)
Definition: CppUtil.cpp:489
bool isDestructor(const Function *F)
Definition: CppUtil.cpp:509
std::unordered_set< Key, Hash, KeyEqual, Allocator > Set
Definition: GeneralType.h:96

◆ extractClsNamesFromTemplate()

Set< std::string > SVF::cppUtil::extractClsNamesFromTemplate ( const std::string oname)

extract class names from template functions

extract class names from template functions

Parameters
oname
Returns

Definition at line 821 of file CppUtil.cpp.

822 {
823  // "std::array<A const*, 2ul>" -> A
824  // "std::queue<A*, std::deque<A*, std::allocator<A*> > >" -> A
825  // __gnu_cxx::__aligned_membuf<std::pair<int const, A> >::_M_ptr() const -> A
826  Set<std::string> ans;
827  std::string demangleName = llvm::demangle(oname);
828  std::vector<std::string> innermosts = findInnermostBrackets(demangleName);
829  for (const auto &innermost: innermosts)
830  {
831  const std::vector<std::string> &allstrs = splitAndStrip(innermost, ',');
832  for (const auto &str: allstrs)
833  {
834  size_t spacePos = str.find(' ');
835  if (spacePos != std::string::npos)
836  {
837  // A const* -> A
838  ans.insert(str.substr(0, spacePos));
839  }
840  else
841  {
842  size_t starPos = str.find('*');
843  if (starPos != std::string::npos)
844  // A* -> A
845  ans.insert(str.substr(0, starPos));
846  else
847  ans.insert(str);
848  }
849  }
850  }
851  return ans;
852 }
std::vector< std::string > splitAndStrip(const std::string &input, char delimiter)
Definition: CppUtil.cpp:800
std::vector< std::string > findInnermostBrackets(const std::string &input)
Definition: CppUtil.cpp:735

◆ getBeforeBrackets()

std::string SVF::cppUtil::getBeforeBrackets ( const std::string name)

get class name before brackets e.g., for ‘namespace::A<...::...>::f’, we get ‘namespace::A’

Definition at line 127 of file CppUtil.cpp.

128 {
129  if (name.empty() || name[name.size() - 1] != '>')
130  {
131  return name;
132  }
133  s32_t bracket_num = 1, pos;
134  for (pos = name.size() - 2; pos >= 0; pos--)
135  {
136  if (name[pos] == '>')
137  bracket_num++;
138  if (name[pos] == '<')
139  bracket_num--;
140  if (bracket_num == 0)
141  break;
142  }
143  return name.substr(0, pos);
144 }

◆ getClassNameFromType()

std::string SVF::cppUtil::getClassNameFromType ( const StructType ty)

Definition at line 583 of file CppUtil.cpp.

584 {
585  std::string className = "";
586  if (!((SVFUtil::cast<StructType>(ty))->isLiteral()))
587  {
588  std::string elemTypeName = ty->getStructName().str();
589  if (elemTypeName.compare(0, clsName.size(), clsName) == 0)
590  {
591  className = elemTypeName.substr(clsName.size());
592  }
593  else if (elemTypeName.compare(0, structName.size(), structName) == 0)
594  {
595  className = elemTypeName.substr(structName.size());
596  }
597  }
598  return className;
599 }
const std::string structName
Definition: CppUtil.cpp:56

◆ getClassNameFromVtblObj()

std::string SVF::cppUtil::getClassNameFromVtblObj ( const std::string vtblName)

Definition at line 304 of file CppUtil.cpp.

305 {
306  std::string className = "";
307 
308  s32_t status;
309  char* realname = abi::__cxa_demangle(vtblName.c_str(), 0, 0, &status);
310  if (realname != nullptr)
311  {
312  std::string realnameStr = std::string(realname);
313  if (realnameStr.compare(0, vtblLabelAfterDemangle.size(),
315  {
316  className = realnameStr.substr(vtblLabelAfterDemangle.size());
317  }
318  std::free(realname);
319  }
320  return className;
321 }
const std::string vtblLabelAfterDemangle
Definition: CppUtil.cpp:43

◆ getClassNameOfThisPtr()

Set< std::string > SVF::cppUtil::getClassNameOfThisPtr ( const CallBase cs)

Definition at line 601 of file CppUtil.cpp.

602 {
603  Set<std::string> thisPtrNames;
604  std::string thisPtrClassName = "";
605  if (const MDNode* N = inst->getMetadata("VCallPtrType"))
606  {
607  const MDString* mdstr = SVFUtil::cast<MDString>(N->getOperand(0).get());
608  thisPtrClassName = mdstr->getString().str();
609  }
610  if (thisPtrClassName.size() == 0)
611  {
612  const Value* thisPtr = getVCallThisPtr(inst);
613  Set<std::string>& names = LLVMModuleSet::getLLVMModuleSet()->getTypeInference()->inferThisPtrClsName(thisPtr);
614  thisPtrNames.insert(names.begin(), names.end());
615  }
616 
617  Set<std::string> ans;
618  std::transform(thisPtrNames.begin(), thisPtrNames.end(), std::inserter(ans, ans.begin()),
619  [](const std::string &thisPtrName) -> std::string
620  {
621  size_t found = thisPtrName.find_last_not_of("0123456789");
622  if (found != std::string::npos)
623  {
624  if (found != thisPtrName.size() - 1 &&
625  thisPtrName[found] == '.')
626  {
627  return thisPtrName.substr(0, found);
628  }
629  }
630  return thisPtrName;
631  });
632  return ans;
633 }
const Value * getVCallThisPtr(const CallBase *cs)
Definition: CppUtil.cpp:411
llvm::MDString MDString
Definition: BasicTypes.h:101
llvm::MDNode MDNode
Definition: BasicTypes.h:112

◆ getClsNamesInBrackets()

Set< std::string > SVF::cppUtil::getClsNamesInBrackets ( const std::string name)

Definition at line 242 of file CppUtil.cpp.

243 {
244  Set<std::string> res;
245  // Lambda to trim whitespace from both ends of a string
246  auto trim = [](std::string& s)
247  {
248  size_t first = s.find_first_not_of(' ');
249  size_t last = s.find_last_not_of(' ');
250  if (first != std::string::npos && last != std::string::npos)
251  {
252  s = s.substr(first, (last - first + 1));
253  }
254  else
255  {
256  s.clear();
257  }
258  };
259 
260  // Lambda to remove trailing '*' and '&' characters
261  auto removePointerAndReference = [](std::string& s)
262  {
263  while (!s.empty() && (s.back() == '*' || s.back() == '&'))
264  {
265  s.pop_back();
266  }
267  };
268 
269  s32_t status;
270  char* realname = abi::__cxa_demangle(name.c_str(), 0, 0, &status);
271  if (realname == nullptr)
272  {
273  // do nothing
274  }
275  else
276  {
277  std::string realnameStr = std::string(realname);
278 
279  // Find the start and end of the parameter list
280  size_t start = realnameStr.find('(');
281  size_t end = realnameStr.find(')');
282  if (start == std::string::npos || end == std::string::npos || start >= end)
283  {
284  return res; // Return empty set if the format is incorrect
285  }
286 
287  // Extract the parameter list
288  std::string paramList = realnameStr.substr(start + 1, end - start - 1);
289 
290  // Split the parameter list by commas
291  std::istringstream ss(paramList);
292  std::string param;
293  while (std::getline(ss, param, ','))
294  {
295  trim(param);
296  removePointerAndReference(param);
297  res.insert(param);
298  }
299  std::free(realname);
300  }
301  return res;
302 }

◆ getConstructorThisPtr()

const Argument * SVF::cppUtil::getConstructorThisPtr ( const Function fun)

Definition at line 461 of file CppUtil.cpp.

462 {
463  assert((isConstructor(fun) || isDestructor(fun)) &&
464  "not a constructor?");
465  assert(fun->arg_size() >= 1 && "argument size >= 1?");
466  const Argument* thisPtr = &*(fun->arg_begin());
467  return thisPtr;
468 }
llvm::Argument Argument
Definition: BasicTypes.h:145

◆ getFunNameOfVCallSite()

std::string SVF::cppUtil::getFunNameOfVCallSite ( const CallBase cs)

Definition at line 635 of file CppUtil.cpp.

636 {
637  std::string funName;
638  if (const MDNode* N = inst->getMetadata("VCallFunName"))
639  {
640  const MDString* mdstr = SVFUtil::cast<MDString>(N->getOperand(0).get());
641  funName = mdstr->getString().str();
642  }
643  return funName;
644 }

◆ getThunkTarget()

const Function * SVF::cppUtil::getThunkTarget ( const Function F)

Definition at line 389 of file CppUtil.cpp.

390 {
391  const Function* ret = nullptr;
392 
393  for (auto& bb : *F)
394  {
395  for (auto& inst : bb)
396  {
397  if (const CallBase* callbase = SVFUtil::dyn_cast<CallBase>(&inst))
398  {
399  // assert(cs.getCalledFunction() &&
400  // "Indirect call detected in thunk func");
401  // assert(ret == nullptr && "multiple callsites in thunk func");
402 
403  ret = callbase->getCalledFunction();
404  }
405  }
406  }
407 
408  return ret;
409 }
#define F(f)
llvm::CallBase CallBase
Definition: BasicTypes.h:146
llvm::Function Function
Definition: BasicTypes.h:85

◆ getVCallIdx()

s32_t SVF::cppUtil::getVCallIdx ( const CallBase cs)

Definition at line 646 of file CppUtil.cpp.

647 {
648  const LoadInst* vfuncloadinst =
649  SVFUtil::dyn_cast<LoadInst>(cs->getCalledOperand());
650  assert(vfuncloadinst != nullptr);
651  const Value* vfuncptr = vfuncloadinst->getPointerOperand();
652  const GetElementPtrInst* vfuncptrgepinst =
653  SVFUtil::dyn_cast<GetElementPtrInst>(vfuncptr);
654  User::const_op_iterator oi = vfuncptrgepinst->idx_begin();
655  const ConstantInt* idx = SVFUtil::dyn_cast<ConstantInt>(oi->get());
656  s32_t idx_value;
657  if (idx == nullptr)
658  {
659  SVFUtil::errs() << "vcall gep idx not constantint\n";
660  idx_value = 0;
661  }
662  else
663  {
664  idx_value = (s32_t)idx->getSExtValue();
665  }
666  return idx_value;
667 }
std::ostream & errs()
Overwrite llvm::errs()
Definition: SVFUtil.h:56
llvm::LoadInst LoadInst
Definition: BasicTypes.h:149
llvm::GetElementPtrInst GetElementPtrInst
Definition: BasicTypes.h:162
llvm::ConstantInt ConstantInt
Definition: BasicTypes.h:125

◆ getVCallThisPtr()

const Value * SVF::cppUtil::getVCallThisPtr ( const CallBase cs)

Definition at line 411 of file CppUtil.cpp.

412 {
413  if (cs->paramHasAttr(0, llvm::Attribute::StructRet))
414  {
415  return cs->getArgOperand(1);
416  }
417  else
418  {
419  return cs->getArgOperand(0);
420  }
421 }

◆ getVCallVtblPtr()

const Value * SVF::cppUtil::getVCallVtblPtr ( const CallBase cs)

Definition at line 537 of file CppUtil.cpp.

538 {
539  const LoadInst* loadInst =
540  SVFUtil::dyn_cast<LoadInst>(cs->getCalledOperand());
541  assert(loadInst != nullptr);
542  const Value* vfuncptr = loadInst->getPointerOperand();
543  const GetElementPtrInst* gepInst =
544  SVFUtil::dyn_cast<GetElementPtrInst>(vfuncptr);
545  assert(gepInst != nullptr);
546  const Value* vtbl = gepInst->getPointerOperand();
547  return vtbl;
548 }

◆ getVtblStruct()

const ConstantStruct * SVF::cppUtil::getVtblStruct ( const GlobalValue vtbl)

Definition at line 323 of file CppUtil.cpp.

324 {
325  const ConstantStruct *vtblStruct = SVFUtil::dyn_cast<ConstantStruct>(vtbl->getOperand(0));
326  assert(vtblStruct && "Initializer of a vtable not a struct?");
327 
328  if (vtblStruct->getNumOperands() == 2 &&
329  SVFUtil::isa<ConstantStruct>(vtblStruct->getOperand(0)) &&
330  vtblStruct->getOperand(1)->getType()->isArrayTy())
331  return SVFUtil::cast<ConstantStruct>(vtblStruct->getOperand(0));
332 
333  return vtblStruct;
334 }
llvm::ConstantStruct ConstantStruct
Definition: BasicTypes.h:106

◆ isClsNameSource()

bool SVF::cppUtil::isClsNameSource ( const Value val)

class sources can be heap allocation or functions where we can extract the class name (constructors/destructors or template functions)

class sources are functions where we can extract the class name (constructors/destructors or template functions)

Parameters
val
Returns

Definition at line 861 of file CppUtil.cpp.

862 {
863  if (const auto *callBase = SVFUtil::dyn_cast<CallBase>(val))
864  {
865  const Function *foo = callBase->getCalledFunction();
866  // indirect call
867  if(!foo) return false;
868  return isConstructor(foo) || isDestructor(foo) || isTemplateFunc(foo) || isDynCast(foo);
869  }
870  else if (const auto *func = SVFUtil::dyn_cast<Function>(val))
871  {
872  return isConstructor(func) || isDestructor(func) || isTemplateFunc(func);
873  }
874  return false;
875 }
bool isDynCast(const Function *foo)
whether foo is a cpp dyncast function
Definition: CppUtil.cpp:910

◆ isConstructor()

bool SVF::cppUtil::isConstructor ( const Function F)

TODO: on mac os function name is an empty string after demangling

Definition at line 489 of file CppUtil.cpp.

490 {
491  if (F->isDeclaration())
492  return false;
493  std::string funcName = F->getName().str();
494  if (funcName.compare(0, vfunPreLabel.size(), vfunPreLabel) != 0)
495  {
496  return false;
497  }
498  struct cppUtil::DemangledName dname = cppUtil::demangle(funcName.c_str());
499  if (dname.className.size() == 0)
500  {
501  return false;
502  }
505  return dname.className.size() > 0 &&
506  dname.className.compare(dname.funcName) == 0;
507 }
void stripBracketsAndNamespace(cppUtil::DemangledName &dname)
Definition: CppUtil.cpp:472
const std::string vfunPreLabel
Definition: CppUtil.cpp:53

◆ isCPPThunkFunction()

bool SVF::cppUtil::isCPPThunkFunction ( const Function F)

Definition at line 383 of file CppUtil.cpp.

384 {
385  cppUtil::DemangledName dname = cppUtil::demangle(F->getName().str());
386  return dname.isThunkFunc;
387 }

◆ isDestructor()

bool SVF::cppUtil::isDestructor ( const Function F)

Definition at line 509 of file CppUtil.cpp.

510 {
511  if (F->isDeclaration())
512  return false;
513  std::string funcName = F->getName().str();
514  if (funcName.compare(0, vfunPreLabel.size(), vfunPreLabel) != 0)
515  {
516  return false;
517  }
518  struct cppUtil::DemangledName dname = cppUtil::demangle(funcName.c_str());
519  if (dname.className.size() == 0)
520  {
521  return false;
522  }
524  return (dname.className.size() > 0 && dname.funcName.size() > 0 &&
525  dname.className.size() + 1 == dname.funcName.size() &&
526  dname.funcName.compare(0, 1, "~") == 0 &&
527  dname.className.compare(dname.funcName.substr(1)) == 0);
528 }

◆ isDynCast()

bool SVF::cppUtil::isDynCast ( const Function foo)

whether foo is a cpp dyncast function

whether foo is a cpp dyncast function

Parameters
foo
Returns

Definition at line 910 of file CppUtil.cpp.

911 {
912  assert(foo->hasName() && "foo does not have a name? possible indirect call");
913  return foo->getName().str() == dyncast;
914 }
const std::string dyncast
Definition: CppUtil.cpp:81

◆ isSameThisPtrInConstructor()

bool SVF::cppUtil::isSameThisPtrInConstructor ( const Argument thisPtr1,
const Value thisPtr2 
)

Given a inheritance relation B is a child of A We assume B::B(thisPtr1){ A::A(thisPtr2) } such that thisPtr1 == thisPtr2 In the following code thisPtr1 is "%class.B1* %this" and thisPtr2 is "%class.A* %0".

define linkonce_odr dso_local void @B1::B1()(class.B1* this) unnamed_addr #6 comdat this.addr = alloca class.B1*, align 8 store class.B1* this, class.B1** this.addr, align 8 this1 = load class.B1*, class.B1** this.addr, align 8 %0 = bitcast class.B1* this1 to class.A* call void @A::A()(class.A* %0)

Definition at line 437 of file CppUtil.cpp.

439 {
440  if (thisPtr1 == thisPtr2)
441  return true;
442  for (const Value* thisU : thisPtr1->users())
443  {
444  if (const StoreInst* store = SVFUtil::dyn_cast<StoreInst>(thisU))
445  {
446  for (const Value* storeU : store->getPointerOperand()->users())
447  {
448  if (const LoadInst* load = SVFUtil::dyn_cast<LoadInst>(storeU))
449  {
450  if (load->getNextNode() &&
451  SVFUtil::isa<CastInst>(load->getNextNode()))
452  return SVFUtil::cast<CastInst>(load->getNextNode()) ==
453  (thisPtr2->stripPointerCasts());
454  }
455  }
456  }
457  }
458  return false;
459 }
llvm::StoreInst StoreInst
Definition: BasicTypes.h:148

◆ isTemplateFunc()

bool SVF::cppUtil::isTemplateFunc ( const Function foo)

whether foo is a cpp template function

whether foo is a cpp template function TODO: we only consider limited label for now (see the very beginning of CppUtil.cpp)

Parameters
foo
Returns

Definition at line 894 of file CppUtil.cpp.

895 {
896  assert(foo->hasName() && "foo does not have a name? possible indirect call");
897  const std::string &name = foo->getName().str();
898  bool matchedLabel = matchesLabel(name, znstLabel) || matchesLabel(name, znkstLabel) ||
900  // we exclude "_ZNK6cArray3dupEv" -> cArray::dup() const
901  const std::string &demangledName = llvm::demangle(name);
902  return matchedLabel && demangledName.find('<') != std::string::npos && demangledName.find('>') != std::string::npos;
903 }
const std::string znstLabel
Definition: CppUtil.cpp:61
const std::string znkstLabel
Definition: CppUtil.cpp:69
const std::string znkLabel
Definition: CppUtil.cpp:76
bool matchesLabel(const std::string &foo, const std::string &label)
whether foo matches the mangler label
Definition: CppUtil.cpp:883

◆ isValVtbl()

bool SVF::cppUtil::isValVtbl ( const Value val)

Definition at line 336 of file CppUtil.cpp.

337 {
338  if (!SVFUtil::isa<GlobalVariable>(val))
339  return false;
340  std::string valName = val->getName().str();
341  return valName.compare(0, vtblLabelBeforeDemangle.size(),
343 }
const std::string vtblLabelBeforeDemangle
Definition: CppUtil.cpp:50

◆ isVirtualCallSite()

bool SVF::cppUtil::isVirtualCallSite ( const CallBase cs)

Definition at line 352 of file CppUtil.cpp.

353 {
354  // the callsite must be an indirect one with at least one argument (this
355  // ptr)
356  if (cs->getCalledFunction() != nullptr || cs->arg_empty())
357  return false;
358 
359  // the first argument (this pointer) must be a pointer type and must be a
360  // class name
361  if (cs->getArgOperand(0)->getType()->isPointerTy() == false)
362  return false;
363 
364  const Value* vfunc = cs->getCalledOperand();
365  if (const LoadInst* vfuncloadinst = SVFUtil::dyn_cast<LoadInst>(vfunc))
366  {
367  const Value* vfuncptr = vfuncloadinst->getPointerOperand();
368  if (const GetElementPtrInst* vfuncptrgepinst =
369  SVFUtil::dyn_cast<GetElementPtrInst>(vfuncptr))
370  {
371  if (vfuncptrgepinst->getNumIndices() != 1)
372  return false;
373  const Value* vtbl = vfuncptrgepinst->getPointerOperand();
374  if (SVFUtil::isa<LoadInst>(vtbl))
375  {
376  return true;
377  }
378  }
379  }
380  return false;
381 }

◆ matchesLabel()

bool SVF::cppUtil::matchesLabel ( const std::string foo,
const std::string label 
)

whether foo matches the mangler label

whether fooName matches the mangler label

Parameters
foo
label
Returns

Definition at line 883 of file CppUtil.cpp.

884 {
885  return foo.compare(0, label.size(), label) == 0;
886 }

◆ VCallInCtorOrDtor()

bool SVF::cppUtil::VCallInCtorOrDtor ( const CallBase cs)

Definition at line 553 of file CppUtil.cpp.

554 {
555  Set<std::string> classNameOfThisPtrs = cppUtil::getClassNameOfThisPtr(cs);
556  const Function* func = cs->getCaller();
557  for (const auto &classNameOfThisPtr: classNameOfThisPtrs)
558  {
560  {
561  cppUtil::DemangledName dname = cppUtil::demangle(func->getName().str());
562  if (classNameOfThisPtr.compare(dname.className) == 0)
563  return true;
564  }
565  }
566  return false;
567 }
Set< std::string > getClassNameOfThisPtr(const CallBase *cs)
Definition: CppUtil.cpp:601