svf-tools 1.0.999 → 1.0.1001

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "svf-tools",
3
- "version": "1.0.999",
3
+ "version": "1.0.1001",
4
4
  "description": "* <b>[TypeClone](https://github.com/SVF-tools/SVF/wiki/TypeClone) published in our [ECOOP paper](https://yuleisui.github.io/publications/ecoop20.pdf) is now available in SVF </b> * <b>SVF now uses a single script for its build. Just type [`source ./build.sh`](https://github.com/SVF-tools/SVF/blob/master/build.sh) in your terminal, that's it!</b> * <b>SVF now supports LLVM-10.0.0! </b> * <b>We thank [bsauce](https://github.com/bsauce) for writing a user manual of SVF ([link1](https://www.jianshu.com/p/068a08ec749c) and [link2](https://www.jianshu.com/p/777c30d4240e)) in Chinese </b> * <b>SVF now supports LLVM-9.0.0 (Thank [Byoungyoung Lee](https://github.com/SVF-tools/SVF/issues/142) for his help!). </b> * <b>SVF now supports a set of [field-sensitive pointer analyses](https://yuleisui.github.io/publications/sas2019a.pdf). </b> * <b>[Use SVF as an external lib](https://github.com/SVF-tools/SVF/wiki/Using-SVF-as-a-lib-in-your-own-tool) for your own project (Contributed by [Hongxu Chen](https://github.com/HongxuChen)). </b> * <b>SVF now supports LLVM-7.0.0. </b> * <b>SVF now supports Docker. [Try SVF in Docker](https://github.com/SVF-tools/SVF/wiki/Try-SVF-in-Docker)! </b> * <b>SVF now supports [LLVM-6.0.0](https://github.com/svf-tools/SVF/pull/38) (Contributed by [Jack Anthony](https://github.com/jackanth)). </b> * <b>SVF now supports [LLVM-4.0.0](https://github.com/svf-tools/SVF/pull/23) (Contributed by Jared Carlson. Thank [Jared](https://github.com/jcarlson23) and [Will](https://github.com/dtzWill) for their in-depth [discussions](https://github.com/svf-tools/SVF/pull/18) about updating SVF!) </b> * <b>SVF now supports analysis for C++ programs.</b> <br />",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -172,6 +172,49 @@ protected:
172
172
  }
173
173
  }
174
174
 
175
+ virtual inline IntraICFGNode* addIntraICFGNode(const SVFBasicBlock* bb, bool isRet)
176
+ {
177
+ IntraICFGNode* intraIcfgNode =
178
+ new IntraICFGNode(totalICFGNode++, bb, isRet);
179
+ addICFGNode(intraIcfgNode);
180
+ return intraIcfgNode;
181
+ }
182
+
183
+ virtual inline CallICFGNode* addCallICFGNode(
184
+ const SVFBasicBlock* bb, const SVFType* ty,
185
+ const SVFFunction* calledFunc, bool isVararg, bool isvcall,
186
+ s32_t vcallIdx, const std::string& funNameOfVcall)
187
+ {
188
+
189
+ CallICFGNode* callICFGNode =
190
+ new CallICFGNode(totalICFGNode++, bb, ty, calledFunc, isVararg,
191
+ isvcall, vcallIdx, funNameOfVcall);
192
+ addICFGNode(callICFGNode);
193
+ return callICFGNode;
194
+ }
195
+
196
+ virtual inline RetICFGNode* addRetICFGNode(CallICFGNode* call)
197
+ {
198
+ RetICFGNode* retICFGNode = new RetICFGNode(totalICFGNode++, call);
199
+ call->setRetICFGNode(retICFGNode);
200
+ addICFGNode(retICFGNode);
201
+ return retICFGNode;
202
+ }
203
+
204
+ virtual inline FunEntryICFGNode* addFunEntryICFGNode(const SVFFunction* svfFunc)
205
+ {
206
+ FunEntryICFGNode* sNode = new FunEntryICFGNode(totalICFGNode++,svfFunc);
207
+ addICFGNode(sNode);
208
+ return FunToFunEntryNodeMap[svfFunc] = sNode;
209
+ }
210
+
211
+ virtual inline FunExitICFGNode* addFunExitICFGNode(const SVFFunction* svfFunc)
212
+ {
213
+ FunExitICFGNode* sNode = new FunExitICFGNode(totalICFGNode++, svfFunc);
214
+ addICFGNode(sNode);
215
+ return FunToFunExitNodeMap[svfFunc] = sNode;
216
+ }
217
+
175
218
  /// Add a ICFG node
