41 SVFUtil::errs() << SVFUtil::errMsg("Error ") << __FILE__ << ':' \
42 << __LINE__ << ": " << (msg) << '\n'; \
44#define ABORT_MSG(msg) \
50#define ABORT_IFNOT(condition, msg) \
58#define WARN_MSG(msg) \
61 SVFUtil::outs() << SVFUtil::wrnMsg("Warning ") << __FILE__ << ':' \
62 << __LINE__ << ": " << msg << '\n'; \
64#define WARN_IFNOT(condition, msg) \
72#define WARN_IFNOT(condition, msg)
76using namespace SVFUtil;
77using namespace LLVMUtil;
78using namespace cppUtil;
86#if LLVM_VERSION_MAJOR >= 21
89 return v->hasUseList();
94 return !SVFUtil::isa<ConstantData>(
v);
106 if (SVFUtil::isa<LoadInst, StoreInst>(
val))
108 return llvm::getLoadStoreType(
const_cast<Value *
>(
val));
110 else if (
const auto *
gepInst = SVFUtil::dyn_cast<GetElementPtrInst>(
val))
112 return gepInst->getSourceElementType();
114 else if (
const auto *call = SVFUtil::dyn_cast<CallBase>(
val))
116 return call->getFunctionType();
118 else if (
const auto *
allocaInst = SVFUtil::dyn_cast<AllocaInst>(
val))
122 else if (
const auto *
globalValue = SVFUtil::dyn_cast<GlobalValue>(
val))
137 SVFUtil::cast<Instruction>(
val)))
173 for (
const auto&
use:
var->users())
175 if (
const CallBase* cs = SVFUtil::dyn_cast<CallBase>(
use))
180 assert(cs->getNumOperands() > 1 &&
"arguments should be greater than 1");
181 const Value* dst = cs->getArgOperand(0);
182 const Value* src = cs->getArgOperand(1);
183 if(
calledFun->getName().find(
"iconv") != std::string::npos)
185 if(
var == cs->getArgOperand(0))
187 dst = cs->getArgOperand(3), src = cs->getArgOperand(1);
212 for (
const auto &
source: sources)
293 SVFUtil::dyn_cast<GetElementPtrInst>(
curValue))
298 for (
const auto it :
curValue->users())
300 if (
const auto*
loadInst = SVFUtil::dyn_cast<LoadInst>(it))
311 SVFUtil::dyn_cast<StoreInst>(it))
325 for (
const auto nit :
335 if (SVFUtil::isa<LoadInst>(
nit))
342 SVFUtil::dyn_cast<GetElementPtrInst>(
364 if (
const auto* load =
365 SVFUtil::dyn_cast<LoadInst>(
gepBase))
368 load->getPointerOperand()->users())
371 !SVFUtil::isa<LoadInst>(
loadUse))
375 if (!SVFUtil::isa<GetElementPtrInst>(
381 if (SVFUtil::isa<LoadInst>(
391 else if (
const auto*
alloc =
392 SVFUtil::dyn_cast<AllocaInst>(
gepBase))
408 if (!SVFUtil::isa<GetElementPtrInst>(
413 if (SVFUtil::isa<LoadInst>(
loadUse2))
425 SVFUtil::dyn_cast<GetElementPtrInst>(it))
438 SVFUtil::dyn_cast<BitCastInst>(it))
443 else if (
const auto*
phiNode = SVFUtil::dyn_cast<PHINode>(it))
449 SVFUtil::dyn_cast<ReturnInst>(it))
462 for (
const auto callsite :
retInst->getFunction()->users())
465 SVFUtil::dyn_cast<CallBase>(callsite))
469 if (
callBase->getCalledFunction() !=
476 else if (
const auto*
callBase = SVFUtil::dyn_cast<CallBase>(it))
491 if (SVFUtil::isa<Function>(
curValue) &&
510 llvm::dyn_cast<llvm::LoadInst>(&I))
513 load->getPointerOperand();
544 WARN_MSG(
"Using default type, trace ID is " +
574 if (visited.count(
curPair))
continue;
591 sources.insert(
vIt->second.begin(),
vIt->second.end());
623 for (
const auto use:
loadInst->getPointerOperand()->users())
636 for (
const auto use:
argument->getParent()->users())
653 if (!
callee->isDeclaration())
696 SVFUtil::dyn_cast<llvm::ConstantInt>(cs->getOperand(1));
697 assert(
pInt &&
"the second argument is a integer");
732 return std::distance(
callBase->arg_begin(), it);
738 if (
objTys.empty())
return nullptr;
755 if (SVFUtil::isa<ArrayType>(
objTy))
757 else if (
const auto *
st = SVFUtil::dyn_cast<StructType>(
objTy))
796 const auto *
func = call->getCalledFunction();
811 if (
const auto *
func = SVFUtil::dyn_cast<Function>(
val))
825 ABORT_IFNOT((SVFUtil::isa<AllocaInst, CallBase, GlobalVariable>(
val)),
830 else if (
const auto *call = SVFUtil::dyn_cast<CallBase>(src))
addNamesFromCall(call);
867 if (visited.count(
curPair))
continue;
884 sources.insert(
vIt->second.begin(),
vIt->second.end());
899 if (
const auto *inst = SVFUtil::dyn_cast<Instruction>(
curValue))
901 if (
const auto *
parent = inst->getFunction())
925 for (
const auto *
op :
phiNode->operand_values())
932 for (
const auto *
user :
loadInst->getPointerOperand()->users())
934 if (
const auto *
storeInst = SVFUtil::dyn_cast<StoreInst>(
user))
947 if (
const auto *
callBase = SVFUtil::dyn_cast<CallBase>(
user))
962 if (!
callee->isDeclaration())
982 return _valueToAllocOrClsNameSources[
startValue];
1008 if (
const auto *
caller = SVFUtil::dyn_cast<CallBase>(
user))
1012 else if (
const auto *
bitcast = SVFUtil::dyn_cast<BitCastInst>(
user))
const std::string TYPEMALLOC
const Type * infersiteToType(const Value *val)
#define ABORT_IFNOT(condition, msg)
static bool hasUseList(const Value *v)
static LLVMModuleSet * getLLVMModuleSet()
LLVMContext & getContext() const
ValueToInferSites _valueToInferSites
LLVMContext & getLLVMCtx()
ValueToSources _valueToAllocs
const Type * selectLargestSizedType(Set< const Type * > &objTys)
select the largest (conservative) type from all types
const Type * inferPointsToType(const Value *var)
Set< const Value * > & bwfindAllocOfVar(const Value *var)
backward collect all possible allocation sites (stack, static, heap) of var
u32_t objTyToNumFields(const Type *objTy)
bool isAlloc(const SVF::Value *val)
is allocation (stack, static, heap)
u32_t getArgPosInCall(const CallBase *callBase, const Value *arg)
Set< const Value * > & bwFindAllocOrClsNameSources(const Value *startValue)
ValueToClassNames _thisPtrClassNames
Set< std::string > & inferThisPtrClsName(const Value *thisPtr)
get or infer the class names of thisptr
void typeSizeDiffTest(const PointerType *oPTy, const Type *iTy, const Value *val)
const Type * fwInferObjType(const Value *var)
forward infer the type of the object pointed by var
const IntegerType * int8Type()
int8 type
const Type * ptrType()
pointer type
const Type * inferObjType(const Value *var)
get or infer the type of the object pointed by the value
const Type * defaultType(const Value *val)
default type
ObjToClsNameSources _objToClsNameSources
Set< const CallBase * > & fwFindClsNameSources(const Value *startValue)
forward find class name sources starting from an allocation
void validateTypeCheck(const CallBase *cs)
validate type inference
ValueToSources _valueToAllocOrClsNameSources
static const Option< u32_t > MaxFieldLimit
Maximum number of field derivations for an object.
bool isHeapAllocExtCallViaRet(const Instruction *inst)
bool isMemcpyExtFun(const Function *fun)
std::string dumpType(const Type *type)
std::pair< s64_t, u64_t > getIntegerValue(const ConstantInt *intValue)
std::string dumpValueAndDbgInfo(const Value *val)
u32_t getNumOfElements(const Type *ety)
Return size of this object based on LLVM value.
bool isObject(const Value *ref)
Return true if this value refers to a object.
static Type * getPtrElementType(const PointerType *pty)
std::string sucMsg(const std::string &msg)
Returns successful message by converting a string into green string output.
std::string pasMsg(const std::string &msg)
Print each pass/phase message by converting a string into blue string output.
std::string errMsg(const std::string &msg)
Print error message by converting a string into red string output.
std::ostream & errs()
Overwrite llvm::errs()
std::ostream & outs()
Overwrite llvm::outs()
constexpr std::remove_reference< T >::type && move(T &&t) noexcept
std::string extractClsNameFromDynCast(const CallBase *callBase)
extract class name from cpp dyncast function
bool classTyHasVTable(const StructType *ty)
bool isClsNameSource(const Value *val)
Set< std::string > extractClsNamesFromFunc(const Function *foo)
extract class name from the c++ function name, e.g., constructor/destructors
bool isDynCast(const Function *foo)
whether foo is a cpp dyncast function
llvm::BasicBlock BasicBlock
llvm::AllocaInst AllocaInst
llvm::GlobalValue GlobalValue
llvm::Value Value
LLVM Basic classes.
llvm::IRBuilder IRBuilder
llvm::PointerType PointerType
llvm::StoreInst StoreInst
llvm::LLVMContext LLVMContext