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#include "Util/GeneralType.h"
37
38namespace SVF
39{
40
41class SVFVar;
42class ValVar;
43class ObjVar;
44class ICFGNode;
45class IntraICFGNode;
46class CallICFGNode;
47class FunEntryICFGNode;
48class FunExitICFGNode;
49class SVFBasicBlock;
50
51/*
52 * SVFIR program statements (PAGEdges)
53 */
56{
57 friend class GraphDBClient;
58
59public:
82
83private:
84 const SVFVar* value;
88
89protected:
92 : GenericPAGEdgeTy({}, {}, k), value{}, basicBlock{}, icfgNode{}
93 {
94 }
95
96 SVFStmt(SVFVar* s, SVFVar* d, GEdgeFlag k, EdgeID eid, SVFVar* value, ICFGNode* icfgNode, bool real = true);
97
101 inline void setBasicBlock(const SVFBasicBlock* bb)
102 {
103 basicBlock = bb;
104 }
105
113
121
129
133 static inline void addInst2Labeled(const ICFGNode* cs, u32_t label)
134 {
135 inst2LabelMap.emplace(cs, label);
136 }
137
138 static inline void addVar2Labeled(const SVFVar* var, u32_t label)
139 {
140 var2LabelMap.emplace(var, label);
141 }
142
143public:
144
146 SVFStmt(SVFVar* s, SVFVar* d, GEdgeFlag k, bool real = true);
149
151
152 static inline bool classof(const SVFStmt*)
153 {
154 return true;
155 }
156 static inline bool classof(const GenericPAGEdgeTy* edge)
157 {
158 return edge->getEdgeKind() == SVFStmt::Addr ||
159 edge->getEdgeKind() == SVFStmt::Copy ||
160 edge->getEdgeKind() == SVFStmt::Store ||
161 edge->getEdgeKind() == SVFStmt::Load ||
162 edge->getEdgeKind() == SVFStmt::Call ||
163 edge->getEdgeKind() == SVFStmt::Ret ||
164 edge->getEdgeKind() == SVFStmt::Gep ||
165 edge->getEdgeKind() == SVFStmt::Phi ||
166 edge->getEdgeKind() == SVFStmt::Select ||
167 edge->getEdgeKind() == SVFStmt::Cmp ||
168 edge->getEdgeKind() == SVFStmt::BinaryOp ||
169 edge->getEdgeKind() == SVFStmt::UnaryOp ||
170 edge->getEdgeKind() == SVFStmt::Branch ||
171 edge->getEdgeKind() == SVFStmt::ThreadFork ||
172 edge->getEdgeKind() == SVFStmt::ThreadJoin;
173 }
175
177 inline EdgeID getEdgeID() const
178 {
179 return edgeId;
180 }
182 virtual bool isPTAEdge() const;
183
185
186
187 inline void setValue(const SVFVar* val)
188 {
189 value = val;
190 }
191 inline const SVFVar* getValue() const
192 {
193 return value;
194 }
195
196 inline void setBB(const SVFBasicBlock* bb)
197 {
198 basicBlock = bb;
199 }
200 inline const SVFBasicBlock* getBB() const
201 {
202 return basicBlock;
203 }
204 inline void setICFGNode(ICFGNode* node)
205 {
206 icfgNode = node;
207 }
208 inline ICFGNode* getICFGNode() const
209 {
210 return icfgNode;
211 }
213
217 const SVFVar* var)
218 {
220 if (it_inserted.second)
222 u64_t label = it_inserted.first->second;
223 return (label << EdgeKindMaskBits) | k;
224 }
225
229 const ICFGNode* cs)
230 {
232 if (it_inserted.second)
234 u64_t label = it_inserted.first->second;
235 return (label << EdgeKindMaskBits) | k;
236 }
237
241 const ICFGNode* store)
242 {
243 auto it_inserted = inst2LabelMap.emplace(store, storeEdgeLabelCounter);
244 if (it_inserted.second)
246 u64_t label = it_inserted.first->second;
247 return (label << EdgeKindMaskBits) | k;
248 }
249
250 virtual const std::string toString() const;
251
253
256 {
257 o << edge.toString();
258 return o;
259 }
261
266
267private:
275
276public:
277 static inline const Inst2LabelMap* getInst2LabelMap()
278 {
279 return &inst2LabelMap;
280 }
281
282 static inline const Var2LabelMap* getVar2LabelMap()
283 {
284 return &var2LabelMap;
285 }
286
287 static inline const u64_t* getCallEdgeLabelCounter()
288 {
289 return &callEdgeLabelCounter;
290 }
291
292 static inline const u64_t* getStoreEdgeLabelCounter()
293 {
294 return &storeEdgeLabelCounter;
295 }
296
297 static inline const u64_t* getMultiOpndLabelCounter()
298 {
299 return &multiOpndLabelCounter;
300 }
301
302};
303
304/*
305 Parent class of Addr, Copy, Store, Load, Call, Ret, NormalGep, VariantGep, ThreadFork, ThreadJoin
306 connecting RHS expression and LHS expression with an assignment (e.g., LHSExpr = RHSExpr)
307 Only one operand on the right hand side of an assignment
308*/
309class AssignStmt : public SVFStmt
310{
311 friend class GraphDBClient;
312
313private:
316 void operator=(const AssignStmt &);
321
322protected:
325
326public:
328
329 static inline bool classof(const AssignStmt*)
330 {
331 return true;
332 }
333 static inline bool classof(const SVFStmt* edge)
334 {
335 return edge->getEdgeKind() == SVFStmt::Addr ||
336 edge->getEdgeKind() == SVFStmt::Copy ||
337 edge->getEdgeKind() == SVFStmt::Store ||
338 edge->getEdgeKind() == SVFStmt::Load ||
339 edge->getEdgeKind() == SVFStmt::Ret ||
340 edge->getEdgeKind() == SVFStmt::Gep ||
341 edge->getEdgeKind() == SVFStmt::ThreadJoin;
342 }
343 static inline bool classof(const GenericPAGEdgeTy* edge)
344 {
345 return edge->getEdgeKind() == SVFStmt::Addr ||
346 edge->getEdgeKind() == SVFStmt::Copy ||
347 edge->getEdgeKind() == SVFStmt::Store ||
348 edge->getEdgeKind() == SVFStmt::Load ||
349 edge->getEdgeKind() == SVFStmt::Ret ||
350 edge->getEdgeKind() == SVFStmt::Gep ||
351 edge->getEdgeKind() == SVFStmt::ThreadJoin;
352 }
354
355 inline SVFVar* getRHSVar() const
356 {
357 return SVFStmt::getSrcNode();
358 }
359 inline SVFVar* getLHSVar() const
360 {
361 return SVFStmt::getDstNode();
362 }
363 inline NodeID getRHSVarID() const
364 {
365 return SVFStmt::getSrcID();
366 }
367 inline NodeID getLHSVarID() const
368 {
369 return SVFStmt::getDstID();
370 }
371
372 virtual const std::string toString() const = 0;
373};
374
378class AddrStmt: public AssignStmt
379{
380 friend class GraphDBClient;
381
382private:
384 void operator=(const AddrStmt&);
385
386 std::vector<SVFVar*> arrSize;
387
388public:
390
391 static inline bool classof(const AddrStmt*)
392 {
393 return true;
394 }
395 static inline bool classof(const SVFStmt* edge)
396 {
397 return edge->getEdgeKind() == SVFStmt::Addr;
398 }
399 static inline bool classof(const GenericPAGEdgeTy* edge)
400 {
401 return edge->getEdgeKind() == SVFStmt::Addr;
402 }
404
407
408 virtual const std::string toString() const override;
409
410 inline void addArrSize(SVFVar* size) //TODO:addSizeVar
411 {
412 arrSize.push_back(size);
413 }
414
416 inline const std::vector<SVFVar*>& getArrSize() const //TODO:getSizeVars
417 {
418 return arrSize;
419 }
420
421 virtual bool isPTAEdge() const override
422 {
423 return true;
424 }
425
426 const ValVar* getLHSVar() const;
427 const ObjVar* getRHSVar() const;
428 const ValVar* getDstNode() const;
429 const ObjVar* getSrcNode() const;
430};
431
435class CopyStmt: public AssignStmt
436{
437
438 friend class GraphDBClient;
439
440private:
442 void operator=(const CopyStmt&);
443public:
445 {
446 COPYVAL, // Value copies (default one)
447 ZEXT, // Zero extend integers
448 SEXT, // Sign extend integers
449 BITCAST, // Type cast
450 TRUNC, // Truncate integers
451 FPTRUNC, // Truncate floating point
452 FPTOUI, // floating point -> UInt
453 FPTOSI, // floating point -> SInt
454 UITOFP, // UInt -> floating point
455 SITOFP, // SInt -> floating point
456 INTTOPTR, // Integer -> Pointer
457 PTRTOINT // Pointer -> Integer
458 };
460
461 static inline bool classof(const CopyStmt*)
462 {
463 return true;
464 }
465 static inline bool classof(const SVFStmt* edge)
466 {
467 return edge->getEdgeKind() == SVFStmt::Copy;
468 }
469 static inline bool classof(const GenericPAGEdgeTy* edge)
470 {
471 return edge->getEdgeKind() == SVFStmt::Copy;
472 }
474
476 inline u32_t getCopyKind() const
477 {
478 return copyKind;
479 }
480
481 inline bool isBitCast() const
482 {
483 return copyKind == BITCAST;
484 }
485
486 inline bool isValueCopy() const
487 {
488 return copyKind == COPYVAL;
489 }
490
491 inline bool isInt2Ptr() const
492 {
493 return copyKind == INTTOPTR;
494 }
495
496 inline bool isPtr2Int() const
497 {
498 return copyKind == PTRTOINT;
499 }
500
501 inline bool isZext() const
502 {
503 return copyKind == ZEXT;
504 }
505
506 inline bool isSext() const
507 {
508 return copyKind == SEXT;
509 }
510
513
514 const ValVar* getRHSVar() const;
515 const ValVar* getLHSVar() const;
516 const ValVar* getSrcNode() const;
517 const ValVar* getDstNode() const;
518
519 virtual const std::string toString() const override;
520
521private:
523};
524
529{
530 friend class GraphDBClient;
531
532private:
534 void operator=(const StoreStmt&);
535
536public:
538
539 static inline bool classof(const StoreStmt*)
540 {
541 return true;
542 }
543 static inline bool classof(const SVFStmt* edge)
544 {
545 return edge->getEdgeKind() == SVFStmt::Store;
546 }
547 static inline bool classof(const GenericPAGEdgeTy* edge)
548 {
549 return edge->getEdgeKind() == SVFStmt::Store;
550 }
552
554 StoreStmt(SVFVar* s, SVFVar* d, const ICFGNode* st);
555
556 const ValVar* getRHSVar() const;
557 const ValVar* getLHSVar() const;
558 const ValVar* getSrcNode() const;
559 const ValVar* getDstNode() const;
560
561 virtual const std::string toString() const override;
562
563};
564
568class LoadStmt: public AssignStmt
569{
570 friend class GraphDBClient;
571
572private:
574 void operator=(const LoadStmt&);
575
576public:
578
579 static inline bool classof(const LoadStmt*)
580 {
581 return true;
582 }
583 static inline bool classof(const SVFStmt* edge)
584 {
585 return edge->getEdgeKind() == SVFStmt::Load;
586 }
587 static inline bool classof(const GenericPAGEdgeTy* edge)
588 {
589 return edge->getEdgeKind() == SVFStmt::Load;
590 }
592
595
596 const ValVar* getRHSVar() const;
597 const ValVar* getLHSVar() const;
598 const ValVar* getSrcNode() const;
599 const ValVar* getDstNode() const;
600
601 virtual const std::string toString() const override;
602};
603
607class GepStmt: public AssignStmt
608{
609 friend class GraphDBClient;
610
611
612private:
613 GepStmt(const GepStmt &);
614 void operator=(const GepStmt &);
615
618public:
620
621 static inline bool classof(const GepStmt*)
622 {
623 return true;
624 }
625 static inline bool classof(const SVFStmt* edge)
626 {
627 return edge->getEdgeKind() == SVFStmt::Gep;
628 }
629 static inline bool classof(const GenericPAGEdgeTy* edge)
630 {
631 return edge->getEdgeKind() == SVFStmt::Gep;
632 }
634
635 inline const AccessPath& getAccessPath() const
636 {
637 return ap;
638 }
644 inline bool isConstantOffset() const
645 {
647 }
648
658
661 {
663 }
666 {
667 assert(isVariantFieldGep()==false && "Can't retrieve the AccessPath if using a variable field index (pointer arithmetic) for struct field access ");
669 }
671 inline bool isVariantFieldGep() const
672 {
673 return variantField;
674 }
675
677 GepStmt(SVFVar* s, SVFVar* d, const AccessPath& ap, bool varfld = false)
679 {
680 }
681
682 const ValVar* getRHSVar() const;
683 const ValVar* getLHSVar() const;
684 const ValVar* getSrcNode() const;
685 const ValVar* getDstNode() const;
686
687 virtual const std::string toString() const;
688
689
690};
691
692
696class RetPE: public AssignStmt
697{
698 friend class GraphDBClient;
699
700private:
701 RetPE(const RetPE&);
702 void operator=(const RetPE&);
703
706
707public:
709
710 static inline bool classof(const RetPE*)
711 {
712 return true;
713 }
714 static inline bool classof(const SVFStmt* edge)
715 {
716 return edge->getEdgeKind() == SVFStmt::Ret ||
717 edge->getEdgeKind() == SVFStmt::ThreadJoin;
718 }
719 static inline bool classof(const GenericPAGEdgeTy* edge)
720 {
721 return edge->getEdgeKind() == SVFStmt::Ret ||
722 edge->getEdgeKind() == SVFStmt::ThreadJoin;
723 }
725
727 RetPE(SVFVar* s, SVFVar* d, const CallICFGNode* i, const FunExitICFGNode* e,
729
731
732 inline const CallICFGNode* getCallInst() const
733 {
734 return call;
735 }
736 inline const CallICFGNode* getCallSite() const
737 {
738 return call;
739 }
741 {
742 return exit;
743 }
745
746 const ValVar* getRHSVar() const;
747 const ValVar* getLHSVar() const;
748 const ValVar* getSrcNode() const;
749 const ValVar* getDstNode() const;
750
751 virtual const std::string toString() const override;
752
753};
754
755/*
756* Program statements with multiple operands including BinaryOPStmt, CmpStmt and PhiStmt
757*/
758class MultiOpndStmt : public SVFStmt
759{
760 friend class GraphDBClient;
761
762public:
763 typedef std::vector<ValVar*> OPVars;
764
765private:
773
774protected:
778
779public:
781
782 static inline bool classof(const MultiOpndStmt*)
783 {
784 return true;
785 }
786 static inline bool classof(const SVFStmt* node)
787 {
788 return node->getEdgeKind() == Phi || node->getEdgeKind() == Select ||
789 node->getEdgeKind() == BinaryOp || node->getEdgeKind() == Cmp ||
790 node->getEdgeKind() == Call || node->getEdgeKind() == ThreadFork;
791 }
792 static inline bool classof(const GenericPAGEdgeTy* node)
793 {
794 return node->getEdgeKind() == Phi || node->getEdgeKind() == Select ||
795 node->getEdgeKind() == BinaryOp || node->getEdgeKind() == Cmp ||
796 node->getEdgeKind() == Call || node->getEdgeKind() == ThreadFork;
797 }
799
801
802
803 inline const ValVar* getOpVar(u32_t pos) const
804 {
805 return opVars.at(pos);
806 }
808 const ValVar* getRes() const;
809
810 NodeID getOpVarID(u32_t pos) const;
811 NodeID getResID() const;
812
813 inline u32_t getOpVarNum() const
814 {
815 return opVars.size();
816 }
817 inline const OPVars& getOpndVars() const
818 {
819 return opVars;
820 }
821 inline OPVars::const_iterator opVarBegin() const
822 {
823 return opVars.begin();
824 }
825 inline OPVars::const_iterator opVerEnd() const
826 {
827 return opVars.end();
828 }
830};
831
839{
840 friend class GraphDBClient;
841
842public:
843 typedef std::vector<const CallICFGNode*> CallICFGNodeVec;
844
845private:
846 CallPE(const CallPE&);
847 void operator=(const CallPE&);
848
851
852public:
854
855 static inline bool classof(const CallPE*)
856 {
857 return true;
858 }
859 static inline bool classof(const SVFStmt* edge)
860 {
861 return edge->getEdgeKind() == SVFStmt::Call ||
862 edge->getEdgeKind() == SVFStmt::ThreadFork;
863 }
864 static inline bool classof(const GenericPAGEdgeTy* edge)
865 {
866 return edge->getEdgeKind() == SVFStmt::Call ||
867 edge->getEdgeKind() == SVFStmt::ThreadFork;
868 }
870
872 CallPE(ValVar* res, const OPVars& opnds,
873 const CallICFGNodeVec& icfgNodes,
874 const FunEntryICFGNode* e,
876
878 void addOpVar(ValVar* op, const CallICFGNode* call)
879 {
880 opVars.push_back(op);
881 opCallICFGNodes.push_back(call);
882 assert(opVars.size() == opCallICFGNodes.size() &&
883 "Numbers of operands and their CallICFGNodes are not consistent?");
884 }
885
888 {
889 return opCallICFGNodes.at(op_idx);
890 }
891
894 {
895 return opCallICFGNodes;
896 }
897
900 {
901 return entry;
902 }
903
904 virtual const std::string toString() const override;
905};
906
912{
913 friend class GraphDBClient;
914public:
915 typedef std::vector<const ICFGNode*> OpICFGNodeVec;
916
917private:
918 PhiStmt(const PhiStmt&);
919 void operator=(const PhiStmt&);
920
922
923public:
925
926 static inline bool classof(const PhiStmt*)
927 {
928 return true;
929 }
930 static inline bool classof(const SVFStmt* edge)
931 {
932 return edge->getEdgeKind() == SVFStmt::Phi;
933 }
934 static inline bool classof(const MultiOpndStmt* edge)
935 {
936 return edge->getEdgeKind() == SVFStmt::Phi;
937 }
938 static inline bool classof(const GenericPAGEdgeTy* edge)
939 {
940 return edge->getEdgeKind() == SVFStmt::Phi;
941 }
943
945 PhiStmt(ValVar* res, const OPVars& opnds, const OpICFGNodeVec& icfgNodes)
946 : MultiOpndStmt(res, opnds, SVFStmt::Phi), opICFGNodes(icfgNodes)
947 {
948 assert(opnds.size() == icfgNodes.size() &&
949 "Numbers of operands and their ICFGNodes are not consistent?");
950 }
952 {
953 opVars.push_back(op);
954 opICFGNodes.push_back(inode);
955 assert(opVars.size() == opICFGNodes.size() &&
956 "Numbers of operands and their ICFGNodes are not consistent?");
957 }
958
960 {
961 assert(opVars.size() == icfgNodes.size() &&
962 "Numbers of operands and their ICFGNodes are not consistent?");
963 opICFGNodes = icfgNodes;
964 }
965
966 inline const OpICFGNodeVec* getOpICFGNodeVec() const
967 {
968 return &opICFGNodes;
969 }
970
972 inline const ICFGNode* getOpICFGNode(u32_t op_idx) const
973 {
974 return opICFGNodes.at(op_idx);
975 }
976
979 bool isFunctionRetPhi() const;
980
981 virtual const std::string toString() const override;
982
983};
984
989{
990 friend class GraphDBClient;
991private:
993 void operator=(const SelectStmt&);
994
996
997public:
999
1000 static inline bool classof(const SelectStmt*)
1001 {
1002 return true;
1003 }
1004 static inline bool classof(const SVFStmt* edge)
1005 {
1006 return edge->getEdgeKind() == SVFStmt::Select;
1007 }
1008 static inline bool classof(const MultiOpndStmt* edge)
1009 {
1010 return edge->getEdgeKind() == SVFStmt::Select;
1011 }
1012 static inline bool classof(const GenericPAGEdgeTy* edge)
1013 {
1014 return edge->getEdgeKind() == SVFStmt::Select;
1015 }
1017
1019 SelectStmt(ValVar* res, const OPVars& opnds, const SVFVar* cond);
1020 virtual const std::string toString() const override;
1021
1022 inline const SVFVar* getCondition() const
1023 {
1024 return condition;
1025 }
1026 inline const ValVar* getTrueValue() const
1027 {
1028 return getOpVar(0);
1029 }
1030 inline const ValVar* getFalseValue() const
1031 {
1032 return getOpVar(1);
1033 }
1034
1035};
1036
1041{
1042 friend class GraphDBClient;
1043private:
1045 void operator=(const CmpStmt&);
1046
1048
1049public:
1087
1089
1090 static inline bool classof(const CmpStmt*)
1091 {
1092 return true;
1093 }
1094 static inline bool classof(const SVFStmt* edge)
1095 {
1096 return edge->getEdgeKind() == SVFStmt::Cmp;
1097 }
1098 static inline bool classof(const MultiOpndStmt* edge)
1099 {
1100 return edge->getEdgeKind() == SVFStmt::Cmp;
1101 }
1102 static inline bool classof(const GenericPAGEdgeTy* edge)
1103 {
1104 return edge->getEdgeKind() == SVFStmt::Cmp;
1105 }
1107
1109 CmpStmt(ValVar* res, const OPVars& opnds, u32_t pre);
1110
1112 {
1113 return predicate;
1114 }
1115
1116 virtual const std::string toString() const override;
1117
1118};
1119
1124{
1125 friend class GraphDBClient;
1126private:
1130
1131public:
1133 enum OpCode : unsigned
1134 {
1135 Add = 13, // Sum of integers
1136 FAdd = 14, // Sum of floats
1137 Sub = 15, // Subtraction of integers
1138 FSub = 16, // Subtraction of floats
1139 Mul = 17, // Product of integers.
1140 FMul = 18, // Product of floats.
1141 UDiv = 19, // Unsigned division.
1142 SDiv = 20, // Signed division.
1143 FDiv = 21, // Float division.
1144 URem = 22, // Unsigned remainder
1145 SRem = 23, // Signed remainder
1146 FRem = 24, // Float remainder
1147 Shl = 25, // Shift left (logical)
1148 LShr = 26, // Shift right (logical)
1149 AShr = 27, // Shift right (arithmetic)
1150 And = 28, // Logical and
1151 Or = 29, // Logical or
1152 Xor = 30 // Logical xor
1154
1156
1157 static inline bool classof(const BinaryOPStmt*)
1158 {
1159 return true;
1160 }
1161 static inline bool classof(const SVFStmt* edge)
1162 {
1163 return edge->getEdgeKind() == SVFStmt::BinaryOp;
1164 }
1165 static inline bool classof(const MultiOpndStmt* edge)
1166 {
1167 return edge->getEdgeKind() == SVFStmt::BinaryOp;
1168 }
1169 static inline bool classof(const GenericPAGEdgeTy* edge)
1170 {
1171 return edge->getEdgeKind() == SVFStmt::BinaryOp;
1172 }
1174
1176 BinaryOPStmt(ValVar* res, const OPVars& opnds, u32_t oc);
1177
1179 {
1180 return opcode;
1181 }
1182
1183 virtual const std::string toString() const override;
1184
1185};
1186
1191{
1192 friend class GraphDBClient;
1193
1194private:
1196 void operator=(const UnaryOPStmt&);
1201
1203
1204public:
1206 enum OpCode : unsigned
1207 {
1208 FNeg = 12
1210
1212
1213 static inline bool classof(const UnaryOPStmt*)
1214 {
1215 return true;
1216 }
1217 static inline bool classof(const SVFStmt* edge)
1218 {
1219 return edge->getEdgeKind() == SVFStmt::UnaryOp;
1220 }
1221 static inline bool classof(const GenericPAGEdgeTy* edge)
1222 {
1223 return edge->getEdgeKind() == SVFStmt::UnaryOp;
1224 }
1226
1229
1231 {
1232 return opcode;
1233 }
1234 const ValVar* getOpVar() const;
1235 const ValVar* getRes() const;
1236 NodeID getOpVarID() const;
1237 NodeID getResID() const;
1238
1239 virtual const std::string toString() const override;
1240
1241};
1242
1246class BranchStmt: public SVFStmt
1247{
1248 friend class GraphDBClient;
1249
1250public:
1251 typedef std::vector<std::pair<const ICFGNode*, s32_t>> SuccAndCondPairVec;
1252
1253private:
1255 void operator=(const BranchStmt&);
1260
1262 const ValVar* cond;
1264
1265public:
1267
1268 static inline bool classof(const BranchStmt*)
1269 {
1270 return true;
1271 }
1272 static inline bool classof(const SVFStmt* edge)
1273 {
1274 return edge->getEdgeKind() == SVFStmt::Branch;
1275 }
1276 static inline bool classof(const GenericPAGEdgeTy* edge)
1277 {
1278 return edge->getEdgeKind() == SVFStmt::Branch;
1279 }
1281
1284
1286 bool isUnconditional() const;
1288 bool isConditional() const;
1290 const ValVar* getCondition() const;
1291 const ValVar* getBranchInst() const
1292 {
1293 return brInst;
1294 }
1295
1299
1303
1307 {
1308 return successors.size();
1309 }
1311 {
1312 return successors;
1313 }
1315 {
1316 return successors.at(i).first;
1317 }
1319 {
1320 return successors.at(i).second;
1321 }
1323 virtual const std::string toString() const override;
1324
1325};
1326
1330class TDForkPE: public CallPE
1331{
1332 friend class GraphDBClient;
1333
1334private:
1336 void operator=(const TDForkPE&);
1337
1338public:
1340
1341 static inline bool classof(const TDForkPE*)
1342 {
1343 return true;
1344 }
1345 static inline bool classof(const SVFStmt* edge)
1346 {
1347 return edge->getEdgeKind() == SVFStmt::ThreadFork;
1348 }
1349 static inline bool classof(const GenericPAGEdgeTy* edge)
1350 {
1351 return edge->getEdgeKind() == SVFStmt::ThreadFork;
1352 }
1354
1357 const CallICFGNodeVec& icfgNodes,
1358 const FunEntryICFGNode* e)
1359 : CallPE(res, opnds, icfgNodes, e, SVFStmt::ThreadFork)
1360 {
1361 }
1362
1363 virtual const std::string toString() const;
1364
1365};
1366
1370class TDJoinPE: public RetPE
1371{
1372 friend class GraphDBClient;
1373
1374private:
1376 void operator=(const TDJoinPE&);
1377
1378public:
1380
1381 static inline bool classof(const TDJoinPE*)
1382 {
1383 return true;
1384 }
1385 static inline bool classof(const SVFStmt* edge)
1386 {
1387 return edge->getEdgeKind() == SVFStmt::ThreadJoin;
1388 }
1389 static inline bool classof(const GenericPAGEdgeTy* edge)
1390 {
1391 return edge->getEdgeKind() == SVFStmt::ThreadJoin;
1392 }
1394
1397 const FunExitICFGNode* e)
1398 : RetPE(s, d, i, e, SVFStmt::ThreadJoin)
1399 {
1400 }
1401
1402 const ValVar* getRHSVar() const;
1403 const ValVar* getLHSVar() const;
1404 const ValVar* getSrcNode() const;
1405 const ValVar* getDstNode() const;
1406
1407 virtual const std::string toString() const;
1408
1409};
1410
1411} // End namespace SVF
1412
1413#endif /* INCLUDE_SVFIR_SVFSTATEMENT_H_ */
std::vector< IdxOperandPair > IdxOperandPairs
Definition AccessPath.h:67
bool isConstantOffset() const
Return TRUE if this is a constant location set.
APOffset computeConstantByteOffset() const
APOffset getConstantStructFldIdx() const
Get methods.
Definition AccessPath.h:102
const IdxOperandPairs & getIdxOperandPairVec() const
Definition AccessPath.h:110
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:69
u32_t NodeID
Definition GeneralType.h:76
s64_t APOffset
Definition GeneralType.h:80
std::ostream OutStream
Definition GeneralType.h:66
llvm::IRBuilder IRBuilder
Definition BasicTypes.h:76
GenericEdge< SVFVar > GenericPAGEdgeTy
unsigned u32_t
Definition GeneralType.h:67
signed long long s64_t
Definition GeneralType.h:70
u32_t EdgeID
Definition GeneralType.h:77