176
219
  virtual inline void addICFGNode(ICFGNode* node)
177
220
  {
@@ -428,19 +428,28 @@ public:
428
428
  typedef std::vector<const SVFVar *> ActualParmNodeVec;
429
429
 
430
430
  protected:
431
- const SVFInstruction* cs;
432
431
  const RetICFGNode* ret;
433
- ActualParmNodeVec APNodes;
432
+ ActualParmNodeVec APNodes; /// arguments
433
+ const SVFFunction* calledFunc; /// called function
434
+ bool isvararg; /// is variable argument
435
+ bool isVirCallInst; /// is virtual call inst
436
+ SVFVar* vtabPtr; /// virtual table pointer
437
+ s32_t virtualFunIdx; /// virtual function index of the virtual table(s) at a virtual call
438
+ std::string funNameOfVcall; /// the function name of this virtual call
434
439
 
435
440
  /// Constructor to create empty CallICFGNode (for SVFIRReader/deserialization)
436
- CallICFGNode(NodeID id) : InterICFGNode(id, FunCallBlock), cs{}, ret{} {}
441
+ CallICFGNode(NodeID id) : InterICFGNode(id, FunCallBlock), ret{} {}
437
442
 
438
443
  public:
439
- CallICFGNode(NodeID id, const SVFInstruction* c, const SVFType* ty)
440
- : InterICFGNode(id, FunCallBlock), cs(c), ret(nullptr)
444
+ CallICFGNode(NodeID id, const SVFBasicBlock* b, const SVFType* ty,
445
+ const SVFFunction* cf, bool iv, bool ivc, s32_t vfi,
446
+ const std::string& fnv)
447
+ : InterICFGNode(id, FunCallBlock), ret(nullptr), calledFunc(cf),
448
+ isvararg(iv), isVirCallInst(ivc), vtabPtr(nullptr),
449
+ virtualFunIdx(vfi), funNameOfVcall(fnv)
441
450
  {
442
- fun = cs->getFunction();
443
- bb = cs->getParent();
451
+ fun = b->getFunction();
452
+ bb = b;
444
453
  type = ty;
445
454
  }
446
455
 
@@ -472,7 +481,7 @@ public:
472
481
  /// Return true if this is an indirect call
473
482
  inline bool isIndirectCall() const
474
483
  {
475
- return nullptr == SVFUtil::cast<SVFCallInst>(cs)->getCalledFunction();
484
+ return nullptr == calledFunc;
476
485
  }
477
486
 
478
487
  /// Return the set of actual parameters
@@ -488,54 +497,61 @@ public:
488
497
  }
489
498
  /// Parameter operations
490
499
  //@{
491
- const SVFVar* getArgument(u32_t ArgNo) const
500
+ inline const SVFVar* getArgument(u32_t ArgNo) const
492
501
  {
493
502
  return getActualParms()[ArgNo];
494
503
  }
495
504
 
496
- u32_t arg_size() const
505
+ inline u32_t arg_size() const
497
506
  {
498
507
  return APNodes.size();
499
508
  }
500
- bool arg_empty() const
509
+ inline bool arg_empty() const
501
510
  {
502
511
  return APNodes.empty();
503
512
  }
504
513
 
505
- u32_t getNumArgOperands() const
514
+ inline u32_t getNumArgOperands() const
506
515
  {
507
516
  return arg_size();
508
517
  }
509
- const SVFFunction* getCalledFunction() const
518
+ inline const SVFFunction* getCalledFunction() const
510
519
  {
511
- return SVFUtil::cast<SVFCallInst>(cs)->getCalledFunction();
520
+ return calledFunc;
512
521
  }
513
- const SVFValue* getCalledValue() const
522
+
523
+ inline bool isVarArg() const
514
524
  {
515
- return SVFUtil::cast<SVFCallInst>(cs)->getCalledOperand();
525
+ return isvararg;
516
526
  }
517
- bool isVarArg() const
527
+ inline bool isVirtualCall() const
518
528
  {
519
- return SVFUtil::cast<SVFCallInst>(cs)->isVarArg();
529
+ return isVirCallInst;
520
530
  }
