1 //===--- CFG.h - Classes for representing and building CFGs------*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // This file defines the CFG and CFGBuilder classes for representing and 11 // building Control-Flow Graphs (CFGs) from ASTs. 12 // 13 //===----------------------------------------------------------------------===// 14 15 #ifndef LLVM_CLANG_ANALYSIS_CFG_H 16 #define LLVM_CLANG_ANALYSIS_CFG_H 17 18 #include "clang/AST/Stmt.h" 19 #include "clang/Analysis/Support/BumpVector.h" 20 #include "clang/Basic/SourceLocation.h" 21 #include "llvm/ADT/DenseMap.h" 22 #include "llvm/ADT/GraphTraits.h" 23 #include "llvm/ADT/Optional.h" 24 #include "llvm/ADT/PointerIntPair.h" 25 #include "llvm/Support/Allocator.h" 26 #include "llvm/Support/Casting.h" 27 #include "llvm/Support/raw_ostream.h" 28 #include <bitset> 29 #include <cassert> 30 #include <iterator> 31 #include <memory> 32 33 namespace clang { 34 class CXXDestructorDecl; 35 class Decl; 36 class Stmt; 37 class Expr; 38 class FieldDecl; 39 class VarDecl; 40 class CXXCtorInitializer; 41 class CXXBaseSpecifier; 42 class CXXBindTemporaryExpr; 43 class CFG; 44 class PrinterHelper; 45 class LangOptions; 46 class ASTContext; 47 class CXXRecordDecl; 48 class CXXDeleteExpr; 49 class CXXNewExpr; 50 class BinaryOperator; 51 52 /// CFGElement - Represents a top-level expression in a basic block. 53 class CFGElement { 54 public: 55 enum Kind { 56 // main kind 57 Statement, 58 Initializer, 59 NewAllocator, 60 // dtor kind 61 AutomaticObjectDtor, 62 DeleteDtor, 63 BaseDtor, 64 MemberDtor, 65 TemporaryDtor, 66 DTOR_BEGIN = AutomaticObjectDtor, 67 DTOR_END = TemporaryDtor 68 }; 69 70 protected: 71 // The int bits are used to mark the kind. 72 llvm::PointerIntPair<void *, 2> Data1; 73 llvm::PointerIntPair<void *, 2> Data2; 74 75 CFGElement(Kind kind, const void *Ptr1, const void *Ptr2 = nullptr) 76 : Data1(const_cast<void*>(Ptr1), ((unsigned) kind) & 0x3), 77 Data2(const_cast<void*>(Ptr2), (((unsigned) kind) >> 2) & 0x3) { 78 assert(getKind() == kind); 79 } 80 CFGElement()81 CFGElement() {} 82 public: 83 84 /// \brief Convert to the specified CFGElement type, asserting that this 85 /// CFGElement is of the desired type. 86 template<typename T> castAs()87 T castAs() const { 88 assert(T::isKind(*this)); 89 T t; 90 CFGElement& e = t; 91 e = *this; 92 return t; 93 } 94 95 /// \brief Convert to the specified CFGElement type, returning None if this 96 /// CFGElement is not of the desired type. 97 template<typename T> getAs()98 Optional<T> getAs() const { 99 if (!T::isKind(*this)) 100 return None; 101 T t; 102 CFGElement& e = t; 103 e = *this; 104 return t; 105 } 106 getKind()107 Kind getKind() const { 108 unsigned x = Data2.getInt(); 109 x <<= 2; 110 x |= Data1.getInt(); 111 return (Kind) x; 112 } 113 }; 114 115 class CFGStmt : public CFGElement { 116 public: CFGStmt(Stmt * S)117 CFGStmt(Stmt *S) : CFGElement(Statement, S) {} 118 getStmt()119 const Stmt *getStmt() const { 120 return static_cast<const Stmt *>(Data1.getPointer()); 121 } 122 123 private: 124 friend class CFGElement; CFGStmt()125 CFGStmt() {} isKind(const CFGElement & E)126 static bool isKind(const CFGElement &E) { 127 return E.getKind() == Statement; 128 } 129 }; 130 131 /// CFGInitializer - Represents C++ base or member initializer from 132 /// constructor's initialization list. 133 class CFGInitializer : public CFGElement { 134 public: CFGInitializer(CXXCtorInitializer * initializer)135 CFGInitializer(CXXCtorInitializer *initializer) 136 : CFGElement(Initializer, initializer) {} 137 getInitializer()138 CXXCtorInitializer* getInitializer() const { 139 return static_cast<CXXCtorInitializer*>(Data1.getPointer()); 140 } 141 142 private: 143 friend class CFGElement; CFGInitializer()144 CFGInitializer() {} isKind(const CFGElement & E)145 static bool isKind(const CFGElement &E) { 146 return E.getKind() == Initializer; 147 } 148 }; 149 150 /// CFGNewAllocator - Represents C++ allocator call. 151 class CFGNewAllocator : public CFGElement { 152 public: CFGNewAllocator(const CXXNewExpr * S)153 explicit CFGNewAllocator(const CXXNewExpr *S) 154 : CFGElement(NewAllocator, S) {} 155 156 // Get the new expression. getAllocatorExpr()157 const CXXNewExpr *getAllocatorExpr() const { 158 return static_cast<CXXNewExpr *>(Data1.getPointer()); 159 } 160 161 private: 162 friend class CFGElement; CFGNewAllocator()163 CFGNewAllocator() {} isKind(const CFGElement & elem)164 static bool isKind(const CFGElement &elem) { 165 return elem.getKind() == NewAllocator; 166 } 167 }; 168 169 /// CFGImplicitDtor - Represents C++ object destructor implicitly generated 170 /// by compiler on various occasions. 171 class CFGImplicitDtor : public CFGElement { 172 protected: CFGImplicitDtor()173 CFGImplicitDtor() {} 174 CFGImplicitDtor(Kind kind, const void *data1, const void *data2 = nullptr) CFGElement(kind,data1,data2)175 : CFGElement(kind, data1, data2) { 176 assert(kind >= DTOR_BEGIN && kind <= DTOR_END); 177 } 178 179 public: 180 const CXXDestructorDecl *getDestructorDecl(ASTContext &astContext) const; 181 bool isNoReturn(ASTContext &astContext) const; 182 183 private: 184 friend class CFGElement; isKind(const CFGElement & E)185 static bool isKind(const CFGElement &E) { 186 Kind kind = E.getKind(); 187 return kind >= DTOR_BEGIN && kind <= DTOR_END; 188 } 189 }; 190 191 /// CFGAutomaticObjDtor - Represents C++ object destructor implicitly generated 192 /// for automatic object or temporary bound to const reference at the point 193 /// of leaving its local scope. 194 class CFGAutomaticObjDtor: public CFGImplicitDtor { 195 public: CFGAutomaticObjDtor(const VarDecl * var,const Stmt * stmt)196 CFGAutomaticObjDtor(const VarDecl *var, const Stmt *stmt) 197 : CFGImplicitDtor(AutomaticObjectDtor, var, stmt) {} 198 getVarDecl()199 const VarDecl *getVarDecl() const { 200 return static_cast<VarDecl*>(Data1.getPointer()); 201 } 202 203 // Get statement end of which triggered the destructor call. getTriggerStmt()204 const Stmt *getTriggerStmt() const { 205 return static_cast<Stmt*>(Data2.getPointer()); 206 } 207 208 private: 209 friend class CFGElement; CFGAutomaticObjDtor()210 CFGAutomaticObjDtor() {} isKind(const CFGElement & elem)211 static bool isKind(const CFGElement &elem) { 212 return elem.getKind() == AutomaticObjectDtor; 213 } 214 }; 215 216 /// CFGDeleteDtor - Represents C++ object destructor generated 217 /// from a call to delete. 218 class CFGDeleteDtor : public CFGImplicitDtor { 219 public: CFGDeleteDtor(const CXXRecordDecl * RD,const CXXDeleteExpr * DE)220 CFGDeleteDtor(const CXXRecordDecl *RD, const CXXDeleteExpr *DE) 221 : CFGImplicitDtor(DeleteDtor, RD, DE) {} 222 getCXXRecordDecl()223 const CXXRecordDecl *getCXXRecordDecl() const { 224 return static_cast<CXXRecordDecl*>(Data1.getPointer()); 225 } 226 227 // Get Delete expression which triggered the destructor call. getDeleteExpr()228 const CXXDeleteExpr *getDeleteExpr() const { 229 return static_cast<CXXDeleteExpr *>(Data2.getPointer()); 230 } 231 232 private: 233 friend class CFGElement; CFGDeleteDtor()234 CFGDeleteDtor() {} isKind(const CFGElement & elem)235 static bool isKind(const CFGElement &elem) { 236 return elem.getKind() == DeleteDtor; 237 } 238 }; 239 240 /// CFGBaseDtor - Represents C++ object destructor implicitly generated for 241 /// base object in destructor. 242 class CFGBaseDtor : public CFGImplicitDtor { 243 public: CFGBaseDtor(const CXXBaseSpecifier * base)244 CFGBaseDtor(const CXXBaseSpecifier *base) 245 : CFGImplicitDtor(BaseDtor, base) {} 246 getBaseSpecifier()247 const CXXBaseSpecifier *getBaseSpecifier() const { 248 return static_cast<const CXXBaseSpecifier*>(Data1.getPointer()); 249 } 250 251 private: 252 friend class CFGElement; CFGBaseDtor()253 CFGBaseDtor() {} isKind(const CFGElement & E)254 static bool isKind(const CFGElement &E) { 255 return E.getKind() == BaseDtor; 256 } 257 }; 258 259 /// CFGMemberDtor - Represents C++ object destructor implicitly generated for 260 /// member object in destructor. 261 class CFGMemberDtor : public CFGImplicitDtor { 262 public: CFGMemberDtor(const FieldDecl * field)263 CFGMemberDtor(const FieldDecl *field) 264 : CFGImplicitDtor(MemberDtor, field, nullptr) {} 265 getFieldDecl()266 const FieldDecl *getFieldDecl() const { 267 return static_cast<const FieldDecl*>(Data1.getPointer()); 268 } 269 270 private: 271 friend class CFGElement; CFGMemberDtor()272 CFGMemberDtor() {} isKind(const CFGElement & E)273 static bool isKind(const CFGElement &E) { 274 return E.getKind() == MemberDtor; 275 } 276 }; 277 278 /// CFGTemporaryDtor - Represents C++ object destructor implicitly generated 279 /// at the end of full expression for temporary object. 280 class CFGTemporaryDtor : public CFGImplicitDtor { 281 public: CFGTemporaryDtor(CXXBindTemporaryExpr * expr)282 CFGTemporaryDtor(CXXBindTemporaryExpr *expr) 283 : CFGImplicitDtor(TemporaryDtor, expr, nullptr) {} 284 getBindTemporaryExpr()285 const CXXBindTemporaryExpr *getBindTemporaryExpr() const { 286 return static_cast<const CXXBindTemporaryExpr *>(Data1.getPointer()); 287 } 288 289 private: 290 friend class CFGElement; CFGTemporaryDtor()291 CFGTemporaryDtor() {} isKind(const CFGElement & E)292 static bool isKind(const CFGElement &E) { 293 return E.getKind() == TemporaryDtor; 294 } 295 }; 296 297 /// CFGTerminator - Represents CFGBlock terminator statement. 298 /// 299 /// TemporaryDtorsBranch bit is set to true if the terminator marks a branch 300 /// in control flow of destructors of temporaries. In this case terminator 301 /// statement is the same statement that branches control flow in evaluation 302 /// of matching full expression. 303 class CFGTerminator { 304 llvm::PointerIntPair<Stmt *, 1> Data; 305 public: CFGTerminator()306 CFGTerminator() {} 307 CFGTerminator(Stmt *S, bool TemporaryDtorsBranch = false) Data(S,TemporaryDtorsBranch)308 : Data(S, TemporaryDtorsBranch) {} 309 getStmt()310 Stmt *getStmt() { return Data.getPointer(); } getStmt()311 const Stmt *getStmt() const { return Data.getPointer(); } 312 isTemporaryDtorsBranch()313 bool isTemporaryDtorsBranch() const { return Data.getInt(); } 314 315 operator Stmt *() { return getStmt(); } 316 operator const Stmt *() const { return getStmt(); } 317 318 Stmt *operator->() { return getStmt(); } 319 const Stmt *operator->() const { return getStmt(); } 320 321 Stmt &operator*() { return *getStmt(); } 322 const Stmt &operator*() const { return *getStmt(); } 323 324 explicit operator bool() const { return getStmt(); } 325 }; 326 327 /// CFGBlock - Represents a single basic block in a source-level CFG. 328 /// It consists of: 329 /// 330 /// (1) A set of statements/expressions (which may contain subexpressions). 331 /// (2) A "terminator" statement (not in the set of statements). 332 /// (3) A list of successors and predecessors. 333 /// 334 /// Terminator: The terminator represents the type of control-flow that occurs 335 /// at the end of the basic block. The terminator is a Stmt* referring to an 336 /// AST node that has control-flow: if-statements, breaks, loops, etc. 337 /// If the control-flow is conditional, the condition expression will appear 338 /// within the set of statements in the block (usually the last statement). 339 /// 340 /// Predecessors: the order in the set of predecessors is arbitrary. 341 /// 342 /// Successors: the order in the set of successors is NOT arbitrary. We 343 /// currently have the following orderings based on the terminator: 344 /// 345 /// Terminator Successor Ordering 346 /// ----------------------------------------------------- 347 /// if Then Block; Else Block 348 /// ? operator LHS expression; RHS expression 349 /// &&, || expression that uses result of && or ||, RHS 350 /// 351 /// But note that any of that may be NULL in case of optimized-out edges. 352 /// 353 class CFGBlock { 354 class ElementList { 355 typedef BumpVector<CFGElement> ImplTy; 356 ImplTy Impl; 357 public: ElementList(BumpVectorContext & C)358 ElementList(BumpVectorContext &C) : Impl(C, 4) {} 359 360 typedef std::reverse_iterator<ImplTy::iterator> iterator; 361 typedef std::reverse_iterator<ImplTy::const_iterator> const_iterator; 362 typedef ImplTy::iterator reverse_iterator; 363 typedef ImplTy::const_iterator const_reverse_iterator; 364 typedef ImplTy::const_reference const_reference; 365 push_back(CFGElement e,BumpVectorContext & C)366 void push_back(CFGElement e, BumpVectorContext &C) { Impl.push_back(e, C); } insert(reverse_iterator I,size_t Cnt,CFGElement E,BumpVectorContext & C)367 reverse_iterator insert(reverse_iterator I, size_t Cnt, CFGElement E, 368 BumpVectorContext &C) { 369 return Impl.insert(I, Cnt, E, C); 370 } 371 front()372 const_reference front() const { return Impl.back(); } back()373 const_reference back() const { return Impl.front(); } 374 begin()375 iterator begin() { return Impl.rbegin(); } end()376 iterator end() { return Impl.rend(); } begin()377 const_iterator begin() const { return Impl.rbegin(); } end()378 const_iterator end() const { return Impl.rend(); } rbegin()379 reverse_iterator rbegin() { return Impl.begin(); } rend()380 reverse_iterator rend() { return Impl.end(); } rbegin()381 const_reverse_iterator rbegin() const { return Impl.begin(); } rend()382 const_reverse_iterator rend() const { return Impl.end(); } 383 384 CFGElement operator[](size_t i) const { 385 assert(i < Impl.size()); 386 return Impl[Impl.size() - 1 - i]; 387 } 388 size()389 size_t size() const { return Impl.size(); } empty()390 bool empty() const { return Impl.empty(); } 391 }; 392 393 /// Stmts - The set of statements in the basic block. 394 ElementList Elements; 395 396 /// Label - An (optional) label that prefixes the executable 397 /// statements in the block. When this variable is non-NULL, it is 398 /// either an instance of LabelStmt, SwitchCase or CXXCatchStmt. 399 Stmt *Label; 400 401 /// Terminator - The terminator for a basic block that 402 /// indicates the type of control-flow that occurs between a block 403 /// and its successors. 404 CFGTerminator Terminator; 405 406 /// LoopTarget - Some blocks are used to represent the "loop edge" to 407 /// the start of a loop from within the loop body. This Stmt* will be 408 /// refer to the loop statement for such blocks (and be null otherwise). 409 const Stmt *LoopTarget; 410 411 /// BlockID - A numerical ID assigned to a CFGBlock during construction 412 /// of the CFG. 413 unsigned BlockID; 414 415 public: 416 /// This class represents a potential adjacent block in the CFG. It encodes 417 /// whether or not the block is actually reachable, or can be proved to be 418 /// trivially unreachable. For some cases it allows one to encode scenarios 419 /// where a block was substituted because the original (now alternate) block 420 /// is unreachable. 421 class AdjacentBlock { 422 enum Kind { 423 AB_Normal, 424 AB_Unreachable, 425 AB_Alternate 426 }; 427 428 CFGBlock *ReachableBlock; 429 llvm::PointerIntPair<CFGBlock*, 2> UnreachableBlock; 430 431 public: 432 /// Construct an AdjacentBlock with a possibly unreachable block. 433 AdjacentBlock(CFGBlock *B, bool IsReachable); 434 435 /// Construct an AdjacentBlock with a reachable block and an alternate 436 /// unreachable block. 437 AdjacentBlock(CFGBlock *B, CFGBlock *AlternateBlock); 438 439 /// Get the reachable block, if one exists. getReachableBlock()440 CFGBlock *getReachableBlock() const { 441 return ReachableBlock; 442 } 443 444 /// Get the potentially unreachable block. getPossiblyUnreachableBlock()445 CFGBlock *getPossiblyUnreachableBlock() const { 446 return UnreachableBlock.getPointer(); 447 } 448 449 /// Provide an implicit conversion to CFGBlock* so that 450 /// AdjacentBlock can be substituted for CFGBlock*. 451 operator CFGBlock*() const { 452 return getReachableBlock(); 453 } 454 455 CFGBlock& operator *() const { 456 return *getReachableBlock(); 457 } 458 459 CFGBlock* operator ->() const { 460 return getReachableBlock(); 461 } 462 isReachable()463 bool isReachable() const { 464 Kind K = (Kind) UnreachableBlock.getInt(); 465 return K == AB_Normal || K == AB_Alternate; 466 } 467 }; 468 469 private: 470 /// Predecessors/Successors - Keep track of the predecessor / successor 471 /// CFG blocks. 472 typedef BumpVector<AdjacentBlock> AdjacentBlocks; 473 AdjacentBlocks Preds; 474 AdjacentBlocks Succs; 475 476 /// NoReturn - This bit is set when the basic block contains a function call 477 /// or implicit destructor that is attributed as 'noreturn'. In that case, 478 /// control cannot technically ever proceed past this block. All such blocks 479 /// will have a single immediate successor: the exit block. This allows them 480 /// to be easily reached from the exit block and using this bit quickly 481 /// recognized without scanning the contents of the block. 482 /// 483 /// Optimization Note: This bit could be profitably folded with Terminator's 484 /// storage if the memory usage of CFGBlock becomes an issue. 485 unsigned HasNoReturnElement : 1; 486 487 /// Parent - The parent CFG that owns this CFGBlock. 488 CFG *Parent; 489 490 public: CFGBlock(unsigned blockid,BumpVectorContext & C,CFG * parent)491 explicit CFGBlock(unsigned blockid, BumpVectorContext &C, CFG *parent) 492 : Elements(C), Label(nullptr), Terminator(nullptr), LoopTarget(nullptr), 493 BlockID(blockid), Preds(C, 1), Succs(C, 1), HasNoReturnElement(false), 494 Parent(parent) {} 495 496 // Statement iterators 497 typedef ElementList::iterator iterator; 498 typedef ElementList::const_iterator const_iterator; 499 typedef ElementList::reverse_iterator reverse_iterator; 500 typedef ElementList::const_reverse_iterator const_reverse_iterator; 501 front()502 CFGElement front() const { return Elements.front(); } back()503 CFGElement back() const { return Elements.back(); } 504 begin()505 iterator begin() { return Elements.begin(); } end()506 iterator end() { return Elements.end(); } begin()507 const_iterator begin() const { return Elements.begin(); } end()508 const_iterator end() const { return Elements.end(); } 509 rbegin()510 reverse_iterator rbegin() { return Elements.rbegin(); } rend()511 reverse_iterator rend() { return Elements.rend(); } rbegin()512 const_reverse_iterator rbegin() const { return Elements.rbegin(); } rend()513 const_reverse_iterator rend() const { return Elements.rend(); } 514 size()515 unsigned size() const { return Elements.size(); } empty()516 bool empty() const { return Elements.empty(); } 517 518 CFGElement operator[](size_t i) const { return Elements[i]; } 519 520 // CFG iterators 521 typedef AdjacentBlocks::iterator pred_iterator; 522 typedef AdjacentBlocks::const_iterator const_pred_iterator; 523 typedef AdjacentBlocks::reverse_iterator pred_reverse_iterator; 524 typedef AdjacentBlocks::const_reverse_iterator const_pred_reverse_iterator; 525 526 typedef AdjacentBlocks::iterator succ_iterator; 527 typedef AdjacentBlocks::const_iterator const_succ_iterator; 528 typedef AdjacentBlocks::reverse_iterator succ_reverse_iterator; 529 typedef AdjacentBlocks::const_reverse_iterator const_succ_reverse_iterator; 530 pred_begin()531 pred_iterator pred_begin() { return Preds.begin(); } pred_end()532 pred_iterator pred_end() { return Preds.end(); } pred_begin()533 const_pred_iterator pred_begin() const { return Preds.begin(); } pred_end()534 const_pred_iterator pred_end() const { return Preds.end(); } 535 pred_rbegin()536 pred_reverse_iterator pred_rbegin() { return Preds.rbegin(); } pred_rend()537 pred_reverse_iterator pred_rend() { return Preds.rend(); } pred_rbegin()538 const_pred_reverse_iterator pred_rbegin() const { return Preds.rbegin(); } pred_rend()539 const_pred_reverse_iterator pred_rend() const { return Preds.rend(); } 540 succ_begin()541 succ_iterator succ_begin() { return Succs.begin(); } succ_end()542 succ_iterator succ_end() { return Succs.end(); } succ_begin()543 const_succ_iterator succ_begin() const { return Succs.begin(); } succ_end()544 const_succ_iterator succ_end() const { return Succs.end(); } 545 succ_rbegin()546 succ_reverse_iterator succ_rbegin() { return Succs.rbegin(); } succ_rend()547 succ_reverse_iterator succ_rend() { return Succs.rend(); } succ_rbegin()548 const_succ_reverse_iterator succ_rbegin() const { return Succs.rbegin(); } succ_rend()549 const_succ_reverse_iterator succ_rend() const { return Succs.rend(); } 550 succ_size()551 unsigned succ_size() const { return Succs.size(); } succ_empty()552 bool succ_empty() const { return Succs.empty(); } 553 pred_size()554 unsigned pred_size() const { return Preds.size(); } pred_empty()555 bool pred_empty() const { return Preds.empty(); } 556 557 558 class FilterOptions { 559 public: FilterOptions()560 FilterOptions() { 561 IgnoreNullPredecessors = 1; 562 IgnoreDefaultsWithCoveredEnums = 0; 563 } 564 565 unsigned IgnoreNullPredecessors : 1; 566 unsigned IgnoreDefaultsWithCoveredEnums : 1; 567 }; 568 569 static bool FilterEdge(const FilterOptions &F, const CFGBlock *Src, 570 const CFGBlock *Dst); 571 572 template <typename IMPL, bool IsPred> 573 class FilteredCFGBlockIterator { 574 private: 575 IMPL I, E; 576 const FilterOptions F; 577 const CFGBlock *From; 578 public: FilteredCFGBlockIterator(const IMPL & i,const IMPL & e,const CFGBlock * from,const FilterOptions & f)579 explicit FilteredCFGBlockIterator(const IMPL &i, const IMPL &e, 580 const CFGBlock *from, 581 const FilterOptions &f) 582 : I(i), E(e), F(f), From(from) { 583 while (hasMore() && Filter(*I)) 584 ++I; 585 } 586 hasMore()587 bool hasMore() const { return I != E; } 588 589 FilteredCFGBlockIterator &operator++() { 590 do { ++I; } while (hasMore() && Filter(*I)); 591 return *this; 592 } 593 594 const CFGBlock *operator*() const { return *I; } 595 private: Filter(const CFGBlock * To)596 bool Filter(const CFGBlock *To) { 597 return IsPred ? FilterEdge(F, To, From) : FilterEdge(F, From, To); 598 } 599 }; 600 601 typedef FilteredCFGBlockIterator<const_pred_iterator, true> 602 filtered_pred_iterator; 603 604 typedef FilteredCFGBlockIterator<const_succ_iterator, false> 605 filtered_succ_iterator; 606 filtered_pred_start_end(const FilterOptions & f)607 filtered_pred_iterator filtered_pred_start_end(const FilterOptions &f) const { 608 return filtered_pred_iterator(pred_begin(), pred_end(), this, f); 609 } 610 filtered_succ_start_end(const FilterOptions & f)611 filtered_succ_iterator filtered_succ_start_end(const FilterOptions &f) const { 612 return filtered_succ_iterator(succ_begin(), succ_end(), this, f); 613 } 614 615 // Manipulation of block contents 616 setTerminator(CFGTerminator Term)617 void setTerminator(CFGTerminator Term) { Terminator = Term; } setLabel(Stmt * Statement)618 void setLabel(Stmt *Statement) { Label = Statement; } setLoopTarget(const Stmt * loopTarget)619 void setLoopTarget(const Stmt *loopTarget) { LoopTarget = loopTarget; } setHasNoReturnElement()620 void setHasNoReturnElement() { HasNoReturnElement = true; } 621 getTerminator()622 CFGTerminator getTerminator() { return Terminator; } getTerminator()623 const CFGTerminator getTerminator() const { return Terminator; } 624 625 Stmt *getTerminatorCondition(bool StripParens = true); 626 627 const Stmt *getTerminatorCondition(bool StripParens = true) const { 628 return const_cast<CFGBlock*>(this)->getTerminatorCondition(StripParens); 629 } 630 getLoopTarget()631 const Stmt *getLoopTarget() const { return LoopTarget; } 632 getLabel()633 Stmt *getLabel() { return Label; } getLabel()634 const Stmt *getLabel() const { return Label; } 635 hasNoReturnElement()636 bool hasNoReturnElement() const { return HasNoReturnElement; } 637 getBlockID()638 unsigned getBlockID() const { return BlockID; } 639 getParent()640 CFG *getParent() const { return Parent; } 641 642 void dump() const; 643 644 void dump(const CFG *cfg, const LangOptions &LO, bool ShowColors = false) const; 645 void print(raw_ostream &OS, const CFG* cfg, const LangOptions &LO, 646 bool ShowColors) const; 647 void printTerminator(raw_ostream &OS, const LangOptions &LO) const; printAsOperand(raw_ostream & OS,bool)648 void printAsOperand(raw_ostream &OS, bool /*PrintType*/) { 649 OS << "BB#" << getBlockID(); 650 } 651 652 /// Adds a (potentially unreachable) successor block to the current block. 653 void addSuccessor(AdjacentBlock Succ, BumpVectorContext &C); 654 appendStmt(Stmt * statement,BumpVectorContext & C)655 void appendStmt(Stmt *statement, BumpVectorContext &C) { 656 Elements.push_back(CFGStmt(statement), C); 657 } 658 appendInitializer(CXXCtorInitializer * initializer,BumpVectorContext & C)659 void appendInitializer(CXXCtorInitializer *initializer, 660 BumpVectorContext &C) { 661 Elements.push_back(CFGInitializer(initializer), C); 662 } 663 appendNewAllocator(CXXNewExpr * NE,BumpVectorContext & C)664 void appendNewAllocator(CXXNewExpr *NE, 665 BumpVectorContext &C) { 666 Elements.push_back(CFGNewAllocator(NE), C); 667 } 668 appendBaseDtor(const CXXBaseSpecifier * BS,BumpVectorContext & C)669 void appendBaseDtor(const CXXBaseSpecifier *BS, BumpVectorContext &C) { 670 Elements.push_back(CFGBaseDtor(BS), C); 671 } 672 appendMemberDtor(FieldDecl * FD,BumpVectorContext & C)673 void appendMemberDtor(FieldDecl *FD, BumpVectorContext &C) { 674 Elements.push_back(CFGMemberDtor(FD), C); 675 } 676 appendTemporaryDtor(CXXBindTemporaryExpr * E,BumpVectorContext & C)677 void appendTemporaryDtor(CXXBindTemporaryExpr *E, BumpVectorContext &C) { 678 Elements.push_back(CFGTemporaryDtor(E), C); 679 } 680 appendAutomaticObjDtor(VarDecl * VD,Stmt * S,BumpVectorContext & C)681 void appendAutomaticObjDtor(VarDecl *VD, Stmt *S, BumpVectorContext &C) { 682 Elements.push_back(CFGAutomaticObjDtor(VD, S), C); 683 } 684 appendDeleteDtor(CXXRecordDecl * RD,CXXDeleteExpr * DE,BumpVectorContext & C)685 void appendDeleteDtor(CXXRecordDecl *RD, CXXDeleteExpr *DE, BumpVectorContext &C) { 686 Elements.push_back(CFGDeleteDtor(RD, DE), C); 687 } 688 689 // Destructors must be inserted in reversed order. So insertion is in two 690 // steps. First we prepare space for some number of elements, then we insert 691 // the elements beginning at the last position in prepared space. beginAutomaticObjDtorsInsert(iterator I,size_t Cnt,BumpVectorContext & C)692 iterator beginAutomaticObjDtorsInsert(iterator I, size_t Cnt, 693 BumpVectorContext &C) { 694 return iterator(Elements.insert(I.base(), Cnt, 695 CFGAutomaticObjDtor(nullptr, nullptr), C)); 696 } insertAutomaticObjDtor(iterator I,VarDecl * VD,Stmt * S)697 iterator insertAutomaticObjDtor(iterator I, VarDecl *VD, Stmt *S) { 698 *I = CFGAutomaticObjDtor(VD, S); 699 return ++I; 700 } 701 }; 702 703 /// \brief CFGCallback defines methods that should be called when a logical 704 /// operator error is found when building the CFG. 705 class CFGCallback { 706 public: CFGCallback()707 CFGCallback() {} compareAlwaysTrue(const BinaryOperator * B,bool isAlwaysTrue)708 virtual void compareAlwaysTrue(const BinaryOperator *B, bool isAlwaysTrue) {} compareBitwiseEquality(const BinaryOperator * B,bool isAlwaysTrue)709 virtual void compareBitwiseEquality(const BinaryOperator *B, 710 bool isAlwaysTrue) {} ~CFGCallback()711 virtual ~CFGCallback() {} 712 }; 713 714 /// CFG - Represents a source-level, intra-procedural CFG that represents the 715 /// control-flow of a Stmt. The Stmt can represent an entire function body, 716 /// or a single expression. A CFG will always contain one empty block that 717 /// represents the Exit point of the CFG. A CFG will also contain a designated 718 /// Entry block. The CFG solely represents control-flow; it consists of 719 /// CFGBlocks which are simply containers of Stmt*'s in the AST the CFG 720 /// was constructed from. 721 class CFG { 722 public: 723 //===--------------------------------------------------------------------===// 724 // CFG Construction & Manipulation. 725 //===--------------------------------------------------------------------===// 726 727 class BuildOptions { 728 std::bitset<Stmt::lastStmtConstant> alwaysAddMask; 729 public: 730 typedef llvm::DenseMap<const Stmt *, const CFGBlock*> ForcedBlkExprs; 731 ForcedBlkExprs **forcedBlkExprs; 732 CFGCallback *Observer; 733 bool PruneTriviallyFalseEdges; 734 bool AddEHEdges; 735 bool AddInitializers; 736 bool AddImplicitDtors; 737 bool AddTemporaryDtors; 738 bool AddStaticInitBranches; 739 bool AddCXXNewAllocator; 740 bool AddCXXDefaultInitExprInCtors; 741 alwaysAdd(const Stmt * stmt)742 bool alwaysAdd(const Stmt *stmt) const { 743 return alwaysAddMask[stmt->getStmtClass()]; 744 } 745 746 BuildOptions &setAlwaysAdd(Stmt::StmtClass stmtClass, bool val = true) { 747 alwaysAddMask[stmtClass] = val; 748 return *this; 749 } 750 setAllAlwaysAdd()751 BuildOptions &setAllAlwaysAdd() { 752 alwaysAddMask.set(); 753 return *this; 754 } 755 BuildOptions()756 BuildOptions() 757 : forcedBlkExprs(nullptr), Observer(nullptr), 758 PruneTriviallyFalseEdges(true), AddEHEdges(false), 759 AddInitializers(false), AddImplicitDtors(false), 760 AddTemporaryDtors(false), AddStaticInitBranches(false), 761 AddCXXNewAllocator(false), AddCXXDefaultInitExprInCtors(false) {} 762 }; 763 764 /// \brief Provides a custom implementation of the iterator class to have the 765 /// same interface as Function::iterator - iterator returns CFGBlock 766 /// (not a pointer to CFGBlock). 767 class graph_iterator { 768 public: 769 typedef CFGBlock value_type; 770 typedef value_type& reference; 771 typedef value_type* pointer; 772 typedef BumpVector<CFGBlock*>::iterator ImplTy; 773 graph_iterator(const ImplTy & i)774 graph_iterator(const ImplTy &i) : I(i) {} 775 776 bool operator==(const graph_iterator &X) const { return I == X.I; } 777 bool operator!=(const graph_iterator &X) const { return I != X.I; } 778 779 reference operator*() const { return **I; } 780 pointer operator->() const { return *I; } 781 operator CFGBlock* () { return *I; } 782 783 graph_iterator &operator++() { ++I; return *this; } 784 graph_iterator &operator--() { --I; return *this; } 785 786 private: 787 ImplTy I; 788 }; 789 790 class const_graph_iterator { 791 public: 792 typedef const CFGBlock value_type; 793 typedef value_type& reference; 794 typedef value_type* pointer; 795 typedef BumpVector<CFGBlock*>::const_iterator ImplTy; 796 const_graph_iterator(const ImplTy & i)797 const_graph_iterator(const ImplTy &i) : I(i) {} 798 799 bool operator==(const const_graph_iterator &X) const { return I == X.I; } 800 bool operator!=(const const_graph_iterator &X) const { return I != X.I; } 801 802 reference operator*() const { return **I; } 803 pointer operator->() const { return *I; } 804 operator CFGBlock* () const { return *I; } 805 806 const_graph_iterator &operator++() { ++I; return *this; } 807 const_graph_iterator &operator--() { --I; return *this; } 808 809 private: 810 ImplTy I; 811 }; 812 813 /// buildCFG - Builds a CFG from an AST. 814 static std::unique_ptr<CFG> buildCFG(const Decl *D, Stmt *AST, ASTContext *C, 815 const BuildOptions &BO); 816 817 /// createBlock - Create a new block in the CFG. The CFG owns the block; 818 /// the caller should not directly free it. 819 CFGBlock *createBlock(); 820 821 /// setEntry - Set the entry block of the CFG. This is typically used 822 /// only during CFG construction. Most CFG clients expect that the 823 /// entry block has no predecessors and contains no statements. setEntry(CFGBlock * B)824 void setEntry(CFGBlock *B) { Entry = B; } 825 826 /// setIndirectGotoBlock - Set the block used for indirect goto jumps. 827 /// This is typically used only during CFG construction. setIndirectGotoBlock(CFGBlock * B)828 void setIndirectGotoBlock(CFGBlock *B) { IndirectGotoBlock = B; } 829 830 //===--------------------------------------------------------------------===// 831 // Block Iterators 832 //===--------------------------------------------------------------------===// 833 834 typedef BumpVector<CFGBlock*> CFGBlockListTy; 835 typedef CFGBlockListTy::iterator iterator; 836 typedef CFGBlockListTy::const_iterator const_iterator; 837 typedef std::reverse_iterator<iterator> reverse_iterator; 838 typedef std::reverse_iterator<const_iterator> const_reverse_iterator; 839 front()840 CFGBlock & front() { return *Blocks.front(); } back()841 CFGBlock & back() { return *Blocks.back(); } 842 begin()843 iterator begin() { return Blocks.begin(); } end()844 iterator end() { return Blocks.end(); } begin()845 const_iterator begin() const { return Blocks.begin(); } end()846 const_iterator end() const { return Blocks.end(); } 847 nodes_begin()848 graph_iterator nodes_begin() { return graph_iterator(Blocks.begin()); } nodes_end()849 graph_iterator nodes_end() { return graph_iterator(Blocks.end()); } nodes_begin()850 const_graph_iterator nodes_begin() const { 851 return const_graph_iterator(Blocks.begin()); 852 } nodes_end()853 const_graph_iterator nodes_end() const { 854 return const_graph_iterator(Blocks.end()); 855 } 856 rbegin()857 reverse_iterator rbegin() { return Blocks.rbegin(); } rend()858 reverse_iterator rend() { return Blocks.rend(); } rbegin()859 const_reverse_iterator rbegin() const { return Blocks.rbegin(); } rend()860 const_reverse_iterator rend() const { return Blocks.rend(); } 861 getEntry()862 CFGBlock & getEntry() { return *Entry; } getEntry()863 const CFGBlock & getEntry() const { return *Entry; } getExit()864 CFGBlock & getExit() { return *Exit; } getExit()865 const CFGBlock & getExit() const { return *Exit; } 866 getIndirectGotoBlock()867 CFGBlock * getIndirectGotoBlock() { return IndirectGotoBlock; } getIndirectGotoBlock()868 const CFGBlock * getIndirectGotoBlock() const { return IndirectGotoBlock; } 869 870 typedef std::vector<const CFGBlock*>::const_iterator try_block_iterator; try_blocks_begin()871 try_block_iterator try_blocks_begin() const { 872 return TryDispatchBlocks.begin(); 873 } try_blocks_end()874 try_block_iterator try_blocks_end() const { 875 return TryDispatchBlocks.end(); 876 } 877 addTryDispatchBlock(const CFGBlock * block)878 void addTryDispatchBlock(const CFGBlock *block) { 879 TryDispatchBlocks.push_back(block); 880 } 881 882 /// Records a synthetic DeclStmt and the DeclStmt it was constructed from. 883 /// 884 /// The CFG uses synthetic DeclStmts when a single AST DeclStmt contains 885 /// multiple decls. addSyntheticDeclStmt(const DeclStmt * Synthetic,const DeclStmt * Source)886 void addSyntheticDeclStmt(const DeclStmt *Synthetic, 887 const DeclStmt *Source) { 888 assert(Synthetic->isSingleDecl() && "Can handle single declarations only"); 889 assert(Synthetic != Source && "Don't include original DeclStmts in map"); 890 assert(!SyntheticDeclStmts.count(Synthetic) && "Already in map"); 891 SyntheticDeclStmts[Synthetic] = Source; 892 } 893 894 typedef llvm::DenseMap<const DeclStmt *, const DeclStmt *>::const_iterator 895 synthetic_stmt_iterator; 896 897 /// Iterates over synthetic DeclStmts in the CFG. 898 /// 899 /// Each element is a (synthetic statement, source statement) pair. 900 /// 901 /// \sa addSyntheticDeclStmt synthetic_stmt_begin()902 synthetic_stmt_iterator synthetic_stmt_begin() const { 903 return SyntheticDeclStmts.begin(); 904 } 905 906 /// \sa synthetic_stmt_begin synthetic_stmt_end()907 synthetic_stmt_iterator synthetic_stmt_end() const { 908 return SyntheticDeclStmts.end(); 909 } 910 911 //===--------------------------------------------------------------------===// 912 // Member templates useful for various batch operations over CFGs. 913 //===--------------------------------------------------------------------===// 914 915 template <typename CALLBACK> VisitBlockStmts(CALLBACK & O)916 void VisitBlockStmts(CALLBACK& O) const { 917 for (const_iterator I=begin(), E=end(); I != E; ++I) 918 for (CFGBlock::const_iterator BI=(*I)->begin(), BE=(*I)->end(); 919 BI != BE; ++BI) { 920 if (Optional<CFGStmt> stmt = BI->getAs<CFGStmt>()) 921 O(const_cast<Stmt*>(stmt->getStmt())); 922 } 923 } 924 925 //===--------------------------------------------------------------------===// 926 // CFG Introspection. 927 //===--------------------------------------------------------------------===// 928 929 /// getNumBlockIDs - Returns the total number of BlockIDs allocated (which 930 /// start at 0). getNumBlockIDs()931 unsigned getNumBlockIDs() const { return NumBlockIDs; } 932 933 /// size - Return the total number of CFGBlocks within the CFG 934 /// This is simply a renaming of the getNumBlockIDs(). This is necessary 935 /// because the dominator implementation needs such an interface. size()936 unsigned size() const { return NumBlockIDs; } 937 938 //===--------------------------------------------------------------------===// 939 // CFG Debugging: Pretty-Printing and Visualization. 940 //===--------------------------------------------------------------------===// 941 942 void viewCFG(const LangOptions &LO) const; 943 void print(raw_ostream &OS, const LangOptions &LO, bool ShowColors) const; 944 void dump(const LangOptions &LO, bool ShowColors) const; 945 946 //===--------------------------------------------------------------------===// 947 // Internal: constructors and data. 948 //===--------------------------------------------------------------------===// 949 CFG()950 CFG() 951 : Entry(nullptr), Exit(nullptr), IndirectGotoBlock(nullptr), NumBlockIDs(0), 952 Blocks(BlkBVC, 10) {} 953 getAllocator()954 llvm::BumpPtrAllocator& getAllocator() { 955 return BlkBVC.getAllocator(); 956 } 957 getBumpVectorContext()958 BumpVectorContext &getBumpVectorContext() { 959 return BlkBVC; 960 } 961 962 private: 963 CFGBlock *Entry; 964 CFGBlock *Exit; 965 CFGBlock* IndirectGotoBlock; // Special block to contain collective dispatch 966 // for indirect gotos 967 unsigned NumBlockIDs; 968 969 BumpVectorContext BlkBVC; 970 971 CFGBlockListTy Blocks; 972 973 /// C++ 'try' statements are modeled with an indirect dispatch block. 974 /// This is the collection of such blocks present in the CFG. 975 std::vector<const CFGBlock *> TryDispatchBlocks; 976 977 /// Collects DeclStmts synthesized for this CFG and maps each one back to its 978 /// source DeclStmt. 979 llvm::DenseMap<const DeclStmt *, const DeclStmt *> SyntheticDeclStmts; 980 }; 981 } // end namespace clang 982 983 //===----------------------------------------------------------------------===// 984 // GraphTraits specializations for CFG basic block graphs (source-level CFGs) 985 //===----------------------------------------------------------------------===// 986 987 namespace llvm { 988 989 /// Implement simplify_type for CFGTerminator, so that we can dyn_cast from 990 /// CFGTerminator to a specific Stmt class. 991 template <> struct simplify_type< ::clang::CFGTerminator> { 992 typedef ::clang::Stmt *SimpleType; 993 static SimpleType getSimplifiedValue(::clang::CFGTerminator Val) { 994 return Val.getStmt(); 995 } 996 }; 997 998 // Traits for: CFGBlock 999 1000 template <> struct GraphTraits< ::clang::CFGBlock *> { 1001 typedef ::clang::CFGBlock NodeType; 1002 typedef ::clang::CFGBlock::succ_iterator ChildIteratorType; 1003 1004 static NodeType* getEntryNode(::clang::CFGBlock *BB) 1005 { return BB; } 1006 1007 static inline ChildIteratorType child_begin(NodeType* N) 1008 { return N->succ_begin(); } 1009 1010 static inline ChildIteratorType child_end(NodeType* N) 1011 { return N->succ_end(); } 1012 }; 1013 1014 template <> struct GraphTraits< const ::clang::CFGBlock *> { 1015 typedef const ::clang::CFGBlock NodeType; 1016 typedef ::clang::CFGBlock::const_succ_iterator ChildIteratorType; 1017 1018 static NodeType* getEntryNode(const clang::CFGBlock *BB) 1019 { return BB; } 1020 1021 static inline ChildIteratorType child_begin(NodeType* N) 1022 { return N->succ_begin(); } 1023 1024 static inline ChildIteratorType child_end(NodeType* N) 1025 { return N->succ_end(); } 1026 }; 1027 1028 template <> struct GraphTraits<Inverse< ::clang::CFGBlock*> > { 1029 typedef ::clang::CFGBlock NodeType; 1030 typedef ::clang::CFGBlock::const_pred_iterator ChildIteratorType; 1031 1032 static NodeType *getEntryNode(Inverse< ::clang::CFGBlock*> G) 1033 { return G.Graph; } 1034 1035 static inline ChildIteratorType child_begin(NodeType* N) 1036 { return N->pred_begin(); } 1037 1038 static inline ChildIteratorType child_end(NodeType* N) 1039 { return N->pred_end(); } 1040 }; 1041 1042 template <> struct GraphTraits<Inverse<const ::clang::CFGBlock*> > { 1043 typedef const ::clang::CFGBlock NodeType; 1044 typedef ::clang::CFGBlock::const_pred_iterator ChildIteratorType; 1045 1046 static NodeType *getEntryNode(Inverse<const ::clang::CFGBlock*> G) 1047 { return G.Graph; } 1048 1049 static inline ChildIteratorType child_begin(NodeType* N) 1050 { return N->pred_begin(); } 1051 1052 static inline ChildIteratorType child_end(NodeType* N) 1053 { return N->pred_end(); } 1054 }; 1055 1056 // Traits for: CFG 1057 1058 template <> struct GraphTraits< ::clang::CFG* > 1059 : public GraphTraits< ::clang::CFGBlock *> { 1060 1061 typedef ::clang::CFG::graph_iterator nodes_iterator; 1062 1063 static NodeType *getEntryNode(::clang::CFG* F) { return &F->getEntry(); } 1064 static nodes_iterator nodes_begin(::clang::CFG* F) { return F->nodes_begin();} 1065 static nodes_iterator nodes_end(::clang::CFG* F) { return F->nodes_end(); } 1066 static unsigned size(::clang::CFG* F) { return F->size(); } 1067 }; 1068 1069 template <> struct GraphTraits<const ::clang::CFG* > 1070 : public GraphTraits<const ::clang::CFGBlock *> { 1071 1072 typedef ::clang::CFG::const_graph_iterator nodes_iterator; 1073 1074 static NodeType *getEntryNode( const ::clang::CFG* F) { 1075 return &F->getEntry(); 1076 } 1077 static nodes_iterator nodes_begin( const ::clang::CFG* F) { 1078 return F->nodes_begin(); 1079 } 1080 static nodes_iterator nodes_end( const ::clang::CFG* F) { 1081 return F->nodes_end(); 1082 } 1083 static unsigned size(const ::clang::CFG* F) { 1084 return F->size(); 1085 } 1086 }; 1087 1088 template <> struct GraphTraits<Inverse< ::clang::CFG*> > 1089 : public GraphTraits<Inverse< ::clang::CFGBlock*> > { 1090 1091 typedef ::clang::CFG::graph_iterator nodes_iterator; 1092 1093 static NodeType *getEntryNode( ::clang::CFG* F) { return &F->getExit(); } 1094 static nodes_iterator nodes_begin( ::clang::CFG* F) {return F->nodes_begin();} 1095 static nodes_iterator nodes_end( ::clang::CFG* F) { return F->nodes_end(); } 1096 }; 1097 1098 template <> struct GraphTraits<Inverse<const ::clang::CFG*> > 1099 : public GraphTraits<Inverse<const ::clang::CFGBlock*> > { 1100 1101 typedef ::clang::CFG::const_graph_iterator nodes_iterator; 1102 1103 static NodeType *getEntryNode(const ::clang::CFG* F) { return &F->getExit(); } 1104 static nodes_iterator nodes_begin(const ::clang::CFG* F) { 1105 return F->nodes_begin(); 1106 } 1107 static nodes_iterator nodes_end(const ::clang::CFG* F) { 1108 return F->nodes_end(); 1109 } 1110 }; 1111 } // end llvm namespace 1112 1113 #endif // LLVM_CLANG_ANALYSIS_CFG_H 1114