diff --git a/svf-llvm/lib/SVFIRBuilder.cpp b/svf-llvm/lib/SVFIRBuilder.cpp index 9e79fb1db..5922017dd 100644 --- a/svf-llvm/lib/SVFIRBuilder.cpp +++ b/svf-llvm/lib/SVFIRBuilder.cpp @@ -345,7 +345,9 @@ void SVFIRBuilder::processCE(const Value* val) const Constant* opnd = gepce->getOperand(0); // handle recursive constant express case (gep (bitcast (gep X 1)) 1) processCE(opnd); - AccessPath ap; + auto &GEPOp = llvm::cast(*gepce); + Type *pType = GEPOp.getSourceElementType(); + AccessPath ap(0, LLVMModuleSet::getLLVMModuleSet()->getSVFType(pType)); bool constGep = computeGepOffset(gepce, ap); // must invoke pag methods here, otherwise it will be a dead recursion cycle const SVFValue* cval = getCurrentValue(); @@ -710,7 +712,7 @@ void SVFIRBuilder::visitGetElementPtrInst(GetElementPtrInst &inst) NodeID src = getValueNode(inst.getPointerOperand()); - AccessPath ap; + AccessPath ap(0, LLVMModuleSet::getLLVMModuleSet()->getSVFType(inst.getSourceElementType())); bool constGep = computeGepOffset(&inst, ap); addGepEdge(src, dst, ap, constGep); } diff --git a/svf/include/MemoryModel/AccessPath.h b/svf/include/MemoryModel/AccessPath.h index b2b632ad2..280c9f3d6 100644 --- a/svf/include/MemoryModel/AccessPath.h +++ b/svf/include/MemoryModel/AccessPath.h @@ -65,12 +65,13 @@ class AccessPath typedef std::vector IdxOperandPairs; /// Constructor - AccessPath(APOffset o = 0) : fldIdx(o) {} + AccessPath(APOffset o = 0, const SVFType* srcTy = nullptr) : fldIdx(o), gepSourceElementType(srcTy) {} /// Copy Constructor AccessPath(const AccessPath& ap) - : fldIdx(ap.fldIdx), - idxOperandPairs(ap.getIdxOperandPairVec()) + : fldIdx(ap.fldIdx), + idxOperandPairs(ap.getIdxOperandPairVec()), + gepSourceElementType(ap.getGepSourceElementType()) { } @@ -84,12 +85,13 @@ class AccessPath { fldIdx = rhs.fldIdx; idxOperandPairs = rhs.getIdxOperandPairVec(); + gepSourceElementType = rhs.gepSourceElementType; return *this; } inline bool operator==(const AccessPath& rhs) const { return this->fldIdx == rhs.fldIdx && - this->idxOperandPairs == rhs.idxOperandPairs; + this->idxOperandPairs == rhs.idxOperandPairs && this->gepSourceElementType == rhs.gepSourceElementType; } //@} @@ -107,6 +109,10 @@ class AccessPath { return idxOperandPairs; } + inline const SVFType* getGepSourceElementType() const + { + return gepSourceElementType; + } //@} /** @@ -167,6 +173,9 @@ class AccessPath APOffset fldIdx; ///< Accumulated Constant Offsets IdxOperandPairs idxOperandPairs; ///< a vector of actual offset in the form of + const SVFType* gepSourceElementType; /// source element type in gep instruction, + /// e.g., %f1 = getelementptr inbounds %struct.MyStruct, %struct.MyStruct* %arrayidx, i32 0, i32 0 + /// the source element type is %struct.MyStruct }; } // End namespace SVF diff --git a/svf/lib/MemoryModel/AccessPath.cpp b/svf/lib/MemoryModel/AccessPath.cpp index c20776250..f508bdf99 100644 --- a/svf/lib/MemoryModel/AccessPath.cpp +++ b/svf/lib/MemoryModel/AccessPath.cpp @@ -209,7 +209,8 @@ APOffset AccessPath::computeConstantOffset() const assert(isConstantOffset() && "not a constant offset"); - if(idxOperandPairs.empty()) + // source element type is struct + if(gepSourceElementType && gepSourceElementType->isStructTy()) return getConstantStructFldIdx(); APOffset totalConstOffset = 0; @@ -255,6 +256,7 @@ NodeBS AccessPath::computeAllLocations() const AccessPath AccessPath::operator+(const AccessPath& rhs) const { + assert(gepSourceElementType == rhs.getGepSourceElementType() && "source element type not match"); AccessPath ap(rhs); ap.fldIdx += getConstantStructFldIdx(); for (auto &p : ap.getIdxOperandPairVec())