521
- bool isVirtualCall() const
531
+
532
+ inline void setVtablePtr(SVFVar* v)
522
533
  {
523
- return SVFUtil::isa<SVFVirtualCallInst>(cs);
534
+ vtabPtr = v;
524
535
  }
525
- const SVFValue* getVtablePtr() const
536
+
537
+ inline const SVFVar* getVtablePtr() const
526
538
  {
527
539
  assert(isVirtualCall() && "not a virtual call?");
528
- return SVFUtil::cast<SVFVirtualCallInst>(cs)->getVtablePtr();
540
+ return vtabPtr;
529
541
  }
530
- s32_t getFunIdxInVtable() const
542
+
543
+
544
+ inline s32_t getFunIdxInVtable() const
531
545
  {
532
546
  assert(isVirtualCall() && "not a virtual call?");
533
- return SVFUtil::cast<SVFVirtualCallInst>(cs)->getFunIdxInVtable();
547
+ assert(virtualFunIdx >=0 && "virtual function idx is less than 0? not set yet?");
548
+ return virtualFunIdx;
534
549
  }
535
- const std::string& getFunNameOfVirtualCall() const
550
+
551
+ inline const std::string& getFunNameOfVirtualCall() const
536
552
  {
537
553
  assert(isVirtualCall() && "not a virtual call?");
538
- return SVFUtil::cast<SVFVirtualCallInst>(cs)->getFunNameOfVirtualCall();
554
+ return funNameOfVcall;
539
555
  }
540
556
  //@}
541
557
 
@@ -585,23 +601,22 @@ class RetICFGNode : public InterICFGNode
585
601
  friend class SVFIRReader;
586
602
 
587
603
  private:
588
- const SVFInstruction* cs;
589
604
  const SVFVar *actualRet;
590
605
  const CallICFGNode* callBlockNode;
591
606
 
592
607
  /// Constructor to create empty RetICFGNode (for SVFIRReader/deserialization)
593
608
  RetICFGNode(NodeID id)
594
- : InterICFGNode(id, FunRetBlock), cs{}, actualRet{}, callBlockNode{}
609
+ : InterICFGNode(id, FunRetBlock), actualRet{}, callBlockNode{}
595
610
  {
596
611
  }
597
612
 
598
613
  public:
599
- RetICFGNode(NodeID id, const SVFInstruction* c, CallICFGNode* cb) :
600
- InterICFGNode(id, FunRetBlock), cs(c), actualRet(nullptr), callBlockNode(cb)
614
+ RetICFGNode(NodeID id, CallICFGNode* cb) :
615
+ InterICFGNode(id, FunRetBlock), actualRet(nullptr), callBlockNode(cb)
601
616
  {
602
- fun = cs->getFunction();
603
- bb = cs->getParent();
604
- type = callBlockNode->getType();
617
+ fun = cb->getFun();
618
+ bb = cb->getBB();
619
+ type = cb->getType();
605
620
  }
606
621
 
607
622
  inline const CallICFGNode* getCallICFGNode() const
