diff --git a/svf-llvm/include/SVF-LLVM/BasicTypes.h b/svf-llvm/include/SVF-LLVM/BasicTypes.h index 01fd94294..1387283ba 100644 --- a/svf-llvm/include/SVF-LLVM/BasicTypes.h +++ b/svf-llvm/include/SVF-LLVM/BasicTypes.h @@ -177,6 +177,7 @@ typedef llvm::VAStartInst VAStartInst; typedef llvm::BinaryOperator BinaryOperator; typedef llvm::UnaryOperator UnaryOperator; typedef llvm::UndefValue UndefValue; +typedef llvm::GEPOperator GEPOperator; // Related to Switch Case typedef std::pair SuccBBAndCondValPair; diff --git a/svf-llvm/include/SVF-LLVM/LLVMUtil.h b/svf-llvm/include/SVF-LLVM/LLVMUtil.h index 374b89b61..a5ea7f113 100644 --- a/svf-llvm/include/SVF-LLVM/LLVMUtil.h +++ b/svf-llvm/include/SVF-LLVM/LLVMUtil.h @@ -126,6 +126,10 @@ static inline Type* getPtrElementType(const PointerType* pty) #endif } +/// Infer type based on llvm value, this is for the migration to opaque pointer +/// please refer to: https://llvm.org/docs/OpaquePointers.html#migration-instructions +Type *getPointeeType(const Value *value); + /// Get the reference type of heap/static object from an allocation site. //@{ inline const PointerType *getRefTypeOfHeapAllocOrStatic(const CallBase* cs) @@ -139,6 +143,7 @@ inline const PointerType *getRefTypeOfHeapAllocOrStatic(const CallBase* cs) int argPos = SVFUtil::getHeapAllocHoldingArgPosition(svfcs); const Value* arg = cs->getArgOperand(argPos); if (const PointerType *argType = SVFUtil::dyn_cast(arg->getType())) + // TODO: getPtrElementType need type inference refType = SVFUtil::dyn_cast(getPtrElementType(argType)); } // Case 2: heap object held by return value. @@ -389,6 +394,7 @@ inline u32_t SVFType2ByteSize(const SVFType* type) const llvm::Type* llvm_rhs = LLVMModuleSet::getLLVMModuleSet()->getLLVMType(type); const llvm::PointerType* llvm_rhs_ptr = SVFUtil::dyn_cast(llvm_rhs); assert(llvm_rhs_ptr && "not a pointer type?"); + // TODO: getPtrElementType need type inference const Type *ptrElementType = getPtrElementType(llvm_rhs_ptr); u32_t llvm_rhs_size = LLVMUtil::getTypeSizeInBytes(ptrElementType); u32_t llvm_elem_size = -1; diff --git a/svf-llvm/lib/LLVMModule.cpp b/svf-llvm/lib/LLVMModule.cpp index c786638e8..4e16d619d 100644 --- a/svf-llvm/lib/LLVMModule.cpp +++ b/svf-llvm/lib/LLVMModule.cpp @@ -1384,6 +1384,7 @@ SVFType* LLVMModuleSet::addSVFTypeInfo(const Type* T) //cast svftype to SVFPointerType SVFPointerType* svfPtrType = SVFUtil::dyn_cast(svftype); assert(svfPtrType && "this is not SVFPointerType"); + // TODO: getPtrElementType to be removed svfPtrType->setPtrElementType(getSVFType(LLVMUtil::getPtrElementType(pt))); } diff --git a/svf-llvm/lib/LLVMUtil.cpp b/svf-llvm/lib/LLVMUtil.cpp index 1e9875db1..37bd716f1 100644 --- a/svf-llvm/lib/LLVMUtil.cpp +++ b/svf-llvm/lib/LLVMUtil.cpp @@ -241,6 +241,51 @@ const Value* LLVMUtil::stripConstantCasts(const Value* val) return val; } +/// Infer type based on llvm value, this is for the migration to opaque pointer +/// please refer to: https://llvm.org/docs/OpaquePointers.html#migration-instructions +Type *LLVMUtil::getPointeeType(const Value *value) { + assert(value && "value cannot be nullptr!"); + if (const LoadInst *loadInst = SVFUtil::dyn_cast(value)) { + // get the pointee type of rhs based on lhs + // e.g., for `%lhs = load i64, ptr %rhs`, we return i64 + return loadInst->getType(); + } else if (const StoreInst *storeInst = SVFUtil::dyn_cast(value)) { + // get the pointee type of op1 based on op0 + // e.g., for `store i64 %op0, ptr %op1`, we return i64 + return storeInst->getValueOperand()->getType(); + } else if (const GetElementPtrInst *gepInst = SVFUtil::dyn_cast(value)) { + // get the source element type of a gep instruction + // e.g., for `gep %struct.foo, ptr %base, i64 0`, we return struct.foo + return gepInst->getSourceElementType(); + } else if (const GEPOperator* gepOperator = SVFUtil::dyn_cast(value)) { + // get the source element type of a gep instruction + // e.g., for `gep %struct.foo, ptr %base, i64 0`, we return struct.foo + return gepOperator->getSourceElementType(); + } else if (const CallInst *callInst = SVFUtil::dyn_cast(value)) { + // get the pointee type of return value + // e.g., for `%call = call ptr @_Znwm(i64 noundef 8)`, we return i64 + return callInst->getFunctionType(); + } else if (const CallBase *callBase = SVFUtil::dyn_cast(value)) { + // get the pointee type of return value + // e.g., for `%call = call ptr @_Znwm(i64 noundef 8)`, we return i64 + return callBase->getFunctionType(); + } else if (const AllocaInst *allocaInst = SVFUtil::dyn_cast(value)) { + // get the type of the allocated memory + // e.g., for `%retval = alloca i64, align 4`, we return i64 + return allocaInst->getAllocatedType(); + } else if (const GlobalVariable *globalVar = SVFUtil::dyn_cast(value)) { + // get the pointee type of the global pointer + return globalVar->getValueType(); + } else if (const Function* func = SVFUtil::dyn_cast(value)) { + // get the pointee type of return value + // e.g., for `%call = call ptr @_Znwm(i64 noundef 8)`, we return i64 + return func->getFunctionType(); + } else { + assert(false && (LLVMUtil::dumpValue(value) + "Unknown llvm Type, cannot get Ptr Element Type").c_str()); + abort(); + } +} + void LLVMUtil::viewCFG(const Function* fun) { if (fun != nullptr) @@ -351,6 +396,7 @@ const Value* LLVMUtil::getFirstUseViaCastInst(const Value* val) const PointerType * type = SVFUtil::dyn_cast(val->getType()); assert(type && "this value should be a pointer type!"); /// If type is void* (i8*) and val is immediately used at a bitcast instruction + // TODO: getPtrElementType to be removed if (IntegerType *IT = SVFUtil::dyn_cast(getPtrElementType(type))) { if (IT->getBitWidth() == 8) @@ -397,6 +443,7 @@ const Type* LLVMUtil::getTypeOfHeapAlloc(const Instruction *inst) } assert(type && "not a pointer type?"); + // TODO: getPtrElementType need type inference return getPtrElementType(type); } @@ -922,6 +969,7 @@ bool LLVMUtil::isLoadVtblInst(const LoadInst* loadInst) const Type* elemTy = valTy; for (u32_t i = 0; i < 3; ++i) { + // TODO: getPtrElementType to be removed if (const PointerType* ptrTy = SVFUtil::dyn_cast(elemTy)) elemTy = LLVMUtil::getPtrElementType(ptrTy); else @@ -933,6 +981,7 @@ bool LLVMUtil::isLoadVtblInst(const LoadInst* loadInst) std::string className = ""; if(const PointerType* ptrTy = SVFUtil::dyn_cast(paramty)) { + // TODO: getPtrElementType need type inference if(const StructType* st = SVFUtil::dyn_cast(getPtrElementType(ptrTy))) className = LLVMUtil::getClassNameFromType(st); } @@ -1198,6 +1247,7 @@ std::string LLVMUtil::getClassNameOfThisPtr(const CallBase* inst) { const Value* thisPtr = LLVMUtil::getVCallThisPtr(inst); if(const PointerType* ptrTy = SVFUtil::dyn_cast(thisPtr->getType())) + // TODO: getPtrElementType need type inference if(const StructType* st = SVFUtil::dyn_cast(getPtrElementType(ptrTy))) thisPtrClassName = getClassNameFromType(st); } diff --git a/svf-llvm/lib/SVFIRBuilder.cpp b/svf-llvm/lib/SVFIRBuilder.cpp index 2c707fa8a..7da12a265 100644 --- a/svf-llvm/lib/SVFIRBuilder.cpp +++ b/svf-llvm/lib/SVFIRBuilder.cpp @@ -318,8 +318,9 @@ bool SVFIRBuilder::computeGepOffset(const User *V, AccessPath& ap) // If it's a non-constant offset access // If its point-to target is struct or array, it's likely an array accessing (%result = gep %struct.A* %a, i32 %non-const-index) // If its point-to target is single value (pointer arithmetic), then it's a variant gep (%result = gep i8* %p, i32 %non-const-index) - if(!op && gepTy->isPointerTy() && getPtrElementType(SVFUtil::dyn_cast(gepTy))->isSingleValueType()) + if(!op && gepTy->isPointerTy() && LLVMUtil::getPointeeType(V)->isSingleValueType()) { isConst = false; + } // The actual index //s32_t idx = op->getSExtValue(); diff --git a/svf-llvm/lib/SymbolTableBuilder.cpp b/svf-llvm/lib/SymbolTableBuilder.cpp index a65a55ca4..68edb958d 100644 --- a/svf-llvm/lib/SymbolTableBuilder.cpp +++ b/svf-llvm/lib/SymbolTableBuilder.cpp @@ -237,6 +237,7 @@ void SymbolTableBuilder::collectSVFTypeInfo(const Value* val) (void)getOrAddSVFTypeInfo(val->getType()); if (const PointerType * ptrType = SVFUtil::dyn_cast(val->getType())) { + // TODO: getPtrElementType to be removed const Type* objtype = LLVMUtil::getPtrElementType(ptrType); (void)getOrAddSVFTypeInfo(objtype); } @@ -575,6 +576,7 @@ void SymbolTableBuilder::handleGlobalInitializerCE(const Constant* C) */ ObjTypeInfo* SymbolTableBuilder::createObjTypeInfo(const Value* val) { + /// TODO: getPtrElementType to be removed const PointerType* refTy = nullptr; const Instruction* I = SVFUtil::dyn_cast(val); @@ -627,7 +629,8 @@ void SymbolTableBuilder::analyzeObjType(ObjTypeInfo* typeinfo, const Value* val) const PointerType* refty = SVFUtil::dyn_cast(val->getType()); assert(refty && "this value should be a pointer type!"); - Type* elemTy = getPtrElementType(refty); + // TODO: getPtrElementType need type inference + Type *elemTy = getPtrElementType(refty); bool isPtrObj = false; // Find the inter nested array element while (const ArrayType* AT = SVFUtil::dyn_cast(elemTy)) diff --git a/svf/include/MemoryModel/AccessPath.h b/svf/include/MemoryModel/AccessPath.h index 7393803e3..0fe766b2a 100644 --- a/svf/include/MemoryModel/AccessPath.h +++ b/svf/include/MemoryModel/AccessPath.h @@ -71,7 +71,7 @@ class AccessPath AccessPath(const AccessPath& ap) : fldIdx(ap.fldIdx), idxOperandPairs(ap.getIdxOperandPairVec()), - gepPointeeType(ap.getGepPointeeType()) + gepPointeeType(ap.gepSrcPointeeType()) { } @@ -109,7 +109,7 @@ class AccessPath { return idxOperandPairs; } - inline const SVFType* getGepPointeeType() const + inline const SVFType* gepSrcPointeeType() const { return gepPointeeType; } diff --git a/svf/lib/AbstractExecution/SVFIR2ConsExeState.cpp b/svf/lib/AbstractExecution/SVFIR2ConsExeState.cpp index 38436f9ed..5490d3327 100644 --- a/svf/lib/AbstractExecution/SVFIR2ConsExeState.cpp +++ b/svf/lib/AbstractExecution/SVFIR2ConsExeState.cpp @@ -655,9 +655,9 @@ std::pair SVFIR2ConsExeState::getGepOffset(const SVF::GepStmt *gep continue; } - if (const SVFPointerType *pty = SVFUtil::dyn_cast(type)) + if (SVFUtil::isa(type)) { - offset = offset * gep->getAccessPath().getElementNum(pty->getPtrElementType()); + offset = offset * gep->getAccessPath().getElementNum(gep->getAccessPath().gepSrcPointeeType()); } else { diff --git a/svf/lib/AbstractExecution/SVFIR2ItvExeState.cpp b/svf/lib/AbstractExecution/SVFIR2ItvExeState.cpp index aa44cfd11..c42326e73 100644 --- a/svf/lib/AbstractExecution/SVFIR2ItvExeState.cpp +++ b/svf/lib/AbstractExecution/SVFIR2ItvExeState.cpp @@ -282,8 +282,8 @@ IntervalValue SVFIR2ItvExeState::getByteOffset(const GepStmt *gep) u32_t elemByteSize = 1; if (const SVFArrayType* arrOperandType = SVFUtil::dyn_cast(idxOperandType)) elemByteSize = arrOperandType->getTypeOfElement()->getByteSize(); - else if (const SVFPointerType* ptrOperandType = SVFUtil::dyn_cast(idxOperandType)) - elemByteSize = ptrOperandType->getPtrElementType()->getByteSize(); + else if (SVFUtil::isa(idxOperandType)) + elemByteSize = gep->getAccessPath().gepSrcPointeeType()->getByteSize(); else assert(false && "idxOperandType must be ArrType or PtrType"); if (const SVFConstantInt *op = SVFUtil::dyn_cast(idxOperandVar->getValue())) @@ -364,9 +364,9 @@ IntervalValue SVFIR2ItvExeState::getItvOfFlattenedElemIndex(const GepStmt *gep) } } // for pointer type, flattened index = elemNum * idx - if (const SVFPointerType *pty = SVFUtil::dyn_cast(type)) + if (SVFUtil::isa(type)) { - u32_t elemNum = gep->getAccessPath().getElementNum(pty->getPtrElementType()); + u32_t elemNum = gep->getAccessPath().getElementNum(gep->getAccessPath().gepSrcPointeeType()); idxLb = (double)Options::MaxFieldLimit() / elemNum < idxLb? Options::MaxFieldLimit(): idxLb * elemNum; idxUb = (double)Options::MaxFieldLimit() / elemNum < idxUb? Options::MaxFieldLimit(): idxUb * elemNum; } diff --git a/svf/lib/MemoryModel/AccessPath.cpp b/svf/lib/MemoryModel/AccessPath.cpp index a6bee2e81..48101ee78 100644 --- a/svf/lib/MemoryModel/AccessPath.cpp +++ b/svf/lib/MemoryModel/AccessPath.cpp @@ -70,6 +70,7 @@ u32_t AccessPath::getElementNum(const SVFType* type) const else if (type->isSingleValueType()) { /// This is a pointer arithmetic + // TODO: getPtrElementType to be removed if(const SVFPointerType* pty = SVFUtil::dyn_cast(type)) return getElementNum(pty->getPtrElementType()); else @@ -122,11 +123,11 @@ APOffset AccessPath::computeConstantByteOffset() const /// for (2) i = 1, arrType: [10 x i8], type2 = i8 type2 = arrType->getTypeOfElement(); } - else if (const SVFPointerType* ptrType = SVFUtil::dyn_cast(type)) + else if (SVFUtil::isa(type)) { /// for (1) i = 0, ptrType: %struct.DEST*, type2: %struct.DEST /// for (2) i = 0, ptrType: [10 x i8]*, type2 = [10 x i8] - type2 = ptrType->getPtrElementType(); + type2 = gepSrcPointeeType(); } const SVFConstantInt* op = SVFUtil::dyn_cast(value); @@ -227,8 +228,8 @@ APOffset AccessPath::computeConstantOffset() const continue; } - if(const SVFPointerType* pty = SVFUtil::dyn_cast(type)) - totalConstOffset += op->getSExtValue() * getElementNum(pty->getPtrElementType()); + if(SVFUtil::isa(type)) + totalConstOffset += op->getSExtValue() * getElementNum(gepPointeeType); else { APOffset offset = op->getSExtValue(); @@ -268,7 +269,7 @@ NodeBS AccessPath::computeAllLocations() const AccessPath AccessPath::operator+(const AccessPath& rhs) const { - assert(gepPointeeType == rhs.getGepPointeeType() && "source element type not match"); + assert(gepPointeeType == rhs.gepSrcPointeeType() && "source element type not match"); AccessPath ap(rhs); ap.fldIdx += getConstantStructFldIdx(); for (auto &p : ap.getIdxOperandPairVec()) diff --git a/svf/lib/MemoryModel/PointerAnalysis.cpp b/svf/lib/MemoryModel/PointerAnalysis.cpp index fcf7991cb..4ba87b075 100644 --- a/svf/lib/MemoryModel/PointerAnalysis.cpp +++ b/svf/lib/MemoryModel/PointerAnalysis.cpp @@ -248,6 +248,7 @@ void PointerAnalysis::dumpAllTypes() const SVFType* type = node->getValue()->getType(); pag->getSymbolInfo()->printFlattenFields(type); + // TODO: getPtrElementType to be removed if (const SVFPointerType* ptType = SVFUtil::dyn_cast(type)) pag->getSymbolInfo()->printFlattenFields(ptType->getPtrElementType()); } diff --git a/svf/lib/SVFIR/SVFType.cpp b/svf/lib/SVFIR/SVFType.cpp index b43d7ca20..5fc313f95 100644 --- a/svf/lib/SVFIR/SVFType.cpp +++ b/svf/lib/SVFIR/SVFType.cpp @@ -20,6 +20,7 @@ std::ostream& operator<<(std::ostream& os, const SVFType& type) void SVFPointerType::print(std::ostream& os) const { + // TODO: getPtrElementType to be removed os << *getPtrElementType() << '*'; } diff --git a/svf/lib/SVFIR/SymbolTableInfo.cpp b/svf/lib/SVFIR/SymbolTableInfo.cpp index 186654a0a..53cd5e84c 100644 --- a/svf/lib/SVFIR/SymbolTableInfo.cpp +++ b/svf/lib/SVFIR/SymbolTableInfo.cpp @@ -258,6 +258,7 @@ void SymbolTableInfo::printFlattenFields(const SVFType* type) } else if (const SVFPointerType* pt= SVFUtil::dyn_cast(type)) { + // TODO: getPtrElementType to be removed u32_t eSize = getNumOfFlattenElements(pt->getPtrElementType()); outs() << " {Type: " << *pt << "}\n" << "\t [target size = " << eSize << "]\n"