diff --git a/svf/include/DDA/DDAVFSolver.h b/svf/include/DDA/DDAVFSolver.h index 7edff0036..aae782f26 100644 --- a/svf/include/DDA/DDAVFSolver.h +++ b/svf/include/DDA/DDAVFSolver.h @@ -189,17 +189,23 @@ class DDAVFSolver backtraceAlongDirectVF(gepPts,dpm); unionDDAPts(pts, processGepPts(SVFUtil::cast(node),gepPts)); } - else if(SVFUtil::isa(node)) + else if(const LoadSVFGNode* load = SVFUtil::dyn_cast(node)) { + if(load->getPAGDstNode()->isPointer() == false) + return; + CPtSet loadpts; startNewPTCompFromLoadSrc(loadpts,dpm); for(typename CPtSet::iterator it = loadpts.begin(), eit = loadpts.end(); it!=eit; ++it) { - backtraceAlongIndirectVF(pts,getDPImWithOldCond(dpm,*it,node)); + backtraceAlongIndirectVF(pts,getDPImWithOldCond(dpm,*it,load)); } } - else if(SVFUtil::isa(node)) + else if(const StoreSVFGNode* store = SVFUtil::dyn_cast(node)) { + if(store->getPAGSrcNode()->isPointer() == false) + return; + if(isMustAlias(getLoadDpm(dpm),dpm)) { DBOUT(DDDA, SVFUtil::outs() << "+++must alias for load and store:"); @@ -217,17 +223,17 @@ class DDAVFSolver { if(propagateViaObj(*it,getLoadCVar(dpm))) { - backtraceToStoreSrc(pts,getDPImWithOldCond(dpm,*it,node)); + backtraceToStoreSrc(pts,getDPImWithOldCond(dpm,*it,store)); - if(isStrongUpdate(storepts,SVFUtil::cast(node))) + if(isStrongUpdate(storepts,store)) { DBOUT(DDDA, SVFUtil::outs() << "backward strong update for obj " << dpm.getCurNodeID() << "\n"); - DOSTAT(addSUStat(dpm,node);) + DOSTAT(addSUStat(dpm,store);) } else { - DOSTAT(rmSUStat(dpm,node);) - backtraceAlongIndirectVF(pts,getDPImWithOldCond(dpm,*it,node)); + DOSTAT(rmSUStat(dpm,store);) + backtraceAlongIndirectVF(pts,getDPImWithOldCond(dpm,*it,store)); } } else @@ -347,7 +353,7 @@ class DDAVFSolver { const SVFGNode* node = oldDpm.getLoc(); NodeID obj = oldDpm.getCurNodeID(); - if (_pag->isConstantObj(obj) || _pag->isNonPointerObj(obj)) + if (_pag->isConstantObj(obj)) return; const SVFGEdgeSet edgeSet(node->getInEdges()); for (SVFGNode::const_iterator it = edgeSet.begin(), eit = edgeSet.end(); it != eit; ++it) diff --git a/svf/include/MemoryModel/PointerAnalysis.h b/svf/include/MemoryModel/PointerAnalysis.h index 12744ece8..76cde0f6f 100644 --- a/svf/include/MemoryModel/PointerAnalysis.h +++ b/svf/include/MemoryModel/PointerAnalysis.h @@ -301,10 +301,6 @@ class PointerAnalysis { return pag->isBlkObjOrConstantObj(ptd); } - inline bool isNonPointerObj(NodeID ptd) const - { - return pag->isNonPointerObj(ptd); - } //@} /// Whether this object is heap or array diff --git a/svf/include/SVFIR/SVFIR.h b/svf/include/SVFIR/SVFIR.h index 47c416da5..60e96bb5b 100644 --- a/svf/include/SVFIR/SVFIR.h +++ b/svf/include/SVFIR/SVFIR.h @@ -434,8 +434,6 @@ class SVFIR : public IRGraph return SymbolTableInfo::isConstantObj(id) || obj->isConstDataOrConstGlobal(); } - /// Whether an object can point to any other object or any of its fields is a pointer type. - bool isNonPointerObj(NodeID id) const; //@} /// Base and Offset methods for Value and Object node diff --git a/svf/include/SVFIR/SymbolTableInfo.h b/svf/include/SVFIR/SymbolTableInfo.h index 114c45b76..f72e45417 100644 --- a/svf/include/SVFIR/SymbolTableInfo.h +++ b/svf/include/SVFIR/SymbolTableInfo.h @@ -461,7 +461,6 @@ class MemObj bool isConstDataOrConstGlobal() const; bool isConstDataOrAggData() const; bool hasPtrObj() const; - bool isNonPtrFieldObj(const APOffset& apOffset) const; //@} /// Operator overloading @@ -651,7 +650,6 @@ class ObjTypeInfo { return hasFlag(HASPTR_OBJ); } - virtual bool isNonPtrFieldObj(const APOffset& apOffset); //@} }; diff --git a/svf/lib/SVFIR/SVFIR.cpp b/svf/lib/SVFIR/SVFIR.cpp index fb8a0e83d..965fa3c3a 100644 --- a/svf/lib/SVFIR/SVFIR.cpp +++ b/svf/lib/SVFIR/SVFIR.cpp @@ -669,31 +669,6 @@ void SVFIR::initialiseCandidatePointers() candidatePointers.insert(nodeId); } } -/*! - * Return true if FIObjVar can point to any object - * Or a field GepObjVar can point to any object. - */ -bool SVFIR::isNonPointerObj(NodeID id) const -{ - SVFVar* node = getGNode(id); - if (const FIObjVar* fiNode = SVFUtil::dyn_cast(node)) - { - return (fiNode->getMemObj()->hasPtrObj()==false); - } - else if (const GepObjVar* gepNode = SVFUtil::dyn_cast(node)) - { - return (gepNode->getMemObj()->isNonPtrFieldObj(gepNode->getConstantFieldIdx())); - } - else if (const DummyObjVar* dummyNode = SVFUtil::dyn_cast(node)) - { - return (dummyNode->getMemObj()->hasPtrObj()==false); - } - else - { - assert(false && "expecting a object node"); - abort(); - } -} /* * If this is a dummy node or node does not have incoming edges and outgoing edges we assume it is not a pointer here. * However, if it is a pointer and it is an argument of a function definition, we assume it is a pointer here. diff --git a/svf/lib/SVFIR/SymbolTableInfo.cpp b/svf/lib/SVFIR/SymbolTableInfo.cpp index 8f9f33e53..86024eb23 100644 --- a/svf/lib/SVFIR/SymbolTableInfo.cpp +++ b/svf/lib/SVFIR/SymbolTableInfo.cpp @@ -362,39 +362,6 @@ void SymbolTableInfo::dump() outs() << "}\n"; } -/*! - * Whether a location set is a pointer type or not - */ -bool ObjTypeInfo::isNonPtrFieldObj(const APOffset& apOffset) -{ - if (hasPtrObj() == false) - return true; - - const SVFType* ety = type; - - if (SVFUtil::isa(ety)) - { - u32_t sz = 0; - if(Options::ModelArrays()) - sz = SymbolTableInfo::SymbolInfo()->getTypeInfo(ety)->getFlattenElementTypes().size(); - else - sz = SymbolTableInfo::SymbolInfo()->getTypeInfo(ety)->getFlattenFieldTypes().size(); - - if(sz <= (u32_t) apOffset) - { - writeWrnMsg("out of bound error when accessing the struct/array"); - return false; - } - - const SVFType* elemTy = SymbolTableInfo::SymbolInfo()->getFlatternedElemType(ety, apOffset); - return (elemTy->isPointerTy() == false); - } - else - { - return (hasPtrObj() == false); - } -} - /*! * Set mem object to be field sensitive (up to maximum field limit) */ @@ -547,11 +514,6 @@ bool MemObj::hasPtrObj() const return typeInfo->hasPtrObj(); } -bool MemObj::isNonPtrFieldObj(const APOffset& apOffset) const -{ - return typeInfo->isNonPtrFieldObj(apOffset); -} - const std::string MemObj::toString() const { std::string str; diff --git a/svf/lib/WPA/Andersen.cpp b/svf/lib/WPA/Andersen.cpp index 86196d773..7dc6806af 100644 --- a/svf/lib/WPA/Andersen.cpp +++ b/svf/lib/WPA/Andersen.cpp @@ -351,8 +351,8 @@ bool Andersen::processLoad(NodeID node, const ConstraintEdge* load) /// TODO: New copy edges are also added for black hole obj node to /// make gcc in spec 2000 pass the flow-sensitive analysis. /// Try to handle black hole obj in an appropriate way. -// if (pag->isBlkObjOrConstantObj(node) || isNonPointerObj(node)) - if (pag->isConstantObj(node) || isNonPointerObj(node)) +// if (pag->isBlkObjOrConstantObj(node)) + if (pag->isConstantObj(node) || pag->getGNode(load->getDstID())->isPointer() == false) return false; numOfProcessedLoad++; @@ -371,8 +371,8 @@ bool Andersen::processStore(NodeID node, const ConstraintEdge* store) /// TODO: New copy edges are also added for black hole obj node to /// make gcc in spec 2000 pass the flow-sensitive analysis. /// Try to handle black hole obj in an appropriate way -// if (pag->isBlkObjOrConstantObj(node) || isNonPointerObj(node)) - if (pag->isConstantObj(node) || isNonPointerObj(node)) +// if (pag->isBlkObjOrConstantObj(node)) + if (pag->isConstantObj(node) || pag->getGNode(store->getSrcID())->isPointer() == false) return false; numOfProcessedStore++; diff --git a/svf/lib/WPA/FlowSensitive.cpp b/svf/lib/WPA/FlowSensitive.cpp index fa158645a..4c8e8d5e6 100644 --- a/svf/lib/WPA/FlowSensitive.cpp +++ b/svf/lib/WPA/FlowSensitive.cpp @@ -557,30 +557,33 @@ bool FlowSensitive::processLoad(const LoadSVFGNode* load) NodeID dstVar = load->getPAGDstNodeID(); const PointsTo& srcPts = getPts(load->getPAGSrcNodeID()); - for (PointsTo::iterator ptdIt = srcPts.begin(); ptdIt != srcPts.end(); ++ptdIt) - { - NodeID ptd = *ptdIt; - if (pag->isConstantObj(ptd) || pag->isNonPointerObj(ptd)) - continue; + // p = *q, the type of p must be a pointer + if(load->getPAGDstNode()->isPointer()) { + for (PointsTo::iterator ptdIt = srcPts.begin(); ptdIt != srcPts.end(); ++ptdIt) + { + NodeID ptd = *ptdIt; - if (unionPtsFromIn(load, ptd, dstVar)) - changed = true; + if (pag->isConstantObj(ptd)) + continue; - if (isFieldInsensitive(ptd)) - { - /// If the ptd is a field-insensitive node, we should also get all field nodes' - /// points-to sets and pass them to pagDst. - const NodeBS& allFields = getAllFieldsObjVars(ptd); - for (NodeBS::iterator fieldIt = allFields.begin(), fieldEit = allFields.end(); - fieldIt != fieldEit; ++fieldIt) + if (unionPtsFromIn(load, ptd, dstVar)) + changed = true; + + if (isFieldInsensitive(ptd)) { - if (unionPtsFromIn(load, *fieldIt, dstVar)) - changed = true; + /// If the ptd is a field-insensitive node, we should also get all field nodes' + /// points-to sets and pass them to pagDst. + const NodeBS& allFields = getAllFieldsObjVars(ptd); + for (NodeBS::iterator fieldIt = allFields.begin(), fieldEit = allFields.end(); + fieldIt != fieldEit; ++fieldIt) + { + if (unionPtsFromIn(load, *fieldIt, dstVar)) + changed = true; + } } } } - double end = stat->getClk(); loadTime += (end - start) / TIMEINTERVAL; return changed; @@ -609,13 +612,14 @@ bool FlowSensitive::processStore(const StoreSVFGNode* store) double start = stat->getClk(); bool changed = false; - if(getPts(store->getPAGSrcNodeID()).empty() == false) + // *p = q, the type of q must be a pointer + if(getPts(store->getPAGSrcNodeID()).empty() == false && store->getPAGSrcNode()->isPointer()) { for (PointsTo::iterator it = dstPts.begin(), eit = dstPts.end(); it != eit; ++it) { NodeID ptd = *it; - if (pag->isConstantObj(ptd) || pag->isNonPointerObj(ptd)) + if (pag->isConstantObj(ptd)) continue; if (unionPtsFromTop(store, store->getPAGSrcNodeID(), ptd)) diff --git a/svf/lib/WPA/VersionedFlowSensitive.cpp b/svf/lib/WPA/VersionedFlowSensitive.cpp index 216e5f794..42c7ae996 100644 --- a/svf/lib/WPA/VersionedFlowSensitive.cpp +++ b/svf/lib/WPA/VersionedFlowSensitive.cpp @@ -656,32 +656,34 @@ bool VersionedFlowSensitive::processLoad(const LoadSVFGNode* load) NodeID q = load->getPAGSrcNodeID(); const PointsTo& qpt = getPts(q); - for (NodeID o : qpt) - { - if (pag->isConstantObj(o) || pag->isNonPointerObj(o)) continue; - - const Version c = getConsume(l, o); - if (c != invalidVersion && vPtD->unionPts(p, atKey(o, c))) + // p = *q, the type of p must be a pointer + if (load->getPAGDstNode()->isPointer()) { + for (NodeID o : qpt) { - changed = true; - } + if (pag->isConstantObj(o)) continue; - if (isFieldInsensitive(o)) - { - /// If o is a field-insensitive object, we should also get all field nodes' - /// points-to sets and pass them to p. - const NodeBS& fields = getAllFieldsObjVars(o); - for (NodeID of : fields) + const Version c = getConsume(l, o); + if (c != invalidVersion && vPtD->unionPts(p, atKey(o, c))) { - const Version c = getConsume(l, of); - if (c != invalidVersion && vPtD->unionPts(p, atKey(of, c))) + changed = true; + } + + if (isFieldInsensitive(o)) + { + /// If o is a field-insensitive object, we should also get all field nodes' + /// points-to sets and pass them to p. + const NodeBS& fields = getAllFieldsObjVars(o); + for (NodeID of : fields) { - changed = true; + const Version c = getConsume(l, of); + if (c != invalidVersion && vPtD->unionPts(p, atKey(of, c))) + { + changed = true; + } } } } } - double end = stat->getClk(); loadTime += (end - start) / TIMEINTERVAL; return changed; @@ -707,15 +709,18 @@ bool VersionedFlowSensitive::processStore(const StoreSVFGNode* store) if (!qpt.empty()) { - for (NodeID o : ppt) - { - if (pag->isConstantObj(o) || pag->isNonPointerObj(o)) continue; - - const Version y = getYield(l, o); - if (y != invalidVersion && vPtD->unionPts(atKey(o, y), q)) + // *p = q, the type of q must be a pointer + if (store->getPAGSrcNode()->isPointer()) { + for (NodeID o : ppt) { - changed = true; - changedObjects.set(o); + if (pag->isConstantObj(o)) continue; + + const Version y = getYield(l, o); + if (y != invalidVersion && vPtD->unionPts(atKey(o, y), q)) + { + changed = true; + changedObjects.set(o); + } } } }