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 ValVar;
42class ObjVar;
43class ICFGNode;
44class IntraICFGNode;
45class CallICFGNode;
46class FunEntryICFGNode;
47class FunExitICFGNode;
48class SVFBasicBlock;
49
50/*
51 * SVFIR program statements (PAGEdges)
52 */
55{
56 friend class GraphDBClient;
57
58public:
81
82private:
83 const SVFVar* value;
87
88protected:
91 : GenericPAGEdgeTy({}, {}, k), value{}, basicBlock{}, icfgNode{}
92 {
93 }
94
95 SVFStmt(SVFVar* s, SVFVar* d, GEdgeFlag k, EdgeID eid, SVFVar* value, ICFGNode* icfgNode, bool real = true);
96
100 inline void setBasicBlock(const SVFBasicBlock* bb)
101 {
102 basicBlock = bb;
103 }
104
112
120
128
132 static inline void addInst2Labeled(const ICFGNode* cs, u32_t label)
133 {
134 inst2LabelMap.emplace(cs, label);
135 }
136
137 static inline void addVar2Labeled(const SVFVar* var, u32_t label)
138 {
139 var2LabelMap.emplace(var, label);
140 }
141
142public:
143
145 SVFStmt(SVFVar* s, SVFVar* d, GEdgeFlag k, bool real = true);
148
150
151 static inline bool classof(const SVFStmt*)
152 {
153 return true;
154 }
155 static inline bool classof(const GenericPAGEdgeTy* edge)
156 {
157 return edge->getEdgeKind() == SVFStmt::Addr ||
158 edge->getEdgeKind() == SVFStmt::Copy ||
159 edge->getEdgeKind() == SVFStmt::Store ||
160 edge->getEdgeKind() == SVFStmt::Load ||
161 edge->getEdgeKind() == SVFStmt::Call ||
162 edge->getEdgeKind() == SVFStmt::Ret ||
163 edge->getEdgeKind() == SVFStmt::Gep ||
164 edge->getEdgeKind() == SVFStmt::Phi ||
165 edge->getEdgeKind() == SVFStmt::Select ||
166 edge->getEdgeKind() == SVFStmt::Cmp ||
167 edge->getEdgeKind() == SVFStmt::BinaryOp ||
168 edge->getEdgeKind() == SVFStmt::UnaryOp ||
169 edge->getEdgeKind() == SVFStmt::Branch ||
170 edge->getEdgeKind() == SVFStmt::ThreadFork ||
171 edge->getEdgeKind() == SVFStmt::ThreadJoin;
172 }
174
176 inline EdgeID getEdgeID() const
177 {
178 return edgeId;
179 }
181 virtual bool isPTAEdge() const;
182
184
185
186 inline void setValue(const SVFVar* val)
187 {
188 value = val;
189 }
190 inline const SVFVar* getValue() const
191 {
192 return value;
193 }
194
195 inline void setBB(const SVFBasicBlock* bb)
196 {
197 basicBlock = bb;
198 }
199 inline const SVFBasicBlock* getBB() const
200 {
201 return basicBlock;
202 }
203 inline void setICFGNode(ICFGNode* node)
204 {
205 icfgNode = node;
206 }
207 inline ICFGNode* getICFGNode() const
208 {
209 return icfgNode;
210 }
212
216 const SVFVar* var)
217 {
219 if (it_inserted.second)
221 u64_t label = it_inserted.first->second;
222 return (label << EdgeKindMaskBits) | k;
223 }
224
228 const ICFGNode* cs)
229 {
231 if (it_inserted.second)
233 u64_t label = it_inserted.first->second;
234 return (label << EdgeKindMaskBits) | k;
235 }
236
240 const ICFGNode* store)
241 {
242 auto it_inserted = inst2LabelMap.emplace(store, storeEdgeLabelCounter);
243 if (it_inserted.second)
245 u64_t label = it_inserted.first->second;
246 return (label << EdgeKindMaskBits) | k;
247 }
248
249 virtual const std::string toString() const;
250
252
255 {
256 o << edge.toString();
257 return o;
258 }
260
265
266private:
274
275public:
276 static inline const Inst2LabelMap* getInst2LabelMap()
277 {
278 return &inst2LabelMap;
279 }
280
281 static inline const Var2LabelMap* getVar2LabelMap()
282 {
283 return &var2LabelMap;
284 }
285
286 static inline const u64_t* getCallEdgeLabelCounter()
287 {
288 return &callEdgeLabelCounter;
289 }
290
291 static inline const u64_t* getStoreEdgeLabelCounter()
292 {
293 return &storeEdgeLabelCounter;
294 }
295
296 static inline const u64_t* getMultiOpndLabelCounter()
297 {
298 return &multiOpndLabelCounter;
299 }
300
301};
302
303/*
304 Parent class of Addr, Copy, Store, Load, Call, Ret, NormalGep, VariantGep, ThreadFork, ThreadJoin
305 connecting RHS expression and LHS expression with an assignment (e.g., LHSExpr = RHSExpr)
306 Only one operand on the right hand side of an assignment
307*/
308class AssignStmt : public SVFStmt
309{
310 friend class GraphDBClient;
311
312private:
315 void operator=(const AssignStmt &);
320
321protected:
324
325public:
327
328 static inline bool classof(const AssignStmt*)
329 {
330 return true;
331 }
332 static inline bool classof(const SVFStmt* edge)
333 {
334 return edge->getEdgeKind() == SVFStmt::Addr ||
335 edge->getEdgeKind() == SVFStmt::Copy ||
336 edge->getEdgeKind() == SVFStmt::Store ||
337 edge->getEdgeKind() == SVFStmt::Load ||
338 edge->getEdgeKind() == SVFStmt::Ret ||
339 edge->getEdgeKind() == SVFStmt::Gep ||
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::Ret ||
349 edge->getEdgeKind() == SVFStmt::Gep ||
350 edge->getEdgeKind() == SVFStmt::ThreadJoin;
351 }
353
354 inline SVFVar* getRHSVar() const
355 {
356 return SVFStmt::getSrcNode();
357 }
358 inline SVFVar* getLHSVar() const
359 {
360 return SVFStmt::getDstNode();
361 }
362 inline NodeID getRHSVarID() const
363 {
364 return SVFStmt::getSrcID();
365 }
366 inline NodeID getLHSVarID() const
367 {
368 return SVFStmt::getDstID();
369 }
370
371 virtual const std::string toString() const = 0;
372};
373
377class AddrStmt: public AssignStmt
378{
379 friend class GraphDBClient;
380
381private:
383 void operator=(const AddrStmt&);
384
385 std::vector<SVFVar*> arrSize;
386
387public:
389
390 static inline bool classof(const AddrStmt*)
391 {
392 return true;
393 }
394 static inline bool classof(const SVFStmt* edge)
395 {
396 return edge->getEdgeKind() == SVFStmt::Addr;
397 }
398 static inline bool classof(const GenericPAGEdgeTy* edge)
399 {
400 return edge->getEdgeKind() == SVFStmt::Addr;
401 }
403
406
407 virtual const std::string toString() const override;
408
409 inline void addArrSize(SVFVar* size) //TODO:addSizeVar
410 {
411 arrSize.push_back(size);
412 }
413
415 inline const std::vector<SVFVar*>& getArrSize() const //TODO:getSizeVars
416 {
417 return arrSize;
418 }
419
420 virtual bool isPTAEdge() const override
421 {
422 return true;
423 }
424
425 const ValVar* getLHSVar() const;
426 const ObjVar* getRHSVar() const;
427 const ValVar* getDstNode() const;
428 const ObjVar* getSrcNode() const;
429};
430
434class CopyStmt: public AssignStmt
435{
436
437 friend class GraphDBClient;
438
439private:
441 void operator=(const CopyStmt&);
442public:
444 {
445 COPYVAL, // Value copies (default one)
446 ZEXT, // Zero extend integers
447 SEXT, // Sign extend integers
448 BITCAST, // Type cast
449 TRUNC, // Truncate integers
450 FPTRUNC, // Truncate floating point
451 FPTOUI, // floating point -> UInt
452 FPTOSI, // floating point -> SInt
453 UITOFP, // UInt -> floating point
454 SITOFP, // SInt -> floating point
455 INTTOPTR, // Integer -> Pointer
456 PTRTOINT // Pointer -> Integer
457 };
459
460 static inline bool classof(const CopyStmt*)
461 {
462 return true;
463 }
464 static inline bool classof(const SVFStmt* edge)
465 {
466 return edge->getEdgeKind() == SVFStmt::Copy;
467 }
468 static inline bool classof(const GenericPAGEdgeTy* edge)
469 {
470 return edge->getEdgeKind() == SVFStmt::Copy;
471 }
473
475 inline u32_t getCopyKind() const
476 {
477 return copyKind;
478 }
479
480 inline bool isBitCast() const
481 {
482 return copyKind == BITCAST;
483 }
484
485 inline bool isValueCopy() const
486 {
487 return copyKind == COPYVAL;
488 }
489
490 inline bool isInt2Ptr() const
491 {
492 return copyKind == INTTOPTR;
493 }
494
495 inline bool isPtr2Int() const
496 {
497 return copyKind == PTRTOINT;
498 }
499
500 inline bool isZext() const
501 {
502 return copyKind == ZEXT;
503 }
504
505 inline bool isSext() const
506 {
507 return copyKind == SEXT;
508 }
509
512
513 const ValVar* getRHSVar() const;
514 const ValVar* getLHSVar() const;
515 const ValVar* getSrcNode() const;
516 const ValVar* getDstNode() const;
517
518 virtual const std::string toString() const override;
519
520private:
522};
523
528{
529 friend class GraphDBClient;
530
531private:
533 void operator=(const StoreStmt&);
534
535public:
537
538 static inline bool classof(const StoreStmt*)
539 {
540 return true;
541 }
542 static inline bool classof(const SVFStmt* edge)
543 {
544 return edge->getEdgeKind() == SVFStmt::Store;
545 }
546 static inline bool classof(const GenericPAGEdgeTy* edge)
547 {
548 return edge->getEdgeKind() == SVFStmt::Store;
549 }
551
553 StoreStmt(SVFVar* s, SVFVar* d, const ICFGNode* st);
554
555 const ValVar* getRHSVar() const;
556 const ValVar* getLHSVar() const;
557 const ValVar* getSrcNode() const;
558 const ValVar* getDstNode() const;
559
560 virtual const std::string toString() const override;
561
562};
563
567class LoadStmt: public AssignStmt
568{
569 friend class GraphDBClient;
570
571private:
573 void operator=(const LoadStmt&);
574
575public:
577
578 static inline bool classof(const LoadStmt*)
579 {
580 return true;
581 }
582 static inline bool classof(const SVFStmt* edge)
583 {
584 return edge->getEdgeKind() == SVFStmt::Load;
585 }
586 static inline bool classof(const GenericPAGEdgeTy* edge)
587 {
588 return edge->getEdgeKind() == SVFStmt::Load;
589 }
591
594
595 const ValVar* getRHSVar() const;
596 const ValVar* getLHSVar() const;
597 const ValVar* getSrcNode() const;
598 const ValVar* getDstNode() const;
599
600 virtual const std::string toString() const override;
601};
602
606class GepStmt: public AssignStmt
607{
608 friend class GraphDBClient;
609
610
611private:
612 GepStmt(const GepStmt &);
613 void operator=(const GepStmt &);
614
617public:
619
620 static inline bool classof(const GepStmt*)
621 {
622 return true;
623 }
624 static inline bool classof(const SVFStmt* edge)
625 {
626 return edge->getEdgeKind() == SVFStmt::Gep;
627 }
628 static inline bool classof(const GenericPAGEdgeTy* edge)
629 {
630 return edge->getEdgeKind() == SVFStmt::Gep;
631 }
633
634 inline const AccessPath& getAccessPath() const
635 {
636 return ap;
637 }
643 inline bool isConstantOffset() const
644 {
646 }
647
657
660 {
662 }
665 {
666 assert(isVariantFieldGep()==false && "Can't retrieve the AccessPath if using a variable field index (pointer arithmetic) for struct field access ");
668 }
670 inline bool isVariantFieldGep() const
671 {
672 return variantField;
673 }
674
676 GepStmt(SVFVar* s, SVFVar* d, const AccessPath& ap, bool varfld = false)
678 {
679 }
680
681 const ValVar* getRHSVar() const;
682 const ValVar* getLHSVar() const;
683 const ValVar* getSrcNode() const;
684 const ValVar* getDstNode() const;
685
686 virtual const std::string toString() const;
687
688
689};
690
691
695class RetPE: public AssignStmt
696{
697 friend class GraphDBClient;
698
699private:
700 RetPE(const RetPE&);
701 void operator=(const RetPE&);
702
705
706public:
708
709 static inline bool classof(const RetPE*)
710 {
711 return true;
712 }
713 static inline bool classof(const SVFStmt* edge)
714 {
715 return edge->getEdgeKind() == SVFStmt::Ret ||
716 edge->getEdgeKind() == SVFStmt::ThreadJoin;
717 }
718 static inline bool classof(const GenericPAGEdgeTy* edge)
719 {
720 return edge->getEdgeKind() == SVFStmt::Ret ||
721 edge->getEdgeKind() == SVFStmt::ThreadJoin;
722 }
724
726 RetPE(SVFVar* s, SVFVar* d, const CallICFGNode* i, const FunExitICFGNode* e,
728
730
731 inline const CallICFGNode* getCallInst() const
732 {
733 return call;
734 }
735 inline const CallICFGNode* getCallSite() const
736 {
737 return call;
738 }
740 {
741 return exit;
742 }
744
745 const ValVar* getRHSVar() const;
746 const ValVar* getLHSVar() const;
747 const ValVar* getSrcNode() const;
748 const ValVar* getDstNode() const;
749
750 virtual const std::string toString() const override;
751
752};
753
754/*
755* Program statements with multiple operands including BinaryOPStmt, CmpStmt and PhiStmt
756*/
757class MultiOpndStmt : public SVFStmt
758{
759 friend class GraphDBClient;
760
761public:
762 typedef std::vector<ValVar*> OPVars;
763
764private:
772
773protected:
777
778public:
780
781 static inline bool classof(const MultiOpndStmt*)
782 {
783 return true;
784 }
785 static inline bool classof(const SVFStmt* node)
786 {
787 return node->getEdgeKind() == Phi || node->getEdgeKind() == Select ||
788 node->getEdgeKind() == BinaryOp || node->getEdgeKind() == Cmp ||
789 node->getEdgeKind() == Call || node->getEdgeKind() == ThreadFork;
790 }
791 static inline bool classof(const GenericPAGEdgeTy* node)
792 {
793 return node->getEdgeKind() == Phi || node->getEdgeKind() == Select ||
794 node->getEdgeKind() == BinaryOp || node->getEdgeKind() == Cmp ||
795 node->getEdgeKind() == Call || node->getEdgeKind() == ThreadFork;
796 }
798
800
801
802 inline const ValVar* getOpVar(u32_t pos) const
803 {
804 return opVars.at(pos);
805 }
807 const ValVar* getRes() const;
808
809 NodeID getOpVarID(u32_t pos) const;
810 NodeID getResID() const;
811
812 inline u32_t getOpVarNum() const
813 {
814 return opVars.size();
815 }
816 inline const OPVars& getOpndVars() const
817 {
818 return opVars;
819 }
820 inline OPVars::const_iterator opVarBegin() const
821 {
822 return opVars.begin();
823 }
824 inline OPVars::const_iterator opVerEnd() const
825 {
826 return opVars.end();
827 }
829};
830
838{
839 friend class GraphDBClient;
840
841public:
842 typedef std::vector<const CallICFGNode*> CallICFGNodeVec;
843
844private:
845 CallPE(const CallPE&);
846 void operator=(const CallPE&);
847
850
851public:
853
854 static inline bool classof(const CallPE*)
855 {
856 return true;
857 }
858 static inline bool classof(const SVFStmt* edge)
859 {
860 return edge->getEdgeKind() == SVFStmt::Call ||
861 edge->getEdgeKind() == SVFStmt::ThreadFork;
862 }
863 static inline bool classof(const GenericPAGEdgeTy* edge)
864 {
865 return edge->getEdgeKind() == SVFStmt::Call ||
866 edge->getEdgeKind() == SVFStmt::ThreadFork;
867 }
869
871 CallPE(ValVar* res, const OPVars& opnds,
872 const CallICFGNodeVec& icfgNodes,
873 const FunEntryICFGNode* e,
875
877 void addOpVar(ValVar* op, const CallICFGNode* call)
878 {
879 opVars.push_back(op);
880 opCallICFGNodes.push_back(call);
881 assert(opVars.size() == opCallICFGNodes.size() &&
882 "Numbers of operands and their CallICFGNodes are not consistent?");
883 }
884
887 {
888 return opCallICFGNodes.at(op_idx);
889 }
890
893 {
894 return opCallICFGNodes;
895 }
896
899 {
900 return entry;
901 }
902
903 virtual const std::string toString() const override;
904};
905
911{
912 friend class GraphDBClient;
913public:
914 typedef std::vector<const ICFGNode*> OpICFGNodeVec;
915
916private:
917 PhiStmt(const PhiStmt&);
918 void operator=(const PhiStmt&);
919
921
922public:
924
925 static inline bool classof(const PhiStmt*)
926 {
927 return true;
928 }
929 static inline bool classof(const SVFStmt* edge)
930 {
931 return edge->getEdgeKind() == SVFStmt::Phi;
932 }
933 static inline bool classof(const MultiOpndStmt* edge)
934 {
935 return edge->getEdgeKind() == SVFStmt::Phi;
936 }
937 static inline bool classof(const GenericPAGEdgeTy* edge)
938 {
939 return edge->getEdgeKind() == SVFStmt::Phi;
940 }
942
944 PhiStmt(ValVar* res, const OPVars& opnds, const OpICFGNodeVec& icfgNodes)
945 : MultiOpndStmt(res, opnds, SVFStmt::Phi), opICFGNodes(icfgNodes)
946 {
947 assert(opnds.size() == icfgNodes.size() &&
948 "Numbers of operands and their ICFGNodes are not consistent?");
949 }
951 {
952 opVars.push_back(op);
953 opICFGNodes.push_back(inode);
954 assert(opVars.size() == opICFGNodes.size() &&
955 "Numbers of operands and their ICFGNodes are not consistent?");
956 }
957
959 {
960 assert(opVars.size() == icfgNodes.size() &&
961 "Numbers of operands and their ICFGNodes are not consistent?");
962 opICFGNodes = icfgNodes;
963 }
964
965 inline const OpICFGNodeVec* getOpICFGNodeVec() const
966 {
967 return &opICFGNodes;
968 }
969
971 inline const ICFGNode* getOpICFGNode(u32_t op_idx) const
972 {
973 return opICFGNodes.at(op_idx);
974 }
975
978 bool isFunctionRetPhi() const;
979
980 virtual const std::string toString() const override;
981
982};
983
988{
989 friend class GraphDBClient;
990private:
992 void operator=(const SelectStmt&);
993
995
996public:
998
999 static inline bool classof(const SelectStmt*)
1000 {
1001 return true;
1002 }
1003 static inline bool classof(const SVFStmt* edge)
1004 {
1005 return edge->getEdgeKind() == SVFStmt::Select;
1006 }
1007 static inline bool classof(const MultiOpndStmt* edge)
1008 {
1009 return edge->getEdgeKind() == SVFStmt::Select;
1010 }
1011 static inline bool classof(const GenericPAGEdgeTy* edge)
1012 {
1013 return edge->getEdgeKind() == SVFStmt::Select;
1014 }
1016
1018 SelectStmt(ValVar* res, const OPVars& opnds, const SVFVar* cond);
1019 virtual const std::string toString() const override;
1020
1021 inline const SVFVar* getCondition() const
1022 {
1023 return condition;
1024 }
1025 inline const ValVar* getTrueValue() const
1026 {
1027 return getOpVar(0);
1028 }
1029 inline const ValVar* getFalseValue() const
1030 {
1031 return getOpVar(1);
1032 }
1033
1034};
1035
1040{
1041 friend class GraphDBClient;
1042private:
1044 void operator=(const CmpStmt&);
1045
1047
1048public:
1086
1088
1089 static inline bool classof(const CmpStmt*)
1090 {
1091 return true;
1092 }
1093 static inline bool classof(const SVFStmt* edge)
1094 {
1095 return edge->getEdgeKind() == SVFStmt::Cmp;
1096 }
1097 static inline bool classof(const MultiOpndStmt* edge)
1098 {
1099 return edge->getEdgeKind() == SVFStmt::Cmp;
1100 }
1101 static inline bool classof(const GenericPAGEdgeTy* edge)
1102 {
1103 return edge->getEdgeKind() == SVFStmt::Cmp;
1104 }
1106
1108 CmpStmt(ValVar* res, const OPVars& opnds, u32_t pre);
1109
1111 {
1112 return predicate;
1113 }
1114
1115 virtual const std::string toString() const override;
1116
1117};
1118
1123{
1124 friend class GraphDBClient;
1125private:
1129
1130public:
1132 enum OpCode : unsigned
1133 {
1134 Add = 13, // Sum of integers
1135 FAdd = 14, // Sum of floats
1136 Sub = 15, // Subtraction of integers
1137 FSub = 16, // Subtraction of floats
1138 Mul = 17, // Product of integers.
1139 FMul = 18, // Product of floats.
1140 UDiv = 19, // Unsigned division.
1141 SDiv = 20, // Signed division.
1142 FDiv = 21, // Float division.
1143 URem = 22, // Unsigned remainder
1144 SRem = 23, // Signed remainder
1145 FRem = 24, // Float remainder
1146 Shl = 25, // Shift left (logical)
1147 LShr = 26, // Shift right (logical)
1148 AShr = 27, // Shift right (arithmetic)
1149 And = 28, // Logical and
1150 Or = 29, // Logical or
1151 Xor = 30 // Logical xor
1153
1155
1156 static inline bool classof(const BinaryOPStmt*)
1157 {
1158 return true;
1159 }
1160 static inline bool classof(const SVFStmt* edge)
1161 {
1162 return edge->getEdgeKind() == SVFStmt::BinaryOp;
1163 }
1164 static inline bool classof(const MultiOpndStmt* edge)
1165 {
1166 return edge->getEdgeKind() == SVFStmt::BinaryOp;
1167 }
1168 static inline bool classof(const GenericPAGEdgeTy* edge)
1169 {
1170 return edge->getEdgeKind() == SVFStmt::BinaryOp;
1171 }
1173
1175 BinaryOPStmt(ValVar* res, const OPVars& opnds, u32_t oc);
1176
1178 {
1179 return opcode;
1180 }
1181
1182 virtual const std::string toString() const override;
1183
1184};
1185
1190{
1191 friend class GraphDBClient;
1192
1193private:
1195 void operator=(const UnaryOPStmt&);
1200
1202
1203public:
1205 enum OpCode : unsigned
1206 {
1207 FNeg = 12
1209
1211
1212 static inline bool classof(const UnaryOPStmt*)
1213 {
1214 return true;
1215 }
1216 static inline bool classof(const SVFStmt* edge)
1217 {
1218 return edge->getEdgeKind() == SVFStmt::UnaryOp;
1219 }
1220 static inline bool classof(const GenericPAGEdgeTy* edge)
1221 {
1222 return edge->getEdgeKind() == SVFStmt::UnaryOp;
1223 }
1225
1228
1230 {
1231 return opcode;
1232 }
1233 const ValVar* getOpVar() const;
1234 const ValVar* getRes() const;
1235 NodeID getOpVarID() const;
1236 NodeID getResID() const;
1237
1238 virtual const std::string toString() const override;
1239
1240};
1241
1245class BranchStmt: public SVFStmt
1246{
1247 friend class GraphDBClient;
1248
1249public:
1250 typedef std::vector<std::pair<const ICFGNode*, s32_t>> SuccAndCondPairVec;
1251
1252private:
1254 void operator=(const BranchStmt&);
1259
1261 const ValVar* cond;
1263
1264public:
1266
1267 static inline bool classof(const BranchStmt*)
1268 {
1269 return true;
1270 }
1271 static inline bool classof(const SVFStmt* edge)
1272 {
1273 return edge->getEdgeKind() == SVFStmt::Branch;
1274 }
1275 static inline bool classof(const GenericPAGEdgeTy* edge)
1276 {
1277 return edge->getEdgeKind() == SVFStmt::Branch;
1278 }
1280
1283
1285 bool isUnconditional() const;
1287 bool isConditional() const;
1289 const ValVar* getCondition() const;
1290 const ValVar* getBranchInst() const
1291 {
1292 return brInst;
1293 }
1294
1298
1302
1306 {
1307 return successors.size();
1308 }
1310 {
1311 return successors;
1312 }
1314 {
1315 return successors.at(i).first;
1316 }
1318 {
1319 return successors.at(i).second;
1320 }
1322 virtual const std::string toString() const override;
1323
1324};
1325
1329class TDForkPE: public CallPE
1330{
1331 friend class GraphDBClient;
1332
1333private:
1335 void operator=(const TDForkPE&);
1336
1337public:
1339
1340 static inline bool classof(const TDForkPE*)
1341 {
1342 return true;
1343 }
1344 static inline bool classof(const SVFStmt* edge)
1345 {
1346 return edge->getEdgeKind() == SVFStmt::ThreadFork;
1347 }
1348 static inline bool classof(const GenericPAGEdgeTy* edge)
1349 {
1350 return edge->getEdgeKind() == SVFStmt::ThreadFork;
1351 }
1353
1356 const CallICFGNodeVec& icfgNodes,
1357 const FunEntryICFGNode* e)
1358 : CallPE(res, opnds, icfgNodes, e, SVFStmt::ThreadFork)
1359 {
1360 }
1361
1362 virtual const std::string toString() const;
1363
1364};
1365
1369class TDJoinPE: public RetPE
1370{
1371 friend class GraphDBClient;
1372
1373private:
1375 void operator=(const TDJoinPE&);
1376
1377public:
1379
1380 static inline bool classof(const TDJoinPE*)
1381 {
1382 return true;
1383 }
1384 static inline bool classof(const SVFStmt* edge)
1385 {
1386 return edge->getEdgeKind() == SVFStmt::ThreadJoin;
1387 }
1388 static inline bool classof(const GenericPAGEdgeTy* edge)
1389 {
1390 return edge->getEdgeKind() == SVFStmt::ThreadJoin;
1391 }
1393
1396 const FunExitICFGNode* e)
1397 : RetPE(s, d, i, e, SVFStmt::ThreadJoin)
1398 {
1399 }
1400
1401 const ValVar* getRHSVar() const;
1402 const ValVar* getLHSVar() const;
1403 const ValVar* getSrcNode() const;
1404 const ValVar* getDstNode() const;
1405
1406 virtual const std::string toString() const;
1407
1408};
1409
1410} // End namespace SVF
1411
1412#endif /* INCLUDE_SVFIR_SVFSTATEMENT_H_ */
std::vector< IdxOperandPair > IdxOperandPairs
Definition AccessPath.h:63
bool isConstantOffset() const
Return TRUE if this is a constant location set.
APOffset computeConstantByteOffset() const
APOffset getConstantStructFldIdx() const
Get methods.
Definition AccessPath.h:98
const IdxOperandPairs & getIdxOperandPairVec() const
Definition AccessPath.h:106
APOffset computeConstantOffset() const
For example,.
const ObjVar * getSrcNode() const
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:
const ObjVar * getRHSVar() const
AddrStmt(SVFVar *s, SVFVar *d)
constructor
const ValVar * getLHSVar() const
static bool classof(const GenericPAGEdgeTy *edge)
const ValVar * getDstNode() const
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 ValVar * getCondition() const
Return the condition.
SuccAndCondPairVec successors
const ValVar * getBranchInst() const
void operator=(const BranchStmt &)
place holder
static bool classof(const SVFStmt *edge)
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
NodeID getSrcID()
place holder, use getOpVarID(pos) instead
const ValVar * cond
friend class GraphDBClient
SVFVar * getSrcNode()
place holder, not allowed
const SuccAndCondPairVec & getSuccessors() const
NodeID getDstID()
place holder, use getResID() instead
static bool classof(const GenericPAGEdgeTy *edge)
const ValVar * brInst
virtual const std::string toString() const override
static bool classof(const GenericPAGEdgeTy *edge)
static bool classof(const SVFStmt *edge)
CallPE(const CallPE &)
place holder
CallICFGNodeVec opCallICFGNodes
const FunEntryICFGNode * getFunEntryICFGNode() const
Return the function entry node.
static bool classof(const CallPE *)
the function entry node
const FunEntryICFGNode * entry
each operand's call site
void operator=(const CallPE &)
place holder
friend class GraphDBClient
void addOpVar(ValVar *op, const CallICFGNode *call)
Add an operand (actual param) from a call site.
virtual const std::string toString() const override
const CallICFGNode * getOpCallICFGNode(u32_t op_idx) const
Return the CallICFGNode of the i-th operand.
const CallICFGNodeVec & getOpCallICFGNodes() const
Return all call site ICFGNodes.
std::vector< const CallICFGNode * > CallICFGNodeVec
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)
const ValVar * getRHSVar() const
const ValVar * getDstNode() const
const ValVar * getSrcNode() const
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
const ValVar * getLHSVar() const
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.
const ValVar * getSrcNode() const
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 ValVar * getRHSVar() 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
const ValVar * getDstNode() const
static bool classof(const SVFStmt *edge)
const AccessPath & getAccessPath() const
const ValVar * getLHSVar() 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:
const ValVar * getLHSVar() const
const ValVar * getDstNode() const
LoadStmt(const LoadStmt &)
place holder
virtual const std::string toString() const override
const ValVar * getRHSVar() const
LoadStmt(SVFVar *s, SVFVar *d)
constructor
const ValVar * getSrcNode() const
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
NodeID getDstID()
not allowed, use getResID() instead
const ValVar * getRes() const
Result SVFVar.
std::vector< ValVar * > OPVars
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:
friend class GraphDBClient
OPVars::const_iterator opVarBegin() const
SVFVar * getDstNode()
not allowed, use getRes() instead
NodeID getSrcID()
not allowed, use getOpVarID(idx) instead
static bool classof(const GenericPAGEdgeTy *node)
OPVars::const_iterator opVerEnd() const
const ValVar * getOpVar(u32_t pos) const
Operand SVFVars.
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
PhiStmt(ValVar *res, const OPVars &opnds, const OpICFGNodeVec &icfgNodes)
constructor
std::vector< const ICFGNode * > OpICFGNodeVec
OpICFGNodeVec opICFGNodes
PhiStmt(const PhiStmt &)
place holder
void addOpVar(ValVar *op, const ICFGNode *inode)
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 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
const ValVar * getDstNode() const
static bool classof(const SVFStmt *edge)
const CallICFGNode * call
const ValVar * getSrcNode() const
friend class GraphDBClient
void operator=(const RetPE &)
place holder
const ValVar * getRHSVar() const
const ValVar * getLHSVar() const
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
static bool classof(const SVFStmt *edge)
virtual const std::string toString() const override
static bool classof(const SelectStmt *)
Methods for support type inquiry through isa, cast, and dyn_cast:
const ValVar * getTrueValue() const
static bool classof(const GenericPAGEdgeTy *edge)
const ValVar * getFalseValue() const
friend class GraphDBClient
SelectStmt(const SelectStmt &)
place holder
void operator=(const SelectStmt &)
place holder
const ValVar * getDstNode() const
StoreStmt(const StoreStmt &)
place holder
const ValVar * getRHSVar() const
const ValVar * getLHSVar() const
static bool classof(const SVFStmt *edge)
virtual const std::string toString() const override
const ValVar * getSrcNode() const
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(ValVar *res, const OPVars &opnds, const CallICFGNodeVec &icfgNodes, const FunEntryICFGNode *e)
constructor
const ValVar * getRHSVar() const
static bool classof(const SVFStmt *edge)
const ValVar * getLHSVar() const
static bool classof(const GenericPAGEdgeTy *edge)
const ValVar * getDstNode() const
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.
const ValVar * getSrcNode() const
virtual const std::string toString() const override
static bool classof(const SVFStmt *edge)
NodeID getSrcID()
place holder, use getOpVarID(pos) instead
const ValVar * getRes() const
void operator=(const UnaryOPStmt &)
place holder
SVFVar * getSrcNode()
place holder, use getOpVar() instead
const ValVar * getOpVar() const
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:
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:70
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:76
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