diff --git a/svf-llvm/include/SVF-LLVM/SymbolTableBuilder.h b/svf-llvm/include/SVF-LLVM/SymbolTableBuilder.h index 6785ef75e..6e813cbd2 100644 --- a/svf-llvm/include/SVF-LLVM/SymbolTableBuilder.h +++ b/svf-llvm/include/SVF-LLVM/SymbolTableBuilder.h @@ -118,9 +118,9 @@ class SymbolTableBuilder ///Get a reference to StructInfo. StInfo* getOrAddSVFTypeInfo(const Type* T); - MemObj* createBlkObj(SymID symId); + ObjTypeInfo* createBlkObjTypeInfo(SymID symId); - MemObj* createConstantObj(SymID symId); + ObjTypeInfo* createConstantObjTypeInfo(SymID symId); }; } // End namespace SVF diff --git a/svf-llvm/lib/SVFIRBuilder.cpp b/svf-llvm/lib/SVFIRBuilder.cpp index d802e6e5f..999bd6803 100644 --- a/svf-llvm/lib/SVFIRBuilder.cpp +++ b/svf-llvm/lib/SVFIRBuilder.cpp @@ -67,25 +67,6 @@ SVFIR* SVFIRBuilder::build() // Set callgraph pag->setCallGraph(llvmModuleSet()->callgraph); - // Set icfgnode in memobj - for (auto& it : SymbolTableInfo::SymbolInfo()->idToObjMap()) - { - if(!it.second->getValue()) - continue; - if (const Instruction* inst = - SVFUtil::dyn_cast(llvmModuleSet()->getLLVMValue( - it.second->getValue()))) - { - if(llvmModuleSet()->hasICFGNode(inst)) - it.second->gNode = llvmModuleSet()->getICFGNode(inst); - } - else if (const Function* func = SVFUtil::dyn_cast(llvmModuleSet()->getLLVMValue( - it.second->getValue()))) - { - it.second->gNode = llvmModuleSet()->getCallGraphNode(func); - } - } - CHGraph* chg = new CHGraph(pag->getModule()); CHGBuilder chgbuilder(chg); chgbuilder.buildCHG(); @@ -309,60 +290,87 @@ void SVFIRBuilder::initialiseNodes() // Check if the value is a function and add a function object node if (const Function* func = SVFUtil::dyn_cast(llvmValue)) { - pag->addFunObjNode(iter->second, llvmModuleSet()->getCallGraphNode(func)); + SymID id = symTable->getObjSym(llvmModuleSet()->getCallGraphNode(func)->getFunction()); + pag->addFunObjNode(iter->first, iter->second, symTable->getObjTypeInfo(id), llvmModuleSet()->getCallGraphNode(func)); } // Check if the value is a heap object and add a heap object node else if (LLVMUtil::isHeapObj(llvmValue)) { + SymID id = symTable->getObjSym(iter->first); const SVFFunction* f = SVFUtil::cast(iter->first)->getFunction(); - pag->addHeapObjNode(iter->first, iter->second, f); + pag->addHeapObjNode(iter->first, iter->second, symTable->getObjTypeInfo(id), f); llvmModuleSet()->addToLLVMVal2SVFVarMap( llvmValue, pag->getGNode(iter->second)); } // Check if the value is an alloca instruction and add a stack object node else if (LLVMUtil::isStackObj(llvmValue)) { + NodeID id = symTable->getObjSym(iter->first); const SVFFunction* f = SVFUtil::cast(iter->first)->getFunction(); - pag->addStackObjNode(iter->first, iter->second, f); + pag->addStackObjNode(iter->first, iter->second, symTable->getObjTypeInfo(id), f); llvmModuleSet()->addToLLVMVal2SVFVarMap( llvmValue, pag->getGNode(iter->second)); } else if (auto fpValue = SVFUtil::dyn_cast(llvmValue)) { - pag->addConstantFPObjNode(iter->first, iter->second, LLVMUtil::getDoubleValue(fpValue)); + NodeID id = symTable->getObjSym(iter->first); + pag->addConstantFPObjNode(iter->first, iter->second, symTable->getObjTypeInfo(id), LLVMUtil::getDoubleValue(fpValue)); llvmModuleSet()->addToLLVMVal2SVFVarMap( fpValue, pag->getGNode(iter->second)); } else if (auto intValue = SVFUtil::dyn_cast(llvmValue)) { - pag->addConstantIntObjNode(iter->first, iter->second, LLVMUtil::getIntegerValue(intValue)); + NodeID id = symTable->getObjSym(iter->first); + pag->addConstantIntObjNode(iter->first, iter->second, symTable->getObjTypeInfo(id), LLVMUtil::getIntegerValue(intValue)); llvmModuleSet()->addToLLVMVal2SVFVarMap( intValue, pag->getGNode(iter->second)); } else if (auto nullValue = SVFUtil::dyn_cast(llvmValue)) { - pag->addConstantNullPtrObjNode(iter->first, iter->second); + NodeID id = symTable->getObjSym(iter->first); + pag->addConstantNullPtrObjNode(iter->first, iter->second, symTable->getObjTypeInfo(id)); llvmModuleSet()->addToLLVMVal2SVFVarMap( nullValue, pag->getGNode(iter->second)); } else if (auto globalValue = SVFUtil::dyn_cast(llvmValue)) { - pag->addGlobalValueObjNode(iter->first, iter->second); + NodeID id = symTable->getObjSym(iter->first); + pag->addGlobalValueObjNode(iter->first, iter->second, symTable->getObjTypeInfo(id)); llvmModuleSet()->addToLLVMVal2SVFVarMap( globalValue, pag->getGNode(iter->second)); } else if (auto dataValue = SVFUtil::dyn_cast(llvmValue)) { - pag->addConstantDataObjNode(iter->first, iter->second); + NodeID id = symTable->getObjSym(iter->first); + pag->addConstantDataObjNode(iter->first, iter->second, symTable->getObjTypeInfo(id)); llvmModuleSet()->addToLLVMVal2SVFVarMap( dataValue, pag->getGNode(iter->second)); } // Add a generic object node for other types of values else { - pag->addObjNode(iter->first, iter->second); + NodeID id = symTable->getObjSym(iter->first); + pag->addObjNode(iter->first, iter->second, symTable->getObjTypeInfo(id)); + } + } + + for (auto& it : SymbolTableInfo::SymbolInfo()->idToObjTypeInfoMap()) { + NodeID id = it.first; + if (BaseObjVar* obj = SVFUtil::dyn_cast(pag->getGNode(id))) { + if (!obj->hasValue()) + continue; + + if (const Instruction* inst = SVFUtil::dyn_cast(llvmModuleSet()->getLLVMValue(obj->getValue()))) + { + if(llvmModuleSet()->hasICFGNode(inst)) + obj->gNode = llvmModuleSet()->getICFGNode(inst); + } + else if (const Function* func = SVFUtil::dyn_cast(llvmModuleSet()->getLLVMValue(obj->getValue()))) + { + obj->gNode = llvmModuleSet()->getCallGraphNode(func); + } } } diff --git a/svf-llvm/lib/SymbolTableBuilder.cpp b/svf-llvm/lib/SymbolTableBuilder.cpp index 2e0a136ff..1aee395ac 100644 --- a/svf-llvm/lib/SymbolTableBuilder.cpp +++ b/svf-llvm/lib/SymbolTableBuilder.cpp @@ -44,28 +44,31 @@ using namespace SVF; using namespace SVFUtil; using namespace LLVMUtil; -MemObj* SymbolTableBuilder::createBlkObj(SymID symId) +ObjTypeInfo* SymbolTableBuilder::createBlkObjTypeInfo(SymID symId) { assert(symInfo->isBlkObj(symId)); - assert(symInfo->objMap.find(symId)==symInfo->objMap.end()); LLVMModuleSet* llvmset = LLVMModuleSet::getLLVMModuleSet(); - MemObj* obj = - new MemObj(symId, symInfo->createObjTypeInfo(llvmset->getSVFType( - IntegerType::get(llvmset->getContext(), 32)))); - symInfo->objMap[symId] = obj; - return obj; + if (symInfo->objTypeInfoMap.find(symId)==symInfo->objTypeInfoMap.end()) { + ObjTypeInfo* ti =symInfo->createObjTypeInfo(llvmset->getSVFType( + IntegerType::get(llvmset->getContext(), 32))); + symInfo->objTypeInfoMap[symId] = ti; + } + ObjTypeInfo* ti = symInfo->objTypeInfoMap[symId]; + return ti; } -MemObj* SymbolTableBuilder::createConstantObj(SymID symId) +ObjTypeInfo* SymbolTableBuilder::createConstantObjTypeInfo(SymID symId) { assert(symInfo->isConstantObj(symId)); - assert(symInfo->objMap.find(symId)==symInfo->objMap.end()); LLVMModuleSet* llvmset = LLVMModuleSet::getLLVMModuleSet(); - MemObj* obj = - new MemObj(symId, symInfo->createObjTypeInfo(llvmset->getSVFType( - IntegerType::get(llvmset->getContext(), 32)))); - symInfo->objMap[symId] = obj; - return obj; + if (symInfo->objTypeInfoMap.find(symId)==symInfo->objTypeInfoMap.end()) + { + ObjTypeInfo* ti = symInfo->createObjTypeInfo( + llvmset->getSVFType(IntegerType::get(llvmset->getContext(), 32))); + symInfo->objTypeInfoMap[symId] = ti; + } + ObjTypeInfo* ti = symInfo->objTypeInfoMap[symId]; + return ti; } @@ -86,11 +89,11 @@ void SymbolTableBuilder::buildMemModel(SVFModule* svfModule) // Object #2 is black hole the object that may point to any object assert(symInfo->totalSymNum++ == SymbolTableInfo::BlackHole && "Something changed!"); - createBlkObj(SymbolTableInfo::BlackHole); + createBlkObjTypeInfo(SymbolTableInfo::BlackHole); // Object #3 always represents the unique constant of a program (merging all constants if Options::ModelConsts is disabled) assert(symInfo->totalSymNum++ == SymbolTableInfo::ConstantObj && "Something changed!"); - createConstantObj(SymbolTableInfo::ConstantObj); + createConstantObjTypeInfo(SymbolTableInfo::ConstantObj); for (Module &M : LLVMModuleSet::getLLVMModuleSet()->getLLVMModules()) { @@ -339,11 +342,9 @@ void SymbolTableBuilder::collectObj(const Value* val) outs() << "create a new obj sym " << id << "\n"); // create a memory object - MemObj* mem = - new MemObj(id, createObjTypeInfo(val), - llvmModuleSet->getSVFValue(val)); - assert(symInfo->objMap.find(id) == symInfo->objMap.end()); - symInfo->objMap[id] = mem; + ObjTypeInfo* ti = createObjTypeInfo(val); + assert(symInfo->objTypeInfoMap.find(id) == symInfo->objTypeInfoMap.end()); + symInfo->objTypeInfoMap[id] = ti; } } } diff --git a/svf/include/DDA/DDAVFSolver.h b/svf/include/DDA/DDAVFSolver.h index 92668f84d..f76e73b70 100644 --- a/svf/include/DDA/DDAVFSolver.h +++ b/svf/include/DDA/DDAVFSolver.h @@ -473,8 +473,6 @@ class DDAVFSolver NodeID id = getPtrNodeID(var); const BaseObjVar* baseObj = _pag->getBaseObject(id); assert(baseObj && "base object is null??"); - const MemObj* obj = _pag->getObject(id); - assert(obj && "object not found!!"); if(SVFUtil::isa(baseObj)) { if(const SVFFunction* svffun = _pag->getGNode(id)->getFunction()) @@ -645,14 +643,14 @@ class DDAVFSolver inline bool isArrayCondMemObj(const CVar& var) const { - const MemObj* mem = _pag->getObject(getPtrNodeID(var)); - assert(mem && "memory object is null??"); - return mem->isArray(); + const BaseObjVar* obj = _pag->getBaseObject(getPtrNodeID(var)); + assert(obj && "base object is null??"); + return obj->isArray(); } inline bool isFieldInsenCondMemObj(const CVar& var) const { - const MemObj* mem = _pag->getBaseObj(getPtrNodeID(var)); - return mem->isFieldInsensitive(); + const BaseObjVar* baseObj = _pag->getBaseObject(getPtrNodeID(var)); + return baseObj->isFieldInsensitive(); } //@} private: diff --git a/svf/include/Graphs/ConsG.h b/svf/include/Graphs/ConsG.h index 109d50af5..a224e0753 100644 --- a/svf/include/Graphs/ConsG.h +++ b/svf/include/Graphs/ConsG.h @@ -323,8 +323,8 @@ class ConstraintGraph : public GenericGraph } inline bool isSingleFieldObj(NodeID id) const { - const MemObj* mem = pag->getBaseObj(id); - return (mem->getMaxFieldOffsetLimit() == 1); + const BaseObjVar* baseObj = pag->getBaseObject(id); + return (baseObj->getMaxFieldOffsetLimit() == 1); } /// Get a field of a memory object inline NodeID getGepObjVar(NodeID id, const APOffset& apOffset) diff --git a/svf/include/Graphs/IRGraph.h b/svf/include/Graphs/IRGraph.h index 33de35613..26c77f295 100644 --- a/svf/include/Graphs/IRGraph.h +++ b/svf/include/Graphs/IRGraph.h @@ -65,10 +65,11 @@ class IRGraph : public GenericGraph SymbolTableInfo* symInfo; /// Add a node into the graph - inline NodeID addNode(SVFVar* node, NodeID i) + inline NodeID addNode(SVFVar* node) { - addGNode(i,node); - return i; + assert(node && "cannot add a null node"); + addGNode(node->getId(),node); + return node->getId(); } /// Add an edge into the graph bool addEdge(SVFVar* src, SVFVar* dst, SVFStmt* edge); @@ -94,12 +95,6 @@ class IRGraph : public GenericGraph inserted.first->second.emplace(edge); } } - /// get MemObj according to LLVM value - inline const MemObj* getMemObj(const SVFValue* val) const - { - return symInfo->getObj(symInfo->getObjSym(val)); - } - public: IRGraph(bool buildFromFile) : fromFile(buildFromFile), nodeNumAfterPAGBuild(0), totalPTAPAGEdge(0) @@ -174,14 +169,6 @@ class IRGraph : public GenericGraph { return symInfo->nullPtrSymID(); } - inline const MemObj* getBlackHoleObj() const - { - return symInfo->getBlkObj(); - } - inline const MemObj* getConstantObj() const - { - return symInfo->getConstantObj(); - } inline u32_t getValueNodeNum() const { @@ -189,7 +176,7 @@ class IRGraph : public GenericGraph } inline u32_t getObjectNodeNum() const { - return symInfo->idToObjMap().size(); + return symInfo->idToObjTypeInfoMap().size(); } inline u32_t getNodeNumAfterPAGBuild() const { diff --git a/svf/include/MemoryModel/PointerAnalysis.h b/svf/include/MemoryModel/PointerAnalysis.h index 2fcf58445..d3244a86a 100644 --- a/svf/include/MemoryModel/PointerAnalysis.h +++ b/svf/include/MemoryModel/PointerAnalysis.h @@ -309,9 +309,9 @@ class PointerAnalysis inline bool isArrayMemObj(NodeID id) const { - const MemObj* mem = pag->getObject(id); - assert(mem && "memory object is null??"); - return mem->isArray(); + const BaseObjVar* obj = pag->getBaseObject(id); + assert(obj && "base object is null??"); + return obj->isArray(); } //@} @@ -339,13 +339,13 @@ class PointerAnalysis } inline void setObjFieldInsensitive(NodeID id) { - MemObj* mem = const_cast(pag->getBaseObj(id)); - mem->setFieldInsensitive(); + BaseObjVar* baseObj = const_cast(pag->getBaseObject(id)); + baseObj->setFieldInsensitive(); } inline bool isFieldInsensitive(NodeID id) const { - const MemObj* mem = pag->getBaseObj(id); - return mem->isFieldInsensitive(); + const BaseObjVar* baseObj = pag->getBaseObject(id); + return baseObj->isFieldInsensitive(); } ///@} diff --git a/svf/include/SVFIR/SVFFileSystem.h b/svf/include/SVFIR/SVFFileSystem.h index 102d91dd8..4843968ba 100644 --- a/svf/include/SVFIR/SVFFileSystem.h +++ b/svf/include/SVFIR/SVFFileSystem.h @@ -129,8 +129,6 @@ class SVFMetadataAsValue; class SVFLoopAndDomInfo; // Part of SVFFunction -// Classes created upon buildSymbolTableInfo -class MemObj; // Classes created upon ICFG construction class ICFGNode; @@ -422,7 +420,6 @@ class SVFIRWriter cJSON* toJson(const AccessPath& ap); cJSON* toJson(const SVFLoop* loop); - cJSON* toJson(const MemObj* memObj); cJSON* toJson(const ObjTypeInfo* objTypeInfo); // Only owned by MemObj cJSON* toJson(const SVFLoopAndDomInfo* ldInfo); // Only owned by SVFFunction cJSON* toJson(const StInfo* stInfo); @@ -528,7 +525,6 @@ class SVFIRWriter // Other classes cJSON* contentToJson(const SVFLoop* loop); - cJSON* contentToJson(const MemObj* memObj); // Owned by SymbolTable->objMap cJSON* contentToJson(const StInfo* stInfo); ///@} @@ -899,13 +895,8 @@ class SymbolTableInfoReader private: const cJSON* symTabFieldJson = nullptr; - ReaderIDToObjMap memObjMap; public: - inline MemObj* getMemObjPtr(unsigned id) const - { - return memObjMap.getPtr(id); - } template void createObjs(const cJSON* symTabJson, MemObjCreator memObjCreator) @@ -915,7 +906,6 @@ class SymbolTableInfoReader const cJSON* const allMemObj = symTabJson->child; CHECK_JSON_KEY(allMemObj); - memObjMap.createObjs(allMemObj, memObjCreator); symTabFieldJson = allMemObj->next; } @@ -1104,7 +1094,6 @@ class SVFIRReader void readJson(const cJSON* obj, AccessPath& ap); void readJson(const cJSON* obj, SVFLoop*& loop); - void readJson(const cJSON* obj, MemObj*& memObj); void readJson(const cJSON* obj, ObjTypeInfo*& objTypeInfo); // Only owned by MemObj void readJson(const cJSON* obj, @@ -1257,7 +1246,6 @@ class SVFIRReader void fill(const cJSON*& fieldJson, TDForkPE* stmt); void fill(const cJSON*& fieldJson, TDJoinPE* stmt); - void fill(const cJSON*& fieldJson, MemObj* memObj); void fill(const cJSON*& fieldJson, StInfo* stInfo); // ICFG void virtFill(const cJSON*& fieldJson, ICFGNode* node); diff --git a/svf/include/SVFIR/SVFIR.h b/svf/include/SVFIR/SVFIR.h index ae0a34930..aca9c7a34 100644 --- a/svf/include/SVFIR/SVFIR.h +++ b/svf/include/SVFIR/SVFIR.h @@ -393,15 +393,6 @@ class SVFIR : public IRGraph /// return whole allocated memory object if this node is a gep obj node /// return nullptr is this node is not a ObjVar type //@{ - inline const MemObj* getObject(NodeID id) const - { - const SVFVar* node = getGNode(id); - if (const ObjVar* objPN = SVFUtil::dyn_cast(node)) - return getObject(objPN); - else - return nullptr; - } - inline const BaseObjVar* getBaseObject(NodeID id) const { const SVFVar* node = getGNode(id); @@ -421,20 +412,15 @@ class SVFIR : public IRGraph else return SVFUtil::dyn_cast(node); } - - inline const MemObj*getObject(const ObjVar* node) const - { - return node->getMemObj(); - } //@} /// Get a field SVFIR Object node according to base mem obj and offset - NodeID getGepObjVar(const MemObj* obj, const APOffset& ap); + NodeID getGepObjVar(const BaseObjVar* baseObj, const APOffset& ap); /// Get a field obj SVFIR node according to a mem obj and a given offset NodeID getGepObjVar(NodeID id, const APOffset& ap) ; /// Get a field-insensitive obj SVFIR node according to a mem obj //@{ - inline NodeID getFIObjVar(const MemObj* obj) const + inline NodeID getFIObjVar(const BaseObjVar* obj) const { return obj->getId(); } @@ -464,7 +450,7 @@ class SVFIR : public IRGraph } inline bool isConstantObj(NodeID id) const { - const MemObj* obj = getObject(id); + const BaseObjVar* obj = getBaseObject(id); assert(obj && "not an object node?"); return SymbolTableInfo::isConstantObj(id) || obj->isConstDataOrConstGlobal(); @@ -476,20 +462,13 @@ class SVFIR : public IRGraph /// Get a base pointer node given a field pointer inline NodeID getBaseObjVar(NodeID id) const { - return getBaseObj(id)->getId(); - } - inline const MemObj* getBaseObj(NodeID id) const - { - const SVFVar* node = pag->getGNode(id); - assert(SVFUtil::isa(node) && "need an object node"); - const ObjVar* obj = SVFUtil::cast(node); - return obj->getMemObj(); + return getBaseObject(id)->getId(); } //@} /// Get all fields of an object //@{ - NodeBS& getAllFieldsObjVars(const MemObj* obj); + NodeBS& getAllFieldsObjVars(const BaseObjVar* obj); NodeBS& getAllFieldsObjVars(NodeID id); NodeBS getFieldsAfterCollapse(NodeID id); //@} @@ -569,157 +548,152 @@ class SVFIR : public IRGraph inline NodeID addValNode(const SVFValue* val, NodeID i, const ICFGNode* icfgNode) { SVFVar *node = new ValVar(val,i, ValVar::ValNode, icfgNode); - return addValNode(val, node, i); + return addValNode(val, node); } NodeID addFunValNode(NodeID i, const ICFGNode* icfgNode, const CallGraphNode* callGraphNode) { FunValVar* node = new FunValVar(i, icfgNode, callGraphNode); - return addValNode(nullptr, node, i); + return addValNode(nullptr, node); } NodeID addArgValNode(NodeID i, u32_t argNo, const ICFGNode* icfgNode, const CallGraphNode* callGraphNode, bool isUncalled = false) { ArgValVar* node = new ArgValVar(i, argNo, icfgNode, callGraphNode, isUncalled); - return addValNode(nullptr, node, i); + return addValNode(nullptr, node); } inline NodeID addConstantFPValNode(const SVFValue* curInst, const NodeID i, double dval, const ICFGNode* icfgNode) { SVFVar* node = new ConstantFPValVar(curInst, i, dval, icfgNode); - return addNode(node, i); + return addNode(node); } inline NodeID addConstantIntValNode(const SVFValue* curInst, NodeID i, const std::pair& intValue, const ICFGNode* icfgNode) { SVFVar* node = new ConstantIntValVar(curInst, i, intValue.first, intValue.second, icfgNode); - return addNode(node, i); + return addNode(node); } inline NodeID addConstantNullPtrValNode(const SVFValue* curInst, const NodeID i, const ICFGNode* icfgNode) { SVFVar* node = new ConstantNullPtrValVar(curInst, i, icfgNode); - return addNode(node, i); + return addNode(node); } inline NodeID addGlobalValueValNode(const SVFValue* curInst, const NodeID i, const ICFGNode* icfgNode) { SVFVar* node = new GlobalValVar(curInst, i, icfgNode); - return addNode(node, i); + return addNode(node); } inline NodeID addConstantDataValNode(const SVFValue* curInst, const NodeID i, const ICFGNode* icfgNode) { SVFVar* node = new ConstantDataValVar(curInst, i, icfgNode); - return addNode(node, i); + return addNode(node); } /// Add a memory obj node - inline NodeID addObjNode(const SVFValue* val, NodeID i) + inline NodeID addObjNode(const SVFValue* val, NodeID i, ObjTypeInfo* ti) { - const MemObj* mem = getMemObj(val); - assert(mem->getId() == i && "not same object id?"); - return addFIObjNode(mem); + return addFIObjNode(val, i, ti); } /** * Creates and adds a heap object node to the SVFIR */ - inline NodeID addHeapObjNode(const SVFValue* val, NodeID i, const SVFFunction* f) + inline NodeID addHeapObjNode(const SVFValue* val, NodeID i, ObjTypeInfo* ti, const SVFFunction* f) { - const MemObj* mem = getMemObj(val); - assert(mem->getId() == i && "not same object id?"); memToFieldsMap[i].set(i); - HeapObjVar *node = new HeapObjVar(i, mem, val->getType(), f); - return addObjNode(val, node, i); + HeapObjVar *heapObj = new HeapObjVar(val, i, ti, f); + return addObjNode(val, heapObj); } /** * Creates and adds a stack object node to the SVFIR */ - inline NodeID addStackObjNode(const SVFValue* val, NodeID i, const SVFFunction* f) + inline NodeID addStackObjNode(const SVFValue* val, NodeID i, ObjTypeInfo* ti, const SVFFunction* f) { - const MemObj* mem = getMemObj(val); - assert(mem->getId() == i && "not same object id?"); memToFieldsMap[i].set(i); - StackObjVar *node = new StackObjVar(i, mem, val->getType(), f); - return addObjNode(val, node, i); + StackObjVar *stackObj = new StackObjVar(val, i, ti, f); + return addObjNode(val, stackObj); } - NodeID addFunObjNode(NodeID id, const CallGraphNode* callGraphNode); + NodeID addFunObjNode(const SVFValue* val, NodeID id, ObjTypeInfo* ti, const CallGraphNode* callGraphNode) + { + memToFieldsMap[id].set(id); + FunObjVar* funObj = new FunObjVar(val, id, ti, callGraphNode); + return addObjNode(val, funObj); + } - inline NodeID addConstantFPObjNode(const SVFValue* curInst, NodeID i, double dval) + inline NodeID addConstantFPObjNode(const SVFValue* curInst, NodeID i, ObjTypeInfo* ti, double dval) { - const MemObj* mem = getMemObj(curInst); - NodeID base = mem->getId(); - memToFieldsMap[base].set(mem->getId()); - ConstantFPObjVar* node = new ConstantFPObjVar(curInst, i, dval, mem); - return addObjNode(curInst, node, mem->getId()); + memToFieldsMap[i].set(i); + ConstantFPObjVar* conObj = new ConstantFPObjVar(curInst, i, dval, ti); + return addObjNode(curInst, conObj); } - inline NodeID addConstantIntObjNode(const SVFValue* curInst, NodeID i, const std::pair& intValue) + inline NodeID addConstantIntObjNode(const SVFValue* curInst, NodeID i, ObjTypeInfo* ti, const std::pair& intValue) { - const MemObj* mem = getMemObj(curInst); - NodeID base = mem->getId(); - memToFieldsMap[base].set(mem->getId()); - ConstantIntObjVar* node = - new ConstantIntObjVar(curInst, i, intValue.first, intValue.second, mem); - return addObjNode(curInst, node, mem->getId()); + memToFieldsMap[i].set(i); + ConstantIntObjVar* conObj = + new ConstantIntObjVar(curInst, i, intValue.first, intValue.second, ti); + return addObjNode(curInst, conObj); } - inline NodeID addConstantNullPtrObjNode(const SVFValue* curInst, const NodeID i) + inline NodeID addConstantNullPtrObjNode(const SVFValue* curInst, const NodeID i, ObjTypeInfo* ti) { - const MemObj* mem = getMemObj(curInst); - NodeID base = mem->getId(); - memToFieldsMap[base].set(mem->getId()); - ConstantNullPtrObjVar* node = new ConstantNullPtrObjVar(curInst, mem->getId(), mem); - return addObjNode(mem->getValue(), node, mem->getId()); + memToFieldsMap[i].set(i); + ConstantNullPtrObjVar* conObj = new ConstantNullPtrObjVar(curInst, i, ti); + return addObjNode(curInst, conObj); } - inline NodeID addGlobalValueObjNode(const SVFValue* curInst, const NodeID i) + inline NodeID addGlobalValueObjNode(const SVFValue* curInst, const NodeID i, ObjTypeInfo* ti) { - const MemObj* mem = getMemObj(curInst); - NodeID base = mem->getId(); - memToFieldsMap[base].set(mem->getId()); - GlobalObjVar* node = new GlobalObjVar(curInst, mem->getId(), mem); - return addObjNode(mem->getValue(), node, mem->getId()); + memToFieldsMap[i].set(i); + GlobalObjVar* gObj = new GlobalObjVar(curInst, i, ti); + return addObjNode(curInst, gObj); } - inline NodeID addConstantDataObjNode(const SVFValue* curInst, const NodeID i) + inline NodeID addConstantDataObjNode(const SVFValue* curInst, const NodeID i, ObjTypeInfo* ti) { - const MemObj* mem = getMemObj(curInst); - NodeID base = mem->getId(); - memToFieldsMap[base].set(mem->getId()); - ConstantDataObjVar* node = new ConstantDataObjVar(curInst, mem->getId(), mem); - return addObjNode(mem->getValue(), node, mem->getId()); + memToFieldsMap[i].set(i); + ConstantDataObjVar* conObj = new ConstantDataObjVar(curInst, i, ti); + return addObjNode(curInst, conObj); } /// Add a unique return node for a procedure inline NodeID addRetNode(NodeID i, const CallGraphNode* callGraphNode) { SVFVar *node = new RetPN(i, callGraphNode); - return addRetNode(callGraphNode, node, i); + return addRetNode(callGraphNode, node); } /// Add a unique vararg node for a procedure inline NodeID addVarargNode(NodeID i, const CallGraphNode* val) { SVFVar *node = new VarArgPN(i, val); - return addNode(node,i); + return addNode(node); } /// Add a temp field value node, this method can only invoked by getGepValVar NodeID addGepValNode(const SVFValue* curInst,const SVFValue* val, const AccessPath& ap, NodeID i, const SVFType* type); /// Add a field obj node, this method can only invoked by getGepObjVar - NodeID addGepObjNode(const MemObj* obj, const APOffset& apOffset, const NodeID gepId); + NodeID addGepObjNode(const BaseObjVar* baseObj, const APOffset& apOffset, const NodeID gepId); /// Add a field-insensitive node, this method can only invoked by getFIGepObjNode - NodeID addFIObjNode(const MemObj* obj); + NodeID addFIObjNode(const SVFValue* val, NodeID i, ObjTypeInfo* ti) + { + memToFieldsMap[i].set(i); + BaseObjVar* baseObj = new BaseObjVar(val, i, ti); + return addObjNode(val, baseObj); + } + //@} @@ -727,28 +701,28 @@ class SVFIR : public IRGraph //@{ inline NodeID addDummyValNode(NodeID i) { - return addValNode(nullptr, new DummyValVar(i), i); + return addValNode(nullptr, new DummyValVar(i)); } inline NodeID addDummyObjNode(NodeID i, const SVFType* type) { - const MemObj* mem = addDummyMemObj(i, type); - return addObjNode(nullptr, new DummyObjVar(i,mem), i); - } - inline const MemObj* addDummyMemObj(NodeID i, const SVFType* type) - { - return getSymbolInfo()->createDummyObj(i,type); + if (symInfo->idToObjTypeInfoMap().find(i) == symInfo->idToObjTypeInfoMap().end()) { + ObjTypeInfo* ti = symInfo->createObjTypeInfo(type); + symInfo->idToObjTypeInfoMap()[i] = ti; + return addObjNode(nullptr, new DummyObjVar(i, ti)); + } + else { + return addObjNode(nullptr, new DummyObjVar(i, symInfo->getObjTypeInfo(i))); + } } + inline NodeID addBlackholeObjNode() { return addObjNode( - nullptr, new DummyObjVar(getBlackHoleNode(), getBlackHoleObj()), - getBlackHoleNode()); + nullptr, new DummyObjVar(getBlackHoleNode(), symInfo->getObjTypeInfo(getBlackHoleNode()))); } inline NodeID addConstantObjNode() { - return addObjNode(nullptr, - new DummyObjVar(getConstantNode(), getConstantObj()), - getConstantNode()); + return addObjNode(nullptr, new DummyObjVar(getConstantNode(), symInfo->getObjTypeInfo(getConstantNode()))); } inline NodeID addBlackholePtrNode() { @@ -757,30 +731,32 @@ class SVFIR : public IRGraph //@} /// Add a value (pointer) node - inline NodeID addValNode(const SVFValue*, SVFVar *node, NodeID i) + inline NodeID addValNode(const SVFValue*, SVFVar *node) { - assert(hasGNode(i) == false && + assert(node && "node cannot be nullptr."); + assert(hasGNode(node->getId()) == false && "This NodeID clashes here. Please check NodeIDAllocator. Switch " "Strategy::DBUG to SEQ or DENSE"); - return addNode(node, i); + return addNode(node); } /// Add a memory obj node - inline NodeID addObjNode(const SVFValue*, SVFVar *node, NodeID i) + inline NodeID addObjNode(const SVFValue*, SVFVar *node) { - assert(hasGNode(i) == false && + assert(node && "node cannot be nullptr."); + assert(hasGNode(node->getId()) == false && "This NodeID clashes here. Please check NodeIDAllocator. Switch " "Strategy::DBUG to SEQ or DENSE"); - return addNode(node, i); + return addNode(node); } /// Add a unique return node for a procedure - inline NodeID addRetNode(const CallGraphNode*, SVFVar *node, NodeID i) + inline NodeID addRetNode(const CallGraphNode*, SVFVar *node) { - return addNode(node,i); + return addNode(node); } /// Add a unique vararg node for a procedure - inline NodeID addVarargNode(const SVFFunction*, SVFVar *node, NodeID i) + inline NodeID addVarargNode(const SVFFunction*, SVFVar *node) { - return addNode(node,i); + return addNode(node); } /// Add global PAGEdges (not in a procedure) diff --git a/svf/include/SVFIR/SVFVariables.h b/svf/include/SVFIR/SVFVariables.h index 8e3fb78a4..787cb8d39 100644 --- a/svf/include/SVFIR/SVFVariables.h +++ b/svf/include/SVFIR/SVFVariables.h @@ -331,12 +331,11 @@ class ObjVar: public SVFVar friend class SVFIRReader; protected: - const MemObj* mem; ///< memory object /// Constructor to create an empty ObjVar (for SVFIRReader/deserialization) - ObjVar(NodeID i, PNODEK ty = ObjNode) : SVFVar(i, ty), mem{} {} + ObjVar(NodeID i, PNODEK ty = ObjNode) : SVFVar(i, ty) {} /// Constructor - ObjVar(const SVFValue* val, NodeID i, const MemObj* m, PNODEK ty = ObjNode) : - SVFVar(val, i, ty), mem(m) + ObjVar(const SVFValue* val, NodeID i, PNODEK ty = ObjNode) : + SVFVar(val, i, ty) { } public: @@ -360,12 +359,6 @@ class ObjVar: public SVFVar } //@} - /// Return memory object - const MemObj* getMemObj() const - { - return mem; - } - /// Return name of a LLVM value virtual const std::string getValueName() const { @@ -376,7 +369,7 @@ class ObjVar: public SVFVar /// Return type of the value inline virtual const SVFType* getType() const { - return mem->getType(); + return value->getType(); } virtual const std::string toString() const; @@ -535,149 +528,297 @@ class GepValVar: public ValVar virtual const std::string toString() const; }; - /* - * Gep Obj variable, this is dynamic generated for field sensitive analysis - * Each gep obj variable is one field of a MemObj (base) + * Field-insensitive Gep Obj variable, this is dynamic generated for field sensitive analysis + * Each field-insensitive gep obj node represents all fields of a MemObj (base) */ -class GepObjVar: public ObjVar +class BaseObjVar : public ObjVar { friend class SVFIRWriter; friend class SVFIRReader; - + friend class SVFIRBuilder; private: - APOffset apOffset = 0; - NodeID base = 0; + ObjTypeInfo* typeInfo; - /// Constructor to create empty GepObjVar (for SVFIRReader/deserialization) - // only for reading from file when we don't have MemObj* - GepObjVar(NodeID i, PNODEK ty = GepObjNode) : ObjVar(i, ty) {} + const SVFBaseNode* gNode; + +protected: + /// Constructor to create empty ObjVar (for SVFIRReader/deserialization) + BaseObjVar(NodeID i, PNODEK ty = BaseObjNode) : ObjVar(i, ty) {} public: - /// Methods for support type inquiry through isa, cast, and dyn_cast: + /// Methods for support type inquiry through isa, cast, and dyn_cast: //@{ - static inline bool classof(const GepObjVar*) + static inline bool classof(const BaseObjVar*) { return true; } static inline bool classof(const ObjVar* node) { - return node->getNodeKind() == SVFVar::GepObjNode; + return isBaseObjVarKinds(node->getNodeKind()); } static inline bool classof(const SVFVar* node) { - return node->getNodeKind() == SVFVar::GepObjNode; + return isBaseObjVarKinds(node->getNodeKind()); } static inline bool classof(const GenericPAGNodeTy* node) { - return node->getNodeKind() == SVFVar::GepObjNode; + return isBaseObjVarKinds(node->getNodeKind()); } static inline bool classof(const SVFBaseNode* node) { - return node->getNodeKind() == SVFVar::GepObjNode; + return isBaseObjVarKinds(node->getNodeKind()); } //@} - /// Constructor - GepObjVar(const MemObj* mem, NodeID i, const APOffset& apOffset, - PNODEK ty = GepObjNode) - : ObjVar(mem->getValue(), i, mem, ty), apOffset(apOffset) + /// Constructorx + BaseObjVar(const SVFValue* val, NodeID i, ObjTypeInfo* ti, PNODEK ty = BaseObjNode) + : ObjVar(val, i, ty), typeInfo(ti) { - base = mem->getId(); } - /// offset of the mem object - inline APOffset getConstantFieldIdx() const + virtual const BaseObjVar* getBaseMemObj() const { + return this; + } + + /// Get the reference value to this object + inline const SVFBaseNode* getGNode() const { - return apOffset; + return gNode; } - /// Set the base object from which this GEP node came from. - inline void setBaseNode(NodeID bs) + /// Return name of a LLVM value + inline const std::string getValueName() const { - this->base = bs; + if (value) + return value->getName() + " (base object)"; + return " (base object)"; } - /// Return the base object from which this GEP node came from. - inline NodeID getBaseNode(void) const + virtual const std::string toString() const; + + /// Get the memory object id + inline SymID getId() const { - return base; + return id; } - /// Return the type of this gep object - inline virtual const SVFType* getType() const + /// Get obj type + const SVFType* getType() const { - return SymbolTableInfo::SymbolInfo()->getFlatternedElemType(mem->getType(), apOffset); + return typeInfo->getType(); } - /// Return name of a LLVM value - inline const std::string getValueName() const + /// Get the number of elements of this object + u32_t getNumOfElements() const { - if (value) - return value->getName() + "_" + std::to_string(apOffset); - return "offset_" + std::to_string(apOffset); + return typeInfo->getNumOfElements(); } - virtual const std::string toString() const; + /// Set the number of elements of this object + void setNumOfElements(u32_t num) + { + return typeInfo->setNumOfElements(num); + } + + /// Get max field offset limit + u32_t getMaxFieldOffsetLimit() const + { + return typeInfo->getMaxFieldOffsetLimit(); + } + + + /// Return true if its field limit is 0 + bool isFieldInsensitive() const + { + return getMaxFieldOffsetLimit() == 0; + } + + /// Set the memory object to be field insensitive + void setFieldInsensitive() + { + typeInfo->setMaxFieldOffsetLimit(0); + } + + + /// Set the memory object to be field sensitive (up to max field limit) + void setFieldSensitive() + { + typeInfo->setMaxFieldOffsetLimit(typeInfo->getNumOfElements()); + } + + /// Whether it is a black hole object + bool isBlackHoleObj() const + { + return SymbolTableInfo::isBlkObj(getId()); + } + + /// Get the byte size of this object + u32_t getByteSizeOfObj() const + { + return typeInfo->getByteSizeOfObj(); + } + + /// Check if byte size is a const value + bool isConstantByteSize() const + { + return typeInfo->isConstantByteSize(); + } + + + /// object attributes methods + //@{ + bool isFunction() const + { + return typeInfo->isFunction(); + } + bool isGlobalObj() const + { + return typeInfo->isGlobalObj(); + } + bool isStaticObj() const + { + return typeInfo->isStaticObj(); + } + bool isStack() const + { + return typeInfo->isStack(); + } + bool isHeap() const + { + return typeInfo->isHeap(); + } + bool isStruct() const + { + return typeInfo->isStruct(); + } + bool isArray() const + { + return typeInfo->isArray(); + } + bool isVarStruct() const + { + return typeInfo->isVarStruct(); + } + bool isVarArray() const + { + return typeInfo->isVarArray(); + } + bool isConstantStruct() const + { + return typeInfo->isConstantStruct(); + } + bool isConstantArray() const + { + return typeInfo->isConstantArray(); + } + bool isConstDataOrConstGlobal() const + { + return typeInfo->isConstDataOrConstGlobal(); + } + bool isConstDataOrAggData() const + { + return typeInfo->isConstDataOrAggData(); + } + //@} + + /// Clean up memory + void destroy() { + delete typeInfo; + typeInfo = nullptr; + } + + }; + /* - * Field-insensitive Gep Obj variable, this is dynamic generated for field sensitive analysis - * Each field-insensitive gep obj node represents all fields of a MemObj (base) + * Gep Obj variable, this is dynamic generated for field sensitive analysis + * Each gep obj variable is one field of a BaseObjVar (base) */ -class BaseObjVar : public ObjVar +class GepObjVar: public ObjVar { friend class SVFIRWriter; friend class SVFIRReader; -protected: - /// Constructor to create empty ObjVar (for SVFIRReader/deserialization) - BaseObjVar(NodeID i, PNODEK ty = BaseObjNode) : ObjVar(i, ty) {} +private: + APOffset apOffset = 0; + + const BaseObjVar* base; + + /// Constructor to create empty GepObjVar (for SVFIRReader/deserialization) + // only for reading from file when we don't have BaseObjVar* + GepObjVar(NodeID i, PNODEK ty = GepObjNode) : ObjVar(i, ty), base{} {} public: - /// Methods for support type inquiry through isa, cast, and dyn_cast: + /// Methods for support type inquiry through isa, cast, and dyn_cast: //@{ - static inline bool classof(const BaseObjVar*) + static inline bool classof(const GepObjVar*) { return true; } static inline bool classof(const ObjVar* node) { - return isBaseObjVarKinds(node->getNodeKind()); + return node->getNodeKind() == SVFVar::GepObjNode; } static inline bool classof(const SVFVar* node) { - return isBaseObjVarKinds(node->getNodeKind()); + return node->getNodeKind() == SVFVar::GepObjNode; } static inline bool classof(const GenericPAGNodeTy* node) { - return isBaseObjVarKinds(node->getNodeKind()); + return node->getNodeKind() == SVFVar::GepObjNode; } static inline bool classof(const SVFBaseNode* node) { - return isBaseObjVarKinds(node->getNodeKind()); + return node->getNodeKind() == SVFVar::GepObjNode; } //@} /// Constructor - BaseObjVar(const SVFValue* val, NodeID i, const MemObj* mem, - PNODEK ty = BaseObjNode) - : ObjVar(val, i, mem, ty) + GepObjVar(const BaseObjVar* baseObj, NodeID i, + const APOffset& apOffset, PNODEK ty = GepObjNode) + : ObjVar(baseObj->hasValue()? baseObj->getValue(): nullptr, i, ty), apOffset(apOffset), base(baseObj) + { + + } + + /// offset of the mem object + inline APOffset getConstantFieldIdx() const + { + return apOffset; + } + + /// Return the base object from which this GEP node came from. + inline NodeID getBaseNode(void) const + { + return base->getId(); + } + + inline const BaseObjVar* getBaseObj() const { + return base; + } + + /// Return the type of this gep object + inline virtual const SVFType* getType() const + { + return SymbolTableInfo::SymbolInfo()->getFlatternedElemType(value->getType(), apOffset); } /// Return name of a LLVM value inline const std::string getValueName() const { if (value) - return value->getName() + " (base object)"; - return " (base object)"; + return value->getName() + "_" + std::to_string(apOffset); + return "offset_" + std::to_string(apOffset); } virtual const std::string toString() const; }; + /** * @brief Class representing a heap object variable in the SVFIR * @@ -724,8 +865,13 @@ class HeapObjVar: public BaseObjVar //@} /// Constructor - HeapObjVar(NodeID i, const MemObj* mem, const SVFType* svfType, - const SVFFunction* fun, PNODEK ty = HeapObjNode); + HeapObjVar(const SVFValue* val, NodeID i, ObjTypeInfo* ti, + const SVFFunction* f, PNODEK ty = HeapObjNode): + BaseObjVar(val, i, ti, ty) + { + isPtr = val->getType()->isPointerTy(); + func = f; + } /// Return name of a LLVM value inline const std::string getValueName() const @@ -785,8 +931,13 @@ class StackObjVar: public BaseObjVar //@} /// Constructor - StackObjVar(NodeID i, const MemObj* mem, const SVFType* svfType, - const SVFFunction* fun, PNODEK ty = StackObjNode); + StackObjVar(const SVFValue* val, NodeID i, ObjTypeInfo* ti, + const SVFFunction* fun, PNODEK ty = StackObjNode): + BaseObjVar(val, i, ti, ty) + { + isPtr = val->getType()->isPointerTy(); + func = fun; + } /// Return name of a LLVM value inline const std::string getValueName() const @@ -886,7 +1037,7 @@ class FunObjVar : public BaseObjVar //@} /// Constructor - FunObjVar(NodeID i, const MemObj* mem, const CallGraphNode* cgNode, + FunObjVar(const SVFValue* val, NodeID i, ObjTypeInfo* ti, const CallGraphNode* cgNode, PNODEK ty = FunObjNode); inline const CallGraphNode* getCallGraphNode() const @@ -894,6 +1045,8 @@ class FunObjVar : public BaseObjVar return callGraphNode; } + virtual const SVFFunction* getFunction() const; + virtual bool isIsolatedNode() const; virtual const std::string toString() const; @@ -1221,8 +1374,8 @@ class GlobalObjVar : public BaseObjVar //@} /// Constructor - GlobalObjVar(const SVFValue* val, NodeID i, const MemObj* mem, - PNODEK ty = GlobalObjNode): BaseObjVar(val, i,mem,ty) + GlobalObjVar(const SVFValue* val, NodeID i, ObjTypeInfo* ti, + PNODEK ty = GlobalObjNode): BaseObjVar(val, i, ti, ty) { } @@ -1270,8 +1423,8 @@ class ConstantDataObjVar: public BaseObjVar //@} /// Constructor - ConstantDataObjVar(const SVFValue* val, NodeID i, const MemObj* m, PNODEK ty = ConstantDataObjNode) - : BaseObjVar(val, i, m, ty) + ConstantDataObjVar(const SVFValue* val, NodeID i, ObjTypeInfo* ti, PNODEK ty = ConstantDataObjNode) + : BaseObjVar(val, i, ti, ty) { } @@ -1327,8 +1480,8 @@ class ConstantFPObjVar: public ConstantDataObjVar //@} /// Constructor - ConstantFPObjVar(const SVFValue* val, NodeID i, double dv, const MemObj* m, PNODEK ty = ConstantFPObjNode) - : ConstantDataObjVar(val, i, m, ty), dval(dv) + ConstantFPObjVar(const SVFValue* val, NodeID i, double dv, ObjTypeInfo* ti, PNODEK ty = ConstantFPObjNode) + : ConstantDataObjVar(val, i, ti, ty), dval(dv) { } @@ -1402,8 +1555,8 @@ class ConstantIntObjVar: public ConstantDataObjVar //@} /// Constructor - ConstantIntObjVar(const SVFValue* val, NodeID i, s64_t sv, u64_t zv, const MemObj* m, PNODEK ty = ConstantIntObjNode) - : ConstantDataObjVar(val, i, m, ty), zval(zv), sval(sv) + ConstantIntObjVar(const SVFValue* val, NodeID i, s64_t sv, u64_t zv, ObjTypeInfo* ti, PNODEK ty = ConstantIntObjNode) + : ConstantDataObjVar(val, i, ti, ty), zval(zv), sval(sv) { } @@ -1457,8 +1610,8 @@ class ConstantNullPtrObjVar: public ConstantDataObjVar //@} /// Constructor - ConstantNullPtrObjVar(const SVFValue* val, NodeID i, const MemObj* m, PNODEK ty = ConstantNullptrObjNode) - : ConstantDataObjVar(val, i, m, ty) + ConstantNullPtrObjVar(const SVFValue* val, NodeID i, ObjTypeInfo* ti, PNODEK ty = ConstantNullptrObjNode) + : ConstantDataObjVar(val, i, ti, ty) { } @@ -1655,8 +1808,8 @@ class DummyObjVar: public BaseObjVar //@} /// Constructor - DummyObjVar(NodeID i, const MemObj* m, PNODEK ty = DummyObjNode) - : BaseObjVar(nullptr, i, m, ty) + DummyObjVar(NodeID i, ObjTypeInfo* ti, PNODEK ty = DummyObjNode) + : BaseObjVar(nullptr, i, ti, ty) { } diff --git a/svf/include/SVFIR/SymbolTableInfo.h b/svf/include/SVFIR/SymbolTableInfo.h index 049dac76a..26420831d 100644 --- a/svf/include/SVFIR/SymbolTableInfo.h +++ b/svf/include/SVFIR/SymbolTableInfo.h @@ -37,9 +37,9 @@ namespace SVF { -class MemObj; class ObjTypeInfo; class StInfo; +class BaseObjVar; /*! * Symbol table of the memory model for analysis @@ -70,8 +70,9 @@ class SymbolTableInfo /// llvm value to sym id map /// local (%) and global (@) identifiers are pointer types which have a value node id. typedef OrderedMap ValueToIDMapTy; - /// sym id to memory object map - typedef OrderedMap IDToMemMapTy; + /// sym id to obj type info map + typedef OrderedMap IDToTypeInfoMapTy; + /// function to sym id map typedef OrderedMap FunToIDMapTy; /// struct type to struct info map @@ -83,7 +84,7 @@ class SymbolTableInfo ValueToIDMapTy objSymMap; ///< map a obj reference to its sym id FunToIDMapTy returnSymMap; ///< return map FunToIDMapTy varargSymMap; ///< vararg map - IDToMemMapTy objMap; ///< map a memory sym id to its obj + IDToTypeInfoMapTy objTypeInfoMap; ///< map a memory sym id to its obj // Singleton pattern here to enable instance of SymbolTableInfo can only be created once. static SymbolTableInfo* symInfo; @@ -171,15 +172,6 @@ class SymbolTableInfo return (isBlkObj(id) || isConstantObj(id)); } - inline MemObj* getBlkObj() const - { - return getObj(blackholeSymID()); - } - inline MemObj* getConstantObj() const - { - return getObj(constantSymID()); - } - inline SymID blkPtrSymID() const { return BlkPtr; @@ -200,10 +192,6 @@ class SymbolTableInfo return BlackHole; } - /// Can only be invoked by SVFIR::addDummyNode() when creating SVFIR from file. - const MemObj* createDummyObj(SymID symId, const SVFType* type); - // @} - /// Get different kinds of syms //@{ SymID getValSym(const SVFValue* val); @@ -220,10 +208,10 @@ class SymbolTableInfo return iter->second; } - inline MemObj* getObj(SymID id) const + inline ObjTypeInfo* getObjTypeInfo(SymID id) const { - IDToMemMapTy::const_iterator iter = objMap.find(id); - assert(iter!=objMap.end() && "obj not found"); + IDToTypeInfoMapTy::const_iterator iter = objTypeInfoMap.find(id); + assert(iter!=objTypeInfoMap.end() && "obj type info not found"); return iter->second; } @@ -267,14 +255,14 @@ class SymbolTableInfo return objSymMap; } - inline IDToMemMapTy& idToObjMap() + inline IDToTypeInfoMapTy& idToObjTypeInfoMap() { - return objMap; + return objTypeInfoMap; } - inline const IDToMemMapTy& idToObjMap() const + inline const IDToTypeInfoMapTy& idToObjTypeInfoMap() const { - return objMap; + return objTypeInfoMap; } inline FunToIDMapTy& retSyms() @@ -311,6 +299,11 @@ class SymbolTableInfo return svfTypes.find(T) != svfTypes.end(); } + /// Create an objectInfo based on LLVM type (value is null, and type could be null, representing a dummy object) + ObjTypeInfo* createObjTypeInfo(const SVFType* type); + + const ObjTypeInfo* createDummyObjTypeInfo(SymID symId, const SVFType* type); + ///Get a reference to the components of struct_info. /// Number of flattened elements of an array or struct u32_t getNumOfFlattenElements(const SVFType* T); @@ -333,8 +326,7 @@ class SymbolTableInfo virtual void dump(); /// Given an offset from a Gep Instruction, return it modulus offset by considering memory layout - virtual APOffset getModulusOffset(const MemObj* obj, - const APOffset& apOffset); + virtual APOffset getModulusOffset(const BaseObjVar* baseObj, const APOffset& apOffset); ///The struct type with the most fields const SVFType* maxStruct; @@ -359,9 +351,6 @@ class SymbolTableInfo /// Return the flattened field type for struct type only const std::vector& getFlattenFieldTypes(const SVFStructType *T); - /// Create an objectInfo based on LLVM type (value is null, and type could be null, representing a dummy object) - ObjTypeInfo* createObjTypeInfo(const SVFType* type); - /// (owned) All SVF Types /// Every type T is mapped to StInfo /// which contains size (fsize) , offset(foffset) @@ -375,113 +364,6 @@ class SymbolTableInfo class SVFBaseNode; -/*! - * Memory object symbols or MemObj (address-taken variables in LLVM-based languages) - */ -class MemObj -{ - friend class SVFIRWriter; - friend class SVFIRReader; - friend class SVFIRBuilder; - -private: - /// Type information of this object - ObjTypeInfo* typeInfo; - /// The unique value of this symbol/variable - const SVFValue* refVal; - /// The unique id to represent this symbol - SymID symId; - - const SVFBaseNode* gNode; - -public: - /// Constructor - MemObj(SymID id, ObjTypeInfo* ti, const SVFValue* val = nullptr, const SVFBaseNode* node = nullptr); - - /// Destructor - virtual ~MemObj() - { - destroy(); - } - - virtual const std::string toString() const; - - /// Get the reference value to this object - inline const SVFValue* getValue() const - { - return refVal; - } - - /// Get the reference value to this object - inline const SVFBaseNode* getGNode() const - { - return gNode; - } - - /// Get the memory object id - inline SymID getId() const - { - return symId; - } - - /// Get obj type - const SVFType* getType() const; - - /// Get the number of elements of this object - u32_t getNumOfElements() const; - - /// Set the number of elements of this object - void setNumOfElements(u32_t num); - - /// Get max field offset limit - u32_t getMaxFieldOffsetLimit() const; - - /// Return true if its field limit is 0 - bool isFieldInsensitive() const; - - /// Set the memory object to be field insensitive - void setFieldInsensitive(); - - /// Set the memory object to be field sensitive (up to max field limit) - void setFieldSensitive(); - - /// Whether it is a black hole object - bool isBlackHoleObj() const; - - /// Get the byte size of this object - u32_t getByteSizeOfObj() const; - - /// Check if byte size is a const value - bool isConstantByteSize() const; - - - /// object attributes methods - //@{ - bool isFunction() const; - bool isGlobalObj() const; - bool isStaticObj() const; - bool isStack() const; - bool isHeap() const; - bool isStruct() const; - bool isArray() const; - bool isVarStruct() const; - bool isVarArray() const; - bool isConstantStruct() const; - bool isConstantArray() const; - bool isConstDataOrConstGlobal() const; - bool isConstDataOrAggData() const; - //@} - - /// Operator overloading - inline bool operator==(const MemObj& mem) const - { - return getValue() == mem.getValue(); - } - - /// Clean up memory - void destroy(); -}; - /*! * Type Info of an abstract memory object */ diff --git a/svf/lib/AE/Core/AbstractState.cpp b/svf/lib/AE/Core/AbstractState.cpp index 913314ed3..63f5b1695 100644 --- a/svf/lib/AE/Core/AbstractState.cpp +++ b/svf/lib/AE/Core/AbstractState.cpp @@ -182,7 +182,7 @@ void AbstractState::initObjVar(ObjVar* objVar) // Check if the object variable has an associated value - const MemObj* obj = objVar->getMemObj(); + const BaseObjVar* obj = PAG::getPAG()->getBaseObject(objVar->getId()); // Handle constant data, arrays, and structures if (obj->isConstDataOrConstGlobal() || obj->isConstantArray() || obj->isConstantStruct()) @@ -471,9 +471,9 @@ const SVFType* AbstractState::getPointeeElement(NodeID id) for (auto addr: addrs.getAddrs()) { NodeID addr_id = AbstractState::getInternalID(addr); - if (addr_id == 0) // nullptr has no memobj, skip + if (addr_id == 0) // nullptr skip continue; - return SVFUtil::dyn_cast(svfir->getGNode(addr_id))->getMemObj()->getType(); + return svfir->getBaseObject(addr_id)->getType(); } } else @@ -487,10 +487,9 @@ u32_t AbstractState::getAllocaInstByteSize(const AddrStmt *addr) { if (const ObjVar* objvar = SVFUtil::dyn_cast(addr->getRHSVar())) { - objvar->getType(); - if (objvar->getMemObj()->isConstantByteSize()) + if (PAG::getPAG()->getBaseObject(objvar->getId())->isConstantByteSize()) { - u32_t sz = objvar->getMemObj()->getByteSizeOfObj(); + u32_t sz = PAG::getPAG()->getBaseObject(objvar->getId())->getByteSizeOfObj(); return sz; } diff --git a/svf/lib/AE/Svfexe/AEDetector.cpp b/svf/lib/AE/Svfexe/AEDetector.cpp index d9963d415..0110745b9 100644 --- a/svf/lib/AE/Svfexe/AEDetector.cpp +++ b/svf/lib/AE/Svfexe/AEDetector.cpp @@ -64,14 +64,14 @@ void BufOverflowDetector::detect(AbstractState& as, const ICFGNode* node) NodeID objId = AbstractState::getInternalID(addr); u32_t size = 0; - if (svfir->getBaseObj(objId)->isConstantByteSize()) + if (svfir->getBaseObject(objId)->isConstantByteSize()) { - size = svfir->getBaseObj(objId)->getByteSizeOfObj(); + size = svfir->getBaseObject(objId)->getByteSizeOfObj(); } else { const ICFGNode* addrNode = SVFUtil::cast( - svfir->getBaseObj(objId)->getGNode()); + svfir->getBaseObject(objId)->getGNode()); for (const SVFStmt* stmt2 : addrNode->getSVFStmts()) { if (const AddrStmt* addrStmt = SVFUtil::dyn_cast(stmt2)) @@ -465,15 +465,15 @@ bool BufOverflowDetector::canSafelyAccessMemory(AbstractState& as, const SVF::SV u32_t size = 0; // if the object is a constant size object, get the size directly - if (svfir->getBaseObj(objId)->isConstantByteSize()) + if (svfir->getBaseObject(objId)->isConstantByteSize()) { - size = svfir->getBaseObj(objId)->getByteSizeOfObj(); + size = svfir->getBaseObject(objId)->getByteSizeOfObj(); } else { // if the object is not a constant size object, get the size from the addrStmt const ICFGNode* addrNode = SVFUtil::cast( - svfir->getBaseObj(objId)->getGNode()); + svfir->getBaseObject(objId)->getGNode()); for (const SVFStmt* stmt2 : addrNode->getSVFStmts()) { if (const AddrStmt* addrStmt = SVFUtil::dyn_cast(stmt2)) diff --git a/svf/lib/AE/Svfexe/AbsExtAPI.cpp b/svf/lib/AE/Svfexe/AbsExtAPI.cpp index 2260d3fba..74dc8529d 100644 --- a/svf/lib/AE/Svfexe/AbsExtAPI.cpp +++ b/svf/lib/AE/Svfexe/AbsExtAPI.cpp @@ -278,13 +278,13 @@ void AbsExtAPI::initExtFunMap() for (const auto& addr : as[value_id].getAddrs()) { NodeID objId = AbstractState::getInternalID(addr); - if (svfir->getBaseObj(objId)->isConstantByteSize()) + if (svfir->getBaseObject(objId)->isConstantByteSize()) { - dst_size = svfir->getBaseObj(objId)->getByteSizeOfObj(); + dst_size = svfir->getBaseObject(objId)->getByteSizeOfObj(); } else { - const ICFGNode* addrNode = SVFUtil::cast(svfir->getBaseObj(objId)->getGNode()); + const ICFGNode* addrNode = SVFUtil::cast(svfir->getBaseObject(objId)->getGNode()); for (const SVFStmt* stmt2: addrNode->getSVFStmts()) { if (const AddrStmt* addrStmt = SVFUtil::dyn_cast(stmt2)) @@ -472,13 +472,13 @@ IntervalValue AbsExtAPI::getStrlen(AbstractState& as, const SVF::SVFVar *strValu for (const auto& addr : as[value_id].getAddrs()) { NodeID objId = AbstractState::getInternalID(addr); - if (svfir->getBaseObj(objId)->isConstantByteSize()) + if (svfir->getBaseObject(objId)->isConstantByteSize()) { - dst_size = svfir->getBaseObj(objId)->getByteSizeOfObj(); + dst_size = svfir->getBaseObject(objId)->getByteSizeOfObj(); } else { - const ICFGNode* icfgNode = SVFUtil::cast( svfir->getBaseObj(objId)->getGNode()); + const ICFGNode* icfgNode = SVFUtil::cast( svfir->getBaseObject(objId)->getGNode()); for (const SVFStmt* stmt2: icfgNode->getSVFStmts()) { if (const AddrStmt* addrStmt = SVFUtil::dyn_cast(stmt2)) diff --git a/svf/lib/CFL/CFLGraphBuilder.cpp b/svf/lib/CFL/CFLGraphBuilder.cpp index fa43a2ca8..971735819 100644 --- a/svf/lib/CFL/CFLGraphBuilder.cpp +++ b/svf/lib/CFL/CFLGraphBuilder.cpp @@ -446,8 +446,8 @@ void AliasCFLGraphBuilder::AliasCFLGraphBuilder::connectVGep(CFLGraph *cflGraph, level -= 1; for (auto eit = src->getAddrInEdges().begin(); eit != src->getAddrInEdges().end(); eit++) { - const MemObj* mem = pag->getBaseObj((*eit)->getSrcID()); - for (u32_t maxField = 0 ; maxField < mem->getNumOfElements(); maxField++) + const BaseObjVar* baseObj = pag->getBaseObject((*eit)->getSrcID()); + for (u32_t maxField = 0 ; maxField < baseObj->getNumOfElements(); maxField++) { addBiGepCFLEdge(cflGraph, (*eit)->getDstNode(), dst, maxField); } diff --git a/svf/lib/DDA/ContextDDA.cpp b/svf/lib/DDA/ContextDDA.cpp index 456b7af60..140736017 100644 --- a/svf/lib/DDA/ContextDDA.cpp +++ b/svf/lib/DDA/ContextDDA.cpp @@ -334,13 +334,13 @@ bool ContextDDA::handleBKCondition(CxtLocDPItem& dpm, const SVFGEdge* edge) /// (2) not inside loop bool ContextDDA::isHeapCondMemObj(const CxtVar& var, const StoreSVFGNode*) { - const MemObj* mem = _pag->getObject(getPtrNodeID(var)); - assert(mem && "memory object is null??"); + const BaseObjVar* obj = _pag->getBaseObject(getPtrNodeID(var)); + assert(obj && "base object is null??"); const BaseObjVar* baseVar = _pag->getBaseObject(getPtrNodeID(var)); assert(baseVar && "base object is null??"); if (SVFUtil::isa(baseVar)) { - if (!mem->getValue()) + if (!obj->getValue()) { PAGNode *pnode = _pag->getGNode(getPtrNodeID(var)); GepObjVar* gepobj = SVFUtil::dyn_cast(pnode); @@ -356,7 +356,7 @@ bool ContextDDA::isHeapCondMemObj(const CxtVar& var, const StoreSVFGNode*) } return true; } - else if(const SVFBaseNode* gNode = mem->getGNode()) + else if(const SVFBaseNode* gNode = obj->getGNode()) { if (const auto& node = SVFUtil::dyn_cast(gNode)) diff --git a/svf/lib/Graphs/ThreadCallGraph.cpp b/svf/lib/Graphs/ThreadCallGraph.cpp index 1be851468..b5aba544a 100644 --- a/svf/lib/Graphs/ThreadCallGraph.cpp +++ b/svf/lib/Graphs/ThreadCallGraph.cpp @@ -83,7 +83,7 @@ void ThreadCallGraph::updateCallGraph(PointerAnalysis* pta) { if(ObjVar* objPN = SVFUtil::dyn_cast(pag->getGNode(*ii))) { - const MemObj* obj = pag->getObject(objPN); + const BaseObjVar* obj = pag->getBaseObject(objPN->getId()); if(obj->isFunction()) { const SVFFunction* svfCallee = SVFUtil::cast(obj->getGNode())->getFunction(); diff --git a/svf/lib/MSSA/MemRegion.cpp b/svf/lib/MSSA/MemRegion.cpp index 230eb04b9..10fbd0508 100644 --- a/svf/lib/MSSA/MemRegion.cpp +++ b/svf/lib/MSSA/MemRegion.cpp @@ -109,7 +109,7 @@ void MRGenerator::collectGlobals() { if(ObjVar* obj = SVFUtil::dyn_cast(nIter->second)) { - if (obj->getMemObj()->isGlobalObj()) + if (pag->getBaseObject(obj->getId())->isGlobalObj()) { allGlobals.set(nIter->first); allGlobals |= CollectPtsChain(nIter->first); @@ -560,9 +560,10 @@ void MRGenerator::getEscapObjviaGlobals(NodeBS& globs, const NodeBS& calleeModRe { for(NodeBS::iterator it = calleeModRef.begin(), eit = calleeModRef.end(); it!=eit; ++it) { - const MemObj* obj = pta->getPAG()->getObject(*it); - (void)obj; // Suppress warning of unused variable under release build - assert(obj && "object not found!!"); + const BaseObjVar* pVar = pta->getPAG()->getBaseObject(*it); + (void)pVar; + //(void)obj; // Suppress warning of unused variable under release build + assert(pVar && "object not found!!"); if(allGlobals.test(*it)) globs.set(*it); } @@ -574,7 +575,8 @@ void MRGenerator::getEscapObjviaGlobals(NodeBS& globs, const NodeBS& calleeModRe */ bool MRGenerator::isNonLocalObject(NodeID id, const SVFFunction* curFun) const { - const MemObj* obj = pta->getPAG()->getObject(id); + //ABTest + const BaseObjVar* obj = pta->getPAG()->getBaseObject(id); assert(obj && "object not found!!"); /// if the object is heap or global const BaseObjVar* pVar = pta->getPAG()->getBaseObject(id); diff --git a/svf/lib/MemoryModel/PointerAnalysis.cpp b/svf/lib/MemoryModel/PointerAnalysis.cpp index d95d1d2d8..f6ad2bfb8 100644 --- a/svf/lib/MemoryModel/PointerAnalysis.cpp +++ b/svf/lib/MemoryModel/PointerAnalysis.cpp @@ -153,7 +153,7 @@ void PointerAnalysis::resetObjFieldSensitive() for (SVFIR::iterator nIter = pag->begin(); nIter != pag->end(); ++nIter) { if(ObjVar* node = SVFUtil::dyn_cast(nIter->second)) - const_cast(node->getMemObj())->setFieldSensitive(); + const_cast(pag->getBaseObject(node->getId()))->setFieldSensitive(); } } @@ -396,11 +396,11 @@ void PointerAnalysis::resolveIndCalls(const CallICFGNode* cs, const PointsTo& ta if(ObjVar* objPN = SVFUtil::dyn_cast(pag->getGNode(*ii))) { - const MemObj* obj = pag->getObject(objPN); + const BaseObjVar* obj = pag->getBaseObject(objPN->getId()); if(obj->isFunction()) { - const SVFFunction* calleefun = SVFUtil::cast(obj->getGNode())->getFunction(); + const SVFFunction* calleefun = SVFUtil::cast(obj)->getFunction(); const SVFFunction* callee = calleefun->getDefFunForMultipleModule(); if(SVFUtil::matchArgs(cs, callee) == false) diff --git a/svf/lib/MemoryModel/PointerAnalysisImpl.cpp b/svf/lib/MemoryModel/PointerAnalysisImpl.cpp index 1490c6ce3..8fb383de6 100644 --- a/svf/lib/MemoryModel/PointerAnalysisImpl.cpp +++ b/svf/lib/MemoryModel/PointerAnalysisImpl.cpp @@ -359,16 +359,22 @@ void BVDataPTAImpl::readGepObjVarMapFromFile(std::ifstream& F) if (iter == gepObjVarMap.end()) { SVFVar* node = pag->getGNode(base); - const MemObj* obj = nullptr; + const BaseObjVar* obj = nullptr; if (GepObjVar* gepObjVar = SVFUtil::dyn_cast(node)) - obj = gepObjVar->getMemObj(); + { + obj = gepObjVar->getBaseObj(); + } else if (BaseObjVar* baseNode = SVFUtil::dyn_cast(node)) - obj = baseNode->getMemObj(); + { + obj = baseNode; + } else if (DummyObjVar* baseNode = SVFUtil::dyn_cast(node)) - obj = baseNode->getMemObj(); + { + obj = baseNode; + } else assert(false && "new gep obj node kind?"); - pag->addGepObjNode(obj, offset, id); + pag->addGepObjNode( obj, offset, id); NodeIDAllocator::get()->increaseNumOfObjAndNodes(); } @@ -532,7 +538,7 @@ void BVDataPTAImpl::onTheFlyThreadCallGraphSolve(const CallSiteToFunPtrMap& call { if(ObjVar *objPN = SVFUtil::dyn_cast(pag->getGNode(*ii))) { - const MemObj *obj = pag->getObject(objPN); + const BaseObjVar* obj = pag->getBaseObject(objPN->getId()); if(obj->isFunction()) { const SVFFunction *svfForkedFun = SVFUtil::cast(obj->getGNode())->getFunction(); @@ -559,9 +565,10 @@ void BVDataPTAImpl::normalizePointsTo() for (auto t: memToFieldsMap) { NodeID base = t.first; - const MemObj* memObj = pag->getObject(base); - assert(memObj && "Invalid memobj in memToFieldsMap"); - if (memObj->isFieldInsensitive()) + const BaseObjVar* obj = pag->getBaseObject(base); + assert(obj && "Invalid baseObj in memToFieldsMap"); + assert(obj->isFieldInsensitive() == obj->isFieldInsensitive()); + if (obj->isFieldInsensitive()) { for (NodeID id : t.second) { diff --git a/svf/lib/SABER/SaberSVFGBuilder.cpp b/svf/lib/SABER/SaberSVFGBuilder.cpp index d5a7163ee..d9a24bc18 100644 --- a/svf/lib/SABER/SaberSVFGBuilder.cpp +++ b/svf/lib/SABER/SaberSVFGBuilder.cpp @@ -232,11 +232,11 @@ bool SaberSVFGBuilder::isStrongUpdate(const SVFGNode* node, NodeID& singleton, B singleton = *it; // Strong update can be made if this points-to target is not heap, array or field-insensitive. - if (!pta->isHeapMemObj(singleton) && !pta->isArrayMemObj(singleton) - && SVFIR::getPAG()->getBaseObj(singleton)->isFieldInsensitive() == false - && !pta->isLocalVarInRecursiveFun(singleton)) - { - isSU = true; + if (!pta->isHeapMemObj(singleton) && !pta->isArrayMemObj(singleton)) { + if (SVFIR::getPAG()->getBaseObject(singleton)->isFieldInsensitive() == false + && !pta->isLocalVarInRecursiveFun(singleton)) { + isSU = true; + } } } } diff --git a/svf/lib/SVFIR/PAGBuilderFromFile.cpp b/svf/lib/SVFIR/PAGBuilderFromFile.cpp index 6cfda819c..3a6af7a9c 100644 --- a/svf/lib/SVFIR/PAGBuilderFromFile.cpp +++ b/svf/lib/SVFIR/PAGBuilderFromFile.cpp @@ -93,8 +93,7 @@ SVFIR* PAGBuilderFromFile::build() pag->addDummyValNode(nodeId); else if (nodetype == "o") { - const MemObj* mem = pag->addDummyMemObj(nodeId, nullptr); - pag->addFIObjNode(mem); + pag->addFIObjNode(nullptr, nodeId, pag->getSymbolInfo()->createObjTypeInfo(nullptr)); } else assert(false && "format not support, pls specify node type"); diff --git a/svf/lib/SVFIR/SVFFileSystem.cpp b/svf/lib/SVFIR/SVFFileSystem.cpp index da7dd8681..b2f07853b 100644 --- a/svf/lib/SVFIR/SVFFileSystem.cpp +++ b/svf/lib/SVFIR/SVFFileSystem.cpp @@ -42,52 +42,6 @@ SVFType* createSVFType(SVFType::GNodeK kind, bool isSingleValTy) } } -static SVFValue* createSVFValue(SVFValue::GNodeK kind, const SVFType* type, - std::string&& name) -{ - auto creator = [=]() -> SVFValue* - { - switch (kind) - { - default: - ABORT_MSG(kind << " is an impossible SVFValueKind in create()"); - case SVFValue::SVFVal: - ABORT_MSG("Creation of RAW SVFValue isn't allowed"); - case SVFValue::SVFFunc: - return new SVFFunction(type, {}, {}, {}, {}, {}, {}); - case SVFValue::SVFBB: - return new SVFBasicBlock(type, {}); - case SVFValue::SVFInst: - return new SVFInstruction(type, {}, {}, {}); - case SVFValue::SVFCall: - return new SVFCallInst(type, {}, {}, {}); - case SVFValue::SVFGlob: - return new SVFGlobalValue(type); - case SVFValue::SVFArg: - return new SVFArgument(type, {}, {}, {}); - case SVFValue::SVFConst: - return new SVFConstant(type); - case SVFValue::SVFConstData: - return new SVFConstantData(type); - case SVFValue::SVFConstInt: - return new SVFConstantInt(type, {}, {}); - case SVFValue::SVFConstFP: - return new SVFConstantFP(type, {}); - case SVFValue::SVFNullPtr: - return new SVFConstantNullPtr(type); - case SVFValue::SVFBlackHole: - return new SVFBlackHoleValue(type); - case SVFValue::SVFMetaAsValue: - return new SVFMetadataAsValue(type); - case SVFValue::SVFOther: - return new SVFOtherValue(type); - } - }; - auto val = creator(); - val->setName(std::move(name)); - return val; -} - template static inline void readSmallNumber(const cJSON* obj, SmallNumberType& val) { @@ -335,7 +289,6 @@ cJSON* SVFIRWriter::contentToJson(const ValVar* var) cJSON* SVFIRWriter::contentToJson(const ObjVar* var) { cJSON* root = contentToJson(static_cast(var)); - JSON_WRITE_FIELD(root, var, mem); return root; } @@ -1178,15 +1131,6 @@ cJSON* SVFIRWriter::toJson(const SVFLoop* loop) return jsonCreateIndex(icfgWriter.getSvfLoopID(loop)); } -cJSON* SVFIRWriter::contentToJson(const MemObj* memObj) -{ - cJSON* root = jsonCreateObject(); - JSON_WRITE_FIELD(root, memObj, symId); - JSON_WRITE_FIELD(root, memObj, typeInfo); - JSON_WRITE_FIELD(root, memObj, refVal); - return root; -} - cJSON* SVFIRWriter::contentToJson(const StInfo* stInfo) { cJSON* root = jsonCreateObject(); @@ -1215,11 +1159,6 @@ cJSON* SVFIRWriter::toJson(const ObjTypeInfo* objTypeInfo) return root; } -cJSON* SVFIRWriter::toJson(const MemObj* memObj) -{ - return jsonCreateIndex(memObj->getId()); -} - cJSON* SVFIRWriter::toJson(const SVFLoopAndDomInfo* ldInfo) { ENSURE_NOT_VISITED(ldInfo); @@ -1267,12 +1206,6 @@ cJSON* SVFIRWriter::toJson(const SymbolTableInfo* symTable) cJSON* root = jsonCreateObject(); cJSON* allMemObj = jsonCreateArray(); - for (const auto& pair : symTable->objMap) - { - const MemObj* memObj = pair.second; - cJSON* memObjJson = contentToJson(memObj); - jsonAddItemToArray(allMemObj, memObjJson); - } #define F(field) JSON_WRITE_FIELD(root, symTable, field) jsonAddItemToObject(root, FIELD_NAME_ITEM(allMemObj)); // Actual field @@ -1387,130 +1320,7 @@ SVFIR* SVFIRReader::read(const cJSON* root) const cJSON* SVFIRReader::createObjs(const cJSON* root) { -#define READ_CREATE_NODE_FWD(GType) \ - [](const cJSON*& nodeJson) { \ - JSON_DEF_READ_FWD(nodeJson, NodeID, id); \ - JSON_DEF_READ_FWD(nodeJson, GNodeK, nodeKind); \ - return std::make_pair(id, create##GType##Node(id, nodeKind)); \ - } -#define READ_CREATE_EDGE_FWD(GType) \ - [](const cJSON*& edgeJson) { \ - JSON_DEF_READ_FWD(edgeJson, GEdgeFlag, edgeFlag); \ - auto kind = applyEdgeMask(edgeFlag); \ - auto edge = create##GType##Edge(kind); \ - setEdgeFlag(edge, edgeFlag); \ - return edge; \ - } - - ABORT_IFNOT(jsonIsObject(root), "Root should be an object"); - - const cJSON* const svfModule = root->child; - CHECK_JSON_KEY(svfModule); - svfModuleReader.createObjs( - svfModule, - // SVFType Creator - [](const cJSON*& svfTypeFldJson) - { - JSON_DEF_READ_FWD(svfTypeFldJson, SVFType::GNodeK, kind); - JSON_DEF_READ_FWD(svfTypeFldJson, bool, isSingleValTy); - return createSVFType(kind, isSingleValTy); - }, - // SVFType Filler - [this](const cJSON*& svfVarFldJson, SVFType* type) - { - virtFill(svfVarFldJson, type); - }, - // SVFValue Creator - [this](const cJSON*& svfValueFldJson) - { - JSON_DEF_READ_FWD(svfValueFldJson, SVFValue::GNodeK, kind); - JSON_DEF_READ_FWD(svfValueFldJson, const SVFType*, type, {}); - JSON_DEF_READ_FWD(svfValueFldJson, std::string, name); - return createSVFValue(kind, type, std::move(name)); - }, - // SVFValue Filler - [this](const cJSON*& svfVarFldJson, SVFValue* value) - { - virtFill(svfVarFldJson, value); - }, - // StInfo Creator (no filler needed) - [this](const cJSON*& stInfoFldJson) - { - JSON_DEF_READ_FWD(stInfoFldJson, u32_t, stride); - auto si = new StInfo(stride); - fill(stInfoFldJson, si); - ABORT_IFNOT(!stInfoFldJson, "StInfo has extra field"); - return si; - }); - - const cJSON* const symInfo = svfModule->next; - CHECK_JSON_KEY(symInfo); - symTableReader.createObjs( - symInfo, - // MemObj Creator (no filler needed) - [this](const cJSON*& memObjFldJson) - { - JSON_DEF_READ_FWD(memObjFldJson, SymID, symId); - JSON_DEF_READ_FWD(memObjFldJson, ObjTypeInfo*, typeInfo, {}); - JSON_DEF_READ_FWD(memObjFldJson, const SVFValue*, refVal, {}); - return std::make_pair(symId, new MemObj(symId, typeInfo, refVal)); - }); - - const cJSON* const icfg = symInfo->next; - CHECK_JSON_KEY(icfg); - icfgReader.createObjs(icfg, READ_CREATE_NODE_FWD(ICFG), - READ_CREATE_EDGE_FWD(ICFG), - [](auto) - { - return new SVFLoop({}, 0); - }); - - const cJSON* const chgraph = icfg->next; - CHECK_JSON_KEY(chgraph); - chGraphReader.createObjs(chgraph, READ_CREATE_NODE_FWD(CH), - READ_CREATE_EDGE_FWD(CH)); - - const cJSON* const irGraph = chgraph->next; - CHECK_JSON_KEY(irGraph); - irGraphReader.createObjs(irGraph, READ_CREATE_NODE_FWD(PAG), - READ_CREATE_EDGE_FWD(PAG)); - - icfgReader.fillObjs( - [this](const cJSON*& j, ICFGNode* node) - { - virtFill(j, node); - }, - [this](const cJSON*& j, ICFGEdge* edge) - { - virtFill(j, edge); - }, - [this](const cJSON*& j, SVFLoop* loop) - { - fill(j, loop); - }); - chGraphReader.fillObjs( - [this](const cJSON*& j, CHNode* node) - { - virtFill(j, node); - }, - [this](const cJSON*& j, CHEdge* edge) - { - virtFill(j, edge); - }); - irGraphReader.fillObjs( - [this](const cJSON*& j, SVFVar* var) - { - virtFill(j, var); - }, - [this](const cJSON*& j, SVFStmt* stmt) - { - virtFill(j, stmt); - }); - - return irGraph->next; - -#undef READ_CREATE_EDGE_FWD -#undef READ_CREATE_NODE_FWD + return nullptr; } void SVFIRReader::readJson(const cJSON* obj, bool& flag) @@ -1698,7 +1508,6 @@ void SVFIRReader::readJson(SymbolTableInfo* symTabInfo) F(objSymMap); F(returnSymMap); F(varargSymMap); - symTableReader.memObjMap.saveToIDToObjMap(symTabInfo->objMap); // objMap F(modelConstants); F(totalSymNum); F(maxStruct); @@ -1857,11 +1666,6 @@ void SVFIRReader::readJson(const cJSON* obj, SVFLoop*& loop) loop = icfgReader.getSVFLoopPtr(id); } -void SVFIRReader::readJson(const cJSON* obj, MemObj*& memObj) -{ - assert(!memObj && "MemObj already read?"); - memObj = symTableReader.getMemObjPtr(jsonGetNumber(obj)); -} void SVFIRReader::readJson(const cJSON* obj, ObjTypeInfo*& objTypeInfo) { @@ -1941,7 +1745,6 @@ void SVFIRReader::fill(const cJSON*& fieldJson, ValVar* var) void SVFIRReader::fill(const cJSON*& fieldJson, ObjVar* var) { fill(fieldJson, static_cast(var)); - JSON_READ_FIELD_FWD(fieldJson, var, mem); } void SVFIRReader::fill(const cJSON*& fieldJson, GepValVar* var) @@ -2125,13 +1928,6 @@ void SVFIRReader::fill(const cJSON*& fieldJson, TDJoinPE* stmt) fill(fieldJson, static_cast(stmt)); } -void SVFIRReader::fill(const cJSON*& fieldJson, MemObj* memObj) -{ - // symId has already been read - JSON_READ_FIELD_FWD(fieldJson, memObj, typeInfo); - JSON_READ_FIELD_FWD(fieldJson, memObj, refVal); -} - void SVFIRReader::fill(const cJSON*& fieldJson, StInfo* stInfo) { #define F(field) JSON_READ_FIELD_FWD(fieldJson, stInfo, field) diff --git a/svf/lib/SVFIR/SVFIR.cpp b/svf/lib/SVFIR/SVFIR.cpp index 42376aa91..51fa2f089 100644 --- a/svf/lib/SVFIR/SVFIR.cpp +++ b/svf/lib/SVFIR/SVFIR.cpp @@ -392,7 +392,7 @@ NodeID SVFIR::addGepValNode(const SVFValue* curInst,const SVFValue* gepVal, cons && "this node should not be created before"); GepValObjMap[curInst][std::make_pair(base, ap)] = i; GepValVar *node = new GepValVar(base, gepVal, i, ap, type); - return addValNode(gepVal, node, i); + return addValNode(gepVal, node); } /*! @@ -402,11 +402,11 @@ NodeID SVFIR::getGepObjVar(NodeID id, const APOffset& apOffset) { SVFVar* node = pag->getGNode(id); if (GepObjVar* gepNode = SVFUtil::dyn_cast(node)) - return getGepObjVar(gepNode->getMemObj(), gepNode->getConstantFieldIdx() + apOffset); + return getGepObjVar(gepNode->getBaseObj(), gepNode->getConstantFieldIdx() + apOffset); else if (BaseObjVar* baseNode = SVFUtil::dyn_cast(node)) - return getGepObjVar(baseNode->getMemObj(), apOffset); + return getGepObjVar(baseNode, apOffset); else if (DummyObjVar* baseNode = SVFUtil::dyn_cast(node)) - return getGepObjVar(baseNode->getMemObj(), apOffset); + return getGepObjVar(baseNode, apOffset); else { assert(false && "new gep obj node kind?"); @@ -420,15 +420,15 @@ NodeID SVFIR::getGepObjVar(NodeID id, const APOffset& apOffset) * offset = offset % obj->getMaxFieldOffsetLimit() to create limited number of mem objects * maximum number of field object creation is obj->getMaxFieldOffsetLimit() */ -NodeID SVFIR::getGepObjVar(const MemObj* obj, const APOffset& apOffset) +NodeID SVFIR::getGepObjVar(const BaseObjVar* baseObj, const APOffset& apOffset) { - NodeID base = obj->getId(); + NodeID base = baseObj->getId(); /// if this obj is field-insensitive, just return the field-insensitive node. - if (obj->isFieldInsensitive()) - return getFIObjVar(obj); + if (baseObj->isFieldInsensitive()) + return getFIObjVar(baseObj); - APOffset newLS = pag->getSymbolInfo()->getModulusOffset(obj, apOffset); + APOffset newLS = pag->getSymbolInfo()->getModulusOffset(baseObj, apOffset); // Base and first field are the same memory location. if (Options::FirstFieldEqBase() && newLS == 0) return base; @@ -437,7 +437,7 @@ NodeID SVFIR::getGepObjVar(const MemObj* obj, const APOffset& apOffset) if (iter == GepObjVarMap.end()) { NodeID gepId = NodeIDAllocator::get()->allocateGepObjectId(base, apOffset, Options::MaxFieldLimit()); - return addGepObjNode(obj, newLS,gepId); + return addGepObjNode(baseObj, newLS, gepId); } else return iter->second; @@ -447,46 +447,24 @@ NodeID SVFIR::getGepObjVar(const MemObj* obj, const APOffset& apOffset) /*! * Add a field obj node, this method can only invoked by getGepObjVar */ -NodeID SVFIR::addGepObjNode(const MemObj* obj, const APOffset& apOffset, const NodeID gepId) +NodeID SVFIR::addGepObjNode(const BaseObjVar* baseObj, const APOffset& apOffset, const NodeID gepId) { //assert(findPAGNode(i) == false && "this node should not be created before"); - NodeID base = obj->getId(); + NodeID base = baseObj->getId(); assert(0==GepObjVarMap.count(std::make_pair(base, apOffset)) && "this node should not be created before"); GepObjVarMap[std::make_pair(base, apOffset)] = gepId; - GepObjVar *node = new GepObjVar(obj, gepId, apOffset); + //ABTest + GepObjVar *node = new GepObjVar(baseObj, gepId, apOffset); memToFieldsMap[base].set(gepId); - return addObjNode(obj->getValue(), node, gepId); -} - -/*! - * Add a field-insensitive node, this method can only invoked by getFIGepObjNode - */ -NodeID SVFIR::addFIObjNode(const MemObj* obj) -{ - //assert(findPAGNode(i) == false && "this node should not be created before"); - NodeID base = obj->getId(); - memToFieldsMap[base].set(obj->getId()); - BaseObjVar*node = new BaseObjVar(obj->getValue(), obj->getId(), obj); - return addObjNode(obj->getValue(), node, obj->getId()); -} - -NodeID SVFIR::addFunObjNode(NodeID id, const CallGraphNode* callGraphNode) -{ - const MemObj* mem = getMemObj(callGraphNode->getFunction()); - assert(mem->getId() == id && "not same object id?"); - //assert(findPAGNode(i) == false && "this node should not be created before"); - NodeID base = mem->getId(); - memToFieldsMap[base].set(mem->getId()); - FunObjVar*node = new FunObjVar(id, mem, callGraphNode); - return addObjNode(mem->getValue(), node, mem->getId()); + return addObjNode(baseObj->hasValue()? baseObj->getValue(): nullptr, node); } /*! * Get all fields object nodes of an object */ -NodeBS& SVFIR::getAllFieldsObjVars(const MemObj* obj) +NodeBS& SVFIR::getAllFieldsObjVars(const BaseObjVar* obj) { NodeID base = obj->getId(); return memToFieldsMap[base]; @@ -499,8 +477,7 @@ NodeBS& SVFIR::getAllFieldsObjVars(NodeID id) { const SVFVar* node = pag->getGNode(id); assert(SVFUtil::isa(node) && "need an object node"); - const ObjVar* obj = SVFUtil::cast(node); - return getAllFieldsObjVars(obj->getMemObj()); + return getAllFieldsObjVars(getBaseObject(id)); } /*! @@ -512,15 +489,15 @@ NodeBS SVFIR::getFieldsAfterCollapse(NodeID id) { const SVFVar* node = pag->getGNode(id); assert(SVFUtil::isa(node) && "need an object node"); - const MemObj* mem = SVFUtil::cast(node)->getMemObj(); - if(mem->isFieldInsensitive()) + const BaseObjVar* obj = getBaseObject(id); + if(obj->isFieldInsensitive()) { NodeBS bs; - bs.set(getFIObjVar(mem)); + bs.set(getFIObjVar(obj)); return bs; } else - return getAllFieldsObjVars(mem); + return getAllFieldsObjVars(obj); } /*! diff --git a/svf/lib/SVFIR/SVFVariables.cpp b/svf/lib/SVFIR/SVFVariables.cpp index 8fcec4d6d..76613a2d7 100644 --- a/svf/lib/SVFIR/SVFVariables.cpp +++ b/svf/lib/SVFIR/SVFVariables.cpp @@ -232,13 +232,6 @@ const std::string BaseObjVar::toString() const return rawstr.str(); } -HeapObjVar::HeapObjVar(NodeID i, const MemObj* mem, const SVFType* svfType, - const SVFFunction* f, PNODEK ty) - : BaseObjVar(mem->getValue(), i, mem, ty) -{ - isPtr = svfType->isPointerTy(); - func = f; -} const std::string HeapObjVar::toString() const { @@ -253,13 +246,6 @@ const std::string HeapObjVar::toString() const return rawstr.str(); } -StackObjVar::StackObjVar(NodeID i, const MemObj* mem, const SVFType* svfType, const SVFFunction* f, PNODEK ty) - : BaseObjVar(mem->getValue(), i, mem, ty) -{ - isPtr = svfType->isPointerTy(); - func = f; -} - const std::string StackObjVar::toString() const { std::string str; @@ -424,9 +410,9 @@ const std::string ConstantNullPtrObjVar::toString() const return rawstr.str(); } -FunObjVar::FunObjVar(NodeID i, const MemObj* mem, const CallGraphNode* cgNode, +FunObjVar::FunObjVar(const SVFValue* val, NodeID i, ObjTypeInfo* ti, const CallGraphNode* cgNode, PNODEK ty) - : BaseObjVar(mem->getValue(), i, mem, ty), callGraphNode(cgNode) + : BaseObjVar(val, i, ti, ty), callGraphNode(cgNode) { isPtr = callGraphNode->getFunction()->getType()->isPointerTy(); } @@ -436,6 +422,11 @@ bool FunObjVar::isIsolatedNode() const return callGraphNode->getFunction()->isIntrinsic(); } +const SVFFunction* FunObjVar::getFunction() const +{ + return callGraphNode->getFunction(); +} + const std::string FunObjVar::toString() const { std::string str; diff --git a/svf/lib/SVFIR/SymbolTableInfo.cpp b/svf/lib/SVFIR/SymbolTableInfo.cpp index 23acf9249..f13b5debb 100644 --- a/svf/lib/SVFIR/SymbolTableInfo.cpp +++ b/svf/lib/SVFIR/SymbolTableInfo.cpp @@ -91,7 +91,7 @@ SymbolTableInfo* SymbolTableInfo::SymbolInfo() /*! * Get modulus offset given the type information */ -APOffset SymbolTableInfo::getModulusOffset(const MemObj* obj, const APOffset& apOffset) +APOffset SymbolTableInfo::getModulusOffset(const BaseObjVar* baseObj, const APOffset& apOffset) { /// if the offset is negative, it's possible that we're looking for an obj node out of range @@ -104,7 +104,7 @@ APOffset SymbolTableInfo::getModulusOffset(const MemObj* obj, const APOffset& ap writeWrnMsg("try to create a gep node with negative offset."); offset = abs(offset); } - u32_t maxOffset = obj->getMaxFieldOffsetLimit(); + u32_t maxOffset = baseObj->getMaxFieldOffsetLimit(); /*! * @offset: the index allocated to the newly generated field node; @@ -143,10 +143,10 @@ APOffset SymbolTableInfo::getModulusOffset(const MemObj* obj, const APOffset& ap void SymbolTableInfo::destroy() { - for (auto &pair: objMap) + for (auto &pair: objTypeInfoMap) { - if (MemObj* memObj = pair.second) - delete memObj; + if (ObjTypeInfo* ti = pair.second) + delete ti; } for (const SVFType* type : svfTypes) @@ -160,12 +160,14 @@ void SymbolTableInfo::destroy() mod = nullptr; } -const MemObj* SymbolTableInfo::createDummyObj(SymID symId, const SVFType* type) +const ObjTypeInfo* SymbolTableInfo::createDummyObjTypeInfo(SymID symId, const SVFType* type) { - assert(objMap.find(symId)==objMap.end() && "this dummy obj has been created before"); - MemObj* memObj = new MemObj(symId, createObjTypeInfo(type)); - objMap[symId] = memObj; - return memObj; + if (objTypeInfoMap.find(symId)==objTypeInfoMap.end()) { + ObjTypeInfo* ti = createObjTypeInfo(type); + objTypeInfoMap[symId] = ti; + } + ObjTypeInfo* ti = objTypeInfoMap[symId]; + return ti; } /// Number of flattened elements of an array or struct @@ -362,161 +364,6 @@ void SymbolTableInfo::dump() outs() << "}\n"; } -/*! - * Set mem object to be field sensitive (up to maximum field limit) - */ -void MemObj::setFieldSensitive() -{ - typeInfo->setMaxFieldOffsetLimit(typeInfo->getNumOfElements()); -} - - -/*! - * Constructor of a memory object - */ -MemObj::MemObj(SymID id, ObjTypeInfo* ti, const SVFValue* val, const SVFBaseNode* node) : - typeInfo(ti), refVal(val), symId(id), gNode(node) -{ -} - -/*! - * Whether it is a black hole object - */ -bool MemObj::isBlackHoleObj() const -{ - return SymbolTableInfo::isBlkObj(getId()); -} - -/// Get the number of elements of this object -u32_t MemObj::getNumOfElements() const -{ - return typeInfo->getNumOfElements(); -} - -/// Get the byte size of this object -u32_t MemObj::getByteSizeOfObj() const -{ - return typeInfo->getByteSizeOfObj(); -} - -/// Check if byte size is static determined -bool MemObj::isConstantByteSize() const -{ - return typeInfo->isConstantByteSize(); -} - - -/// Set the number of elements of this object -void MemObj::setNumOfElements(u32_t num) -{ - return typeInfo->setNumOfElements(num); -} - -/// Get obj type info -const SVFType* MemObj::getType() const -{ - return typeInfo->getType(); -} -/* - * Destroy the fields of the memory object - */ -void MemObj::destroy() -{ - delete typeInfo; - typeInfo = nullptr; -} - -/// Get max field offset limit -u32_t MemObj::getMaxFieldOffsetLimit() const -{ - return typeInfo->getMaxFieldOffsetLimit(); -} - -/// Return true if its field limit is 0 -bool MemObj::isFieldInsensitive() const -{ - return getMaxFieldOffsetLimit() == 0; -} - -/// Set the memory object to be field insensitive -void MemObj::setFieldInsensitive() -{ - typeInfo->setMaxFieldOffsetLimit(0); -} - -bool MemObj::isFunction() const -{ - return typeInfo->isFunction(); -} - -bool MemObj::isGlobalObj() const -{ - return typeInfo->isGlobalObj(); -} - -bool MemObj::isStaticObj() const -{ - return typeInfo->isStaticObj(); -} - -bool MemObj::isStack() const -{ - return typeInfo->isStack(); -} - -bool MemObj::isHeap() const -{ - return typeInfo->isHeap(); -} - -bool MemObj::isStruct() const -{ - return typeInfo->isStruct(); -} - -bool MemObj::isArray() const -{ - return typeInfo->isArray(); -} - -bool MemObj::isVarStruct() const -{ - return typeInfo->isVarStruct(); -} - -bool MemObj::isVarArray() const -{ - return typeInfo->isVarArray(); -} - -bool MemObj::isConstantStruct() const -{ - return typeInfo->isConstantStruct(); -} - -bool MemObj::isConstantArray() const -{ - return typeInfo->isConstantArray(); -} - -bool MemObj::isConstDataOrConstGlobal() const -{ - return typeInfo->isConstDataOrConstGlobal(); -} - -bool MemObj::isConstDataOrAggData() const -{ - return typeInfo->isConstDataOrAggData(); -} - - -const std::string MemObj::toString() const -{ - std::string str; - std::stringstream rawstr(str); - rawstr << "MemObj : " << getId() << getValue()->toString() << "\n"; - return rawstr.str(); -} /// Get different kinds of syms //@{ diff --git a/svf/lib/Util/SVFStat.cpp b/svf/lib/Util/SVFStat.cpp index a6936bd6e..02867ce19 100644 --- a/svf/lib/Util/SVFStat.cpp +++ b/svf/lib/Util/SVFStat.cpp @@ -133,7 +133,7 @@ void SVFStat::performStat() PAGNode* node = it->second; if(ObjVar* obj = SVFUtil::dyn_cast(node)) { - const MemObj* mem = obj->getMemObj(); + const BaseObjVar* mem = pag->getBaseObject(obj->getId()); if (memObjSet.insert(mem->getId()).second == false) continue; if(mem->isBlackHoleObj()) diff --git a/svf/lib/WPA/AndersenSFR.cpp b/svf/lib/WPA/AndersenSFR.cpp index 8161baeab..c6525be82 100644 --- a/svf/lib/WPA/AndersenSFR.cpp +++ b/svf/lib/WPA/AndersenSFR.cpp @@ -131,8 +131,10 @@ void AndersenSFR::fieldExpand(NodeSet& initials, APOffset offset, NodeBS& stride else { PAGNode* initPN = pag->getGNode(init); - const MemObj* obj = pag->getBaseObj(init); - const u32_t maxLimit = obj->getMaxFieldOffsetLimit(); + // ABTest + const BaseObjVar* baseObj = pag->getBaseObject(init); + + const u32_t maxLimit = baseObj->getMaxFieldOffsetLimit(); APOffset initOffset; if (GepObjVar *gepNode = SVFUtil::dyn_cast(initPN)) initOffset = gepNode->getConstantFieldIdx(); diff --git a/svf/lib/WPA/FlowSensitive.cpp b/svf/lib/WPA/FlowSensitive.cpp index 9d523c35d..200f36c47 100644 --- a/svf/lib/WPA/FlowSensitive.cpp +++ b/svf/lib/WPA/FlowSensitive.cpp @@ -670,11 +670,12 @@ bool FlowSensitive::isStrongUpdate(const SVFGNode* node, NodeID& singleton) singleton = *it; // Strong update can be made if this points-to target is not heap, array or field-insensitive. - if (!isHeapMemObj(singleton) && !isArrayMemObj(singleton) - && pag->getBaseObj(singleton)->isFieldInsensitive() == false - && !isLocalVarInRecursiveFun(singleton)) - { - isSU = true; + if (!isHeapMemObj(singleton) && !isArrayMemObj(singleton)) { + assert(pag->getBaseObject(singleton)->isFieldInsensitive() == pag->getBaseObject(singleton)->isFieldInsensitive()); + if (pag->getBaseObject(singleton)->isFieldInsensitive() == false + && !isLocalVarInRecursiveFun(singleton)) { + isSU = true; + } } } } diff --git a/svf/lib/WPA/FlowSensitiveStat.cpp b/svf/lib/WPA/FlowSensitiveStat.cpp index ef98c4190..ceaa6a878 100644 --- a/svf/lib/WPA/FlowSensitiveStat.cpp +++ b/svf/lib/WPA/FlowSensitiveStat.cpp @@ -108,11 +108,11 @@ void FlowSensitiveStat::performStat() PAGNode* pagNode = nodeIt->second; if(SVFUtil::isa(pagNode)) { - const MemObj * memObj = pag->getBaseObj(nodeId); - SymID baseId = memObj->getId(); + const BaseObjVar* baseObj = pag->getBaseObject(nodeId); + SymID baseId = baseObj->getId(); if (nodeSet.insert(baseId).second) { - if (memObj->isFieldInsensitive()) + if (baseObj->isFieldInsensitive()) fiObjNumber++; else fsObjNumber++; diff --git a/svf/lib/WPA/VersionedFlowSensitive.cpp b/svf/lib/WPA/VersionedFlowSensitive.cpp index 4f094632b..551bf000a 100644 --- a/svf/lib/WPA/VersionedFlowSensitive.cpp +++ b/svf/lib/WPA/VersionedFlowSensitive.cpp @@ -783,8 +783,9 @@ void VersionedFlowSensitive::cluster(void) for (SVFIR::iterator pit = pag->begin(); pit != pag->end(); ++pit) { unsigned occ = 1; + //ABTest unsigned v = pit->first; - if (Options::PredictPtOcc() && pag->getObject(v) != nullptr) occ = stmtReliance[v].size() + 1; + if (Options::PredictPtOcc() && pag->getBaseObject(v) != nullptr) occ = stmtReliance[v].size() + 1; assert(occ != 0); keys.push_back(std::make_pair(v, occ)); } diff --git a/svf/lib/WPA/VersionedFlowSensitiveStat.cpp b/svf/lib/WPA/VersionedFlowSensitiveStat.cpp index 042652cd7..163bccc89 100644 --- a/svf/lib/WPA/VersionedFlowSensitiveStat.cpp +++ b/svf/lib/WPA/VersionedFlowSensitiveStat.cpp @@ -55,11 +55,11 @@ void VersionedFlowSensitiveStat::performStat() PAGNode* pagNode = it->second; if (SVFUtil::isa(pagNode)) { - const MemObj *memObj = pag->getBaseObj(nodeId); - SymID baseId = memObj->getId(); + const BaseObjVar* baseObj = pag->getBaseObject(nodeId); + SymID baseId = baseObj->getId(); if (nodeSet.insert(baseId).second) { - if (memObj->isFieldInsensitive()) fiObjNumber++; + if (baseObj->isFieldInsensitive()) fiObjNumber++; else fsObjNumber++; } }