Static Value-Flow Analysis
SVFStatements.h
Go to the documentation of this file.
1 //===- SVFStatements.h -- SVF statements-------------------------------------------//
2 //
3 // SVF: Static Value-Flow Analysis
4 //
5 // Copyright (C) <2013-> <Yulei Sui>
6 //
7 
8 // This program is free software: you can redistribute it and/or modify
9 // it under the terms of the GNU Affero General Public License as published by
10 // the Free Software Foundation, either version 3 of the License, or
11 // (at your option) any later version.
12 
13 // This program is distributed in the hope that it will be useful,
14 // but WITHOUT ANY WARRANTY; without even the implied warranty of
15 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 // GNU Affero General Public License for more details.
17 
18 // You should have received a copy of the GNU Affero General Public License
19 // along with this program. If not, see <http://www.gnu.org/licenses/>.
20 //
21 //===----------------------------------------------------------------------===//
22 
23 
24 /*
25  * SVFStatements.h
26  *
27  * Created on: Nov 10, 2013
28  * Author: Yulei Sui
29  */
30 
31 #ifndef INCLUDE_SVFIR_SVFSTATEMENT_H_
32 #define INCLUDE_SVFIR_SVFSTATEMENT_H_
33 
34 #include "Graphs/GenericGraph.h"
35 #include "MemoryModel/AccessPath.h"
36 
37 namespace SVF
38 {
39 
40 class SVFVar;
41 class ICFGNode;
42 class IntraICFGNode;
43 class CallICFGNode;
44 class FunEntryICFGNode;
45 class FunExitICFGNode;
46 
47 /*
48  * SVFIR program statements (PAGEdges)
49  */
51 class SVFStmt : public GenericPAGEdgeTy
52 {
53  friend class SVFIRWriter;
54  friend class SVFIRReader;
55 
56 public:
61  enum PEDGEK
62  {
68  Ret,
69  Gep,
70  Phi,
72  Cmp,
78  };
79 
80 private:
81  const SVFValue* value;
85 
86 protected:
89  : GenericPAGEdgeTy({}, {}, k), value{}, basicBlock{}, icfgNode{}
90  {
91  }
92 
93 public:
95 
97  SVFStmt(SVFVar* s, SVFVar* d, GEdgeFlag k, bool real = true);
99  ~SVFStmt() {}
100 
102 
103  static inline bool classof(const SVFStmt*)
104  {
105  return true;
106  }
107  static inline bool classof(const GenericPAGEdgeTy* edge)
108  {
109  return edge->getEdgeKind() == SVFStmt::Addr ||
110  edge->getEdgeKind() == SVFStmt::Copy ||
111  edge->getEdgeKind() == SVFStmt::Store ||
112  edge->getEdgeKind() == SVFStmt::Load ||
113  edge->getEdgeKind() == SVFStmt::Call ||
114  edge->getEdgeKind() == SVFStmt::Ret ||
115  edge->getEdgeKind() == SVFStmt::Gep ||
116  edge->getEdgeKind() == SVFStmt::Phi ||
117  edge->getEdgeKind() == SVFStmt::Select ||
118  edge->getEdgeKind() == SVFStmt::Cmp ||
119  edge->getEdgeKind() == SVFStmt::BinaryOp ||
120  edge->getEdgeKind() == SVFStmt::UnaryOp ||
121  edge->getEdgeKind() == SVFStmt::Branch ||
122  edge->getEdgeKind() == SVFStmt::ThreadFork ||
123  edge->getEdgeKind() == SVFStmt::ThreadJoin;
124  }
126 
128  inline EdgeID getEdgeID() const
129  {
130  return edgeId;
131  }
133  bool isPTAEdge() const;
134 
136 
137  inline const SVFInstruction* getInst() const
138  {
139  if (const SVFInstruction* i = SVFUtil::dyn_cast<SVFInstruction>(value))
140  return i;
141  return nullptr;
142  }
143  inline void setValue(const SVFValue* val)
144  {
145  value = val;
146  }
147  inline const SVFValue* getValue() const
148  {
149  return value;
150  }
151  inline void setBB(const SVFBasicBlock* bb)
152  {
153  basicBlock = bb;
154  }
155  inline const SVFBasicBlock* getBB() const
156  {
157  return basicBlock;
158  }
159  inline void setICFGNode(ICFGNode* node)
160  {
161  icfgNode = node;
162  }
163  inline ICFGNode* getICFGNode() const
164  {
165  return icfgNode;
166  }
168 
172  const SVFVar* var)
173  {
174  auto it_inserted = var2LabelMap.emplace(var, multiOpndLabelCounter);
175  if (it_inserted.second)
177  u64_t label = it_inserted.first->second;
178  return (label << EdgeKindMaskBits) | k;
179  }
180 
184  const ICFGNode* cs)
185  {
186  auto it_inserted = inst2LabelMap.emplace(cs, callEdgeLabelCounter);
187  if (it_inserted.second)
189  u64_t label = it_inserted.first->second;
190  return (label << EdgeKindMaskBits) | k;
191  }
192 
196  const ICFGNode* store)
197  {
198  auto it_inserted = inst2LabelMap.emplace(store, storeEdgeLabelCounter);
199  if (it_inserted.second)
201  u64_t label = it_inserted.first->second;
202  return (label << EdgeKindMaskBits) | k;
203  }
204 
205  virtual const std::string toString() const;
206 
208 
210  friend OutStream& operator<<(OutStream& o, const SVFStmt& edge)
211  {
212  o << edge.toString();
213  return o;
214  }
216 
221 
222 private:
230 };
231 
232 /*
233  Parent class of Addr, Copy, Store, Load, Call, Ret, NormalGep, VariantGep, ThreadFork, ThreadJoin
234  connecting RHS expression and LHS expression with an assignment (e.g., LHSExpr = RHSExpr)
235  Only one operand on the right hand side of an assignment
236 */
237 class AssignStmt : public SVFStmt
238 {
239  friend class SVFIRWriter;
240  friend class SVFIRReader;
241 
242 private:
245  void operator=(const AssignStmt &);
250 
251 protected:
253  AssignStmt(SVFVar* s, SVFVar* d, GEdgeFlag k) : SVFStmt(s, d, k) {}
256 
257 public:
259 
260  static inline bool classof(const AssignStmt*)
261  {
262  return true;
263  }
264  static inline bool classof(const SVFStmt* edge)
265  {
266  return edge->getEdgeKind() == SVFStmt::Addr ||
267  edge->getEdgeKind() == SVFStmt::Copy ||
268  edge->getEdgeKind() == SVFStmt::Store ||
269  edge->getEdgeKind() == SVFStmt::Load ||
270  edge->getEdgeKind() == SVFStmt::Call ||
271  edge->getEdgeKind() == SVFStmt::Ret ||
272  edge->getEdgeKind() == SVFStmt::Gep ||
273  edge->getEdgeKind() == SVFStmt::ThreadFork ||
274  edge->getEdgeKind() == SVFStmt::ThreadJoin;
275  }
276  static inline bool classof(const GenericPAGEdgeTy* edge)
277  {
278  return edge->getEdgeKind() == SVFStmt::Addr ||
279  edge->getEdgeKind() == SVFStmt::Copy ||
280  edge->getEdgeKind() == SVFStmt::Store ||
281  edge->getEdgeKind() == SVFStmt::Load ||
282  edge->getEdgeKind() == SVFStmt::Call ||
283  edge->getEdgeKind() == SVFStmt::Ret ||
284  edge->getEdgeKind() == SVFStmt::Gep ||
285  edge->getEdgeKind() == SVFStmt::ThreadFork ||
286  edge->getEdgeKind() == SVFStmt::ThreadJoin;
287  }
289 
290  inline SVFVar* getRHSVar() const
291  {
292  return SVFStmt::getSrcNode();
293  }
294  inline SVFVar* getLHSVar() const
295  {
296  return SVFStmt::getDstNode();
297  }
298  inline NodeID getRHSVarID() const
299  {
300  return SVFStmt::getSrcID();
301  }
302  inline NodeID getLHSVarID() const
303  {
304  return SVFStmt::getDstID();
305  }
306 
307  virtual const std::string toString() const = 0;
308 };
309 
313 class AddrStmt: public AssignStmt
314 {
315  friend class SVFIRWriter;
316  friend class SVFIRReader;
317 
318 private:
321  AddrStmt(const AddrStmt&);
322  void operator=(const AddrStmt&);
323 
324  std::vector<SVFValue*> arrSize;
325 
326 public:
328 
329  static inline bool classof(const AddrStmt*)
330  {
331  return true;
332  }
333  static inline bool classof(const SVFStmt* edge)
334  {
335  return edge->getEdgeKind() == SVFStmt::Addr;
336  }
337  static inline bool classof(const GenericPAGEdgeTy* edge)
338  {
339  return edge->getEdgeKind() == SVFStmt::Addr;
340  }
342 
345 
346  virtual const std::string toString() const override;
347 
348  inline void addArrSize(SVFValue* size) //TODO:addSizeVar
349  {
350  arrSize.push_back(size);
351  }
352 
354  inline const std::vector<SVFValue*>& getArrSize() const //TODO:getSizeVars
355  {
356  return arrSize;
357  }
358 
359 };
360 
364 class CopyStmt: public AssignStmt
365 {
366  friend class SVFIRWriter;
367  friend class SVFIRReader;
368 private:
371  CopyStmt(const CopyStmt&);
372  void operator=(const CopyStmt&);
373 public:
374  enum CopyKind
375  {
376  COPYVAL, // Value copies (default one)
377  ZEXT, // Zero extend integers
378  SEXT, // Sign extend integers
379  BITCAST, // Type cast
380  TRUNC, // Truncate integers
381  FPTRUNC, // Truncate floating point
382  FPTOUI, // floating point -> UInt
383  FPTOSI, // floating point -> SInt
384  UITOFP, // UInt -> floating point
385  SITOFP, // SInt -> floating point
386  INTTOPTR, // Integer -> Pointer
387  PTRTOINT // Pointer -> Integer
388  };
390 
391  static inline bool classof(const CopyStmt*)
392  {
393  return true;
394  }
395  static inline bool classof(const SVFStmt* edge)
396  {
397  return edge->getEdgeKind() == SVFStmt::Copy;
398  }
399  static inline bool classof(const GenericPAGEdgeTy* edge)
400  {
401  return edge->getEdgeKind() == SVFStmt::Copy;
402  }
404 
406  inline u32_t getCopyKind() const
407  {
408  return copyKind;
409  }
410 
411  inline bool isBitCast() const
412  {
413  return copyKind == BITCAST;
414  }
415 
416  inline bool isValueCopy() const
417  {
418  return copyKind == COPYVAL;
419  }
420 
421  inline bool isInt2Ptr() const
422  {
423  return copyKind == INTTOPTR;
424  }
425 
426  inline bool isPtr2Int() const
427  {
428  return copyKind == PTRTOINT;
429  }
430 
431  inline bool isZext() const
432  {
433  return copyKind == ZEXT;
434  }
435 
436  inline bool isSext() const
437  {
438  return copyKind == SEXT;
439  }
440 
443 
444  virtual const std::string toString() const override;
445 private:
447 };
448 
452 class StoreStmt: public AssignStmt
453 {
454  friend class SVFIRWriter;
455  friend class SVFIRReader;
456 
457 private:
461  void operator=(const StoreStmt&);
462 
463 public:
465 
466  static inline bool classof(const StoreStmt*)
467  {
468  return true;
469  }
470  static inline bool classof(const SVFStmt* edge)
471  {
472  return edge->getEdgeKind() == SVFStmt::Store;
473  }
474  static inline bool classof(const GenericPAGEdgeTy* edge)
475  {
476  return edge->getEdgeKind() == SVFStmt::Store;
477  }
479 
481  StoreStmt(SVFVar* s, SVFVar* d, const ICFGNode* st);
482 
483  virtual const std::string toString() const override;
484 };
485 
489 class LoadStmt: public AssignStmt
490 {
491  friend class SVFIRWriter;
492  friend class SVFIRReader;
493 
494 private:
497  LoadStmt(const LoadStmt&);
498  void operator=(const LoadStmt&);
499 
500 public:
502 
503  static inline bool classof(const LoadStmt*)
504  {
505  return true;
506  }
507  static inline bool classof(const SVFStmt* edge)
508  {
509  return edge->getEdgeKind() == SVFStmt::Load;
510  }
511  static inline bool classof(const GenericPAGEdgeTy* edge)
512  {
513  return edge->getEdgeKind() == SVFStmt::Load;
514  }
516 
519 
520  virtual const std::string toString() const override;
521 };
522 
526 class GepStmt: public AssignStmt
527 {
528  friend class SVFIRWriter;
529  friend class SVFIRReader;
530 
531 private:
534  GepStmt(const GepStmt &);
535  void operator=(const GepStmt &);
536 
539 public:
541 
542  static inline bool classof(const GepStmt*)
543  {
544  return true;
545  }
546  static inline bool classof(const SVFStmt* edge)
547  {
548  return edge->getEdgeKind() == SVFStmt::Gep;
549  }
550  static inline bool classof(const GenericPAGEdgeTy* edge)
551  {
552  return edge->getEdgeKind() == SVFStmt::Gep;
553  }
555 
556  inline const AccessPath& getAccessPath() const
557  {
558  return ap;
559  }
561  {
563  }
565  inline bool isConstantOffset() const
566  {
567  return getAccessPath().isConstantOffset();
568  }
569 
576  {
578  }
579 
582  {
584  }
587  {
588  assert(isVariantFieldGep()==false && "Can't retrieve the AccessPath if using a variable field index (pointer arithmetic) for struct field access ");
590  }
592  inline bool isVariantFieldGep() const
593  {
594  return variantField;
595  }
596 
598  GepStmt(SVFVar* s, SVFVar* d, const AccessPath& ap, bool varfld = false)
599  : AssignStmt(s, d, SVFStmt::Gep), ap(ap), variantField(varfld)
600  {
601  }
602 
603  virtual const std::string toString() const;
604 
605 };
606 
607 
611 class CallPE: public AssignStmt
612 {
613  friend class SVFIRWriter;
614  friend class SVFIRReader;
615 
616 private:
617  CallPE(const CallPE&);
618  void operator=(const CallPE&);
619 
622 protected:
625 
626 public:
628 
629  static inline bool classof(const CallPE*)
630  {
631  return true;
632  }
633  static inline bool classof(const SVFStmt* edge)
634  {
635  return edge->getEdgeKind() == SVFStmt::Call ||
636  edge->getEdgeKind() == SVFStmt::ThreadFork;
637  }
638  static inline bool classof(const GenericPAGEdgeTy* edge)
639  {
640  return edge->getEdgeKind() == SVFStmt::Call ||
641  edge->getEdgeKind() == SVFStmt::ThreadFork;
642  }
644 
646  CallPE(SVFVar* s, SVFVar* d, const CallICFGNode* i,
648 
650 
651  inline const CallICFGNode* getCallInst() const
652  {
653  return call;
654  }
655  inline const CallICFGNode* getCallSite() const
656  {
657  return call;
658  }
659  inline const FunEntryICFGNode* getFunEntryICFGNode() const
660  {
661  return entry;
662  }
664 
665  virtual const std::string toString() const override;
666 };
667 
671 class RetPE: public AssignStmt
672 {
673  friend class SVFIRWriter;
674  friend class SVFIRReader;
675 
676 private:
677  RetPE(const RetPE&);
678  void operator=(const RetPE&);
679 
682 
683 protected:
686 
687 public:
689 
690  static inline bool classof(const RetPE*)
691  {
692  return true;
693  }
694  static inline bool classof(const SVFStmt* edge)
695  {
696  return edge->getEdgeKind() == SVFStmt::Ret ||
697  edge->getEdgeKind() == SVFStmt::ThreadJoin;
698  }
699  static inline bool classof(const GenericPAGEdgeTy* edge)
700  {
701  return edge->getEdgeKind() == SVFStmt::Ret ||
702  edge->getEdgeKind() == SVFStmt::ThreadJoin;
703  }
705 
707  RetPE(SVFVar* s, SVFVar* d, const CallICFGNode* i, const FunExitICFGNode* e,
708  GEdgeKind k = SVFStmt::Ret);
709 
711 
712  inline const CallICFGNode* getCallInst() const
713  {
714  return call;
715  }
716  inline const CallICFGNode* getCallSite() const
717  {
718  return call;
719  }
720  inline const FunExitICFGNode* getFunExitICFGNode() const
721  {
722  return exit;
723  }
725 
726  virtual const std::string toString() const override;
727 };
728 
729 /*
730 * Program statements with multiple operands including BinaryOPStmt, CmpStmt and PhiStmt
731 */
732 class MultiOpndStmt : public SVFStmt
733 {
734  friend class SVFIRWriter;
735  friend class SVFIRReader;
736 
737 public:
738  typedef std::vector<SVFVar*> OPVars;
739 
740 private:
743  void operator=(const MultiOpndStmt&);
748 
749 protected:
752  MultiOpndStmt(SVFVar* r, const OPVars& opnds, GEdgeFlag k);
755 
756 public:
758 
759  static inline bool classof(const MultiOpndStmt*)
760  {
761  return true;
762  }
763  static inline bool classof(const SVFStmt* node)
764  {
765  return node->getEdgeKind() == Phi || node->getEdgeKind() == Select ||
766  node->getEdgeKind() == BinaryOp || node->getEdgeKind() == Cmp;
767  }
768  static inline bool classof(const GenericPAGEdgeTy* node)
769  {
770  return node->getEdgeKind() == Phi || node->getEdgeKind() == Select ||
771  node->getEdgeKind() == BinaryOp || node->getEdgeKind() == Cmp;
772  }
774 
777  inline const SVFVar* getOpVar(u32_t pos) const
779  {
780  return opVars.at(pos);
781  }
783  inline const SVFVar* getRes() const
784  {
785  return SVFStmt::getDstNode();
786  }
787 
788  NodeID getOpVarID(u32_t pos) const;
789  NodeID getResID() const;
790 
791  inline u32_t getOpVarNum() const
792  {
793  return opVars.size();
794  }
795  inline const OPVars& getOpndVars() const
796  {
797  return opVars;
798  }
799  inline OPVars::const_iterator opVarBegin() const
800  {
801  return opVars.begin();
802  }
803  inline OPVars::const_iterator opVerEnd() const
804  {
805  return opVars.end();
806  }
808 };
809 
814 class PhiStmt: public MultiOpndStmt
815 {
816  friend class SVFIRWriter;
817  friend class SVFIRReader;
818 
819 public:
820  typedef std::vector<const ICFGNode*> OpICFGNodeVec;
821 
822 private:
825  PhiStmt(const PhiStmt&);
826  void operator=(const PhiStmt&);
827 
829 
830 public:
832 
833  static inline bool classof(const PhiStmt*)
834  {
835  return true;
836  }
837  static inline bool classof(const SVFStmt* edge)
838  {
839  return edge->getEdgeKind() == SVFStmt::Phi;
840  }
841  static inline bool classof(const MultiOpndStmt* edge)
842  {
843  return edge->getEdgeKind() == SVFStmt::Phi;
844  }
845  static inline bool classof(const GenericPAGEdgeTy* edge)
846  {
847  return edge->getEdgeKind() == SVFStmt::Phi;
848  }
850 
852  PhiStmt(SVFVar* s, const OPVars& opnds, const OpICFGNodeVec& icfgNodes)
853  : MultiOpndStmt(s, opnds, SVFStmt::Phi), opICFGNodes(icfgNodes)
854  {
855  assert(opnds.size() == icfgNodes.size() &&
856  "Numbers of operands and their ICFGNodes are not consistent?");
857  }
858  void addOpVar(SVFVar* op, const ICFGNode* inode)
859  {
860  opVars.push_back(op);
861  opICFGNodes.push_back(inode);
862  assert(opVars.size() == opICFGNodes.size() &&
863  "Numbers of operands and their ICFGNodes are not consistent?");
864  }
865 
867  inline const ICFGNode* getOpICFGNode(u32_t op_idx) const
868  {
869  return opICFGNodes.at(op_idx);
870  }
871 
874  bool isFunctionRetPhi() const;
875 
876  virtual const std::string toString() const override;
877 };
878 
883 {
884  friend class SVFIRWriter;
885  friend class SVFIRReader;
886 
887 private:
891  void operator=(const SelectStmt&);
892 
894 
895 public:
897 
898  static inline bool classof(const SelectStmt*)
899  {
900  return true;
901  }
902  static inline bool classof(const SVFStmt* edge)
903  {
904  return edge->getEdgeKind() == SVFStmt::Select;
905  }
906  static inline bool classof(const MultiOpndStmt* edge)
907  {
908  return edge->getEdgeKind() == SVFStmt::Select;
909  }
910  static inline bool classof(const GenericPAGEdgeTy* edge)
911  {
912  return edge->getEdgeKind() == SVFStmt::Select;
913  }
915 
917  SelectStmt(SVFVar* s, const OPVars& opnds, const SVFVar* cond);
918  virtual const std::string toString() const override;
919 
920  inline const SVFVar* getCondition() const
921  {
922  return condition;
923  }
924  inline const SVFVar* getTrueValue() const
925  {
926  return getOpVar(0);
927  }
928  inline const SVFVar* getFalseValue() const
929  {
930  return getOpVar(1);
931  }
932 };
933 
937 class CmpStmt: public MultiOpndStmt
938 {
939  friend class SVFIRWriter;
940  friend class SVFIRReader;
941 
942 private:
945  CmpStmt(const CmpStmt&);
946  void operator=(const CmpStmt&);
947 
949 
950 public:
952  enum Predicate : unsigned
953  {
954  // Opcode U L G E Intuitive operation
956  FCMP_OEQ = 1,
957  FCMP_OGT = 2,
958  FCMP_OGE = 3,
959  FCMP_OLT = 4,
960  FCMP_OLE = 5,
961  FCMP_ONE = 6,
962  FCMP_ORD = 7,
963  FCMP_UNO = 8,
964  FCMP_UEQ = 9,
965  FCMP_UGT = 10,
966  FCMP_UGE = 11,
967  FCMP_ULT = 12,
968  FCMP_ULE = 13,
969  FCMP_UNE = 14,
970  FCMP_TRUE = 15,
974  ICMP_EQ = 32,
975  ICMP_NE = 33,
976  ICMP_UGT = 34,
977  ICMP_UGE = 35,
978  ICMP_ULT = 36,
979  ICMP_ULE = 37,
980  ICMP_SGT = 38,
981  ICMP_SGE = 39,
982  ICMP_SLT = 40,
983  ICMP_SLE = 41,
987  };
988 
990 
991  static inline bool classof(const CmpStmt*)
992  {
993  return true;
994  }
995  static inline bool classof(const SVFStmt* edge)
996  {
997  return edge->getEdgeKind() == SVFStmt::Cmp;
998  }
999  static inline bool classof(const MultiOpndStmt* edge)
1000  {
1001  return edge->getEdgeKind() == SVFStmt::Cmp;
1002  }
1003  static inline bool classof(const GenericPAGEdgeTy* edge)
1004  {
1005  return edge->getEdgeKind() == SVFStmt::Cmp;
1006  }
1008 
1010  CmpStmt(SVFVar* s, const OPVars& opnds, u32_t pre);
1011 
1013  {
1014  return predicate;
1015  }
1016 
1017  virtual const std::string toString() const override;
1018 };
1019 
1024 {
1025  friend class SVFIRWriter;
1026  friend class SVFIRReader;
1027 
1028 private:
1032  void operator=(const BinaryOPStmt&);
1034 
1035 public:
1037  enum OpCode : unsigned
1038  {
1039  Add = 13, // Sum of integers
1040  FAdd = 14, // Sum of floats
1041  Sub = 15, // Subtraction of integers
1042  FSub = 16, // Subtraction of floats
1043  Mul = 17, // Product of integers.
1044  FMul = 18, // Product of floats.
1045  UDiv = 19, // Unsigned division.
1046  SDiv = 20, // Signed division.
1047  FDiv = 21, // Float division.
1048  URem = 22, // Unsigned remainder
1049  SRem = 23, // Signed remainder
1050  FRem = 24, // Float remainder
1051  Shl = 25, // Shift left (logical)
1052  LShr = 26, // Shift right (logical)
1053  AShr = 27, // Shift right (arithmetic)
1054  And = 28, // Logical and
1055  Or = 29, // Logical or
1056  Xor = 30 // Logical xor
1057  };
1058 
1060 
1061  static inline bool classof(const BinaryOPStmt*)
1062  {
1063  return true;
1064  }
1065  static inline bool classof(const SVFStmt* edge)
1066  {
1067  return edge->getEdgeKind() == SVFStmt::BinaryOp;
1068  }
1069  static inline bool classof(const MultiOpndStmt* edge)
1070  {
1071  return edge->getEdgeKind() == SVFStmt::BinaryOp;
1072  }
1073  static inline bool classof(const GenericPAGEdgeTy* edge)
1074  {
1075  return edge->getEdgeKind() == SVFStmt::BinaryOp;
1076  }
1078 
1080  BinaryOPStmt(SVFVar* s, const OPVars& opnds, u32_t oc);
1081 
1083  {
1084  return opcode;
1085  }
1086 
1087  virtual const std::string toString() const override;
1088 };
1089 
1093 class UnaryOPStmt: public SVFStmt
1094 {
1095  friend class SVFIRWriter;
1096  friend class SVFIRReader;
1097 
1098 private:
1102  void operator=(const UnaryOPStmt&);
1107 
1109 
1110 public:
1112  enum OpCode : unsigned
1113  {
1114  FNeg = 12
1115  };
1116 
1118 
1119  static inline bool classof(const UnaryOPStmt*)
1120  {
1121  return true;
1122  }
1123  static inline bool classof(const SVFStmt* edge)
1124  {
1125  return edge->getEdgeKind() == SVFStmt::UnaryOp;
1126  }
1127  static inline bool classof(const GenericPAGEdgeTy* edge)
1128  {
1129  return edge->getEdgeKind() == SVFStmt::UnaryOp;
1130  }
1132 
1135  : SVFStmt(s, d, SVFStmt::UnaryOp), opcode(oc)
1136  {
1137  }
1138 
1140  {
1141  return opcode;
1142  }
1143  inline const SVFVar* getOpVar() const
1144  {
1145  return SVFStmt::getSrcNode();
1146  }
1147  inline const SVFVar* getRes() const
1148  {
1149  return SVFStmt::getDstNode();
1150  }
1151  NodeID getOpVarID() const;
1152  NodeID getResID() const;
1153 
1154  virtual const std::string toString() const override;
1155 };
1156 
1160 class BranchStmt: public SVFStmt
1161 {
1162  friend class SVFIRWriter;
1163  friend class SVFIRReader;
1164 
1165 public:
1166  typedef std::vector<std::pair<const ICFGNode*, s32_t>> SuccAndCondPairVec;
1167 
1168 private:
1172  void operator=(const BranchStmt&);
1177 
1179  const SVFVar* cond;
1180  const SVFVar* brInst;
1181 
1182 public:
1184 
1185  static inline bool classof(const BranchStmt*)
1186  {
1187  return true;
1188  }
1189  static inline bool classof(const SVFStmt* edge)
1190  {
1191  return edge->getEdgeKind() == SVFStmt::Branch;
1192  }
1193  static inline bool classof(const GenericPAGEdgeTy* edge)
1194  {
1195  return edge->getEdgeKind() == SVFStmt::Branch;
1196  }
1198 
1200  BranchStmt(SVFVar* inst, SVFVar* c, const SuccAndCondPairVec& succs)
1201  : SVFStmt(c, inst, SVFStmt::Branch), successors(succs), cond(c),
1202  brInst(inst)
1203  {
1204  }
1205 
1207  bool isUnconditional() const;
1209  bool isConditional() const;
1211  const SVFVar* getCondition() const;
1212  const SVFVar* getBranchInst() const
1213  {
1214  return brInst;
1215  }
1216 
1220 
1224 
1228  {
1229  return successors.size();
1230  }
1232  {
1233  return successors;
1234  }
1235  const ICFGNode* getSuccessor(u32_t i) const
1236  {
1237  return successors.at(i).first;
1238  }
1240  {
1241  return successors.at(i).second;
1242  }
1244  virtual const std::string toString() const override;
1245 };
1246 
1250 class TDForkPE: public CallPE
1251 {
1252  friend class SVFIRWriter;
1253  friend class SVFIRReader;
1254 
1255 private:
1258  TDForkPE(const TDForkPE&);
1259  void operator=(const TDForkPE&);
1260 
1261 public:
1263 
1264  static inline bool classof(const TDForkPE*)
1265  {
1266  return true;
1267  }
1268  static inline bool classof(const SVFStmt* edge)
1269  {
1270  return edge->getEdgeKind() == SVFStmt::ThreadFork;
1271  }
1272  static inline bool classof(const GenericPAGEdgeTy* edge)
1273  {
1274  return edge->getEdgeKind() == SVFStmt::ThreadFork;
1275  }
1277 
1280  const FunEntryICFGNode* entry)
1281  : CallPE(s, d, i, entry, SVFStmt::ThreadFork)
1282  {
1283  }
1284 
1285  virtual const std::string toString() const;
1286 };
1287 
1291 class TDJoinPE: public RetPE
1292 {
1293  friend class SVFIRWriter;
1294  friend class SVFIRReader;
1295 
1296 private:
1299  TDJoinPE(const TDJoinPE&);
1300  void operator=(const TDJoinPE&);
1301 
1302 public:
1304 
1305  static inline bool classof(const TDJoinPE*)
1306  {
1307  return true;
1308  }
1309  static inline bool classof(const SVFStmt* edge)
1310  {
1311  return edge->getEdgeKind() == SVFStmt::ThreadJoin;
1312  }
1313  static inline bool classof(const GenericPAGEdgeTy* edge)
1314  {
1315  return edge->getEdgeKind() == SVFStmt::ThreadJoin;
1316  }
1318 
1321  const FunExitICFGNode* e)
1322  : RetPE(s, d, i, e, SVFStmt::ThreadJoin)
1323  {
1324  }
1325 
1326  virtual const std::string toString() const;
1327 };
1328 
1329 } // End namespace SVF
1330 
1331 #endif /* INCLUDE_SVFIR_SVFSTATEMENT_H_ */
const char *const string
Definition: cJSON.h:172
std::vector< IdxOperandPair > IdxOperandPairs
Definition: AccessPath.h:65
bool isConstantOffset() const
Return TRUE if this is a constant location set.
Definition: AccessPath.cpp:49
APOffset computeConstantByteOffset() const
Definition: AccessPath.cpp:125
APOffset getConstantStructFldIdx() const
Get methods.
Definition: AccessPath.h:100
const IdxOperandPairs & getIdxOperandPairVec() const
Definition: AccessPath.h:108
APOffset computeConstantOffset() const
For example,.
Definition: AccessPath.cpp:213
AddrStmt()
Constructs empty AddrStmt (for SVFIRReader/serialization)
void operator=(const AddrStmt &)
place holder
AddrStmt(const AddrStmt &)
place holder
static bool classof(const AddrStmt *)
Methods for support type inquiry through isa, cast, and dyn_cast:
std::vector< SVFValue * > arrSize
Array size of the allocated memory.
AddrStmt(SVFVar *s, SVFVar *d)
constructor
static bool classof(const GenericPAGEdgeTy *edge)
const std::vector< SVFValue * > & getArrSize() const
virtual const std::string toString() const override
void addArrSize(SVFValue *size)
get array size of the allocated memory
static bool classof(const SVFStmt *edge)
AssignStmt(GEdgeFlag k)
Constructor to create empty AssignStmt (for SVFIRReader/serialization)
AssignStmt(const AssignStmt &)
place holder
NodeID getRHSVarID() const
static bool classof(const AssignStmt *)
Methods for support type inquiry through isa, cast, and dyn_cast:
SVFVar * getDstNode()
not allowed, use getLHSVar() instead
static bool classof(const GenericPAGEdgeTy *edge)
SVFVar * getLHSVar() const
NodeID getLHSVarID() const
NodeID getDstID()
not allowed, use getLHSVarID() instead
NodeID getSrcID()
not allowed, use getRHSVarID() instead
virtual const std::string toString() const =0
AssignStmt()
place holder
SVFVar * getRHSVar() const
void operator=(const AssignStmt &)
place holder
static bool classof(const SVFStmt *edge)
SVFVar * getSrcNode()
not allowed, use getRHSVar() instead
AssignStmt(SVFVar *s, SVFVar *d, GEdgeFlag k)
constructor
virtual const std::string toString() const override
OpCode
OpCode for BinaryOPStmt, enum value is same to llvm BinaryOperator (llvm/IR/Instruction....
BinaryOPStmt()
Constructs empty BinaryOPStmt (for SVFIRReader/serialization)
static bool classof(const MultiOpndStmt *edge)
void operator=(const BinaryOPStmt &)
place holder
BinaryOPStmt(const BinaryOPStmt &)
place holder
static bool classof(const BinaryOPStmt *)
Methods for support type inquiry through isa, cast, and dyn_cast:
static bool classof(const SVFStmt *edge)
static bool classof(const GenericPAGEdgeTy *edge)
u32_t getOpcode() const
u32_t getNumSuccessors() const
bool isUnconditional() const
The branch is unconditional if cond is a null value.
const SVFVar * getBranchInst() const
const SVFVar * brInst
SuccAndCondPairVec successors
void operator=(const BranchStmt &)
place holder
static bool classof(const SVFStmt *edge)
BranchStmt(SVFVar *inst, SVFVar *c, const SuccAndCondPairVec &succs)
constructor
std::vector< std::pair< const ICFGNode *, s32_t > > SuccAndCondPairVec
BranchStmt(const BranchStmt &)
place holder
bool isConditional() const
The branch is conditional if cond is not a null value.
static bool classof(const BranchStmt *)
Methods for support type inquiry through isa, cast, and dyn_cast:
s64_t getSuccessorCondValue(u32_t i) const
const ICFGNode * getSuccessor(u32_t i) const
BranchStmt()
Constructs empty BranchStmt (for SVFIRReader/serialization)
const SVFVar * getCondition() const
Return the condition.
const SuccAndCondPairVec & getSuccessors() const
NodeID getSrcID()
place holder, use getOpVarID(pos) instead
NodeID getDstID()
place holder, use getResID() instead
const SVFVar * cond
SVFVar * getDstNode()
place holder, not allowed
static bool classof(const GenericPAGEdgeTy *edge)
SVFVar * getSrcNode()
place holder, not allowed
virtual const std::string toString() const override
static bool classof(const GenericPAGEdgeTy *edge)
CallPE(GEdgeFlag k=SVFStmt::Call)
the function exit statement calling to
static bool classof(const SVFStmt *edge)
CallPE(const CallPE &)
place holder
static bool classof(const CallPE *)
Methods for support type inquiry through isa, cast, and dyn_cast:
const FunEntryICFGNode * entry
the callsite statement calling from
const FunEntryICFGNode * getFunEntryICFGNode() const
void operator=(const CallPE &)
place holder
const CallICFGNode * getCallInst() const
Get method for the call instruction.
const CallICFGNode * getCallSite() const
const CallICFGNode * call
virtual const std::string toString() const override
static bool classof(const SVFStmt *edge)
virtual const std::string toString() const override
static bool classof(const MultiOpndStmt *edge)
CmpStmt()
Constructs empty CmpStmt (for SVFIRReader/serialization)
void operator=(const CmpStmt &)
place holder
u32_t getPredicate() const
CmpStmt(const CmpStmt &)
place holder
Predicate
OpCode for CmpStmt, enum value is same to llvm CmpInst.
@ ICMP_SGT
signed greater than
@ FCMP_UEQ
1 0 0 1 True if unordered or equal
@ FCMP_ONE
0 1 1 0 True if ordered and operands are unequal
@ ICMP_UGE
unsigned greater or equal
@ FCMP_UGT
1 0 1 0 True if unordered or greater than
@ ICMP_ULE
unsigned less or equal
@ FCMP_OGE
0 0 1 1 True if ordered and greater than or equal
@ FCMP_OLT
0 1 0 0 True if ordered and less than
@ FCMP_OGT
0 0 1 0 True if ordered and greater than
@ ICMP_NE
not equal
@ FCMP_TRUE
1 1 1 1 Always true (always folded)
@ ICMP_ULT
unsigned less than
@ FCMP_ULE
1 1 0 1 True if unordered, less than, or equal
@ ICMP_SLT
signed less than
@ ICMP_UGT
unsigned greater than
@ FCMP_OEQ
0 0 0 1 True if ordered and equal
@ FCMP_ORD
0 1 1 1 True if ordered (no nans)
@ FCMP_OLE
0 1 0 1 True if ordered and less than or equal
@ FCMP_FALSE
0 0 0 0 Always false (always folded)
@ FCMP_ULT
1 1 0 0 True if unordered or less than
@ FCMP_UNO
1 0 0 0 True if unordered: isnan(X) | isnan(Y)
@ FCMP_UGE
1 0 1 1 True if unordered, greater than, or equal
@ ICMP_SGE
signed greater or equal
@ FCMP_UNE
1 1 1 0 True if unordered or not equal
@ ICMP_SLE
signed less or equal
static bool classof(const CmpStmt *)
Methods for support type inquiry through isa, cast, and dyn_cast:
static bool classof(const GenericPAGEdgeTy *edge)
static bool classof(const GenericPAGEdgeTy *edge)
static bool classof(const CopyStmt *)
Methods for support type inquiry through isa, cast, and dyn_cast:
CopyStmt(SVFVar *s, SVFVar *d, CopyKind k)
constructor
u32_t getCopyKind() const
Return the kind of the copy statement.
bool isZext() const
bool isPtr2Int() const
static bool classof(const SVFStmt *edge)
CopyStmt()
Constructs empty CopyStmt (for SVFIRReader/serialization)
bool isBitCast() const
void operator=(const CopyStmt &)
place holder
CopyStmt(const CopyStmt &)
place holder
bool isValueCopy() const
virtual const std::string toString() const override
bool isInt2Ptr() const
bool isSext() const
NodeType * getSrcNode() const
Definition: GenericGraph.h:97
GEdgeKind getEdgeKind() const
Definition: GenericGraph.h:89
NodeID getDstID() const
Definition: GenericGraph.h:85
NodeID getSrcID() const
get methods of the components
Definition: GenericGraph.h:81
NodeType * getDstNode() const
Definition: GenericGraph.h:101
static constexpr unsigned char EdgeKindMaskBits
We use the lower 8 bits to denote edge kind.
Definition: GenericGraph.h:132
OrderedSet< EdgeType *, typename EdgeType::equalGEdge > GEdgeSetTy
Edge kind.
Definition: GenericGraph.h:402
bool isVariantFieldGep() const
Gep statement with a variant field index (pointer arithmetic) for struct field access.
APOffset accumulateConstantOffset() const
Return accumulated constant offset (when accessing array or struct) if this offset is a constant.
APOffset accumulateConstantByteOffset() const
const AccessPath::IdxOperandPairs getOffsetVarAndGepTypePairVec() const
static bool classof(const GepStmt *)
Methods for support type inquiry through isa, cast, and dyn_cast:
const AccessPath & getAccessPath() const
APOffset getConstantStructFldIdx() const
Field index of the gep statement if it access the field of a struct.
GepStmt(const GepStmt &)
place holder
GepStmt(SVFVar *s, SVFVar *d, const AccessPath &ap, bool varfld=false)
constructor
static bool classof(const SVFStmt *edge)
GepStmt()
Constructs empty GepStmt (for SVFIRReader/serialization)
void operator=(const GepStmt &)
place holder
bool isConstantOffset() const
Return TRUE if this is a constant location set.
static bool classof(const GenericPAGEdgeTy *edge)
virtual const std::string toString() const
AccessPath ap
Access path of the GEP edge.
bool variantField
Gep statement with a variant field index (pointer arithmetic) for struct field access (e....
static bool classof(const LoadStmt *)
Methods for support type inquiry through isa, cast, and dyn_cast:
LoadStmt(const LoadStmt &)
place holder
LoadStmt()
Constructs empty LoadStmt (for SVFIRReader/serialization)
virtual const std::string toString() const override
LoadStmt(SVFVar *s, SVFVar *d)
constructor
static bool classof(const GenericPAGEdgeTy *edge)
static bool classof(const SVFStmt *edge)
void operator=(const LoadStmt &)
place holder
const SVFVar * getRes() const
Result SVFVar.
const OPVars & getOpndVars() const
SVFVar * getSrcNode()
not allowed, use getOpVar(idx) instead
const SVFVar * getOpVar(u32_t pos) const
Operand SVFVars.
NodeID getDstID()
not allowed, use getResID() instead
NodeID getOpVarID(u32_t pos) const
static bool classof(const SVFStmt *node)
MultiOpndStmt()
place holder
MultiOpndStmt(const MultiOpndStmt &)
place holder
NodeID getResID() const
MultiOpndStmt(GEdgeFlag k)
Constructs empty MultiOpndStmt (for SVFIRReader/serialization)
static bool classof(const MultiOpndStmt *)
Methods for support type inquiry through isa, cast, and dyn_cast:
OPVars::const_iterator opVarBegin() const
NodeID getSrcID()
not allowed, use getOpVarID(idx) instead
std::vector< SVFVar * > OPVars
static bool classof(const GenericPAGEdgeTy *node)
OPVars::const_iterator opVerEnd() const
SVFVar * getDstNode()
not allowed, use getRes() instead
u32_t getOpVarNum() const
void operator=(const MultiOpndStmt &)
place holder
virtual const std::string toString() const override
const ICFGNode * getOpICFGNode(u32_t op_idx) const
Return the corresponding ICFGNode of this operand.
void operator=(const PhiStmt &)
place holder
std::vector< const ICFGNode * > OpICFGNodeVec
OpICFGNodeVec opICFGNodes
PhiStmt()
Constructs empty PhiStmt (for SVFIRReader/serialization)
PhiStmt(const PhiStmt &)
place holder
bool isFunctionRetPhi() const
static bool classof(const GenericPAGEdgeTy *edge)
static bool classof(const PhiStmt *)
Methods for support type inquiry through isa, cast, and dyn_cast:
static bool classof(const SVFStmt *edge)
PhiStmt(SVFVar *s, const OPVars &opnds, const OpICFGNodeVec &icfgNodes)
constructor
void addOpVar(SVFVar *op, const ICFGNode *inode)
static bool classof(const MultiOpndStmt *edge)
RetPE(const RetPE &)
place holder
const FunExitICFGNode * getFunExitICFGNode() const
static bool classof(const GenericPAGEdgeTy *edge)
static bool classof(const RetPE *)
Methods for support type inquiry through isa, cast, and dyn_cast:
virtual const std::string toString() const override
const FunExitICFGNode * exit
the callsite statement returning to
RetPE(GEdgeFlag k=SVFStmt::Ret)
the function exit statement returned from
const CallICFGNode * getCallInst() const
Get method for call instruction at caller.
static bool classof(const SVFStmt *edge)
const CallICFGNode * call
const CallICFGNode * getCallSite() const
void operator=(const RetPE &)
place holder
static bool classof(const GenericPAGEdgeTy *edge)
friend OutStream & operator<<(OutStream &o, const SVFStmt &edge)
Overloading operator << for dumping SVFVar value.
bool isPTAEdge() const
Whether src and dst nodes are both of pointer type.
void setBB(const SVFBasicBlock *bb)
Map< EdgeID, SVFStmtSetTy > PAGEdgeToSetMapTy
static u64_t callEdgeLabelCounter
Call site Instruction counter.
static Var2LabelMap var2LabelMap
Second operand of MultiOpndStmt to label map.
SVFStmtSetTy PAGEdgeSetTy
static GEdgeFlag makeEdgeFlagWithAddionalOpnd(GEdgeKind k, const SVFVar *var)
static GEdgeFlag makeEdgeFlagWithCallInst(GEdgeKind k, const ICFGNode *cs)
const SVFBasicBlock * getBB() const
SVFStmt(GEdgeFlag k)
Private constructor for reading SVFIR from file without side-effect.
Definition: SVFStatements.h:88
ICFGNode * icfgNode
ICFGNode.
Definition: SVFStatements.h:83
static u64_t storeEdgeLabelCounter
Store Instruction counter.
EdgeID edgeId
Edge ID.
Definition: SVFStatements.h:84
Map< const ICFGNode *, u32_t > Inst2LabelMap
const SVFValue * value
LLVM value.
Definition: SVFStatements.h:81
void setValue(const SVFValue *val)
const SVFInstruction * getInst() const
Get/set methods for llvm instruction.
const SVFBasicBlock * basicBlock
LLVM BasicBlock.
Definition: SVFStatements.h:82
GenericNode< SVFVar, SVFStmt >::GEdgeSetTy SVFStmtSetTy
PAGEdgeToSetMapTy KindToSVFStmtMapTy
static u64_t multiOpndLabelCounter
MultiOpndStmt counter.
ICFGNode * getICFGNode() const
~SVFStmt()
Destructor.
Definition: SVFStatements.h:99
const SVFValue * getValue() const
static Inst2LabelMap inst2LabelMap
Call site Instruction to label map.
static bool classof(const SVFStmt *)
ClassOf.
virtual const std::string toString() const
Map< const SVFVar *, u32_t > Var2LabelMap
static GEdgeFlag makeEdgeFlagWithStoreInst(GEdgeKind k, const ICFGNode *store)
void setICFGNode(ICFGNode *node)
static u32_t totalEdgeNum
Total edge number.
Definition: SVFStatements.h:94
EdgeID getEdgeID() const
Return Edge ID.
static bool classof(const MultiOpndStmt *edge)
const SVFVar * condition
static bool classof(const SVFStmt *edge)
const SVFVar * getTrueValue() const
virtual const std::string toString() const override
static bool classof(const SelectStmt *)
Methods for support type inquiry through isa, cast, and dyn_cast:
SelectStmt()
Constructs empty SelectStmt (for SVFIRReader/serialization)
static bool classof(const GenericPAGEdgeTy *edge)
const SVFVar * getCondition() const
SelectStmt(const SelectStmt &)
place holder
void operator=(const SelectStmt &)
place holder
const SVFVar * getFalseValue() const
StoreStmt(const StoreStmt &)
place holder
static bool classof(const SVFStmt *edge)
virtual const std::string toString() const override
static bool classof(const GenericPAGEdgeTy *edge)
void operator=(const StoreStmt &)
place holder
StoreStmt()
Constructs empty StoreStmt (for SVFIRReader/serialization)
static bool classof(const StoreStmt *)
Methods for support type inquiry through isa, cast, and dyn_cast:
void operator=(const TDForkPE &)
place holder
static bool classof(const SVFStmt *edge)
static bool classof(const TDForkPE *)
Methods for support type inquiry through isa, cast, and dyn_cast:
TDForkPE()
Constructs empty TDForkPE (for SVFIRReader/serialization)
static bool classof(const GenericPAGEdgeTy *edge)
virtual const std::string toString() const
TDForkPE(const TDForkPE &)
place holder
TDForkPE(SVFVar *s, SVFVar *d, const CallICFGNode *i, const FunEntryICFGNode *entry)
constructor
static bool classof(const SVFStmt *edge)
static bool classof(const GenericPAGEdgeTy *edge)
TDJoinPE()
Constructs empty TDJoinPE (for SVFIRReader/serialization)
void operator=(const TDJoinPE &)
place holder
TDJoinPE(const TDJoinPE &)
place holder
virtual const std::string toString() const
static bool classof(const TDJoinPE *)
Methods for support type inquiry through isa, cast, and dyn_cast:
TDJoinPE(SVFVar *s, SVFVar *d, const CallICFGNode *i, const FunExitICFGNode *e)
Constructor.
UnaryOPStmt()
Constructs empty UnaryOPStmt (for SVFIRReader/serialization)
virtual const std::string toString() const override
static bool classof(const SVFStmt *edge)
UnaryOPStmt(SVFVar *s, SVFVar *d, u32_t oc)
constructor
NodeID getSrcID()
place holder, use getOpVarID(pos) instead
SVFVar * getDstNode()
place holder, use getRes() instead
void operator=(const UnaryOPStmt &)
place holder
NodeID getOpVarID() const
const SVFVar * getRes() const
UnaryOPStmt(const UnaryOPStmt &)
place holder
NodeID getDstID()
place holder, use getResID() instead
SVFVar * getSrcNode()
place holder, use getOpVar() instead
static bool classof(const UnaryOPStmt *)
Methods for support type inquiry through isa, cast, and dyn_cast:
const SVFVar * getOpVar() const
OpCode
OpCode for UnaryOPStmt, enum value is same to llvm::UnaryOperator.
static bool classof(const GenericPAGEdgeTy *edge)
NodeID getResID() const
u32_t getOpcode() const
for isBitcode
Definition: BasicTypes.h:68
unsigned long long u64_t
Definition: GeneralType.h:48
u32_t NodeID
Definition: GeneralType.h:55
s64_t APOffset
Definition: GeneralType.h:60
std::unordered_map< Key, Value, Hash, KeyEqual, Allocator > Map
Definition: GeneralType.h:101
std::ostream OutStream
Definition: GeneralType.h:45
GenericEdge< SVFVar > GenericPAGEdgeTy
Definition: SVFStatements.h:45
unsigned u32_t
Definition: GeneralType.h:46
signed long long s64_t
Definition: GeneralType.h:49
u32_t EdgeID
Definition: GeneralType.h:56