3434#include " Graphs/CallGraph.h"
3535#include " WPA/Andersen.h"
3636#include < cmath>
37+ #include < deque>
3738
3839using namespace SVF ;
3940using namespace SVFUtil ;
@@ -163,9 +164,10 @@ void AbstractInterpretation::initWTO()
163164}
164165
165166// / Collect all entry point functions (functions without callers)
166- std::vector<const FunObjVar*> AbstractInterpretation::collectEntryFunctions ()
167+ // / Uses a deque to allow efficient insertion at front for prioritizing main()
168+ std::deque<const FunObjVar*> AbstractInterpretation::collectProgEntryFuns ()
167169{
168- std::vector <const FunObjVar*> entryFunctions;
170+ std::deque <const FunObjVar*> entryFunctions;
169171 const CallGraph* callGraph = svfir->getCallGraph ();
170172
171173 for (auto it = callGraph->begin (); it != callGraph->end (); ++it)
@@ -180,18 +182,18 @@ std::vector<const FunObjVar*> AbstractInterpretation::collectEntryFunctions()
180182 // Check if function has no callers (entry point)
181183 if (cgNode->getInEdges ().empty ())
182184 {
183- entryFunctions.push_back (fun);
185+ // If main exists, put it first for priority using deque's push_front
186+ if (fun->getName () == " main" )
187+ {
188+ entryFunctions.push_front (fun);
189+ }
190+ else
191+ {
192+ entryFunctions.push_back (fun);
193+ }
184194 }
185195 }
186196
187- // If main exists, put it first for priority
188- auto mainIt = std::find_if (entryFunctions.begin (), entryFunctions.end (),
189- [](const FunObjVar* f) { return f->getName () == " main" ; });
190- if (mainIt != entryFunctions.end () && mainIt != entryFunctions.begin ())
191- {
192- std::iter_swap (entryFunctions.begin (), mainIt);
193- }
194-
195197 return entryFunctions;
196198}
197199
@@ -207,14 +209,12 @@ void AbstractInterpretation::analyse()
207209 initWTO ();
208210 // handle Global ICFGNode of SVFModule
209211 handleGlobalNode ();
210- getAbsStateFromTrace (
211- icfg->getGlobalICFGNode ())[PAG::getPAG ()->getBlkPtr ()] = IntervalValue::top ();
212212
213213 // If -ae-multientry is set, always use multi-entry analysis
214214 if (Options::AEMultiEntry ())
215215 {
216216 SVFUtil::outs () << " Multi-entry analysis enabled, analyzing from all entry points...\n " ;
217- analyseFromAllEntries ();
217+ analyzeFromAllProgEntries ();
218218 return ;
219219 }
220220
@@ -229,17 +229,17 @@ void AbstractInterpretation::analyse()
229229 {
230230 // No main function found, analyze from all entry points (library code)
231231 SVFUtil::outs () << " No main function found, analyzing from all entry points...\n " ;
232- analyseFromAllEntries ();
232+ analyzeFromAllProgEntries ();
233233 }
234234}
235235
236236// / Analyze all entry points (functions without callers) - for whole-program analysis without main
237- void AbstractInterpretation::analyseFromAllEntries ()
237+ void AbstractInterpretation::analyzeFromAllProgEntries ()
238238{
239239 initWTO ();
240240
241241 // Collect all entry point functions
242- std::vector <const FunObjVar*> entryFunctions = collectEntryFunctions ();
242+ std::deque <const FunObjVar*> entryFunctions = collectProgEntryFuns ();
243243
244244 if (entryFunctions.empty ())
245245 {
@@ -255,8 +255,6 @@ void AbstractInterpretation::analyseFromAllEntries()
255255
256256 // Handle global node for each entry (global state is shared across entries)
257257 handleGlobalNode ();
258- getAbsStateFromTrace (
259- icfg->getGlobalICFGNode ())[PAG::getPAG ()->getBlkPtr ()] = IntervalValue::top ();
260258
261259 // Analyze from this entry function
262260 const ICFGNode* funEntry = icfg->getFunEntryICFGNode (entryFun);
@@ -265,16 +263,25 @@ void AbstractInterpretation::analyseFromAllEntries()
265263}
266264
267265// / handle global node
266+ // / Initializes the abstract state for the global ICFG node and processes all global statements.
267+ // / This includes setting up the null pointer and black hole pointer (blkPtr) to top value,
268+ // / which represents unknown/uninitialized memory that can point to any location.
268269void AbstractInterpretation::handleGlobalNode ()
269270{
270271 const ICFGNode* node = icfg->getGlobalICFGNode ();
271272 abstractTrace[node] = AbstractState ();
272273 abstractTrace[node][IRGraph::NullPtr] = AddressValue ();
274+
273275 // Global Node, we just need to handle addr, load, store, copy and gep
274276 for (const SVFStmt *stmt: node->getSVFStmts ())
275277 {
276278 handleSVFStatement (stmt);
277279 }
280+
281+ // Set black hole pointer to top value - this represents unknown/uninitialized
282+ // memory locations that may point anywhere. This is essential for soundness
283+ // when analyzing code where pointers may not be fully initialized.
284+ abstractTrace[node][PAG::getPAG ()->getBlkPtr ()] = IntervalValue::top ();
278285}
279286
280287// / get execution state by merging states of predecessor blocks
0 commit comments