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

Classes

class  CXXABI
 
struct  DemangledName
 
class  ItaniumABI
 
class  MSVCABI
 

Functions

CXXABI * getCXXABI ()
 
CXXABI * getCXXABI (const Module *M)
 
CXXABI * getCXXABI (const Value *val)
 
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 ConstantStruct * getVtblStruct (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 Function * getThunkTarget (const Function *F)
 
const Argument * getConstructorThisPtr (const Function *fun)
 
const Value * getVCallThisPtr (const CallBase *cs)
 
const Value * getVCallVtblPtr (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 Type * cppClsNameToType (const std::string &className)
 

Function Documentation

◆ classTyHasVTable()

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

Definition at line 581 of file CppUtil.cpp.

582{
583 if(getClassNameFromType(ty).empty()==false)
584 {
585 for(auto it = ty->element_begin(); it!=ty->element_end(); it++)
586 {
587 const std::string& str = LLVMUtil::dumpType(*it);
588 if (str.find(vtableType) != std::string::npos)
589 return true;
590 }
591 }
592 return false;
593}
const std::string vtableType
Definition CppUtil.cpp:57
std::string dumpType(const Type *type)
Definition LLVMUtil.cpp:627
std::string getClassNameFromType(const StructType *ty)
Definition CppUtil.cpp:595
llvm::IRBuilder IRBuilder
Definition BasicTypes.h:76

◆ cppClsNameToType()

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

Definition at line 946 of file CppUtil.cpp.

947{
948 StructType *classTy = StructType::getTypeByName(LLVMModuleSet::getLLVMModuleSet()->getContext(),
949 clsName + className);
951}
const std::string clsName
Definition CppUtil.cpp:55
static LLVMModuleSet * getLLVMModuleSet()
Definition LLVMModule.h:133
ObjTypeInference * getTypeInference()
const Type * ptrType()
pointer type
llvm::StructType StructType
LLVM types.
Definition BasicTypes.h:98

◆ demangle()

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

Definition at line 195 of file CppUtil.cpp.

196{
197 return getCXXABI()->demangle(name);
198}
const char *const name
Definition cJSON.h:264
virtual DemangledName demangle(const std::string &name)=0
CXXABI * getCXXABI()
Definition CppUtil.cpp:994

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

931{
932 Value *tgtCast = callBase->getArgOperand(2);
933 const std::string &valueStr = LLVMUtil::dumpValue(tgtCast);
935 assert(leftPos != (u32_t) std::string::npos && "does not find ZTI for dyncast?");
937 while (rightPos < valueStr.size() && valueStr[rightPos] != ' ') rightPos++;
938 const std::string &substr = valueStr.substr(leftPos, rightPos - leftPos);
939 std::string demangleName = llvm::demangle(substr);
940 const std::string &realName = demangleName.substr(ztiprefix.size(),
941 demangleName.size() - ztiprefix.size());
942 assert(realName != "" && "real name for dyncast empty?");
943 return realName;
944}
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:616
llvm::Value Value
LLVM Basic classes.
Definition BasicTypes.h:86
unsigned u32_t
Definition GeneralType.h:67

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

719{
720 const std::string &name = foo->getName().str();
722 {
723 // c++ constructor or destructor
727 clsNameInBrackets.insert(demangledName.className);
728 return clsNameInBrackets;
729 }
730 else if (isTemplateFunc(foo))
731 {
732 // array index
733 Set<std::string> classNames = extractClsNamesFromTemplate(name);
734 assert(!classNames.empty() && "empty class names?");
735 return classNames;
736 }
737 return {};
738}
Set< std::string > getClsNamesInBrackets(const std::string &name)
Definition CppUtil.cpp:202
struct DemangledName demangle(const std::string &name)
Definition CppUtil.cpp:195
bool isConstructor(const Function *F)
Definition CppUtil.cpp:501
bool isDestructor(const Function *F)
Definition CppUtil.cpp:521

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

833{
834 // "std::array<A const*, 2ul>" -> A
835 // "std::queue<A*, std::deque<A*, std::allocator<A*> > >" -> A
836 // __gnu_cxx::__aligned_membuf<std::pair<int const, A> >::_M_ptr() const -> A
838 std::string demangleName = llvm::demangle(oname);
839 std::vector<std::string> innermosts = findInnermostBrackets(demangleName);
840 for (const auto &innermost: innermosts)
841 {
842 const std::vector<std::string> &allstrs = splitAndStrip(innermost, ',');
843 for (const auto &str: allstrs)
844 {
845 size_t spacePos = str.find(' ');
846 if (spacePos != std::string::npos)
847 {
848 // A const* -> A
849 ans.insert(str.substr(0, spacePos));
850 }
851 else
852 {
853 size_t starPos = str.find('*');
854 if (starPos != std::string::npos)
855 // A* -> A
856 ans.insert(str.substr(0, starPos));
857 else
858 ans.insert(str);
859 }
860 }
861 }
862 return ans;
863}
std::vector< std::string > findInnermostBrackets(const std::string &input)
Definition CppUtil.cpp:746
std::vector< std::string > splitAndStrip(const std::string &input, char delimiter)
Definition CppUtil.cpp:811

◆ 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}
signed s32_t
Definition GeneralType.h:68

◆ getClassNameFromType()

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

Definition at line 595 of file CppUtil.cpp.

596{
597 std::string className = "";
598 if (!((SVFUtil::cast<StructType>(ty))->isLiteral()))
599 {
600 std::string elemTypeName = ty->getStructName().str();
601 if (elemTypeName.compare(0, clsName.size(), clsName) == 0)
602 {
603 className = elemTypeName.substr(clsName.size());
604 }
605 else if (elemTypeName.compare(0, structName.size(), structName) == 0)
606 {
607 className = elemTypeName.substr(structName.size());
608 }
609 }
610 return className;
611}
const std::string structName
Definition CppUtil.cpp:56

◆ getClassNameFromVtblObj()

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

Definition at line 256 of file CppUtil.cpp.

257{
259}
virtual std::string extractClassName(const std::string &name)=0

◆ getClassNameOfThisPtr()

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

Definition at line 613 of file CppUtil.cpp.

614{
616 std::string thisPtrClassName = "";
617 if (const MDNode* N = inst->getMetadata("VCallPtrType"))
618 {
619 const MDString* mdstr = SVFUtil::cast<MDString>(N->getOperand(0).get());
620 thisPtrClassName = mdstr->getString().str();
621 }
622 if (thisPtrClassName.size() == 0)
623 {
624 const Value* thisPtr = getVCallThisPtr(inst);
626 thisPtrNames.insert(names.begin(), names.end());
627 }
628
630 std::transform(thisPtrNames.begin(), thisPtrNames.end(), std::inserter(ans, ans.begin()),
631 [](const std::string &thisPtrName) -> std::string
632 {
633 size_t found = thisPtrName.find_last_not_of("0123456789");
634 if (found != std::string::npos)
635 {
636 if (found != thisPtrName.size() - 1 &&
637 thisPtrName[found] == '.')
638 {
639 return thisPtrName.substr(0, found);
640 }
641 }
642 return thisPtrName;
643 });
644 return ans;
645}
Set< std::string > & inferThisPtrClsName(const Value *thisPtr)
get or infer the class names of thisptr
llvm::MDString MDString
Definition BasicTypes.h:105
llvm::MDNode MDNode
Definition BasicTypes.h:116

◆ getClsNamesInBrackets()

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

Definition at line 202 of file CppUtil.cpp.

203{
205 // Lambda to trim whitespace from both ends of a string
206 auto trim = [](std::string& s)
207 {
208 size_t first = s.find_first_not_of(' ');
209 size_t last = s.find_last_not_of(' ');
210 if (first != std::string::npos && last != std::string::npos)
211 {
212 s = s.substr(first, (last - first + 1));
213 }
214 else
215 {
216 s.clear();
217 }
218 };
219
220 // Lambda to remove trailing '*' and '&' characters
221 auto removePointerAndReference = [](std::string& s)
222 {
223 while (!s.empty() && (s.back() == '*' || s.back() == '&'))
224 {
225 s.pop_back();
226 }
227 };
228
229 const std::string realnameStr = llvm::demangle(name);
230 if (realnameStr != name && !realnameStr.empty())
231 {
232 // Find the start and end of the parameter list
233 size_t start = realnameStr.find('(');
234 size_t end = realnameStr.find(')');
235 if (start == std::string::npos || end == std::string::npos || start >= end)
236 {
237 return res; // Return empty set if the format is incorrect
238 }
239
240 // Extract the parameter list
241 std::string paramList = realnameStr.substr(start + 1, end - start - 1);
242
243 // Split the parameter list by commas
244 std::istringstream ss(paramList);
245 std::string param;
246 while (std::getline(ss, param, ','))
247 {
248 trim(param);
250 res.insert(param);
251 }
252 }
253 return res;
254}

◆ getConstructorThisPtr()

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

Definition at line 465 of file CppUtil.cpp.

466{
467 assert((isConstructor(fun) || isDestructor(fun)) &&
468 "not a constructor?");
469 // We always need at least one argument to return something meaningful.
470 assert(fun->arg_size() >= 1 && "expected at least one argument");
471
472 // If param 0 is sret, 'this' is typically param 1, but be defensive.
473 const bool isStructRet = fun->hasParamAttribute(0, llvm::Attribute::StructRet);
474
475 // Prefer arg1 when sret is present and available; otherwise fall back to arg0.
476 const u32_t thisIdx = (isStructRet && fun->arg_size() >= 2) ? 1 : 0;
477 const Argument* thisPtr = fun->getArg(thisIdx);
478
479 return thisPtr;
480}
llvm::Argument Argument
Definition BasicTypes.h:152

◆ getCXXABI() [1/3]

CXXABI * SVF::cppUtil::getCXXABI ( )

Definition at line 994 of file CppUtil.cpp.

995{
998 {
999 return getCXXABI(
1000 LLVMModuleSet::getLLVMModuleSet()->getMainLLVMModule());
1001 }
1002 static ItaniumABI itaniumabi;
1003 return &itaniumabi;
1004}

◆ getCXXABI() [2/3]

CXXABI * SVF::cppUtil::getCXXABI ( const Module *  M)

Definition at line 958 of file CppUtil.cpp.

959{
960 if (M)
961 {
962 llvm::Triple triple(M->getTargetTriple());
963 if (triple.isKnownWindowsMSVCEnvironment() ||
964 triple.isOSBinFormatCOFF())
965 {
966 static MSVCABI msvcabi;
967 return &msvcabi;
968 }
969 }
970 static ItaniumABI itaniumabi;
971 return &itaniumabi;
972}

◆ getCXXABI() [3/3]

CXXABI * SVF::cppUtil::getCXXABI ( const Value *  val)

Definition at line 974 of file CppUtil.cpp.

975{
976 if (val)
977 {
978 if (const GlobalValue* GV = SVFUtil::dyn_cast<GlobalValue>(val))
979 {
980 return getCXXABI(GV->getParent());
981 }
982 if (const Instruction* I = SVFUtil::dyn_cast<Instruction>(val))
983 {
984 return getCXXABI(I->getFunction()->getParent());
985 }
986 if (const Argument* Arg = SVFUtil::dyn_cast<Argument>(val))
987 {
988 return getCXXABI(Arg->getParent()->getParent());
989 }
990 }
991 return getCXXABI();
992}
llvm::GlobalValue GlobalValue
Definition BasicTypes.h:92
llvm::Instruction Instruction
Definition BasicTypes.h:91

◆ getFunNameOfVCallSite()

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

Definition at line 647 of file CppUtil.cpp.

648{
649 std::string funName;
650 if (const MDNode* N = inst->getMetadata("VCallFunName"))
651 {
652 const MDString* mdstr = SVFUtil::cast<MDString>(N->getOperand(0).get());
653 funName = mdstr->getString().str();
654 }
655 return funName;
656}

◆ getThunkTarget()

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

Definition at line 326 of file CppUtil.cpp.

327{
328 const Function* ret = nullptr;
329
330 for (auto& bb : *F)
331 {
332 for (auto& inst : bb)
333 {
334 if (const CallBase* callbase = SVFUtil::dyn_cast<CallBase>(&inst))
335 {
336 // assert(cs.getCalledFunction() &&
337 // "Indirect call detected in thunk func");
338 // assert(ret == nullptr && "multiple callsites in thunk func");
339
340 ret = callbase->getCalledFunction();
341 }
342 }
343 }
344
345 return ret;
346}
llvm::CallBase CallBase
Definition BasicTypes.h:153
llvm::Function Function
Definition BasicTypes.h:89

◆ getVCallIdx()

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

Definition at line 658 of file CppUtil.cpp.

659{
660 const LoadInst* vfuncloadinst =
661 SVFUtil::dyn_cast<LoadInst>(cs->getCalledOperand());
662 assert(vfuncloadinst != nullptr);
663 const Value* vfuncptr = vfuncloadinst->getPointerOperand();
665 SVFUtil::dyn_cast<GetElementPtrInst>(vfuncptr);
666 User::const_op_iterator oi = vfuncptrgepinst->idx_begin();
667 const ConstantInt* idx = SVFUtil::dyn_cast<ConstantInt>(oi->get());
669 if (idx == nullptr)
670 {
671 SVFUtil::errs() << "vcall gep idx not constantint\n";
672 idx_value = 0;
673 }
674 else
675 {
677 }
678 return idx_value;
679}
std::pair< s64_t, u64_t > getIntegerValue(const ConstantInt *intValue)
Definition LLVMUtil.h:85
std::ostream & errs()
Overwrite llvm::errs()
Definition SVFUtil.h:64
llvm::LoadInst LoadInst
Definition BasicTypes.h:156
llvm::GetElementPtrInst GetElementPtrInst
Definition BasicTypes.h:169
llvm::ConstantInt ConstantInt
Definition BasicTypes.h:129

◆ getVCallThisPtr()

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

Definition at line 348 of file CppUtil.cpp.

349{
350 if (cs->paramHasAttr(0, llvm::Attribute::StructRet))
351 {
352 return cs->getArgOperand(1);
353 }
354 else
355 {
356 return cs->getArgOperand(0);
357 }
358}

◆ getVCallVtblPtr()

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

Definition at line 549 of file CppUtil.cpp.

550{
551 const LoadInst* loadInst =
552 SVFUtil::dyn_cast<LoadInst>(cs->getCalledOperand());
553 assert(loadInst != nullptr);
554 const Value* vfuncptr = loadInst->getPointerOperand();
556 SVFUtil::dyn_cast<GetElementPtrInst>(vfuncptr);
557 assert(gepInst != nullptr);
558 const Value* vtbl = gepInst->getPointerOperand();
559 return vtbl;
560}

◆ getVtblStruct()

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

Definition at line 261 of file CppUtil.cpp.

262{
263 const ConstantStruct *vtblStruct = SVFUtil::dyn_cast<ConstantStruct>(vtbl->getOperand(0));
264 assert(vtblStruct && "Initializer of a vtable not a struct?");
265
266 if (vtblStruct->getNumOperands() == 2 &&
267 SVFUtil::isa<ConstantStruct>(vtblStruct->getOperand(0)) &&
268 vtblStruct->getOperand(1)->getType()->isArrayTy())
269 return SVFUtil::cast<ConstantStruct>(vtblStruct->getOperand(0));
270
271 return vtblStruct;
272}
llvm::ConstantStruct ConstantStruct
Definition BasicTypes.h:110

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

873{
874 if (const auto *callBase = SVFUtil::dyn_cast<CallBase>(val))
875 {
876 const Function *foo = callBase->getCalledFunction();
877 // indirect call
878 if(!foo) return false;
880 }
881 else if (const auto *func = SVFUtil::dyn_cast<Function>(val))
882 {
883 return isConstructor(func) || isDestructor(func) || isTemplateFunc(func);
884 }
885 return false;
886}
bool isTemplateFunc(const Function *foo)
whether foo is a cpp template function
Definition CppUtil.cpp:905
bool isDynCast(const Function *foo)
whether foo is a cpp dyncast function
Definition CppUtil.cpp:920

◆ isConstructor()

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

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

Definition at line 501 of file CppUtil.cpp.

502{
503 if (F->isDeclaration())
504 return false;
505 std::string funcName = F->getName().str();
506 if (funcName.compare(0, vfunPreLabel.size(), vfunPreLabel) != 0)
507 {
508 return false;
509 }
511 if (dname.className.size() == 0)
512 {
513 return false;
514 }
517 return dname.className.size() > 0 &&
518 dname.className.compare(dname.funcName) == 0;
519}
void stripBracketsAndNamespace(cppUtil::DemangledName &dname)
Definition CppUtil.cpp:484
const std::string vfunPreLabel
Definition CppUtil.cpp:53

◆ isCPPThunkFunction()

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

Definition at line 320 of file CppUtil.cpp.

321{
322 cppUtil::DemangledName dname = cppUtil::demangle(F->getName().str());
323 return dname.isThunkFunc;
324}

◆ isDestructor()

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

Definition at line 521 of file CppUtil.cpp.

522{
523 if (F->isDeclaration())
524 return false;
525 std::string funcName = F->getName().str();
526 if (funcName.compare(0, vfunPreLabel.size(), vfunPreLabel) != 0)
527 {
528 return false;
529 }
531 if (dname.className.size() == 0)
532 {
533 return false;
534 }
536 return (dname.className.size() > 0 && dname.funcName.size() > 0 &&
537 dname.className.size() + 1 == dname.funcName.size() &&
538 dname.funcName.compare(0, 1, "~") == 0 &&
539 dname.className.compare(dname.funcName.substr(1)) == 0);
540}

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

921{
922 return foo->getName().str() == dyncast;
923}
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 421 of file CppUtil.cpp.

423{
424 if (thisPtr1 == thisPtr2)
425 return true;
426
427 const Value* stripped = thisPtr2->stripPointerCasts();
428 if (stripped == thisPtr1)
429 return true;
430
431 // === Opaque pointer: Load from this.addr (Case 2: primary base at O0) ===
433 return true;
434
435 // === Opaque pointer: GEP check (Case 3 & 4) ===
436 if (const GetElementPtrInst* GEP = SVFUtil::dyn_cast<GetElementPtrInst>(stripped))
437 {
438 if (!isDerivedFromThisPtr(thisPtr1, GEP->getPointerOperand()))
439 return false;
440 // i8 GEP = non-primary base class (Case 3)
441 // struct GEP = member field (Case 4)
442 return GEP->getSourceElementType()->isIntegerTy(8);
443 }
444
445 // === Typed pointer (legacy): store -> load -> bitcast ===
446 for (const Value* thisU : thisPtr1->users())
447 {
448 if (const StoreInst* store = SVFUtil::dyn_cast<StoreInst>(thisU))
449 {
450 for (const Value* storeU : store->getPointerOperand()->users())
451 {
452 if (const LoadInst* load = SVFUtil::dyn_cast<LoadInst>(storeU))
453 {
454 if (load->getNextNode() &&
455 SVFUtil::isa<CastInst>(load->getNextNode()))
456 return SVFUtil::cast<CastInst>(load->getNextNode()) ==
457 (thisPtr2->stripPointerCasts());
458 }
459 }
460 }
461 }
462 return false;
463}
static bool isDerivedFromThisPtr(const Argument *thisPtr, const Value *V)
Definition CppUtil.cpp:362
llvm::StoreInst StoreInst
Definition BasicTypes.h:155

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

906{
907 const std::string &name = foo->getName().str();
910 // we exclude "_ZNK6cArray3dupEv" -> cArray::dup() const
911 const std::string &demangledName = llvm::demangle(name);
912 return matchedLabel && demangledName.find('<') != std::string::npos && demangledName.find('>') != std::string::npos;
913}
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:894

◆ isValVtbl()

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

Definition at line 274 of file CppUtil.cpp.

275{
276 if (!SVFUtil::isa<GlobalVariable>(val))
277 return false;
278 std::string valName = val->getName().str();
279 return getCXXABI(val)->isVtable(valName);
280}
virtual bool isVtable(const std::string &name)=0

◆ isVirtualCallSite()

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

Definition at line 289 of file CppUtil.cpp.

290{
291 // the callsite must be an indirect one with at least one argument (this
292 // ptr)
293 if (cs->getCalledFunction() != nullptr || cs->arg_empty())
294 return false;
295
296 // the first argument (this pointer) must be a pointer type and must be a
297 // class name
298 if (cs->getArgOperand(0)->getType()->isPointerTy() == false)
299 return false;
300
301 const Value* vfunc = cs->getCalledOperand();
302 if (const LoadInst* vfuncloadinst = SVFUtil::dyn_cast<LoadInst>(vfunc))
303 {
304 const Value* vfuncptr = vfuncloadinst->getPointerOperand();
306 SVFUtil::dyn_cast<GetElementPtrInst>(vfuncptr))
307 {
308 if (vfuncptrgepinst->getNumIndices() != 1)
309 return false;
310 const Value* vtbl = vfuncptrgepinst->getPointerOperand();
311 if (SVFUtil::isa<LoadInst>(vtbl))
312 {
313 return true;
314 }
315 }
316 }
317 return false;
318}

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

895{
896 return foo.compare(0, label.size(), label) == 0;
897}

◆ VCallInCtorOrDtor()

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

Definition at line 565 of file CppUtil.cpp.

566{
568 const Function* func = cs->getCaller();
569 for (const auto &classNameOfThisPtr: classNameOfThisPtrs)
570 {
572 {
574 if (classNameOfThisPtr.compare(dname.className) == 0)
575 return true;
576 }
577 }
578 return false;
579}
Set< std::string > getClassNameOfThisPtr(const CallBase *cs)
Definition CppUtil.cpp:613