@@ -44,9 +44,10 @@ void CFLAlias::onTheFlyCallGraphSolve(const CallSiteToFunPtrMap& callsites, Call
44
44
 
45
45
  if (cs->isVirtualCall())
46
46
  {
47
- const SVFValue* vtbl = cs->getVtablePtr();
48
- assert(pag->hasValueNode(vtbl));
49
- NodeID vtblId = pag->getValueNode(vtbl);
47
+ const SVFVar* vtbl = cs->getVtablePtr();
48
+
49
+ assert(vtbl != nullptr);
50
+ NodeID vtblId = vtbl->getId();
50
51
  resolveCPPIndCalls(cs, getCFLPts(vtblId), newEdges);
51
52
  }
52
53
  else
@@ -83,9 +83,9 @@ OrderedNodeSet& FunptrDDAClient::collectCandidateQueries(SVFIR* p)
83
83
  {
84
84
  if (it->first->isVirtualCall())
85
85
  {
86
- const SVFValue* vtblPtr = it->first->getVtablePtr();
87
- assert(pag->hasValueNode(vtblPtr) && "not a vtable pointer?");
88
- NodeID vtblId = pag->getValueNode(vtblPtr);
86
+ const SVFVar* vtblPtr = it->first->getVtablePtr();
87
+ assert(vtblPtr != nullptr && "not a vtable pointer?");
88
+ NodeID vtblId = vtblPtr->getId();
89
89
  addCandidate(vtblId);
90
90
  vtableToCallSiteMap[vtblId] = it->first;
91
91
  }
@@ -497,9 +497,9 @@ void BVDataPTAImpl::onTheFlyCallGraphSolve(const CallSiteToFunPtrMap& callsites,
497
497
 
498
498
  if (cs->isVirtualCall())
499
499
  {
500
- const SVFValue* vtbl = cs->getVtablePtr();
501
- assert(pag->hasValueNode(vtbl));
502
- NodeID vtblId = pag->getValueNode(vtbl);
500
+ const SVFVar* vtbl = cs->getVtablePtr();
501
+ assert(vtbl != nullptr);
502
+ NodeID vtblId = vtbl->getId();
503
503
  resolveCPPIndCalls(cs, getPts(vtblId), newEdges);
504
504
  }
505
505
  else
@@ -412,7 +412,6 @@ cJSON* SVFIRWriter::contentToJson(const FunExitICFGNode* node)
412
412
  cJSON* SVFIRWriter::contentToJson(const CallICFGNode* node)
413
413
  {
414
414
  cJSON* root = contentToJson(static_cast<const ICFGNode*>(node));
415
- JSON_WRITE_FIELD(root, node, cs);
416
415
  JSON_WRITE_FIELD(root, node, ret);
417
416
  JSON_WRITE_FIELD(root, node, APNodes);
418
417
  return root;
@@ -421,7 +420,6 @@ cJSON* SVFIRWriter::contentToJson(const CallICFGNode* node)
421
420
  cJSON* SVFIRWriter::contentToJson(const RetICFGNode* node)
422
421
  {
423
422
  cJSON* root = contentToJson(static_cast<const ICFGNode*>(node));
424
- JSON_WRITE_FIELD(root, node, cs);
425
423
  JSON_WRITE_FIELD(root, node, actualRet);
426
424
  JSON_WRITE_FIELD(root, node, callBlockNode);
427
425
  return root;
@@ -2205,7 +2203,6 @@ void SVFIRReader::fill(const cJSON*& fieldJson, FunExitICFGNode* node)
2205
2203
  void SVFIRReader::fill(const cJSON*& fieldJson, CallICFGNode* node)
2206
2204
  {
2207
2205
  fill(fieldJson, static_cast<ICFGNode*>(node));
2208
- JSON_READ_FIELD_FWD(fieldJson, node, cs);
2209
2206
  JSON_READ_FIELD_FWD(fieldJson, node, ret);
2210
2207
  JSON_READ_FIELD_FWD(fieldJson, node, APNodes);
2211
2208
  }
@@ -2213,7 +2210,6 @@ void SVFIRReader::fill(const cJSON*& fieldJson, CallICFGNode* node)
2213
2210
  void SVFIRReader::fill(const cJSON*& fieldJson, RetICFGNode* node)
2214
2211
  {
2215
2212
  fill(fieldJson, static_cast<ICFGNode*>(node));
2216
- JSON_READ_FIELD_FWD(fieldJson, node, cs);
2217
2213
  JSON_READ_FIELD_FWD(fieldJson, node, actualRet);
2218
2214
  JSON_READ_FIELD_FWD(fieldJson, node, callBlockNode);
2219
2215
  }
@@ -1,16 +1,10 @@
1
1
  #include "SVFIR/SVFValue.h"
2
2
  #include "Util/SVFUtil.h"
3
+ #include "Graphs/GenericGraph.h"
3
4
 
4
5
  using namespace SVF;
5
6
  using namespace SVFUtil;
6
7
 
7
- __attribute__((weak))
8
- std::string SVFValue::toString() const
9
- {
10
- assert("SVFValue::toString should be implemented or supported by fronted" && false);
11
- abort();
12
- }
13
-
14
8
  /// Add field (index and offset) with its corresponding type
15
9
  void StInfo::addFldWithType(u32_t fldIdx, const SVFType* type, u32_t elemIdx)
16
10
  {
@@ -274,3 +268,17 @@ SVFInstruction::SVFInstruction(const SVFType* ty, const SVFBasicBlock* b,
274
268
  : SVFValue(ty, k), bb(b), terminator(tm), ret(isRet)
275
269
  {
276
270
  }
271
+
272
+ __attribute__((weak))
273
+ std::string SVFValue::toString() const
274
+ {
275
+ assert("SVFValue::toString should be implemented or supported by fronted" && false);
276
+ abort();
277
+ }
278
+
279
+ __attribute__((weak))
280
+ const std::string SVFBaseNode::valueOnlyToString() const
281
+ {
282
+ assert("SVFBaseNode::valueOnlyToString should be implemented or supported by fronted" && false);
283
+ abort();
284
+ }
@@ -396,11 +396,4 @@ bool SVFUtil::isRetInstNode(const ICFGNode* node)
396
396
  bool SVFUtil::isProgExitCall(const CallICFGNode* cs)
397
397
  {
398
398
  return isProgExitFunction(cs->getCalledFunction());
399
- }
400
-
401
- __attribute__((weak))
402
- const std::string SVFBaseNode::valueOnlyToString() const
403
- {
404
- assert("SVFBaseNode::valueOnlyToString should be implemented or supported by fronted" && false);
405
- abort();
406
399
  }
@@ -79,9 +79,9 @@ void TypeAnalysis::callGraphSolveBasedOnCHA(const CallSiteToFunPtrMap& callsites
79
79
  const CallICFGNode* cbn = iter->first;
80
80
  if (cbn->isVirtualCall())
81
81
  {
82
- const SVFValue* vtbl = cbn->getVtablePtr();
82
+ const SVFVar* vtbl = cbn->getVtablePtr();
83
83
  (void)vtbl; // Suppress warning of unused variable under release build
84
- assert(pag->hasValueNode(vtbl));
84
+ assert(vtbl != nullptr);
85
85
  VFunSet vfns;
86
86
  getVFnsFromCHA(cbn, vfns);
87
87
  connectVCallToVFns(cbn, vfns, newEdges);
@@ -29,6 +29,7 @@
29
29
  */
30
30
 
31
31
  #include "SVF-LLVM/ICFGBuilder.h"
32
+ #include "SVF-LLVM/CppUtil.h"
32
33
  #include "SVF-LLVM/LLVMModule.h"
33
34
  #include "SVF-LLVM/LLVMUtil.h"
34
35
 
@@ -239,17 +240,30 @@ InterICFGNode* ICFGBuilder::addInterBlockICFGNode(const Instruction* inst)
239
240
  assert(LLVMUtil::isCallSite(inst) && "not a call instruction?");
240
241
  assert(LLVMUtil::isNonInstricCallSite(inst) && "associating an intrinsic debug instruction with an ICFGNode!");
241
242
  assert(llvmModuleSet()->getCallBlock(inst)==nullptr && "duplicate CallICFGNode");
242
- CallICFGNode* callICFGNode =
243
- new CallICFGNode(icfg->totalICFGNode++, svfInst,
244
- llvmModuleSet()->getSVFType(inst->getType()));
245
- icfg->addICFGNode(callICFGNode);
243
+ const CallBase* cb = SVFUtil::dyn_cast<CallBase>(inst);
244
+ bool isvcall = cppUtil::isVirtualCallSite(cb);
245
+ SVFFunction* calledFunc = nullptr;
246
+ auto called_llvmval = cb->getCalledOperand()->stripPointerCasts();
247
+ if (const Function* called_llvmfunc = SVFUtil::dyn_cast<Function>(called_llvmval))
248
+ {
249
+ calledFunc = llvmModuleSet()->getSVFFunction(called_llvmfunc);
250
+ }
251
+ else
252
+ {
253
+ calledFunc = SVFUtil::dyn_cast<SVFFunction>(
254
+ llvmModuleSet()->getSVFValue(called_llvmval));
255
+ }
256
+
257
+ CallICFGNode* callICFGNode = icfg->addCallICFGNode(
258
+ svfInst->getParent(), llvmModuleSet()->getSVFType(inst->getType()),
259
+ calledFunc, cb->getFunctionType()->isVarArg(), isvcall,
260
+ isvcall ? cppUtil::getVCallIdx(cb) : 0,
261
+ isvcall ? cppUtil::getFunNameOfVCallSite(cb) : "");
246
262
  csToCallNodeMap()[inst] = callICFGNode;
247
263
  llvmModuleSet()->setValueAttr(inst, callICFGNode);
248
264
 
249
265
  assert(llvmModuleSet()->getRetBlock(inst)==nullptr && "duplicate RetICFGNode");
250
- RetICFGNode* retICFGNode = new RetICFGNode(icfg->totalICFGNode++, svfInst, callICFGNode);
251
- callICFGNode->setRetICFGNode(retICFGNode);
252
- icfg->addICFGNode(retICFGNode);
266
+ RetICFGNode* retICFGNode = icfg->addRetICFGNode(callICFGNode);
253
267
  csToRetNodeMap()[inst] = retICFGNode;
254
268
  llvmModuleSet()->setValueAttr(inst, retICFGNode);
255
269
 
@@ -333,10 +347,8 @@ IntraICFGNode* ICFGBuilder::addIntraBlockICFGNode(const Instruction* inst)
333
347
  llvmModuleSet()->getSVFInstruction(inst);
334
348
  IntraICFGNode* node = llvmModuleSet()->getIntraBlock(inst);
335
349
  assert (node==nullptr && "no IntraICFGNode for this instruction?");
336
- IntraICFGNode* sNode =
337
- new IntraICFGNode(icfg->totalICFGNode++, svfInst->getParent(),
338
- SVFUtil::isa<ReturnInst>(inst));
339
- icfg->addICFGNode(sNode);
350
+ IntraICFGNode* sNode = icfg->addIntraICFGNode(
351
+ svfInst->getParent(), SVFUtil::isa<ReturnInst>(inst));
340
352
  instToBlockNodeMap()[inst] = sNode;
341
353
  llvmModuleSet()->setValueAttr(inst, sNode);
342
354
  return sNode;
@@ -344,22 +356,12 @@ IntraICFGNode* ICFGBuilder::addIntraBlockICFGNode(const Instruction* inst)
344
356
 
345
357
  FunEntryICFGNode* ICFGBuilder::addFunEntryBlock(const Function* fun)
346
358
  {
347
- SVFFunction* svfFunc =
348
- llvmModuleSet()->getSVFFunction(fun);
349
- FunEntryICFGNode* sNode = new FunEntryICFGNode(icfg->totalICFGNode++,svfFunc);
350
- icfg->addICFGNode(sNode);
351
- funToFunEntryNodeMap()[fun] = sNode;
352
- icfg->FunToFunEntryNodeMap[svfFunc] = sNode;
353
- return sNode;
359
+ return funToFunEntryNodeMap()[fun] =
360
+ icfg->addFunEntryICFGNode(llvmModuleSet()->getSVFFunction(fun));
354
361
  }
355
362
 
356
363
  inline FunExitICFGNode* ICFGBuilder::addFunExitBlock(const Function* fun)
357
364
  {
358
- SVFFunction* svfFunc =
359
- llvmModuleSet()->getSVFFunction(fun);
360
- FunExitICFGNode* sNode = new FunExitICFGNode(icfg->totalICFGNode++, svfFunc);
361
- icfg->addICFGNode(sNode);
362
- funToFunExitNodeMap()[fun] = sNode;
363
- icfg->FunToFunExitNodeMap[svfFunc] = sNode;
364
- return sNode;
365
+ return funToFunExitNodeMap()[fun] =
366
+ icfg->addFunExitICFGNode(llvmModuleSet()->getSVFFunction(fun));
365
367
  }
@@ -871,6 +871,11 @@ void SVFIRBuilder::visitCallSite(CallBase* cs)
871
871
  if(!cs->getType()->isVoidTy())
872
872
  pag->addCallSiteRets(retBlockNode,pag->getGNode(getValueNode(cs)));
873
873
 
874
+ if (callBlockNode->isVirtualCall())
875
+ {
876
+ const Value* value = cppUtil::getVCallVtblPtr(cs);
877
+ callBlockNode->setVtablePtr(pag->getGNode(getValueNode(value)));
878
+ }
874
879
  if (const Function *callee = LLVMUtil::getCallee(cs))
875
880
  {
876
881
  const SVFFunction* svfcallee = llvmModuleSet()->getSVFFunction(callee);