Static Value-Flow Analysis
Loading...
Searching...
No Matches
Namespaces | Classes | Functions
SVF::cppUtil Namespace Reference

Namespaces

namespace  ctir
 

Classes

struct  DemangledName
 

Functions

struct DemangledName demangle (const std::string &name)
 
Set< std::string > getClsNamesInBrackets (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::string > getClassNameOfThisPtr (const CallBase *cs)
 
std::string getFunNameOfVCallSite (const CallBase *cs)
 
bool VCallInCtorOrDtor (const CallBase *cs)
 
bool isSameThisPtrInConstructor (const Argument *thisPtr1, const Value *thisPtr2)
 
Set< std::string > extractClsNamesFromFunc (const Function *foo)
 extract class name from the c++ function name, e.g., constructor/destructors
 
Set< std::string > extractClsNamesFromTemplate (const std::string &oname)
 extract class names from template functions
 
bool isClsNameSource (const Value *val)
 
bool matchesLabel (const std::string &foo, const std::string &label)
 whether foo matches the mangler label
 
bool isTemplateFunc (const Function *foo)
 whether foo is a cpp template function
 
bool isDynCast (const Function *foo)
 whether foo is a cpp dyncast function
 
std::string extractClsNameFromDynCast (const CallBase *callBase)
 extract class name from cpp dyncast function
 
const TypecppClsNameToType (const std::string &className)
 

Function Documentation

◆ classTyHasVTable()

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

Definition at line 640 of file CppUtil.cpp.

641{
642 if(getClassNameFromType(ty).empty()==false)
643 {
644 for(auto it = ty->element_begin(); it!=ty->element_end(); it++)
645 {
646 const std::string& str = LLVMUtil::dumpType(*it);
647 if (str.find(vtableType) != std::string::npos)
648 return true;
649 }
650 }
651 return false;
652}
const std::string vtableType
Definition CppUtil.cpp:57
std::string dumpType(const Type *type)
Definition LLVMUtil.cpp:611
std::string getClassNameFromType(const StructType *ty)
Definition CppUtil.cpp:654
llvm::IRBuilder IRBuilder
Definition BasicTypes.h:74

◆ cppClsNameToType()

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

Definition at line 1005 of file CppUtil.cpp.

1006{
1007 StructType *classTy = StructType::getTypeByName(LLVMModuleSet::getLLVMModuleSet()->getContext(),
1008 clsName + className);
1010}
const std::string clsName
Definition CppUtil.cpp:55
static LLVMModuleSet * getLLVMModuleSet()
Definition LLVMModule.h:131
ObjTypeInference * getTypeInference()
const Type * ptrType()
pointer type
llvm::StructType StructType
LLVM types.
Definition BasicTypes.h:94

◆ demangle()

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

Definition at line 195 of file CppUtil.cpp.

196{
198 dname.isThunkFunc = false;
199
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);
211 if (beforeParenthesis.find("::") == std::string::npos ||
213 {
214 dname.className = "";
215 dname.funcName = "";
216 }
217 else
218 {
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
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:48

◆ 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 989 of file CppUtil.cpp.

990{
991 Value *tgtCast = callBase->getArgOperand(2);
992 const std::string &valueStr = LLVMUtil::dumpValue(tgtCast);
994 assert(leftPos != (u32_t) std::string::npos && "does not find ZTI for dyncast?");
996 while (rightPos < valueStr.size() && valueStr[rightPos] != ' ') rightPos++;
997 const std::string &substr = valueStr.substr(leftPos, rightPos - leftPos);
998 std::string demangleName = llvm::demangle(substr);
999 const std::string &realName = demangleName.substr(ztiprefix.size(),
1000 demangleName.size() - ztiprefix.size());
1001 assert(realName != "" && "real name for dyncast empty?");
1002 return realName;
1003}
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:600
llvm::Value Value
LLVM Basic classes.
Definition BasicTypes.h:82
unsigned u32_t
Definition GeneralType.h:47

◆ 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 777 of file CppUtil.cpp.

778{
779 const std::string &name = foo->getName().str();
781 {
782 // c++ constructor or destructor
786 clsNameInBrackets.insert(demangledName.className);
787 return clsNameInBrackets;
788 }
789 else if (isTemplateFunc(foo))
790 {
791 // array index
792 Set<std::string> classNames = extractClsNamesFromTemplate(name);
793 assert(!classNames.empty() && "empty class names?");
794 return classNames;
795 }
796 return {};
797}
Set< std::string > getClsNamesInBrackets(const std::string &name)
Definition CppUtil.cpp:242
struct DemangledName demangle(const std::string &name)
Definition CppUtil.cpp:195
bool isConstructor(const Function *F)
Definition CppUtil.cpp:560
bool isDestructor(const Function *F)
Definition CppUtil.cpp:580

◆ 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 891 of file CppUtil.cpp.

892{
893 // "std::array<A const*, 2ul>" -> A
894 // "std::queue<A*, std::deque<A*, std::allocator<A*> > >" -> A
895 // __gnu_cxx::__aligned_membuf<std::pair<int const, A> >::_M_ptr() const -> A
897 std::string demangleName = llvm::demangle(oname);
898 std::vector<std::string> innermosts = findInnermostBrackets(demangleName);
899 for (const auto &innermost: innermosts)
900 {
901 const std::vector<std::string> &allstrs = splitAndStrip(innermost, ',');
902 for (const auto &str: allstrs)
903 {
904 size_t spacePos = str.find(' ');
905 if (spacePos != std::string::npos)
906 {
907 // A const* -> A
908 ans.insert(str.substr(0, spacePos));
909 }
910 else
911 {
912 size_t starPos = str.find('*');
913 if (starPos != std::string::npos)
914 // A* -> A
915 ans.insert(str.substr(0, starPos));
916 else
917 ans.insert(str);
918 }
919 }
920 }
921 return ans;
922}
std::vector< std::string > findInnermostBrackets(const std::string &input)
Definition CppUtil.cpp:805
std::vector< std::string > splitAndStrip(const std::string &input, char delimiter)
Definition CppUtil.cpp:870

◆ 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 654 of file CppUtil.cpp.

655{
656 std::string className = "";
657 if (!((SVFUtil::cast<StructType>(ty))->isLiteral()))
658 {
659 std::string elemTypeName = ty->getStructName().str();
660 if (elemTypeName.compare(0, clsName.size(), clsName) == 0)
661 {
662 className = elemTypeName.substr(clsName.size());
663 }
664 else if (elemTypeName.compare(0, structName.size(), structName) == 0)
665 {
666 className = elemTypeName.substr(structName.size());
667 }
668 }
669 return className;
670}
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
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 672 of file CppUtil.cpp.

673{
675 std::string thisPtrClassName = "";
676 if (const MDNode* N = inst->getMetadata("VCallPtrType"))
677 {
678 const MDString* mdstr = SVFUtil::cast<MDString>(N->getOperand(0).get());
679 thisPtrClassName = mdstr->getString().str();
680 }
681 if (thisPtrClassName.size() == 0)
682 {
683 const Value* thisPtr = getVCallThisPtr(inst);
685 thisPtrNames.insert(names.begin(), names.end());
686 }
687
689 std::transform(thisPtrNames.begin(), thisPtrNames.end(), std::inserter(ans, ans.begin()),
690 [](const std::string &thisPtrName) -> std::string
691 {
692 size_t found = thisPtrName.find_last_not_of("0123456789");
693 if (found != std::string::npos)
694 {
695 if (found != thisPtrName.size() - 1 &&
696 thisPtrName[found] == '.')
697 {
698 return thisPtrName.substr(0, found);
699 }
700 }
701 return thisPtrName;
702 });
703 return ans;
704}
Set< std::string > & inferThisPtrClsName(const Value *thisPtr)
get or infer the class names of thisptr
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{
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
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);
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 528 of file CppUtil.cpp.

529{
530 assert((isConstructor(fun) || isDestructor(fun)) &&
531 "not a constructor?");
532 assert(fun->arg_size() >= 1 && "argument size >= 1?");
533 const bool isStructRet = fun->hasParamAttribute(0, llvm::Attribute::StructRet);
534 assert((isStructRet ? fun->arg_size() >= 2 : true) &&
535 "argument size for struct ret constructor >= 2?");
536 const Argument* thisPtr = isStructRet ?
537 fun->getArg(1) : fun->getArg(0);
538 return thisPtr;
539}
#define true
Definition cJSON.cpp:65
llvm::Argument Argument
Definition BasicTypes.h:145

◆ getFunNameOfVCallSite()

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

Definition at line 706 of file CppUtil.cpp.

707{
708 std::string funName;
709 if (const MDNode* N = inst->getMetadata("VCallFunName"))
710 {
711 const MDString* mdstr = SVFUtil::cast<MDString>(N->getOperand(0).get());
712 funName = mdstr->getString().str();
713 }
714 return funName;
715}

◆ 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}
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 717 of file CppUtil.cpp.

718{
719 const LoadInst* vfuncloadinst =
720 SVFUtil::dyn_cast<LoadInst>(cs->getCalledOperand());
721 assert(vfuncloadinst != nullptr);
722 const Value* vfuncptr = vfuncloadinst->getPointerOperand();
724 SVFUtil::dyn_cast<GetElementPtrInst>(vfuncptr);
725 User::const_op_iterator oi = vfuncptrgepinst->idx_begin();
726 const ConstantInt* idx = SVFUtil::dyn_cast<ConstantInt>(oi->get());
728 if (idx == nullptr)
729 {
730 SVFUtil::errs() << "vcall gep idx not constantint\n";
731 idx_value = 0;
732 }
733 else
734 {
736 }
737 return idx_value;
738}
std::pair< s64_t, u64_t > getIntegerValue(const ConstantInt *intValue)
Definition LLVMUtil.h:82
std::ostream & errs()
Overwrite llvm::errs()
Definition SVFUtil.h:58
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 608 of file CppUtil.cpp.

609{
610 const LoadInst* loadInst =
611 SVFUtil::dyn_cast<LoadInst>(cs->getCalledOperand());
612 assert(loadInst != nullptr);
613 const Value* vfuncptr = loadInst->getPointerOperand();
615 SVFUtil::dyn_cast<GetElementPtrInst>(vfuncptr);
616 assert(gepInst != nullptr);
617 const Value* vtbl = gepInst->getPointerOperand();
618 return vtbl;
619}

◆ 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 931 of file CppUtil.cpp.

932{
933 if (const auto *callBase = SVFUtil::dyn_cast<CallBase>(val))
934 {
935 const Function *foo = callBase->getCalledFunction();
936 // indirect call
937 if(!foo) return false;
939 }
940 else if (const auto *func = SVFUtil::dyn_cast<Function>(val))
941 {
942 return isConstructor(func) || isDestructor(func) || isTemplateFunc(func);
943 }
944 return false;
945}
bool isTemplateFunc(const Function *foo)
whether foo is a cpp template function
Definition CppUtil.cpp:964
bool isDynCast(const Function *foo)
whether foo is a cpp dyncast function
Definition CppUtil.cpp:979

◆ isConstructor()

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

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

Definition at line 560 of file CppUtil.cpp.

561{
562 if (F->isDeclaration())
563 return false;
564 std::string funcName = F->getName().str();
565 if (funcName.compare(0, vfunPreLabel.size(), vfunPreLabel) != 0)
566 {
567 return false;
568 }
570 if (dname.className.size() == 0)
571 {
572 return false;
573 }
576 return dname.className.size() > 0 &&
577 dname.className.compare(dname.funcName) == 0;
578}
void stripBracketsAndNamespace(cppUtil::DemangledName &dname)
Definition CppUtil.cpp:543
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 580 of file CppUtil.cpp.

581{
582 if (F->isDeclaration())
583 return false;
584 std::string funcName = F->getName().str();
585 if (funcName.compare(0, vfunPreLabel.size(), vfunPreLabel) != 0)
586 {
587 return false;
588 }
590 if (dname.className.size() == 0)
591 {
592 return false;
593 }
595 return (dname.className.size() > 0 && dname.funcName.size() > 0 &&
596 dname.className.size() + 1 == dname.funcName.size() &&
597 dname.funcName.compare(0, 1, "~") == 0 &&
598 dname.className.compare(dname.funcName.substr(1)) == 0);
599}

◆ 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 979 of file CppUtil.cpp.

980{
981 return foo->getName().str() == dyncast;
982}
const std::string dyncast
Definition CppUtil.cpp:81

◆ isSameThisPtrInConstructor()

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

Given an inheritance relation B is a child of A We assume B::B(thisPtr1){ A::A(thisPtr2) } such that thisPtr1 == thisPtr2

=== Typed pointer mode === this.addr = alloca class.B1* store class.B1* this, class.B1** this.addr this1 = load class.B1*, class.B1** this.addr %0 = bitcast class.B1* this1 to class.A* call void @AA()(class.A* %0)

=== Opaque pointer mode ===

Case 1: Primary base class (offset 0) at O1+ call ptr @Base::Base(ptr this) → thisPtr2 == thisPtr1, return true

Case 2: Primary base class (offset 0) at O0 this.addr = alloca ptr store ptr this, ptr this.addr this1 = load ptr, ptr this.addr call void @Base::Base(ptr this1) → thisPtr2 is LoadInst from alloca storing thisPtr1, return true

Case 3: Non-primary base class (multiple inheritance, offset > 0) %0 = getelementptr inbounds i8, ptr this1, i64 4 call void @Base2Base2(ptr %0) → i8 GEP from this, return true

Case 4: Member field initialization (NOT base class) mem = getelementptr inbounds struct.Derived, ptr this1, i32 0, i32 1 call void @MemberMember(ptr mem) → struct GEP from this, return false

Definition at line 484 of file CppUtil.cpp.

486{
487 if (thisPtr1 == thisPtr2)
488 return true;
489
490 const Value* stripped = thisPtr2->stripPointerCasts();
491 if (stripped == thisPtr1)
492 return true;
493
494 // === Opaque pointer: Load from this.addr (Case 2: primary base at O0) ===
496 return true;
497
498 // === Opaque pointer: GEP check (Case 3 & 4) ===
499 if (const GetElementPtrInst* GEP = SVFUtil::dyn_cast<GetElementPtrInst>(stripped))
500 {
501 if (!isDerivedFromThisPtr(thisPtr1, GEP->getPointerOperand()))
502 return false;
503 // i8 GEP = non-primary base class (Case 3)
504 // struct GEP = member field (Case 4)
505 return GEP->getSourceElementType()->isIntegerTy(8);
506 }
507
508 // === Typed pointer (legacy): store -> load -> bitcast ===
509 for (const Value* thisU : thisPtr1->users())
510 {
511 if (const StoreInst* store = SVFUtil::dyn_cast<StoreInst>(thisU))
512 {
513 for (const Value* storeU : store->getPointerOperand()->users())
514 {
515 if (const LoadInst* load = SVFUtil::dyn_cast<LoadInst>(storeU))
516 {
517 if (load->getNextNode() &&
518 SVFUtil::isa<CastInst>(load->getNextNode()))
519 return SVFUtil::cast<CastInst>(load->getNextNode()) ==
520 (thisPtr2->stripPointerCasts());
521 }
522 }
523 }
524 }
525 return false;
526}
static bool isDerivedFromThisPtr(const Argument *thisPtr, const Value *V)
Definition CppUtil.cpp:425
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 964 of file CppUtil.cpp.

965{
966 const std::string &name = foo->getName().str();
969 // we exclude "_ZNK6cArray3dupEv" -> cArray::dup() const
970 const std::string &demangledName = llvm::demangle(name);
971 return matchedLabel && demangledName.find('<') != std::string::npos && demangledName.find('>') != std::string::npos;
972}
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:953

◆ 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();
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 953 of file CppUtil.cpp.

954{
955 return foo.compare(0, label.size(), label) == 0;
956}

◆ VCallInCtorOrDtor()

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

Definition at line 624 of file CppUtil.cpp.

625{
627 const Function* func = cs->getCaller();
628 for (const auto &classNameOfThisPtr: classNameOfThisPtrs)
629 {
631 {
633 if (classNameOfThisPtr.compare(dname.className) == 0)
634 return true;
635 }
636 }
637 return false;
638}
Set< std::string > getClassNameOfThisPtr(const CallBase *cs)
Definition CppUtil.cpp:672