Static Value-Flow Analysis
Loading...
Searching...
No Matches
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"
36
37namespace SVF
38{
39
40class SVFVar;
41class ICFGNode;
42class IntraICFGNode;
43class CallICFGNode;
44class FunEntryICFGNode;
45class FunExitICFGNode;
46class SVFBasicBlock;
47
48/*
49 * SVFIR program statements (PAGEdges)
50 */
53{
54 friend class GraphDBClient;
55
56public:
79
80private:
81 const SVFVar* value;
85
86protected:
89 : GenericPAGEdgeTy({}, {}, k), value{}, basicBlock{}, icfgNode{}
90 {
91 }
92
93 SVFStmt(SVFVar* s, SVFVar* d, GEdgeFlag k, EdgeID eid, SVFVar* value, ICFGNode* icfgNode, bool real = true);
94
98 inline void setBasicBlock(const SVFBasicBlock* bb)
99 {
100 basicBlock = bb;
101 }
102
110
118
126
130 static inline void addInst2Labeled(const ICFGNode* cs, u32_t label)
131 {
132 inst2LabelMap.emplace(cs, label);
133 }
134
135 static inline void addVar2Labeled(const SVFVar* var, u32_t label)
136 {
137 var2LabelMap.emplace(var, label);
138 }
139
140public:
141
143 SVFStmt(SVFVar* s, SVFVar* d, GEdgeFlag k, bool real = true);
146
148
149 static inline bool classof(const SVFStmt*)
150 {
151 return true;
152 }
153 static inline bool classof(const GenericPAGEdgeTy* edge)
154 {
155 return edge->getEdgeKind() == SVFStmt::Addr ||
156 edge->getEdgeKind() == SVFStmt::Copy ||
157 edge->getEdgeKind() == SVFStmt::Store ||
158 edge->getEdgeKind() == SVFStmt::Load ||
159 edge->getEdgeKind() == SVFStmt::Call ||
160 edge->getEdgeKind() == SVFStmt::Ret ||
161 edge->getEdgeKind() == SVFStmt::Gep ||
162 edge->getEdgeKind() == SVFStmt::Phi ||
163 edge->getEdgeKind() == SVFStmt::Select ||
164 edge->getEdgeKind() == SVFStmt::Cmp ||
165 edge->getEdgeKind() == SVFStmt::BinaryOp ||
166 edge->getEdgeKind() == SVFStmt::UnaryOp ||
167 edge->getEdgeKind() == SVFStmt::Branch ||
168 edge->getEdgeKind() == SVFStmt::ThreadFork ||
169 edge->getEdgeKind() == SVFStmt::ThreadJoin;
170 }
172
174 inline EdgeID getEdgeID() const
175 {
176 return edgeId;
177 }
179 virtual bool isPTAEdge() const;
180
182
183
184 inline void setValue(const SVFVar* val)
185 {
186 value = val;
187 }
188 inline const SVFVar* getValue() const
189 {
190 return value;
191 }
192
193 inline void setBB(const SVFBasicBlock* bb)
194 {
195 basicBlock = bb;
196 }
197 inline const SVFBasicBlock* getBB() const
198 {
199 return basicBlock;
200 }
201 inline void setICFGNode(ICFGNode* node)
202 {
203 icfgNode = node;
204 }
205 inline ICFGNode* getICFGNode() const
206 {
207 return icfgNode;
208 }
210
214 const SVFVar* var)
215 {
217 if (it_inserted.second)
219 u64_t label = it_inserted.first->second;
220 return (label << EdgeKindMaskBits) | k;
221 }
222
226 const ICFGNode* cs)
227 {
229 if (it_inserted.second)
231 u64_t label = it_inserted.first->second;
232 return (label << EdgeKindMaskBits) | k;
233 }
234
238 const ICFGNode* store)
239 {
240 auto it_inserted = inst2LabelMap.emplace(store, storeEdgeLabelCounter);
241 if (it_inserted.second)
243 u64_t label = it_inserted.first->second;
244 return (label << EdgeKindMaskBits) | k;
245 }
246
247 virtual const std::string toString() const;
248
250
253 {
254 o << edge.toString();
255 return o;
256 }
258
263
264private:
272
273public:
274 static inline const Inst2LabelMap* getInst2LabelMap()
275 {
276 return &inst2LabelMap;
277 }
278
279 static inline const Var2LabelMap* getVar2LabelMap()
280 {
281 return &var2LabelMap;
282 }
283
284 static inline const u64_t* getCallEdgeLabelCounter()
285 {
286 return &callEdgeLabelCounter;
287 }
288
289 static inline const u64_t* getStoreEdgeLabelCounter()
290 {
291 return &storeEdgeLabelCounter;
292 }
293
294 static inline const u64_t* getMultiOpndLabelCounter()
295 {
296 return &multiOpndLabelCounter;
297 }
298
299};
300
301/*
302 Parent class of Addr, Copy, Store, Load, Call, Ret, NormalGep, VariantGep, ThreadFork, ThreadJoin
303 connecting RHS expression and LHS expression with an assignment (e.g., LHSExpr = RHSExpr)
304 Only one operand on the right hand side of an assignment
305*/
306class AssignStmt : public SVFStmt
307{
308 friend class GraphDBClient;
309
310private:
313 void operator=(const AssignStmt &);
318
319protected:
322
323public:
325
326 static inline bool classof(const AssignStmt*)
327 {
328 return true;
329 }
330 static inline bool classof(const SVFStmt* edge)
331 {
332 return edge->getEdgeKind() == SVFStmt::Addr ||
333 edge->getEdgeKind() == SVFStmt::Copy ||
334 edge->getEdgeKind() == SVFStmt::Store ||
335 edge->getEdgeKind() == SVFStmt::Load ||
336 edge->getEdgeKind() == SVFStmt::Call ||
337 edge->getEdgeKind() == SVFStmt::Ret ||
338 edge->getEdgeKind() == SVFStmt::Gep ||
339 edge->getEdgeKind() == SVFStmt::ThreadFork ||
340 edge->getEdgeKind() == SVFStmt::ThreadJoin;
341 }
342 static inline bool classof(const GenericPAGEdgeTy* edge)
343 {
344 return edge->getEdgeKind() == SVFStmt::Addr ||
345 edge->getEdgeKind() == SVFStmt::Copy ||
346 edge->getEdgeKind() == SVFStmt::Store ||
347 edge->getEdgeKind() == SVFStmt::Load ||
348 edge->getEdgeKind() == SVFStmt::Call ||
349 edge->getEdgeKind() == SVFStmt::Ret ||
350 edge->getEdgeKind() == SVFStmt::Gep ||
351 edge->getEdgeKind() == SVFStmt::ThreadFork ||
352 edge->getEdgeKind() == SVFStmt::ThreadJoin;
353 }
355
356 inline SVFVar* getRHSVar() const
357 {
358 return SVFStmt::getSrcNode();
359 }
360 inline SVFVar* getLHSVar() const
361 {
362 return SVFStmt::getDstNode();
363 }
364 inline NodeID getRHSVarID() const
365 {
366 return SVFStmt::getSrcID();
367 }
368 inline NodeID getLHSVarID() const
369 {
370 return SVFStmt::getDstID();
371 }
372
373 virtual const std::string toString() const = 0;
374};
375
379class AddrStmt: public AssignStmt
380{
381 friend class GraphDBClient;
382
383private:
385 void operator=(const AddrStmt&);
386
387 std::vector<SVFVar*> arrSize;
388
389public:
391
392 static inline bool classof(const AddrStmt*)
393 {
394 return true;
395 }
396 static inline bool classof(const SVFStmt* edge)
397 {
398 return edge->getEdgeKind() == SVFStmt::Addr;
399 }
400 static inline bool classof(const GenericPAGEdgeTy* edge)
401 {
402 return edge->getEdgeKind() == SVFStmt::Addr;
403 }
405
408
409 virtual const std::string toString() const override;
410
411 inline void addArrSize(SVFVar* size) //TODO:addSizeVar
412 {
413 arrSize.push_back(size);
414 }
415
417 inline const std::vector<SVFVar*>& getArrSize() const //TODO:getSizeVars
418 {
419 return arrSize;
420 }
421
422 virtual bool isPTAEdge() const override
423 {
424 return true;
425 }
426};
427
431class CopyStmt: public AssignStmt
432{
433
434 friend class GraphDBClient;
435
436private:
438 void operator=(const CopyStmt&);
439public:
441 {
442 COPYVAL, // Value copies (default one)
443 ZEXT, // Zero extend integers
444 SEXT, // Sign extend integers
445 BITCAST, // Type cast
446 TRUNC, // Truncate integers
447 FPTRUNC, // Truncate floating point
448 FPTOUI, // floating point -> UInt
449 FPTOSI, // floating point -> SInt
450 UITOFP, // UInt -> floating point
451 SITOFP, // SInt -> floating point
452 INTTOPTR, // Integer -> Pointer
453 PTRTOINT // Pointer -> Integer
454 };
456
457 static inline bool classof(const CopyStmt*)
458 {
459 return true;
460 }
461 static inline bool classof(const SVFStmt* edge)
462 {
463 return edge->getEdgeKind() == SVFStmt::Copy;
464 }
465 static inline bool classof(const GenericPAGEdgeTy* edge)
466 {
467 return edge->getEdgeKind() == SVFStmt::Copy;
468 }
470
472 inline u32_t getCopyKind() const
473 {
474 return copyKind;
475 }
476
477 inline bool isBitCast() const
478 {
479 return copyKind == BITCAST;
480 }
481
482 inline bool isValueCopy() const
483 {
484 return copyKind == COPYVAL;
485 }
486
487 inline bool isInt2Ptr() const
488 {
489 return copyKind == INTTOPTR;
490 }
491
492 inline bool isPtr2Int() const
493 {
494 return copyKind == PTRTOINT;
495 }
496
497 inline bool isZext() const
498 {
499 return copyKind == ZEXT;
500 }
501
502 inline bool isSext() const
503 {
504 return copyKind == SEXT;
505 }
506
509
510 virtual const std::string toString() const override;
511
512private:
514};
515
520{
521 friend class GraphDBClient;
522
523private:
525 void operator=(const StoreStmt&);
526
527public:
529
530 static inline bool classof(const StoreStmt*)
531 {
532 return true;
533 }
534 static inline bool classof(const SVFStmt* edge)
535 {
536 return edge->getEdgeKind() == SVFStmt::Store;
537 }
538 static inline bool classof(const GenericPAGEdgeTy* edge)
539 {
540 return edge->getEdgeKind() == SVFStmt::Store;
541 }
543
545 StoreStmt(SVFVar* s, SVFVar* d, const ICFGNode* st);
546
547 virtual const std::string toString() const override;
548
549};
550
554class LoadStmt: public AssignStmt
555{
556 friend class GraphDBClient;
557
558private:
560 void operator=(const LoadStmt&);
561
562public:
564
565 static inline bool classof(const LoadStmt*)
566 {
567 return true;
568 }
569 static inline bool classof(const SVFStmt* edge)
570 {
571 return edge->getEdgeKind() == SVFStmt::Load;
572 }
573 static inline bool classof(const GenericPAGEdgeTy* edge)
574 {
575 return edge->getEdgeKind() == SVFStmt::Load;
576 }
578
581
582 virtual const std::string toString() const override;
583};
584
588class GepStmt: public AssignStmt
589{
590 friend class GraphDBClient;
591
592
593private:
594 GepStmt(const GepStmt &);
595 void operator=(const GepStmt &);
596
599public:
601
602 static inline bool classof(const GepStmt*)
603 {
604 return true;
605 }
606 static inline bool classof(const SVFStmt* edge)
607 {
608 return edge->getEdgeKind() == SVFStmt::Gep;
609 }
610 static inline bool classof(const GenericPAGEdgeTy* edge)
611 {
612 return edge->getEdgeKind() == SVFStmt::Gep;
613 }
615
616 inline const AccessPath& getAccessPath() const
617 {
618 return ap;
619 }
625 inline bool isConstantOffset() const
626 {
628 }
629
639
642 {
644 }
647 {
648 assert(isVariantFieldGep()==false && "Can't retrieve the AccessPath if using a variable field index (pointer arithmetic) for struct field access ");
650 }
652 inline bool isVariantFieldGep() const
653 {
654 return variantField;
655 }
656
658 GepStmt(SVFVar* s, SVFVar* d, const AccessPath& ap, bool varfld = false)
660 {
661 }
662
663 virtual const std::string toString() const;
664
665
666};
667
668
672class CallPE: public AssignStmt
673{
674 friend class GraphDBClient;
675
676private:
677 CallPE(const CallPE&);
678 void operator=(const CallPE&);
679
682
683public:
685
686 static inline bool classof(const CallPE*)
687 {
688 return true;
689 }
690 static inline bool classof(const SVFStmt* edge)
691 {
692 return edge->getEdgeKind() == SVFStmt::Call ||
693 edge->getEdgeKind() == SVFStmt::ThreadFork;
694 }
695 static inline bool classof(const GenericPAGEdgeTy* edge)
696 {
697 return edge->getEdgeKind() == SVFStmt::Call ||
698 edge->getEdgeKind() == SVFStmt::ThreadFork;
699 }
701
703 CallPE(SVFVar* s, SVFVar* d, const CallICFGNode* i,
705
707
708 inline const CallICFGNode* getCallInst() const
709 {
710 return call;
711 }
712 inline const CallICFGNode* getCallSite() const
713 {
714 return call;
715 }
717 {
718 return entry;
719 }
721
722 virtual const std::string toString() const override;
723};
724
728class RetPE: public AssignStmt
729{
730 friend class GraphDBClient;
731
732private:
733 RetPE(const RetPE&);
734 void operator=(const RetPE&);
735
738
739public:
741
742 static inline bool classof(const RetPE*)
743 {
744 return true;
745 }
746 static inline bool classof(const SVFStmt* edge)
747 {
748 return edge->getEdgeKind() == SVFStmt::Ret ||
749 edge->getEdgeKind() == SVFStmt::ThreadJoin;
750 }
751 static inline bool classof(const GenericPAGEdgeTy* edge)
752 {
753 return edge->getEdgeKind() == SVFStmt::Ret ||
754 edge->getEdgeKind() == SVFStmt::ThreadJoin;
755 }
757
759 RetPE(SVFVar* s, SVFVar* d, const CallICFGNode* i, const FunExitICFGNode* e,
761
763
764 inline const CallICFGNode* getCallInst() const
765 {
766 return call;
767 }
768 inline const CallICFGNode* getCallSite() const
769 {
770 return call;
771 }
773 {
774 return exit;
775 }
777
778 virtual const std::string toString() const override;
779
780};
781
782/*
783* Program statements with multiple operands including BinaryOPStmt, CmpStmt and PhiStmt
784*/
785class MultiOpndStmt : public SVFStmt
786{
787 friend class GraphDBClient;
788
789
790
791public:
792 typedef std::vector<SVFVar*> OPVars;
793
794private:
802
803protected:
807
808public:
810
811 static inline bool classof(const MultiOpndStmt*)
812 {
813 return true;
814 }
815 static inline bool classof(const SVFStmt* node)
816 {
817 return node->getEdgeKind() == Phi || node->getEdgeKind() == Select ||
818 node->getEdgeKind() == BinaryOp || node->getEdgeKind() == Cmp;
819 }
820 static inline bool classof(const GenericPAGEdgeTy* node)
821 {
822 return node->getEdgeKind() == Phi || node->getEdgeKind() == Select ||
823 node->getEdgeKind() == BinaryOp || node->getEdgeKind() == Cmp;
824 }
826
828
829
830 inline const SVFVar* getOpVar(u32_t pos) const
831 {
832 return opVars.at(pos);
833 }
835 inline const SVFVar* getRes() const
836 {
837 return SVFStmt::getDstNode();
838 }
839
840 NodeID getOpVarID(u32_t pos) const;
841 NodeID getResID() const;
842
843 inline u32_t getOpVarNum() const
844 {
845 return opVars.size();
846 }
847 inline const OPVars& getOpndVars() const
848 {
849 return opVars;
850 }
851 inline OPVars::const_iterator opVarBegin() const
852 {
853 return opVars.begin();
854 }
855 inline OPVars::const_iterator opVerEnd() const
856 {
857 return opVars.end();
858 }
860};
861
867{
868 friend class GraphDBClient;
869public:
870 typedef std::vector<const ICFGNode*> OpICFGNodeVec;
871
872private:
873 PhiStmt(const PhiStmt&);
874 void operator=(const PhiStmt&);
875
877
878public:
880
881 static inline bool classof(const PhiStmt*)
882 {
883 return true;
884 }
885 static inline bool classof(const SVFStmt* edge)
886 {
887 return edge->getEdgeKind() == SVFStmt::Phi;
888 }
889 static inline bool classof(const MultiOpndStmt* edge)
890 {
891 return edge->getEdgeKind() == SVFStmt::Phi;
892 }
893 static inline bool classof(const GenericPAGEdgeTy* edge)
894 {
895 return edge->getEdgeKind() == SVFStmt::Phi;
896 }
898
900 PhiStmt(SVFVar* res, const OPVars& opnds, const OpICFGNodeVec& icfgNodes)
901 : MultiOpndStmt(res, opnds, SVFStmt::Phi), opICFGNodes(icfgNodes)
902 {
903 assert(opnds.size() == icfgNodes.size() &&
904 "Numbers of operands and their ICFGNodes are not consistent?");
905 }
907 {
908 opVars.push_back(op);
909 opICFGNodes.push_back(inode);
910 assert(opVars.size() == opICFGNodes.size() &&
911 "Numbers of operands and their ICFGNodes are not consistent?");
912 }
913
915 {
916 assert(opVars.size() == icfgNodes.size() &&
917 "Numbers of operands and their ICFGNodes are not consistent?");
918 opICFGNodes = icfgNodes;
919 }
920
921 inline const OpICFGNodeVec* getOpICFGNodeVec() const
922 {
923 return &opICFGNodes;
924 }
925
927 inline const ICFGNode* getOpICFGNode(u32_t op_idx) const
928 {
929 return opICFGNodes.at(op_idx);
930 }
931
934 bool isFunctionRetPhi() const;
935
936 virtual const std::string toString() const override;
937
938};
939
944{
945 friend class GraphDBClient;
946private:
948 void operator=(const SelectStmt&);
949
951
952public:
954
955 static inline bool classof(const SelectStmt*)
956 {
957 return true;
958 }
959 static inline bool classof(const SVFStmt* edge)
960 {
961 return edge->getEdgeKind() == SVFStmt::Select;
962 }
963 static inline bool classof(const MultiOpndStmt* edge)
964 {
965 return edge->getEdgeKind() == SVFStmt::Select;
966 }
967 static inline bool classof(const GenericPAGEdgeTy* edge)
968 {
969 return edge->getEdgeKind() == SVFStmt::Select;
970 }
972
974 SelectStmt(SVFVar* res, const OPVars& opnds, const SVFVar* cond);
975 virtual const std::string toString() const override;
976
977 inline const SVFVar* getCondition() const
978 {
979 return condition;
980 }
981 inline const SVFVar* getTrueValue() const
982 {
983 return getOpVar(0);
984 }
985 inline const SVFVar* getFalseValue() const
986 {
987 return getOpVar(1);
988 }
989
990};
991
996{
997 friend class GraphDBClient;
998private:
999 CmpStmt(const CmpStmt&);
1000 void operator=(const CmpStmt&);
1001
1003
1004public:
1042
1044
1045 static inline bool classof(const CmpStmt*)
1046 {
1047 return true;
1048 }
1049 static inline bool classof(const SVFStmt* edge)
1050 {
1051 return edge->getEdgeKind() == SVFStmt::Cmp;
1052 }
1053 static inline bool classof(const MultiOpndStmt* edge)
1054 {
1055 return edge->getEdgeKind() == SVFStmt::Cmp;
1056 }
1057 static inline bool classof(const GenericPAGEdgeTy* edge)
1058 {
1059 return edge->getEdgeKind() == SVFStmt::Cmp;
1060 }
1062
1064 CmpStmt(SVFVar* res, const OPVars& opnds, u32_t pre);
1065
1067 {
1068 return predicate;
1069 }
1070
1071 virtual const std::string toString() const override;
1072
1073};
1074
1079{
1080 friend class GraphDBClient;
1081private:
1085
1086public:
1088 enum OpCode : unsigned
1089 {
1090 Add = 13, // Sum of integers
1091 FAdd = 14, // Sum of floats
1092 Sub = 15, // Subtraction of integers
1093 FSub = 16, // Subtraction of floats
1094 Mul = 17, // Product of integers.
1095 FMul = 18, // Product of floats.
1096 UDiv = 19, // Unsigned division.
1097 SDiv = 20, // Signed division.
1098 FDiv = 21, // Float division.
1099 URem = 22, // Unsigned remainder
1100 SRem = 23, // Signed remainder
1101 FRem = 24, // Float remainder
1102 Shl = 25, // Shift left (logical)
1103 LShr = 26, // Shift right (logical)
1104 AShr = 27, // Shift right (arithmetic)
1105 And = 28, // Logical and
1106 Or = 29, // Logical or
1107 Xor = 30 // Logical xor
1109
1111
1112 static inline bool classof(const BinaryOPStmt*)
1113 {
1114 return true;
1115 }
1116 static inline bool classof(const SVFStmt* edge)
1117 {
1118 return edge->getEdgeKind() == SVFStmt::BinaryOp;
1119 }
1120 static inline bool classof(const MultiOpndStmt* edge)
1121 {
1122 return edge->getEdgeKind() == SVFStmt::BinaryOp;
1123 }
1124 static inline bool classof(const GenericPAGEdgeTy* edge)
1125 {
1126 return edge->getEdgeKind() == SVFStmt::BinaryOp;
1127 }
1129
1131 BinaryOPStmt(SVFVar* res, const OPVars& opnds, u32_t oc);
1132
1134 {
1135 return opcode;
1136 }
1137
1138 virtual const std::string toString() const override;
1139
1140};
1141
1146{
1147 friend class GraphDBClient;
1148
1149private:
1151 void operator=(const UnaryOPStmt&);
1156
1158
1159public:
1161 enum OpCode : unsigned
1162 {
1163 FNeg = 12
1165
1167
1168 static inline bool classof(const UnaryOPStmt*)
1169 {
1170 return true;
1171 }
1172 static inline bool classof(const SVFStmt* edge)
1173 {
1174 return edge->getEdgeKind() == SVFStmt::UnaryOp;
1175 }
1176 static inline bool classof(const GenericPAGEdgeTy* edge)
1177 {
1178 return edge->getEdgeKind() == SVFStmt::UnaryOp;
1179 }
1181
1185 {
1186 }
1187
1189 {
1190 return opcode;
1191 }
1192 inline const SVFVar* getOpVar() const
1193 {
1194 return SVFStmt::getSrcNode();
1195 }
1196 inline const SVFVar* getRes() const
1197 {
1198 return SVFStmt::getDstNode();
1199 }
1200 NodeID getOpVarID() const;
1201 NodeID getResID() const;
1202
1203 virtual const std::string toString() const override;
1204
1205};
1206
1210class BranchStmt: public SVFStmt
1211{
1212 friend class GraphDBClient;
1213
1214public:
1215 typedef std::vector<std::pair<const ICFGNode*, s32_t>> SuccAndCondPairVec;
1216
1217private:
1219 void operator=(const BranchStmt&);
1224
1226 const SVFVar* cond;
1228
1229public:
1231
1232 static inline bool classof(const BranchStmt*)
1233 {
1234 return true;
1235 }
1236 static inline bool classof(const SVFStmt* edge)
1237 {
1238 return edge->getEdgeKind() == SVFStmt::Branch;
1239 }
1240 static inline bool classof(const GenericPAGEdgeTy* edge)
1241 {
1242 return edge->getEdgeKind() == SVFStmt::Branch;
1243 }
1245
1248 : SVFStmt(c, inst, SVFStmt::Branch), successors(succs), cond(c),
1249 brInst(inst)
1250 {
1251 }
1252
1254 bool isUnconditional() const;
1256 bool isConditional() const;
1258 const SVFVar* getCondition() const;
1259 const SVFVar* getBranchInst() const
1260 {
1261 return brInst;
1262 }
1263
1267
1271
1275 {
1276 return successors.size();
1277 }
1279 {
1280 return successors;
1281 }
1283 {
1284 return successors.at(i).first;
1285 }
1287 {
1288 return successors.at(i).second;
1289 }
1291 virtual const std::string toString() const override;
1292
1293};
1294
1298class TDForkPE: public CallPE
1299{
1300 friend class GraphDBClient;
1301
1302private:
1304 void operator=(const TDForkPE&);
1305
1306public:
1308
1309 static inline bool classof(const TDForkPE*)
1310 {
1311 return true;
1312 }
1313 static inline bool classof(const SVFStmt* edge)
1314 {
1315 return edge->getEdgeKind() == SVFStmt::ThreadFork;
1316 }
1317 static inline bool classof(const GenericPAGEdgeTy* edge)
1318 {
1319 return edge->getEdgeKind() == SVFStmt::ThreadFork;
1320 }
1322
1325 const FunEntryICFGNode* entry)
1327 {
1328 }
1329
1330 virtual const std::string toString() const;
1331
1332};
1333
1337class TDJoinPE: public RetPE
1338{
1339 friend class GraphDBClient;
1340
1341private:
1343 void operator=(const TDJoinPE&);
1344
1345public:
1347
1348 static inline bool classof(const TDJoinPE*)
1349 {
1350 return true;
1351 }
1352 static inline bool classof(const SVFStmt* edge)
1353 {
1354 return edge->getEdgeKind() == SVFStmt::ThreadJoin;
1355 }
1356 static inline bool classof(const GenericPAGEdgeTy* edge)
1357 {
1358 return edge->getEdgeKind() == SVFStmt::ThreadJoin;
1359 }
1361
1364 const FunExitICFGNode* e)
1365 : RetPE(s, d, i, e, SVFStmt::ThreadJoin)
1366 {
1367 }
1368
1369 virtual const std::string toString() const;
1370
1371};
1372
1373} // End namespace SVF
1374
1375#endif /* INCLUDE_SVFIR_SVFSTATEMENT_H_ */
std::vector< IdxOperandPair > IdxOperandPairs
Definition AccessPath.h:62
bool isConstantOffset() const
Return TRUE if this is a constant location set.
APOffset computeConstantByteOffset() const
APOffset getConstantStructFldIdx() const
Get methods.
Definition AccessPath.h:97
const IdxOperandPairs & getIdxOperandPairVec() const
Definition AccessPath.h:105
APOffset computeConstantOffset() const
For example,.
void operator=(const AddrStmt &)
place holder
AddrStmt(const AddrStmt &)
place holder
void addArrSize(SVFVar *size)
get array size of the allocated memory
static bool classof(const AddrStmt *)
Methods for support type inquiry through isa, cast, and dyn_cast:
AddrStmt(SVFVar *s, SVFVar *d)
constructor
static bool classof(const GenericPAGEdgeTy *edge)
friend class GraphDBClient
virtual bool isPTAEdge() const override
Whether src and dst nodes are both of pointer type.
virtual const std::string toString() const override
std::vector< SVFVar * > arrSize
Array size of the allocated memory.
const std::vector< SVFVar * > & getArrSize() const
static bool classof(const SVFStmt *edge)
SVFVar * getSrcNode()
not allowed, use getRHSVar() instead
SVFVar * getDstNode()
not allowed, use getLHSVar() instead
AssignStmt(const AssignStmt &)
place holder
NodeID getRHSVarID() const
static bool classof(const AssignStmt *)
Methods for support type inquiry through isa, cast, and dyn_cast:
static bool classof(const GenericPAGEdgeTy *edge)
NodeID getLHSVarID() const
NodeID getDstID()
not allowed, use getLHSVarID() instead
NodeID getSrcID()
not allowed, use getRHSVarID() instead
SVFVar * getLHSVar() const
friend class GraphDBClient
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)
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....
static bool classof(const MultiOpndStmt *edge)
void operator=(const BinaryOPStmt &)
place holder
BinaryOPStmt(const BinaryOPStmt &)
place holder
friend class GraphDBClient
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 ICFGNode * getSuccessor(u32_t i) 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
SVFVar * getDstNode()
place holder, not allowed
const SVFVar * getCondition() const
Return the condition.
NodeID getSrcID()
place holder, use getOpVarID(pos) instead
const SVFVar * getBranchInst() const
friend class GraphDBClient
SVFVar * getSrcNode()
place holder, not allowed
const SuccAndCondPairVec & getSuccessors() const
NodeID getDstID()
place holder, use getResID() instead
const SVFVar * cond
static bool classof(const GenericPAGEdgeTy *edge)
virtual const std::string toString() const override
static bool classof(const GenericPAGEdgeTy *edge)
static bool classof(const SVFStmt *edge)
CallPE(const CallPE &)
place holder
const CallICFGNode * getCallSite() const
const FunEntryICFGNode * getFunEntryICFGNode() const
static bool classof(const CallPE *)
the function exit statement calling to
const FunEntryICFGNode * entry
the callsite statement calling from
void operator=(const CallPE &)
place holder
friend class GraphDBClient
const CallICFGNode * call
const CallICFGNode * getCallInst() const
Get method for the call instruction.
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)
void operator=(const CmpStmt &)
place holder
u32_t getPredicate() const
friend class GraphDBClient
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)
bool isBitCast() const
void operator=(const CopyStmt &)
place holder
CopyStmt(const CopyStmt &)
place holder
friend class GraphDBClient
bool isValueCopy() const
virtual const std::string toString() const override
bool isInt2Ptr() const
bool isSext() const
NodeType * getSrcNode() const
NodeType * getDstNode() const
GEdgeKind getEdgeKind() const
NodeID getDstID() const
NodeID getSrcID() const
get methods of the components
static constexpr unsigned char EdgeKindMaskBits
We use the lower 8 bits to denote edge kind.
OrderedSet< EdgeType *, typename EdgeType::equalGEdge > GEdgeSetTy
Edge kind.
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:
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)
const AccessPath & getAccessPath() const
void operator=(const GepStmt &)
place holder
friend class GraphDBClient
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
virtual const std::string toString() const override
LoadStmt(SVFVar *s, SVFVar *d)
constructor
friend class GraphDBClient
static bool classof(const GenericPAGEdgeTy *edge)
static bool classof(const SVFStmt *edge)
void operator=(const LoadStmt &)
place holder
const OPVars & getOpndVars() const
const SVFVar * getRes() const
Result SVFVar.
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
SVFVar * getSrcNode()
not allowed, use getOpVar(idx) instead
static bool classof(const MultiOpndStmt *)
Methods for support type inquiry through isa, cast, and dyn_cast:
const SVFVar * getOpVar(u32_t pos) const
Operand SVFVars.
friend class GraphDBClient
OPVars::const_iterator opVarBegin() const
SVFVar * getDstNode()
not allowed, use getRes() instead
NodeID getSrcID()
not allowed, use getOpVarID(idx) instead
std::vector< SVFVar * > OPVars
static bool classof(const GenericPAGEdgeTy *node)
OPVars::const_iterator opVerEnd() const
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(const PhiStmt &)
place holder
const OpICFGNodeVec * getOpICFGNodeVec() const
bool isFunctionRetPhi() const
static bool classof(const GenericPAGEdgeTy *edge)
friend class GraphDBClient
static bool classof(const PhiStmt *)
Methods for support type inquiry through isa, cast, and dyn_cast:
static bool classof(const SVFStmt *edge)
void addOpVar(SVFVar *op, const ICFGNode *inode)
PhiStmt(SVFVar *res, const OPVars &opnds, const OpICFGNodeVec &icfgNodes)
constructor
void setOpICFGNodeVec(OpICFGNodeVec &icfgNodes)
static bool classof(const MultiOpndStmt *edge)
RetPE(const RetPE &)
place holder
const CallICFGNode * getCallSite() const
static bool classof(const GenericPAGEdgeTy *edge)
static bool classof(const RetPE *)
the function exit statement returned from
const CallICFGNode * getCallInst() const
Get method for call instruction at caller.
virtual const std::string toString() const override
const FunExitICFGNode * exit
the callsite statement returning to
const FunExitICFGNode * getFunExitICFGNode() const
static bool classof(const SVFStmt *edge)
const CallICFGNode * call
friend class GraphDBClient
void operator=(const RetPE &)
place holder
static bool classof(const GenericPAGEdgeTy *edge)
static void addInst2Labeled(const ICFGNode *cs, u32_t label)
ICFGNode * getICFGNode() const
virtual bool isPTAEdge() const
Whether src and dst nodes are both of pointer type.
void setBasicBlock(const SVFBasicBlock *bb)
void setBB(const SVFBasicBlock *bb)
friend OutStream & operator<<(OutStream &o, const SVFStmt &edge)
Overloading operator << for dumping SVFVar value.
void setMultiOpndLabelCounter(u64_t counter)
const SVFVar * getValue() const
void setValue(const SVFVar *val)
Get/set methods for llvm instruction.
Map< EdgeID, SVFStmtSetTy > PAGEdgeToSetMapTy
static u64_t callEdgeLabelCounter
Call site Instruction counter.
static Var2LabelMap var2LabelMap
Second operand of MultiOpndStmt to label map.
SVFStmtSetTy PAGEdgeSetTy
void setCallEdgeLabelCounter(u64_t counter)
static GEdgeFlag makeEdgeFlagWithAddionalOpnd(GEdgeKind k, const SVFVar *var)
const SVFBasicBlock * getBB() const
static GEdgeFlag makeEdgeFlagWithCallInst(GEdgeKind k, const ICFGNode *cs)
SVFStmt(GEdgeFlag k)
Private constructor for reading SVFIR from file without side-effect.
ICFGNode * icfgNode
ICFGNode.
static u64_t storeEdgeLabelCounter
Store Instruction counter.
EdgeID edgeId
Edge ID.
static const Inst2LabelMap * getInst2LabelMap()
Map< const ICFGNode *, u32_t > Inst2LabelMap
void setStoreEdgeLabelCounter(u64_t counter)
static const u64_t * getStoreEdgeLabelCounter()
const SVFBasicBlock * basicBlock
LLVM BasicBlock.
GenericNode< SVFVar, SVFStmt >::GEdgeSetTy SVFStmtSetTy
PAGEdgeToSetMapTy KindToSVFStmtMapTy
static u64_t multiOpndLabelCounter
MultiOpndStmt counter.
static const u64_t * getCallEdgeLabelCounter()
~SVFStmt()
Destructor.
friend class GraphDBClient
static Inst2LabelMap inst2LabelMap
Call site Instruction to label map.
static bool classof(const SVFStmt *)
ClassOf.
static const u64_t * getMultiOpndLabelCounter()
virtual const std::string toString() const
Map< const SVFVar *, u32_t > Var2LabelMap
static GEdgeFlag makeEdgeFlagWithStoreInst(GEdgeKind k, const ICFGNode *store)
const SVFVar * value
LLVM value.
void setICFGNode(ICFGNode *node)
static void addVar2Labeled(const SVFVar *var, u32_t label)
static const Var2LabelMap * getVar2LabelMap()
EdgeID getEdgeID() const
Return Edge ID.
static bool classof(const MultiOpndStmt *edge)
const SVFVar * getCondition() const
const SVFVar * condition
const SVFVar * getTrueValue() const
static bool classof(const SVFStmt *edge)
virtual const std::string toString() const override
const SVFVar * getFalseValue() const
static bool classof(const SelectStmt *)
Methods for support type inquiry through isa, cast, and dyn_cast:
static bool classof(const GenericPAGEdgeTy *edge)
friend class GraphDBClient
SelectStmt(const SelectStmt &)
place holder
void operator=(const SelectStmt &)
place holder
StoreStmt(const StoreStmt &)
place holder
static bool classof(const SVFStmt *edge)
virtual const std::string toString() const override
friend class GraphDBClient
static bool classof(const GenericPAGEdgeTy *edge)
void operator=(const StoreStmt &)
place holder
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:
static bool classof(const GenericPAGEdgeTy *edge)
virtual const std::string toString() const
friend class GraphDBClient
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)
void operator=(const TDJoinPE &)
place holder
TDJoinPE(const TDJoinPE &)
place holder
friend class GraphDBClient
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.
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
const SVFVar * getOpVar() const
void operator=(const UnaryOPStmt &)
place holder
SVFVar * getSrcNode()
place holder, use getOpVar() instead
NodeID getOpVarID() const
SVFVar * getDstNode()
place holder, use getRes() instead
UnaryOPStmt(const UnaryOPStmt &)
place holder
friend class GraphDBClient
NodeID getDstID()
place holder, use getResID() instead
static bool classof(const UnaryOPStmt *)
Methods for support type inquiry through isa, cast, and dyn_cast:
const SVFVar * getRes() 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:49
u32_t NodeID
Definition GeneralType.h:56
s64_t APOffset
Definition GeneralType.h:60
std::ostream OutStream
Definition GeneralType.h:46
llvm::IRBuilder IRBuilder
Definition BasicTypes.h:74
GenericEdge< SVFVar > GenericPAGEdgeTy
unsigned u32_t
Definition GeneralType.h:47
signed long long s64_t
Definition GeneralType.h:50
u32_t EdgeID
Definition GeneralType.h:57