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;
88 if (SVFUtil::isa<LoadInst, StoreInst>(
val))
90 return llvm::getLoadStoreType(
const_cast<Value *
>(
val));
92 else if (
const auto *
gepInst = SVFUtil::dyn_cast<GetElementPtrInst>(
val))
94 return gepInst->getSourceElementType();
96 else if (
const auto *call = SVFUtil::dyn_cast<CallBase>(
val))
98 return call->getFunctionType();
100 else if (
const auto *
allocaInst = SVFUtil::dyn_cast<AllocaInst>(
val))
104 else if (
const auto *
globalValue = SVFUtil::dyn_cast<GlobalValue>(
val))
119 SVFUtil::cast<Instruction>(
val)))
152 if (!
var->hasUseList())
return res;
153 for (
const auto&
use:
var->users())
155 if (
const CallBase* cs = SVFUtil::dyn_cast<CallBase>(
use))
160 assert(cs->getNumOperands() > 1 &&
"arguments should be greater than 1");
161 const Value* dst = cs->getArgOperand(0);
162 const Value* src = cs->getArgOperand(1);
163 if(
calledFun->getName().find(
"iconv") != std::string::npos)
165 if(
var == cs->getArgOperand(0))
167 dst = cs->getArgOperand(3), src = cs->getArgOperand(1);
192 for (
const auto &
source: sources)
273 SVFUtil::dyn_cast<GetElementPtrInst>(
curValue))
275 if (!
curValue->hasUseList())
continue;
278 if (
const auto*
loadInst = SVFUtil::dyn_cast<LoadInst>(
it))
289 SVFUtil::dyn_cast<StoreInst>(
it))
303 for (
const auto nit :
313 if (SVFUtil::isa<LoadInst>(
nit))
320 SVFUtil::dyn_cast<GetElementPtrInst>(
342 if (
const auto* load =
343 SVFUtil::dyn_cast<LoadInst>(
gepBase))
346 load->getPointerOperand()->users())
349 !SVFUtil::isa<LoadInst>(
loadUse))
353 if (!SVFUtil::isa<GetElementPtrInst>(
359 if (SVFUtil::isa<LoadInst>(
369 else if (
const auto*
alloc =
370 SVFUtil::dyn_cast<AllocaInst>(
gepBase))
386 if (!SVFUtil::isa<GetElementPtrInst>(
391 if (SVFUtil::isa<LoadInst>(
loadUse2))
403 SVFUtil::dyn_cast<GetElementPtrInst>(
it))
416 SVFUtil::dyn_cast<BitCastInst>(
it))
421 else if (
const auto*
phiNode = SVFUtil::dyn_cast<PHINode>(
it))
427 SVFUtil::dyn_cast<ReturnInst>(
it))
440 for (
const auto callsite :
retInst->getFunction()->users())
443 SVFUtil::dyn_cast<CallBase>(callsite))
447 if (
callBase->getCalledFunction() !=
454 else if (
const auto*
callBase = SVFUtil::dyn_cast<CallBase>(
it))
469 if (SVFUtil::isa<Function>(
curValue) &&
488 llvm::dyn_cast<llvm::LoadInst>(&I))
491 load->getPointerOperand();
522 WARN_MSG(
"Using default type, trace ID is " +
552 if (visited.count(
curPair))
continue;
569 sources.insert(
vIt->second.begin(),
vIt->second.end());
601 for (
const auto use:
loadInst->getPointerOperand()->users())
614 for (
const auto use:
argument->getParent()->users())
631 if (!
callee->isDeclaration())
674 SVFUtil::dyn_cast<llvm::ConstantInt>(cs->getOperand(1));
675 assert(
pInt &&
"the second argument is a integer");
710 return std::distance(
callBase->arg_begin(),
it);
716 if (
objTys.empty())
return nullptr;
733 if (SVFUtil::isa<ArrayType>(
objTy))
735 else if (
const auto *
st = SVFUtil::dyn_cast<StructType>(
objTy))
774 const auto *
func = call->getCalledFunction();
789 if (
const auto *
func = SVFUtil::dyn_cast<Function>(
val))
803 ABORT_IFNOT((SVFUtil::isa<AllocaInst, CallBase, GlobalVariable>(
val)),
808 else if (
const auto *call = SVFUtil::dyn_cast<CallBase>(src))
addNamesFromCall(call);
845 if (visited.count(
curPair))
continue;
862 sources.insert(
vIt->second.begin(),
vIt->second.end());
877 if (
const auto *inst = SVFUtil::dyn_cast<Instruction>(
curValue))
879 if (
const auto *
parent = inst->getFunction())
903 for (
const auto *
op :
phiNode->operand_values())
910 for (
const auto *
user :
loadInst->getPointerOperand()->users())
912 if (
const auto *
storeInst = SVFUtil::dyn_cast<StoreInst>(
user))
925 if (
const auto *
callBase = SVFUtil::dyn_cast<CallBase>(
user))
940 if (!
callee->isDeclaration())
960 return _valueToAllocOrClsNameSources[
startValue];
986 if (
const auto *
caller = SVFUtil::dyn_cast<CallBase>(
user))
990 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 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