1 //===- CFG.h - Classes for representing and building CFGs -------*- C++ -*-===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 // This file defines the CFG and CFGBuilder classes for representing and 10 // building Control-Flow Graphs (CFGs) from ASTs. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #ifndef LLVM_CLANG_ANALYSIS_CFG_H 15 #define LLVM_CLANG_ANALYSIS_CFG_H 16 17 #include "clang/Analysis/Support/BumpVector.h" 18 #include "clang/Analysis/ConstructionContext.h" 19 #include "clang/AST/ExprCXX.h" 20 #include "clang/AST/ExprObjC.h" 21 #include "clang/Basic/LLVM.h" 22 #include "llvm/ADT/DenseMap.h" 23 #include "llvm/ADT/GraphTraits.h" 24 #include "llvm/ADT/PointerIntPair.h" 25 #include "llvm/ADT/iterator_range.h" 26 #include "llvm/Support/Allocator.h" 27 #include "llvm/Support/raw_ostream.h" 28 #include <bitset> 29 #include <cassert> 30 #include <cstddef> 31 #include <iterator> 32 #include <memory> 33 #include <optional> 34 #include <vector> 35 36 namespace clang { 37 38 class ASTContext; 39 class BinaryOperator; 40 class CFG; 41 class CXXBaseSpecifier; 42 class CXXBindTemporaryExpr; 43 class CXXCtorInitializer; 44 class CXXDeleteExpr; 45 class CXXDestructorDecl; 46 class CXXNewExpr; 47 class CXXRecordDecl; 48 class Decl; 49 class FieldDecl; 50 class LangOptions; 51 class VarDecl; 52 53 /// Represents a top-level expression in a basic block. 54 class CFGElement { 55 public: 56 enum Kind { 57 // main kind 58 Initializer, 59 ScopeBegin, 60 ScopeEnd, 61 NewAllocator, 62 LifetimeEnds, 63 LoopExit, 64 // stmt kind 65 Statement, 66 Constructor, 67 CXXRecordTypedCall, 68 STMT_BEGIN = Statement, 69 STMT_END = CXXRecordTypedCall, 70 // dtor kind 71 AutomaticObjectDtor, 72 DeleteDtor, 73 BaseDtor, 74 MemberDtor, 75 TemporaryDtor, 76 DTOR_BEGIN = AutomaticObjectDtor, 77 DTOR_END = TemporaryDtor 78 }; 79 80 protected: 81 // The int bits are used to mark the kind. 82 llvm::PointerIntPair<void *, 2> Data1; 83 llvm::PointerIntPair<void *, 2> Data2; 84 85 CFGElement(Kind kind, const void *Ptr1, const void *Ptr2 = nullptr) 86 : Data1(const_cast<void*>(Ptr1), ((unsigned) kind) & 0x3), 87 Data2(const_cast<void*>(Ptr2), (((unsigned) kind) >> 2) & 0x3) { 88 assert(getKind() == kind); 89 } 90 91 CFGElement() = default; 92 93 public: 94 /// Convert to the specified CFGElement type, asserting that this 95 /// CFGElement is of the desired type. 96 template<typename T> castAs()97 T castAs() const { 98 assert(T::isKind(*this)); 99 T t; 100 CFGElement& e = t; 101 e = *this; 102 return t; 103 } 104 105 /// Convert to the specified CFGElement type, returning std::nullopt if this 106 /// CFGElement is not of the desired type. getAs()107 template <typename T> std::optional<T> getAs() const { 108 if (!T::isKind(*this)) 109 return std::nullopt; 110 T t; 111 CFGElement& e = t; 112 e = *this; 113 return t; 114 } 115 getKind()116 Kind getKind() const { 117 unsigned x = Data2.getInt(); 118 x <<= 2; 119 x |= Data1.getInt(); 120 return (Kind) x; 121 } 122 123 void dumpToStream(llvm::raw_ostream &OS) const; 124 dump()125 void dump() const { 126 dumpToStream(llvm::errs()); 127 } 128 }; 129 130 class CFGStmt : public CFGElement { 131 public: CFGElement(K,S)132 explicit CFGStmt(const Stmt *S, Kind K = Statement) : CFGElement(K, S) { 133 assert(isKind(*this)); 134 } 135 getStmt()136 const Stmt *getStmt() const { 137 return static_cast<const Stmt *>(Data1.getPointer()); 138 } 139 140 private: 141 friend class CFGElement; 142 isKind(const CFGElement & E)143 static bool isKind(const CFGElement &E) { 144 return E.getKind() >= STMT_BEGIN && E.getKind() <= STMT_END; 145 } 146 147 protected: 148 CFGStmt() = default; 149 }; 150 151 /// Represents C++ constructor call. Maintains information necessary to figure 152 /// out what memory is being initialized by the constructor expression. For now 153 /// this is only used by the analyzer's CFG. 154 class CFGConstructor : public CFGStmt { 155 public: CFGConstructor(const CXXConstructExpr * CE,const ConstructionContext * C)156 explicit CFGConstructor(const CXXConstructExpr *CE, 157 const ConstructionContext *C) 158 : CFGStmt(CE, Constructor) { 159 assert(C); 160 Data2.setPointer(const_cast<ConstructionContext *>(C)); 161 } 162 getConstructionContext()163 const ConstructionContext *getConstructionContext() const { 164 return static_cast<ConstructionContext *>(Data2.getPointer()); 165 } 166 167 private: 168 friend class CFGElement; 169 170 CFGConstructor() = default; 171 isKind(const CFGElement & E)172 static bool isKind(const CFGElement &E) { 173 return E.getKind() == Constructor; 174 } 175 }; 176 177 /// Represents a function call that returns a C++ object by value. This, like 178 /// constructor, requires a construction context in order to understand the 179 /// storage of the returned object . In C such tracking is not necessary because 180 /// no additional effort is required for destroying the object or modeling copy 181 /// elision. Like CFGConstructor, this element is for now only used by the 182 /// analyzer's CFG. 183 class CFGCXXRecordTypedCall : public CFGStmt { 184 public: 185 /// Returns true when call expression \p CE needs to be represented 186 /// by CFGCXXRecordTypedCall, as opposed to a regular CFGStmt. isCXXRecordTypedCall(const Expr * E)187 static bool isCXXRecordTypedCall(const Expr *E) { 188 assert(isa<CallExpr>(E) || isa<ObjCMessageExpr>(E)); 189 // There is no such thing as reference-type expression. If the function 190 // returns a reference, it'll return the respective lvalue or xvalue 191 // instead, and we're only interested in objects. 192 return !E->isGLValue() && 193 E->getType().getCanonicalType()->getAsCXXRecordDecl(); 194 } 195 CFGCXXRecordTypedCall(const Expr * E,const ConstructionContext * C)196 explicit CFGCXXRecordTypedCall(const Expr *E, const ConstructionContext *C) 197 : CFGStmt(E, CXXRecordTypedCall) { 198 assert(isCXXRecordTypedCall(E)); 199 assert(C && (isa<TemporaryObjectConstructionContext>(C) || 200 // These are possible in C++17 due to mandatory copy elision. 201 isa<ReturnedValueConstructionContext>(C) || 202 isa<VariableConstructionContext>(C) || 203 isa<ConstructorInitializerConstructionContext>(C) || 204 isa<ArgumentConstructionContext>(C) || 205 isa<LambdaCaptureConstructionContext>(C))); 206 Data2.setPointer(const_cast<ConstructionContext *>(C)); 207 } 208 getConstructionContext()209 const ConstructionContext *getConstructionContext() const { 210 return static_cast<ConstructionContext *>(Data2.getPointer()); 211 } 212 213 private: 214 friend class CFGElement; 215 216 CFGCXXRecordTypedCall() = default; 217 isKind(const CFGElement & E)218 static bool isKind(const CFGElement &E) { 219 return E.getKind() == CXXRecordTypedCall; 220 } 221 }; 222 223 /// Represents C++ base or member initializer from constructor's initialization 224 /// list. 225 class CFGInitializer : public CFGElement { 226 public: CFGInitializer(const CXXCtorInitializer * initializer)227 explicit CFGInitializer(const CXXCtorInitializer *initializer) 228 : CFGElement(Initializer, initializer) {} 229 getInitializer()230 CXXCtorInitializer* getInitializer() const { 231 return static_cast<CXXCtorInitializer*>(Data1.getPointer()); 232 } 233 234 private: 235 friend class CFGElement; 236 237 CFGInitializer() = default; 238 isKind(const CFGElement & E)239 static bool isKind(const CFGElement &E) { 240 return E.getKind() == Initializer; 241 } 242 }; 243 244 /// Represents C++ allocator call. 245 class CFGNewAllocator : public CFGElement { 246 public: CFGNewAllocator(const CXXNewExpr * S)247 explicit CFGNewAllocator(const CXXNewExpr *S) 248 : CFGElement(NewAllocator, S) {} 249 250 // Get the new expression. getAllocatorExpr()251 const CXXNewExpr *getAllocatorExpr() const { 252 return static_cast<CXXNewExpr *>(Data1.getPointer()); 253 } 254 255 private: 256 friend class CFGElement; 257 258 CFGNewAllocator() = default; 259 isKind(const CFGElement & elem)260 static bool isKind(const CFGElement &elem) { 261 return elem.getKind() == NewAllocator; 262 } 263 }; 264 265 /// Represents the point where a loop ends. 266 /// This element is only produced when building the CFG for the static 267 /// analyzer and hidden behind the 'cfg-loopexit' analyzer config flag. 268 /// 269 /// Note: a loop exit element can be reached even when the loop body was never 270 /// entered. 271 class CFGLoopExit : public CFGElement { 272 public: CFGLoopExit(const Stmt * stmt)273 explicit CFGLoopExit(const Stmt *stmt) : CFGElement(LoopExit, stmt) {} 274 getLoopStmt()275 const Stmt *getLoopStmt() const { 276 return static_cast<Stmt *>(Data1.getPointer()); 277 } 278 279 private: 280 friend class CFGElement; 281 282 CFGLoopExit() = default; 283 isKind(const CFGElement & elem)284 static bool isKind(const CFGElement &elem) { 285 return elem.getKind() == LoopExit; 286 } 287 }; 288 289 /// Represents the point where the lifetime of an automatic object ends 290 class CFGLifetimeEnds : public CFGElement { 291 public: CFGLifetimeEnds(const VarDecl * var,const Stmt * stmt)292 explicit CFGLifetimeEnds(const VarDecl *var, const Stmt *stmt) 293 : CFGElement(LifetimeEnds, var, stmt) {} 294 getVarDecl()295 const VarDecl *getVarDecl() const { 296 return static_cast<VarDecl *>(Data1.getPointer()); 297 } 298 getTriggerStmt()299 const Stmt *getTriggerStmt() const { 300 return static_cast<Stmt *>(Data2.getPointer()); 301 } 302 303 private: 304 friend class CFGElement; 305 306 CFGLifetimeEnds() = default; 307 isKind(const CFGElement & elem)308 static bool isKind(const CFGElement &elem) { 309 return elem.getKind() == LifetimeEnds; 310 } 311 }; 312 313 /// Represents beginning of a scope implicitly generated 314 /// by the compiler on encountering a CompoundStmt 315 class CFGScopeBegin : public CFGElement { 316 public: CFGScopeBegin()317 CFGScopeBegin() {} CFGScopeBegin(const VarDecl * VD,const Stmt * S)318 CFGScopeBegin(const VarDecl *VD, const Stmt *S) 319 : CFGElement(ScopeBegin, VD, S) {} 320 321 // Get statement that triggered a new scope. getTriggerStmt()322 const Stmt *getTriggerStmt() const { 323 return static_cast<Stmt*>(Data2.getPointer()); 324 } 325 326 // Get VD that triggered a new scope. getVarDecl()327 const VarDecl *getVarDecl() const { 328 return static_cast<VarDecl *>(Data1.getPointer()); 329 } 330 331 private: 332 friend class CFGElement; isKind(const CFGElement & E)333 static bool isKind(const CFGElement &E) { 334 Kind kind = E.getKind(); 335 return kind == ScopeBegin; 336 } 337 }; 338 339 /// Represents end of a scope implicitly generated by 340 /// the compiler after the last Stmt in a CompoundStmt's body 341 class CFGScopeEnd : public CFGElement { 342 public: CFGScopeEnd()343 CFGScopeEnd() {} CFGScopeEnd(const VarDecl * VD,const Stmt * S)344 CFGScopeEnd(const VarDecl *VD, const Stmt *S) : CFGElement(ScopeEnd, VD, S) {} 345 getVarDecl()346 const VarDecl *getVarDecl() const { 347 return static_cast<VarDecl *>(Data1.getPointer()); 348 } 349 getTriggerStmt()350 const Stmt *getTriggerStmt() const { 351 return static_cast<Stmt *>(Data2.getPointer()); 352 } 353 354 private: 355 friend class CFGElement; isKind(const CFGElement & E)356 static bool isKind(const CFGElement &E) { 357 Kind kind = E.getKind(); 358 return kind == ScopeEnd; 359 } 360 }; 361 362 /// Represents C++ object destructor implicitly generated by compiler on various 363 /// occasions. 364 class CFGImplicitDtor : public CFGElement { 365 protected: 366 CFGImplicitDtor() = default; 367 368 CFGImplicitDtor(Kind kind, const void *data1, const void *data2 = nullptr) CFGElement(kind,data1,data2)369 : CFGElement(kind, data1, data2) { 370 assert(kind >= DTOR_BEGIN && kind <= DTOR_END); 371 } 372 373 public: 374 const CXXDestructorDecl *getDestructorDecl(ASTContext &astContext) const; 375 bool isNoReturn(ASTContext &astContext) const; 376 377 private: 378 friend class CFGElement; 379 isKind(const CFGElement & E)380 static bool isKind(const CFGElement &E) { 381 Kind kind = E.getKind(); 382 return kind >= DTOR_BEGIN && kind <= DTOR_END; 383 } 384 }; 385 386 /// Represents C++ object destructor implicitly generated for automatic object 387 /// or temporary bound to const reference at the point of leaving its local 388 /// scope. 389 class CFGAutomaticObjDtor: public CFGImplicitDtor { 390 public: CFGAutomaticObjDtor(const VarDecl * var,const Stmt * stmt)391 CFGAutomaticObjDtor(const VarDecl *var, const Stmt *stmt) 392 : CFGImplicitDtor(AutomaticObjectDtor, var, stmt) {} 393 getVarDecl()394 const VarDecl *getVarDecl() const { 395 return static_cast<VarDecl*>(Data1.getPointer()); 396 } 397 398 // Get statement end of which triggered the destructor call. getTriggerStmt()399 const Stmt *getTriggerStmt() const { 400 return static_cast<Stmt*>(Data2.getPointer()); 401 } 402 403 private: 404 friend class CFGElement; 405 406 CFGAutomaticObjDtor() = default; 407 isKind(const CFGElement & elem)408 static bool isKind(const CFGElement &elem) { 409 return elem.getKind() == AutomaticObjectDtor; 410 } 411 }; 412 413 /// Represents C++ object destructor generated from a call to delete. 414 class CFGDeleteDtor : public CFGImplicitDtor { 415 public: CFGDeleteDtor(const CXXRecordDecl * RD,const CXXDeleteExpr * DE)416 CFGDeleteDtor(const CXXRecordDecl *RD, const CXXDeleteExpr *DE) 417 : CFGImplicitDtor(DeleteDtor, RD, DE) {} 418 getCXXRecordDecl()419 const CXXRecordDecl *getCXXRecordDecl() const { 420 return static_cast<CXXRecordDecl*>(Data1.getPointer()); 421 } 422 423 // Get Delete expression which triggered the destructor call. getDeleteExpr()424 const CXXDeleteExpr *getDeleteExpr() const { 425 return static_cast<CXXDeleteExpr *>(Data2.getPointer()); 426 } 427 428 private: 429 friend class CFGElement; 430 431 CFGDeleteDtor() = default; 432 isKind(const CFGElement & elem)433 static bool isKind(const CFGElement &elem) { 434 return elem.getKind() == DeleteDtor; 435 } 436 }; 437 438 /// Represents C++ object destructor implicitly generated for base object in 439 /// destructor. 440 class CFGBaseDtor : public CFGImplicitDtor { 441 public: CFGBaseDtor(const CXXBaseSpecifier * base)442 CFGBaseDtor(const CXXBaseSpecifier *base) 443 : CFGImplicitDtor(BaseDtor, base) {} 444 getBaseSpecifier()445 const CXXBaseSpecifier *getBaseSpecifier() const { 446 return static_cast<const CXXBaseSpecifier*>(Data1.getPointer()); 447 } 448 449 private: 450 friend class CFGElement; 451 452 CFGBaseDtor() = default; 453 isKind(const CFGElement & E)454 static bool isKind(const CFGElement &E) { 455 return E.getKind() == BaseDtor; 456 } 457 }; 458 459 /// Represents C++ object destructor implicitly generated for member object in 460 /// destructor. 461 class CFGMemberDtor : public CFGImplicitDtor { 462 public: CFGMemberDtor(const FieldDecl * field)463 CFGMemberDtor(const FieldDecl *field) 464 : CFGImplicitDtor(MemberDtor, field, nullptr) {} 465 getFieldDecl()466 const FieldDecl *getFieldDecl() const { 467 return static_cast<const FieldDecl*>(Data1.getPointer()); 468 } 469 470 private: 471 friend class CFGElement; 472 473 CFGMemberDtor() = default; 474 isKind(const CFGElement & E)475 static bool isKind(const CFGElement &E) { 476 return E.getKind() == MemberDtor; 477 } 478 }; 479 480 /// Represents C++ object destructor implicitly generated at the end of full 481 /// expression for temporary object. 482 class CFGTemporaryDtor : public CFGImplicitDtor { 483 public: CFGTemporaryDtor(const CXXBindTemporaryExpr * expr)484 CFGTemporaryDtor(const CXXBindTemporaryExpr *expr) 485 : CFGImplicitDtor(TemporaryDtor, expr, nullptr) {} 486 getBindTemporaryExpr()487 const CXXBindTemporaryExpr *getBindTemporaryExpr() const { 488 return static_cast<const CXXBindTemporaryExpr *>(Data1.getPointer()); 489 } 490 491 private: 492 friend class CFGElement; 493 494 CFGTemporaryDtor() = default; 495 isKind(const CFGElement & E)496 static bool isKind(const CFGElement &E) { 497 return E.getKind() == TemporaryDtor; 498 } 499 }; 500 501 /// Represents CFGBlock terminator statement. 502 /// 503 class CFGTerminator { 504 public: 505 enum Kind { 506 /// A branch that corresponds to a statement in the code, 507 /// such as an if-statement. 508 StmtBranch, 509 /// A branch in control flow of destructors of temporaries. In this case 510 /// terminator statement is the same statement that branches control flow 511 /// in evaluation of matching full expression. 512 TemporaryDtorsBranch, 513 /// A shortcut around virtual base initializers. It gets taken when 514 /// virtual base classes have already been initialized by the constructor 515 /// of the most derived class while we're in the base class. 516 VirtualBaseBranch, 517 518 /// Number of different kinds, for assertions. We subtract 1 so that 519 /// to keep receiving compiler warnings when we don't cover all enum values 520 /// in a switch. 521 NumKindsMinusOne = VirtualBaseBranch 522 }; 523 524 private: 525 static constexpr int KindBits = 2; 526 static_assert((1 << KindBits) > NumKindsMinusOne, 527 "Not enough room for kind!"); 528 llvm::PointerIntPair<Stmt *, KindBits> Data; 529 530 public: CFGTerminator()531 CFGTerminator() { assert(!isValid()); } Data(S,K)532 CFGTerminator(Stmt *S, Kind K = StmtBranch) : Data(S, K) {} 533 isValid()534 bool isValid() const { return Data.getOpaqueValue() != nullptr; } getStmt()535 Stmt *getStmt() { return Data.getPointer(); } getStmt()536 const Stmt *getStmt() const { return Data.getPointer(); } getKind()537 Kind getKind() const { return static_cast<Kind>(Data.getInt()); } 538 isStmtBranch()539 bool isStmtBranch() const { 540 return getKind() == StmtBranch; 541 } isTemporaryDtorsBranch()542 bool isTemporaryDtorsBranch() const { 543 return getKind() == TemporaryDtorsBranch; 544 } isVirtualBaseBranch()545 bool isVirtualBaseBranch() const { 546 return getKind() == VirtualBaseBranch; 547 } 548 }; 549 550 /// Represents a single basic block in a source-level CFG. 551 /// It consists of: 552 /// 553 /// (1) A set of statements/expressions (which may contain subexpressions). 554 /// (2) A "terminator" statement (not in the set of statements). 555 /// (3) A list of successors and predecessors. 556 /// 557 /// Terminator: The terminator represents the type of control-flow that occurs 558 /// at the end of the basic block. The terminator is a Stmt* referring to an 559 /// AST node that has control-flow: if-statements, breaks, loops, etc. 560 /// If the control-flow is conditional, the condition expression will appear 561 /// within the set of statements in the block (usually the last statement). 562 /// 563 /// Predecessors: the order in the set of predecessors is arbitrary. 564 /// 565 /// Successors: the order in the set of successors is NOT arbitrary. We 566 /// currently have the following orderings based on the terminator: 567 /// 568 /// Terminator | Successor Ordering 569 /// ------------------|------------------------------------ 570 /// if | Then Block; Else Block 571 /// ? operator | LHS expression; RHS expression 572 /// logical and/or | expression that consumes the op, RHS 573 /// vbase inits | already handled by the most derived class; not yet 574 /// 575 /// But note that any of that may be NULL in case of optimized-out edges. 576 class CFGBlock { 577 class ElementList { 578 using ImplTy = BumpVector<CFGElement>; 579 580 ImplTy Impl; 581 582 public: ElementList(BumpVectorContext & C)583 ElementList(BumpVectorContext &C) : Impl(C, 4) {} 584 585 using iterator = std::reverse_iterator<ImplTy::iterator>; 586 using const_iterator = std::reverse_iterator<ImplTy::const_iterator>; 587 using reverse_iterator = ImplTy::iterator; 588 using const_reverse_iterator = ImplTy::const_iterator; 589 using const_reference = ImplTy::const_reference; 590 push_back(CFGElement e,BumpVectorContext & C)591 void push_back(CFGElement e, BumpVectorContext &C) { Impl.push_back(e, C); } 592 insert(reverse_iterator I,size_t Cnt,CFGElement E,BumpVectorContext & C)593 reverse_iterator insert(reverse_iterator I, size_t Cnt, CFGElement E, 594 BumpVectorContext &C) { 595 return Impl.insert(I, Cnt, E, C); 596 } 597 front()598 const_reference front() const { return Impl.back(); } back()599 const_reference back() const { return Impl.front(); } 600 begin()601 iterator begin() { return Impl.rbegin(); } end()602 iterator end() { return Impl.rend(); } begin()603 const_iterator begin() const { return Impl.rbegin(); } end()604 const_iterator end() const { return Impl.rend(); } rbegin()605 reverse_iterator rbegin() { return Impl.begin(); } rend()606 reverse_iterator rend() { return Impl.end(); } rbegin()607 const_reverse_iterator rbegin() const { return Impl.begin(); } rend()608 const_reverse_iterator rend() const { return Impl.end(); } 609 610 CFGElement operator[](size_t i) const { 611 assert(i < Impl.size()); 612 return Impl[Impl.size() - 1 - i]; 613 } 614 size()615 size_t size() const { return Impl.size(); } empty()616 bool empty() const { return Impl.empty(); } 617 }; 618 619 /// A convenience class for comparing CFGElements, since methods of CFGBlock 620 /// like operator[] return CFGElements by value. This is practically a wrapper 621 /// around a (CFGBlock, Index) pair. 622 template <bool IsConst> class ElementRefImpl { 623 624 template <bool IsOtherConst> friend class ElementRefImpl; 625 626 using CFGBlockPtr = 627 std::conditional_t<IsConst, const CFGBlock *, CFGBlock *>; 628 629 using CFGElementPtr = 630 std::conditional_t<IsConst, const CFGElement *, CFGElement *>; 631 632 protected: 633 CFGBlockPtr Parent; 634 size_t Index; 635 636 public: ElementRefImpl(CFGBlockPtr Parent,size_t Index)637 ElementRefImpl(CFGBlockPtr Parent, size_t Index) 638 : Parent(Parent), Index(Index) {} 639 640 template <bool IsOtherConst> ElementRefImpl(ElementRefImpl<IsOtherConst> Other)641 ElementRefImpl(ElementRefImpl<IsOtherConst> Other) 642 : ElementRefImpl(Other.Parent, Other.Index) {} 643 getIndexInBlock()644 size_t getIndexInBlock() const { return Index; } 645 getParent()646 CFGBlockPtr getParent() { return Parent; } getParent()647 CFGBlockPtr getParent() const { return Parent; } 648 649 bool operator<(ElementRefImpl Other) const { 650 return std::make_pair(Parent, Index) < 651 std::make_pair(Other.Parent, Other.Index); 652 } 653 654 bool operator==(ElementRefImpl Other) const { 655 return Parent == Other.Parent && Index == Other.Index; 656 } 657 658 bool operator!=(ElementRefImpl Other) const { return !(*this == Other); } 659 CFGElement operator*() const { return (*Parent)[Index]; } 660 CFGElementPtr operator->() const { return &*(Parent->begin() + Index); } 661 dumpToStream(llvm::raw_ostream & OS)662 void dumpToStream(llvm::raw_ostream &OS) const { 663 OS << getIndexInBlock() + 1 << ": "; 664 (*this)->dumpToStream(OS); 665 } 666 dump()667 void dump() const { 668 dumpToStream(llvm::errs()); 669 } 670 }; 671 672 template <bool IsReverse, bool IsConst> class ElementRefIterator { 673 674 template <bool IsOtherReverse, bool IsOtherConst> 675 friend class ElementRefIterator; 676 677 using CFGBlockRef = 678 std::conditional_t<IsConst, const CFGBlock *, CFGBlock *>; 679 680 using UnderlayingIteratorTy = std::conditional_t< 681 IsConst, 682 std::conditional_t<IsReverse, ElementList::const_reverse_iterator, 683 ElementList::const_iterator>, 684 std::conditional_t<IsReverse, ElementList::reverse_iterator, 685 ElementList::iterator>>; 686 687 using IteratorTraits = typename std::iterator_traits<UnderlayingIteratorTy>; 688 using ElementRef = typename CFGBlock::ElementRefImpl<IsConst>; 689 690 public: 691 using difference_type = typename IteratorTraits::difference_type; 692 using value_type = ElementRef; 693 using pointer = ElementRef *; 694 using iterator_category = typename IteratorTraits::iterator_category; 695 696 private: 697 CFGBlockRef Parent; 698 UnderlayingIteratorTy Pos; 699 700 public: ElementRefIterator(CFGBlockRef Parent,UnderlayingIteratorTy Pos)701 ElementRefIterator(CFGBlockRef Parent, UnderlayingIteratorTy Pos) 702 : Parent(Parent), Pos(Pos) {} 703 704 template <bool IsOtherConst> ElementRefIterator(ElementRefIterator<false,IsOtherConst> E)705 ElementRefIterator(ElementRefIterator<false, IsOtherConst> E) 706 : ElementRefIterator(E.Parent, E.Pos.base()) {} 707 708 template <bool IsOtherConst> ElementRefIterator(ElementRefIterator<true,IsOtherConst> E)709 ElementRefIterator(ElementRefIterator<true, IsOtherConst> E) 710 : ElementRefIterator(E.Parent, std::make_reverse_iterator(E.Pos)) {} 711 712 bool operator<(ElementRefIterator Other) const { 713 assert(Parent == Other.Parent); 714 return Pos < Other.Pos; 715 } 716 717 bool operator==(ElementRefIterator Other) const { 718 return Parent == Other.Parent && Pos == Other.Pos; 719 } 720 721 bool operator!=(ElementRefIterator Other) const { 722 return !(*this == Other); 723 } 724 725 private: 726 template <bool IsOtherConst> 727 static size_t getIndexInBlock(CFGBlock::ElementRefIterator<true,IsOtherConst> E)728 getIndexInBlock(CFGBlock::ElementRefIterator<true, IsOtherConst> E) { 729 return E.Parent->size() - (E.Pos - E.Parent->rbegin()) - 1; 730 } 731 732 template <bool IsOtherConst> 733 static size_t getIndexInBlock(CFGBlock::ElementRefIterator<false,IsOtherConst> E)734 getIndexInBlock(CFGBlock::ElementRefIterator<false, IsOtherConst> E) { 735 return E.Pos - E.Parent->begin(); 736 } 737 738 public: 739 value_type operator*() { return {Parent, getIndexInBlock(*this)}; } 740 741 difference_type operator-(ElementRefIterator Other) const { 742 return Pos - Other.Pos; 743 } 744 745 ElementRefIterator operator++() { 746 ++this->Pos; 747 return *this; 748 } 749 ElementRefIterator operator++(int) { 750 ElementRefIterator Ret = *this; 751 ++*this; 752 return Ret; 753 } 754 ElementRefIterator operator+(size_t count) { 755 this->Pos += count; 756 return *this; 757 } 758 ElementRefIterator operator-(size_t count) { 759 this->Pos -= count; 760 return *this; 761 } 762 }; 763 764 public: 765 /// The set of statements in the basic block. 766 ElementList Elements; 767 768 /// An (optional) label that prefixes the executable statements in the block. 769 /// When this variable is non-NULL, it is either an instance of LabelStmt, 770 /// SwitchCase or CXXCatchStmt. 771 Stmt *Label = nullptr; 772 773 /// The terminator for a basic block that indicates the type of control-flow 774 /// that occurs between a block and its successors. 775 CFGTerminator Terminator; 776 777 /// Some blocks are used to represent the "loop edge" to the start of a loop 778 /// from within the loop body. This Stmt* will be refer to the loop statement 779 /// for such blocks (and be null otherwise). 780 const Stmt *LoopTarget = nullptr; 781 782 /// A numerical ID assigned to a CFGBlock during construction of the CFG. 783 unsigned BlockID; 784 785 public: 786 /// This class represents a potential adjacent block in the CFG. It encodes 787 /// whether or not the block is actually reachable, or can be proved to be 788 /// trivially unreachable. For some cases it allows one to encode scenarios 789 /// where a block was substituted because the original (now alternate) block 790 /// is unreachable. 791 class AdjacentBlock { 792 enum Kind { 793 AB_Normal, 794 AB_Unreachable, 795 AB_Alternate 796 }; 797 798 CFGBlock *ReachableBlock; 799 llvm::PointerIntPair<CFGBlock *, 2> UnreachableBlock; 800 801 public: 802 /// Construct an AdjacentBlock with a possibly unreachable block. 803 AdjacentBlock(CFGBlock *B, bool IsReachable); 804 805 /// Construct an AdjacentBlock with a reachable block and an alternate 806 /// unreachable block. 807 AdjacentBlock(CFGBlock *B, CFGBlock *AlternateBlock); 808 809 /// Get the reachable block, if one exists. getReachableBlock()810 CFGBlock *getReachableBlock() const { 811 return ReachableBlock; 812 } 813 814 /// Get the potentially unreachable block. getPossiblyUnreachableBlock()815 CFGBlock *getPossiblyUnreachableBlock() const { 816 return UnreachableBlock.getPointer(); 817 } 818 819 /// Provide an implicit conversion to CFGBlock* so that 820 /// AdjacentBlock can be substituted for CFGBlock*. 821 operator CFGBlock*() const { 822 return getReachableBlock(); 823 } 824 825 CFGBlock& operator *() const { 826 return *getReachableBlock(); 827 } 828 829 CFGBlock* operator ->() const { 830 return getReachableBlock(); 831 } 832 isReachable()833 bool isReachable() const { 834 Kind K = (Kind) UnreachableBlock.getInt(); 835 return K == AB_Normal || K == AB_Alternate; 836 } 837 }; 838 839 private: 840 /// Keep track of the predecessor / successor CFG blocks. 841 using AdjacentBlocks = BumpVector<AdjacentBlock>; 842 AdjacentBlocks Preds; 843 AdjacentBlocks Succs; 844 845 /// This bit is set when the basic block contains a function call 846 /// or implicit destructor that is attributed as 'noreturn'. In that case, 847 /// control cannot technically ever proceed past this block. All such blocks 848 /// will have a single immediate successor: the exit block. This allows them 849 /// to be easily reached from the exit block and using this bit quickly 850 /// recognized without scanning the contents of the block. 851 /// 852 /// Optimization Note: This bit could be profitably folded with Terminator's 853 /// storage if the memory usage of CFGBlock becomes an issue. 854 unsigned HasNoReturnElement : 1; 855 856 /// The parent CFG that owns this CFGBlock. 857 CFG *Parent; 858 859 public: CFGBlock(unsigned blockid,BumpVectorContext & C,CFG * parent)860 explicit CFGBlock(unsigned blockid, BumpVectorContext &C, CFG *parent) 861 : Elements(C), Terminator(nullptr), BlockID(blockid), Preds(C, 1), 862 Succs(C, 1), HasNoReturnElement(false), Parent(parent) {} 863 864 // Statement iterators 865 using iterator = ElementList::iterator; 866 using const_iterator = ElementList::const_iterator; 867 using reverse_iterator = ElementList::reverse_iterator; 868 using const_reverse_iterator = ElementList::const_reverse_iterator; 869 870 size_t getIndexInCFG() const; 871 front()872 CFGElement front() const { return Elements.front(); } back()873 CFGElement back() const { return Elements.back(); } 874 begin()875 iterator begin() { return Elements.begin(); } end()876 iterator end() { return Elements.end(); } begin()877 const_iterator begin() const { return Elements.begin(); } end()878 const_iterator end() const { return Elements.end(); } 879 rbegin()880 reverse_iterator rbegin() { return Elements.rbegin(); } rend()881 reverse_iterator rend() { return Elements.rend(); } rbegin()882 const_reverse_iterator rbegin() const { return Elements.rbegin(); } rend()883 const_reverse_iterator rend() const { return Elements.rend(); } 884 885 using CFGElementRef = ElementRefImpl<false>; 886 using ConstCFGElementRef = ElementRefImpl<true>; 887 888 using ref_iterator = ElementRefIterator<false, false>; 889 using ref_iterator_range = llvm::iterator_range<ref_iterator>; 890 using const_ref_iterator = ElementRefIterator<false, true>; 891 using const_ref_iterator_range = llvm::iterator_range<const_ref_iterator>; 892 893 using reverse_ref_iterator = ElementRefIterator<true, false>; 894 using reverse_ref_iterator_range = llvm::iterator_range<reverse_ref_iterator>; 895 896 using const_reverse_ref_iterator = ElementRefIterator<true, true>; 897 using const_reverse_ref_iterator_range = 898 llvm::iterator_range<const_reverse_ref_iterator>; 899 ref_begin()900 ref_iterator ref_begin() { return {this, begin()}; } ref_end()901 ref_iterator ref_end() { return {this, end()}; } ref_begin()902 const_ref_iterator ref_begin() const { return {this, begin()}; } ref_end()903 const_ref_iterator ref_end() const { return {this, end()}; } 904 rref_begin()905 reverse_ref_iterator rref_begin() { return {this, rbegin()}; } rref_end()906 reverse_ref_iterator rref_end() { return {this, rend()}; } rref_begin()907 const_reverse_ref_iterator rref_begin() const { return {this, rbegin()}; } rref_end()908 const_reverse_ref_iterator rref_end() const { return {this, rend()}; } 909 refs()910 ref_iterator_range refs() { return {ref_begin(), ref_end()}; } refs()911 const_ref_iterator_range refs() const { return {ref_begin(), ref_end()}; } rrefs()912 reverse_ref_iterator_range rrefs() { return {rref_begin(), rref_end()}; } rrefs()913 const_reverse_ref_iterator_range rrefs() const { 914 return {rref_begin(), rref_end()}; 915 } 916 size()917 unsigned size() const { return Elements.size(); } empty()918 bool empty() const { return Elements.empty(); } 919 920 CFGElement operator[](size_t i) const { return Elements[i]; } 921 922 // CFG iterators 923 using pred_iterator = AdjacentBlocks::iterator; 924 using const_pred_iterator = AdjacentBlocks::const_iterator; 925 using pred_reverse_iterator = AdjacentBlocks::reverse_iterator; 926 using const_pred_reverse_iterator = AdjacentBlocks::const_reverse_iterator; 927 using pred_range = llvm::iterator_range<pred_iterator>; 928 using pred_const_range = llvm::iterator_range<const_pred_iterator>; 929 930 using succ_iterator = AdjacentBlocks::iterator; 931 using const_succ_iterator = AdjacentBlocks::const_iterator; 932 using succ_reverse_iterator = AdjacentBlocks::reverse_iterator; 933 using const_succ_reverse_iterator = AdjacentBlocks::const_reverse_iterator; 934 using succ_range = llvm::iterator_range<succ_iterator>; 935 using succ_const_range = llvm::iterator_range<const_succ_iterator>; 936 pred_begin()937 pred_iterator pred_begin() { return Preds.begin(); } pred_end()938 pred_iterator pred_end() { return Preds.end(); } pred_begin()939 const_pred_iterator pred_begin() const { return Preds.begin(); } pred_end()940 const_pred_iterator pred_end() const { return Preds.end(); } 941 pred_rbegin()942 pred_reverse_iterator pred_rbegin() { return Preds.rbegin(); } pred_rend()943 pred_reverse_iterator pred_rend() { return Preds.rend(); } pred_rbegin()944 const_pred_reverse_iterator pred_rbegin() const { return Preds.rbegin(); } pred_rend()945 const_pred_reverse_iterator pred_rend() const { return Preds.rend(); } 946 preds()947 pred_range preds() { 948 return pred_range(pred_begin(), pred_end()); 949 } 950 preds()951 pred_const_range preds() const { 952 return pred_const_range(pred_begin(), pred_end()); 953 } 954 succ_begin()955 succ_iterator succ_begin() { return Succs.begin(); } succ_end()956 succ_iterator succ_end() { return Succs.end(); } succ_begin()957 const_succ_iterator succ_begin() const { return Succs.begin(); } succ_end()958 const_succ_iterator succ_end() const { return Succs.end(); } 959 succ_rbegin()960 succ_reverse_iterator succ_rbegin() { return Succs.rbegin(); } succ_rend()961 succ_reverse_iterator succ_rend() { return Succs.rend(); } succ_rbegin()962 const_succ_reverse_iterator succ_rbegin() const { return Succs.rbegin(); } succ_rend()963 const_succ_reverse_iterator succ_rend() const { return Succs.rend(); } 964 succs()965 succ_range succs() { 966 return succ_range(succ_begin(), succ_end()); 967 } 968 succs()969 succ_const_range succs() const { 970 return succ_const_range(succ_begin(), succ_end()); 971 } 972 succ_size()973 unsigned succ_size() const { return Succs.size(); } succ_empty()974 bool succ_empty() const { return Succs.empty(); } 975 pred_size()976 unsigned pred_size() const { return Preds.size(); } pred_empty()977 bool pred_empty() const { return Preds.empty(); } 978 979 980 class FilterOptions { 981 public: 982 unsigned IgnoreNullPredecessors : 1; 983 unsigned IgnoreDefaultsWithCoveredEnums : 1; 984 FilterOptions()985 FilterOptions() 986 : IgnoreNullPredecessors(1), IgnoreDefaultsWithCoveredEnums(0) {} 987 }; 988 989 static bool FilterEdge(const FilterOptions &F, const CFGBlock *Src, 990 const CFGBlock *Dst); 991 992 template <typename IMPL, bool IsPred> 993 class FilteredCFGBlockIterator { 994 private: 995 IMPL I, E; 996 const FilterOptions F; 997 const CFGBlock *From; 998 999 public: FilteredCFGBlockIterator(const IMPL & i,const IMPL & e,const CFGBlock * from,const FilterOptions & f)1000 explicit FilteredCFGBlockIterator(const IMPL &i, const IMPL &e, 1001 const CFGBlock *from, 1002 const FilterOptions &f) 1003 : I(i), E(e), F(f), From(from) { 1004 while (hasMore() && Filter(*I)) 1005 ++I; 1006 } 1007 hasMore()1008 bool hasMore() const { return I != E; } 1009 1010 FilteredCFGBlockIterator &operator++() { 1011 do { ++I; } while (hasMore() && Filter(*I)); 1012 return *this; 1013 } 1014 1015 const CFGBlock *operator*() const { return *I; } 1016 1017 private: Filter(const CFGBlock * To)1018 bool Filter(const CFGBlock *To) { 1019 return IsPred ? FilterEdge(F, To, From) : FilterEdge(F, From, To); 1020 } 1021 }; 1022 1023 using filtered_pred_iterator = 1024 FilteredCFGBlockIterator<const_pred_iterator, true>; 1025 1026 using filtered_succ_iterator = 1027 FilteredCFGBlockIterator<const_succ_iterator, false>; 1028 filtered_pred_start_end(const FilterOptions & f)1029 filtered_pred_iterator filtered_pred_start_end(const FilterOptions &f) const { 1030 return filtered_pred_iterator(pred_begin(), pred_end(), this, f); 1031 } 1032 filtered_succ_start_end(const FilterOptions & f)1033 filtered_succ_iterator filtered_succ_start_end(const FilterOptions &f) const { 1034 return filtered_succ_iterator(succ_begin(), succ_end(), this, f); 1035 } 1036 1037 // Manipulation of block contents 1038 setTerminator(CFGTerminator Term)1039 void setTerminator(CFGTerminator Term) { Terminator = Term; } setLabel(Stmt * Statement)1040 void setLabel(Stmt *Statement) { Label = Statement; } setLoopTarget(const Stmt * loopTarget)1041 void setLoopTarget(const Stmt *loopTarget) { LoopTarget = loopTarget; } setHasNoReturnElement()1042 void setHasNoReturnElement() { HasNoReturnElement = true; } 1043 1044 /// Returns true if the block would eventually end with a sink (a noreturn 1045 /// node). 1046 bool isInevitablySinking() const; 1047 getTerminator()1048 CFGTerminator getTerminator() const { return Terminator; } 1049 getTerminatorStmt()1050 Stmt *getTerminatorStmt() { return Terminator.getStmt(); } getTerminatorStmt()1051 const Stmt *getTerminatorStmt() const { return Terminator.getStmt(); } 1052 1053 /// \returns the last (\c rbegin()) condition, e.g. observe the following code 1054 /// snippet: 1055 /// if (A && B && C) 1056 /// A block would be created for \c A, \c B, and \c C. For the latter, 1057 /// \c getTerminatorStmt() would retrieve the entire condition, rather than 1058 /// C itself, while this method would only return C. 1059 const Expr *getLastCondition() const; 1060 1061 Stmt *getTerminatorCondition(bool StripParens = true); 1062 1063 const Stmt *getTerminatorCondition(bool StripParens = true) const { 1064 return const_cast<CFGBlock*>(this)->getTerminatorCondition(StripParens); 1065 } 1066 getLoopTarget()1067 const Stmt *getLoopTarget() const { return LoopTarget; } 1068 getLabel()1069 Stmt *getLabel() { return Label; } getLabel()1070 const Stmt *getLabel() const { return Label; } 1071 hasNoReturnElement()1072 bool hasNoReturnElement() const { return HasNoReturnElement; } 1073 getBlockID()1074 unsigned getBlockID() const { return BlockID; } 1075 getParent()1076 CFG *getParent() const { return Parent; } 1077 1078 void dump() const; 1079 1080 void dump(const CFG *cfg, const LangOptions &LO, bool ShowColors = false) const; 1081 void print(raw_ostream &OS, const CFG* cfg, const LangOptions &LO, 1082 bool ShowColors) const; 1083 1084 void printTerminator(raw_ostream &OS, const LangOptions &LO) const; 1085 void printTerminatorJson(raw_ostream &Out, const LangOptions &LO, 1086 bool AddQuotes) const; 1087 printAsOperand(raw_ostream & OS,bool)1088 void printAsOperand(raw_ostream &OS, bool /*PrintType*/) { 1089 OS << "BB#" << getBlockID(); 1090 } 1091 1092 /// Adds a (potentially unreachable) successor block to the current block. 1093 void addSuccessor(AdjacentBlock Succ, BumpVectorContext &C); 1094 appendStmt(Stmt * statement,BumpVectorContext & C)1095 void appendStmt(Stmt *statement, BumpVectorContext &C) { 1096 Elements.push_back(CFGStmt(statement), C); 1097 } 1098 appendConstructor(CXXConstructExpr * CE,const ConstructionContext * CC,BumpVectorContext & C)1099 void appendConstructor(CXXConstructExpr *CE, const ConstructionContext *CC, 1100 BumpVectorContext &C) { 1101 Elements.push_back(CFGConstructor(CE, CC), C); 1102 } 1103 appendCXXRecordTypedCall(Expr * E,const ConstructionContext * CC,BumpVectorContext & C)1104 void appendCXXRecordTypedCall(Expr *E, 1105 const ConstructionContext *CC, 1106 BumpVectorContext &C) { 1107 Elements.push_back(CFGCXXRecordTypedCall(E, CC), C); 1108 } 1109 appendInitializer(CXXCtorInitializer * initializer,BumpVectorContext & C)1110 void appendInitializer(CXXCtorInitializer *initializer, 1111 BumpVectorContext &C) { 1112 Elements.push_back(CFGInitializer(initializer), C); 1113 } 1114 appendNewAllocator(CXXNewExpr * NE,BumpVectorContext & C)1115 void appendNewAllocator(CXXNewExpr *NE, 1116 BumpVectorContext &C) { 1117 Elements.push_back(CFGNewAllocator(NE), C); 1118 } 1119 appendScopeBegin(const VarDecl * VD,const Stmt * S,BumpVectorContext & C)1120 void appendScopeBegin(const VarDecl *VD, const Stmt *S, 1121 BumpVectorContext &C) { 1122 Elements.push_back(CFGScopeBegin(VD, S), C); 1123 } 1124 prependScopeBegin(const VarDecl * VD,const Stmt * S,BumpVectorContext & C)1125 void prependScopeBegin(const VarDecl *VD, const Stmt *S, 1126 BumpVectorContext &C) { 1127 Elements.insert(Elements.rbegin(), 1, CFGScopeBegin(VD, S), C); 1128 } 1129 appendScopeEnd(const VarDecl * VD,const Stmt * S,BumpVectorContext & C)1130 void appendScopeEnd(const VarDecl *VD, const Stmt *S, BumpVectorContext &C) { 1131 Elements.push_back(CFGScopeEnd(VD, S), C); 1132 } 1133 prependScopeEnd(const VarDecl * VD,const Stmt * S,BumpVectorContext & C)1134 void prependScopeEnd(const VarDecl *VD, const Stmt *S, BumpVectorContext &C) { 1135 Elements.insert(Elements.rbegin(), 1, CFGScopeEnd(VD, S), C); 1136 } 1137 appendBaseDtor(const CXXBaseSpecifier * BS,BumpVectorContext & C)1138 void appendBaseDtor(const CXXBaseSpecifier *BS, BumpVectorContext &C) { 1139 Elements.push_back(CFGBaseDtor(BS), C); 1140 } 1141 appendMemberDtor(FieldDecl * FD,BumpVectorContext & C)1142 void appendMemberDtor(FieldDecl *FD, BumpVectorContext &C) { 1143 Elements.push_back(CFGMemberDtor(FD), C); 1144 } 1145 appendTemporaryDtor(CXXBindTemporaryExpr * E,BumpVectorContext & C)1146 void appendTemporaryDtor(CXXBindTemporaryExpr *E, BumpVectorContext &C) { 1147 Elements.push_back(CFGTemporaryDtor(E), C); 1148 } 1149 appendAutomaticObjDtor(VarDecl * VD,Stmt * S,BumpVectorContext & C)1150 void appendAutomaticObjDtor(VarDecl *VD, Stmt *S, BumpVectorContext &C) { 1151 Elements.push_back(CFGAutomaticObjDtor(VD, S), C); 1152 } 1153 appendLifetimeEnds(VarDecl * VD,Stmt * S,BumpVectorContext & C)1154 void appendLifetimeEnds(VarDecl *VD, Stmt *S, BumpVectorContext &C) { 1155 Elements.push_back(CFGLifetimeEnds(VD, S), C); 1156 } 1157 appendLoopExit(const Stmt * LoopStmt,BumpVectorContext & C)1158 void appendLoopExit(const Stmt *LoopStmt, BumpVectorContext &C) { 1159 Elements.push_back(CFGLoopExit(LoopStmt), C); 1160 } 1161 appendDeleteDtor(CXXRecordDecl * RD,CXXDeleteExpr * DE,BumpVectorContext & C)1162 void appendDeleteDtor(CXXRecordDecl *RD, CXXDeleteExpr *DE, BumpVectorContext &C) { 1163 Elements.push_back(CFGDeleteDtor(RD, DE), C); 1164 } 1165 1166 // Destructors must be inserted in reversed order. So insertion is in two 1167 // steps. First we prepare space for some number of elements, then we insert 1168 // the elements beginning at the last position in prepared space. beginAutomaticObjDtorsInsert(iterator I,size_t Cnt,BumpVectorContext & C)1169 iterator beginAutomaticObjDtorsInsert(iterator I, size_t Cnt, 1170 BumpVectorContext &C) { 1171 return iterator(Elements.insert(I.base(), Cnt, 1172 CFGAutomaticObjDtor(nullptr, nullptr), C)); 1173 } insertAutomaticObjDtor(iterator I,VarDecl * VD,Stmt * S)1174 iterator insertAutomaticObjDtor(iterator I, VarDecl *VD, Stmt *S) { 1175 *I = CFGAutomaticObjDtor(VD, S); 1176 return ++I; 1177 } 1178 1179 // Scope leaving must be performed in reversed order. So insertion is in two 1180 // steps. First we prepare space for some number of elements, then we insert 1181 // the elements beginning at the last position in prepared space. beginLifetimeEndsInsert(iterator I,size_t Cnt,BumpVectorContext & C)1182 iterator beginLifetimeEndsInsert(iterator I, size_t Cnt, 1183 BumpVectorContext &C) { 1184 return iterator( 1185 Elements.insert(I.base(), Cnt, CFGLifetimeEnds(nullptr, nullptr), C)); 1186 } insertLifetimeEnds(iterator I,VarDecl * VD,Stmt * S)1187 iterator insertLifetimeEnds(iterator I, VarDecl *VD, Stmt *S) { 1188 *I = CFGLifetimeEnds(VD, S); 1189 return ++I; 1190 } 1191 1192 // Scope leaving must be performed in reversed order. So insertion is in two 1193 // steps. First we prepare space for some number of elements, then we insert 1194 // the elements beginning at the last position in prepared space. beginScopeEndInsert(iterator I,size_t Cnt,BumpVectorContext & C)1195 iterator beginScopeEndInsert(iterator I, size_t Cnt, BumpVectorContext &C) { 1196 return iterator( 1197 Elements.insert(I.base(), Cnt, CFGScopeEnd(nullptr, nullptr), C)); 1198 } insertScopeEnd(iterator I,VarDecl * VD,Stmt * S)1199 iterator insertScopeEnd(iterator I, VarDecl *VD, Stmt *S) { 1200 *I = CFGScopeEnd(VD, S); 1201 return ++I; 1202 } 1203 }; 1204 1205 /// CFGCallback defines methods that should be called when a logical 1206 /// operator error is found when building the CFG. 1207 class CFGCallback { 1208 public: 1209 CFGCallback() = default; 1210 virtual ~CFGCallback() = default; 1211 compareAlwaysTrue(const BinaryOperator * B,bool isAlwaysTrue)1212 virtual void compareAlwaysTrue(const BinaryOperator *B, bool isAlwaysTrue) {} compareBitwiseEquality(const BinaryOperator * B,bool isAlwaysTrue)1213 virtual void compareBitwiseEquality(const BinaryOperator *B, 1214 bool isAlwaysTrue) {} compareBitwiseOr(const BinaryOperator * B)1215 virtual void compareBitwiseOr(const BinaryOperator *B) {} 1216 }; 1217 1218 /// Represents a source-level, intra-procedural CFG that represents the 1219 /// control-flow of a Stmt. The Stmt can represent an entire function body, 1220 /// or a single expression. A CFG will always contain one empty block that 1221 /// represents the Exit point of the CFG. A CFG will also contain a designated 1222 /// Entry block. The CFG solely represents control-flow; it consists of 1223 /// CFGBlocks which are simply containers of Stmt*'s in the AST the CFG 1224 /// was constructed from. 1225 class CFG { 1226 public: 1227 //===--------------------------------------------------------------------===// 1228 // CFG Construction & Manipulation. 1229 //===--------------------------------------------------------------------===// 1230 1231 class BuildOptions { 1232 std::bitset<Stmt::lastStmtConstant> alwaysAddMask; 1233 1234 public: 1235 using ForcedBlkExprs = llvm::DenseMap<const Stmt *, const CFGBlock *>; 1236 1237 ForcedBlkExprs **forcedBlkExprs = nullptr; 1238 CFGCallback *Observer = nullptr; 1239 bool PruneTriviallyFalseEdges = true; 1240 bool AddEHEdges = false; 1241 bool AddInitializers = false; 1242 bool AddImplicitDtors = false; 1243 bool AddLifetime = false; 1244 bool AddLoopExit = false; 1245 bool AddTemporaryDtors = false; 1246 bool AddScopes = false; 1247 bool AddStaticInitBranches = false; 1248 bool AddCXXNewAllocator = false; 1249 bool AddCXXDefaultInitExprInCtors = false; 1250 bool AddCXXDefaultInitExprInAggregates = false; 1251 bool AddRichCXXConstructors = false; 1252 bool MarkElidedCXXConstructors = false; 1253 bool AddVirtualBaseBranches = false; 1254 bool OmitImplicitValueInitializers = false; 1255 1256 BuildOptions() = default; 1257 alwaysAdd(const Stmt * stmt)1258 bool alwaysAdd(const Stmt *stmt) const { 1259 return alwaysAddMask[stmt->getStmtClass()]; 1260 } 1261 1262 BuildOptions &setAlwaysAdd(Stmt::StmtClass stmtClass, bool val = true) { 1263 alwaysAddMask[stmtClass] = val; 1264 return *this; 1265 } 1266 setAllAlwaysAdd()1267 BuildOptions &setAllAlwaysAdd() { 1268 alwaysAddMask.set(); 1269 return *this; 1270 } 1271 }; 1272 1273 /// Builds a CFG from an AST. 1274 static std::unique_ptr<CFG> buildCFG(const Decl *D, Stmt *AST, ASTContext *C, 1275 const BuildOptions &BO); 1276 1277 /// Create a new block in the CFG. The CFG owns the block; the caller should 1278 /// not directly free it. 1279 CFGBlock *createBlock(); 1280 1281 /// Set the entry block of the CFG. This is typically used only during CFG 1282 /// construction. Most CFG clients expect that the entry block has no 1283 /// predecessors and contains no statements. setEntry(CFGBlock * B)1284 void setEntry(CFGBlock *B) { Entry = B; } 1285 1286 /// Set the block used for indirect goto jumps. This is typically used only 1287 /// during CFG construction. setIndirectGotoBlock(CFGBlock * B)1288 void setIndirectGotoBlock(CFGBlock *B) { IndirectGotoBlock = B; } 1289 1290 //===--------------------------------------------------------------------===// 1291 // Block Iterators 1292 //===--------------------------------------------------------------------===// 1293 1294 using CFGBlockListTy = BumpVector<CFGBlock *>; 1295 using iterator = CFGBlockListTy::iterator; 1296 using const_iterator = CFGBlockListTy::const_iterator; 1297 using reverse_iterator = std::reverse_iterator<iterator>; 1298 using const_reverse_iterator = std::reverse_iterator<const_iterator>; 1299 front()1300 CFGBlock & front() { return *Blocks.front(); } back()1301 CFGBlock & back() { return *Blocks.back(); } 1302 begin()1303 iterator begin() { return Blocks.begin(); } end()1304 iterator end() { return Blocks.end(); } begin()1305 const_iterator begin() const { return Blocks.begin(); } end()1306 const_iterator end() const { return Blocks.end(); } 1307 nodes_begin()1308 iterator nodes_begin() { return iterator(Blocks.begin()); } nodes_end()1309 iterator nodes_end() { return iterator(Blocks.end()); } 1310 nodes()1311 llvm::iterator_range<iterator> nodes() { return {begin(), end()}; } const_nodes()1312 llvm::iterator_range<const_iterator> const_nodes() const { 1313 return {begin(), end()}; 1314 } 1315 nodes_begin()1316 const_iterator nodes_begin() const { return const_iterator(Blocks.begin()); } nodes_end()1317 const_iterator nodes_end() const { return const_iterator(Blocks.end()); } 1318 rbegin()1319 reverse_iterator rbegin() { return Blocks.rbegin(); } rend()1320 reverse_iterator rend() { return Blocks.rend(); } rbegin()1321 const_reverse_iterator rbegin() const { return Blocks.rbegin(); } rend()1322 const_reverse_iterator rend() const { return Blocks.rend(); } 1323 reverse_nodes()1324 llvm::iterator_range<reverse_iterator> reverse_nodes() { 1325 return {rbegin(), rend()}; 1326 } const_reverse_nodes()1327 llvm::iterator_range<const_reverse_iterator> const_reverse_nodes() const { 1328 return {rbegin(), rend()}; 1329 } 1330 getEntry()1331 CFGBlock & getEntry() { return *Entry; } getEntry()1332 const CFGBlock & getEntry() const { return *Entry; } getExit()1333 CFGBlock & getExit() { return *Exit; } getExit()1334 const CFGBlock & getExit() const { return *Exit; } 1335 getIndirectGotoBlock()1336 CFGBlock * getIndirectGotoBlock() { return IndirectGotoBlock; } getIndirectGotoBlock()1337 const CFGBlock * getIndirectGotoBlock() const { return IndirectGotoBlock; } 1338 1339 using try_block_iterator = std::vector<const CFGBlock *>::const_iterator; 1340 using try_block_range = llvm::iterator_range<try_block_iterator>; 1341 try_blocks_begin()1342 try_block_iterator try_blocks_begin() const { 1343 return TryDispatchBlocks.begin(); 1344 } 1345 try_blocks_end()1346 try_block_iterator try_blocks_end() const { 1347 return TryDispatchBlocks.end(); 1348 } 1349 try_blocks()1350 try_block_range try_blocks() const { 1351 return try_block_range(try_blocks_begin(), try_blocks_end()); 1352 } 1353 addTryDispatchBlock(const CFGBlock * block)1354 void addTryDispatchBlock(const CFGBlock *block) { 1355 TryDispatchBlocks.push_back(block); 1356 } 1357 1358 /// Records a synthetic DeclStmt and the DeclStmt it was constructed from. 1359 /// 1360 /// The CFG uses synthetic DeclStmts when a single AST DeclStmt contains 1361 /// multiple decls. addSyntheticDeclStmt(const DeclStmt * Synthetic,const DeclStmt * Source)1362 void addSyntheticDeclStmt(const DeclStmt *Synthetic, 1363 const DeclStmt *Source) { 1364 assert(Synthetic->isSingleDecl() && "Can handle single declarations only"); 1365 assert(Synthetic != Source && "Don't include original DeclStmts in map"); 1366 assert(!SyntheticDeclStmts.count(Synthetic) && "Already in map"); 1367 SyntheticDeclStmts[Synthetic] = Source; 1368 } 1369 1370 using synthetic_stmt_iterator = 1371 llvm::DenseMap<const DeclStmt *, const DeclStmt *>::const_iterator; 1372 using synthetic_stmt_range = llvm::iterator_range<synthetic_stmt_iterator>; 1373 1374 /// Iterates over synthetic DeclStmts in the CFG. 1375 /// 1376 /// Each element is a (synthetic statement, source statement) pair. 1377 /// 1378 /// \sa addSyntheticDeclStmt synthetic_stmt_begin()1379 synthetic_stmt_iterator synthetic_stmt_begin() const { 1380 return SyntheticDeclStmts.begin(); 1381 } 1382 1383 /// \sa synthetic_stmt_begin synthetic_stmt_end()1384 synthetic_stmt_iterator synthetic_stmt_end() const { 1385 return SyntheticDeclStmts.end(); 1386 } 1387 1388 /// \sa synthetic_stmt_begin synthetic_stmts()1389 synthetic_stmt_range synthetic_stmts() const { 1390 return synthetic_stmt_range(synthetic_stmt_begin(), synthetic_stmt_end()); 1391 } 1392 1393 //===--------------------------------------------------------------------===// 1394 // Member templates useful for various batch operations over CFGs. 1395 //===--------------------------------------------------------------------===// 1396 VisitBlockStmts(Callback & O)1397 template <typename Callback> void VisitBlockStmts(Callback &O) const { 1398 for (const_iterator I = begin(), E = end(); I != E; ++I) 1399 for (CFGBlock::const_iterator BI = (*I)->begin(), BE = (*I)->end(); 1400 BI != BE; ++BI) { 1401 if (std::optional<CFGStmt> stmt = BI->getAs<CFGStmt>()) 1402 O(const_cast<Stmt *>(stmt->getStmt())); 1403 } 1404 } 1405 1406 //===--------------------------------------------------------------------===// 1407 // CFG Introspection. 1408 //===--------------------------------------------------------------------===// 1409 1410 /// Returns the total number of BlockIDs allocated (which start at 0). getNumBlockIDs()1411 unsigned getNumBlockIDs() const { return NumBlockIDs; } 1412 1413 /// Return the total number of CFGBlocks within the CFG This is simply a 1414 /// renaming of the getNumBlockIDs(). This is necessary because the dominator 1415 /// implementation needs such an interface. size()1416 unsigned size() const { return NumBlockIDs; } 1417 1418 /// Returns true if the CFG has no branches. Usually it boils down to the CFG 1419 /// having exactly three blocks (entry, the actual code, exit), but sometimes 1420 /// more blocks appear due to having control flow that can be fully 1421 /// resolved in compile time. 1422 bool isLinear() const; 1423 1424 //===--------------------------------------------------------------------===// 1425 // CFG Debugging: Pretty-Printing and Visualization. 1426 //===--------------------------------------------------------------------===// 1427 1428 void viewCFG(const LangOptions &LO) const; 1429 void print(raw_ostream &OS, const LangOptions &LO, bool ShowColors) const; 1430 void dump(const LangOptions &LO, bool ShowColors) const; 1431 1432 //===--------------------------------------------------------------------===// 1433 // Internal: constructors and data. 1434 //===--------------------------------------------------------------------===// 1435 CFG()1436 CFG() : Blocks(BlkBVC, 10) {} 1437 getAllocator()1438 llvm::BumpPtrAllocator& getAllocator() { 1439 return BlkBVC.getAllocator(); 1440 } 1441 getBumpVectorContext()1442 BumpVectorContext &getBumpVectorContext() { 1443 return BlkBVC; 1444 } 1445 1446 private: 1447 CFGBlock *Entry = nullptr; 1448 CFGBlock *Exit = nullptr; 1449 1450 // Special block to contain collective dispatch for indirect gotos 1451 CFGBlock* IndirectGotoBlock = nullptr; 1452 1453 unsigned NumBlockIDs = 0; 1454 1455 BumpVectorContext BlkBVC; 1456 1457 CFGBlockListTy Blocks; 1458 1459 /// C++ 'try' statements are modeled with an indirect dispatch block. 1460 /// This is the collection of such blocks present in the CFG. 1461 std::vector<const CFGBlock *> TryDispatchBlocks; 1462 1463 /// Collects DeclStmts synthesized for this CFG and maps each one back to its 1464 /// source DeclStmt. 1465 llvm::DenseMap<const DeclStmt *, const DeclStmt *> SyntheticDeclStmts; 1466 }; 1467 1468 Expr *extractElementInitializerFromNestedAILE(const ArrayInitLoopExpr *AILE); 1469 1470 } // namespace clang 1471 1472 //===----------------------------------------------------------------------===// 1473 // GraphTraits specializations for CFG basic block graphs (source-level CFGs) 1474 //===----------------------------------------------------------------------===// 1475 1476 namespace llvm { 1477 1478 /// Implement simplify_type for CFGTerminator, so that we can dyn_cast from 1479 /// CFGTerminator to a specific Stmt class. 1480 template <> struct simplify_type< ::clang::CFGTerminator> { 1481 using SimpleType = ::clang::Stmt *; 1482 1483 static SimpleType getSimplifiedValue(::clang::CFGTerminator Val) { 1484 return Val.getStmt(); 1485 } 1486 }; 1487 1488 // Traits for: CFGBlock 1489 1490 template <> struct GraphTraits< ::clang::CFGBlock *> { 1491 using NodeRef = ::clang::CFGBlock *; 1492 using ChildIteratorType = ::clang::CFGBlock::succ_iterator; 1493 1494 static NodeRef getEntryNode(::clang::CFGBlock *BB) { return BB; } 1495 static ChildIteratorType child_begin(NodeRef N) { return N->succ_begin(); } 1496 static ChildIteratorType child_end(NodeRef N) { return N->succ_end(); } 1497 }; 1498 1499 template <> struct GraphTraits< const ::clang::CFGBlock *> { 1500 using NodeRef = const ::clang::CFGBlock *; 1501 using ChildIteratorType = ::clang::CFGBlock::const_succ_iterator; 1502 1503 static NodeRef getEntryNode(const clang::CFGBlock *BB) { return BB; } 1504 static ChildIteratorType child_begin(NodeRef N) { return N->succ_begin(); } 1505 static ChildIteratorType child_end(NodeRef N) { return N->succ_end(); } 1506 }; 1507 1508 template <> struct GraphTraits<Inverse< ::clang::CFGBlock *>> { 1509 using NodeRef = ::clang::CFGBlock *; 1510 using ChildIteratorType = ::clang::CFGBlock::const_pred_iterator; 1511 1512 static NodeRef getEntryNode(Inverse<::clang::CFGBlock *> G) { 1513 return G.Graph; 1514 } 1515 1516 static ChildIteratorType child_begin(NodeRef N) { return N->pred_begin(); } 1517 static ChildIteratorType child_end(NodeRef N) { return N->pred_end(); } 1518 }; 1519 1520 template <> struct GraphTraits<Inverse<const ::clang::CFGBlock *>> { 1521 using NodeRef = const ::clang::CFGBlock *; 1522 using ChildIteratorType = ::clang::CFGBlock::const_pred_iterator; 1523 1524 static NodeRef getEntryNode(Inverse<const ::clang::CFGBlock *> G) { 1525 return G.Graph; 1526 } 1527 1528 static ChildIteratorType child_begin(NodeRef N) { return N->pred_begin(); } 1529 static ChildIteratorType child_end(NodeRef N) { return N->pred_end(); } 1530 }; 1531 1532 // Traits for: CFG 1533 1534 template <> struct GraphTraits< ::clang::CFG* > 1535 : public GraphTraits< ::clang::CFGBlock *> { 1536 using nodes_iterator = ::clang::CFG::iterator; 1537 1538 static NodeRef getEntryNode(::clang::CFG *F) { return &F->getEntry(); } 1539 static nodes_iterator nodes_begin(::clang::CFG* F) { return F->nodes_begin();} 1540 static nodes_iterator nodes_end(::clang::CFG* F) { return F->nodes_end(); } 1541 static unsigned size(::clang::CFG* F) { return F->size(); } 1542 }; 1543 1544 template <> struct GraphTraits<const ::clang::CFG* > 1545 : public GraphTraits<const ::clang::CFGBlock *> { 1546 using nodes_iterator = ::clang::CFG::const_iterator; 1547 1548 static NodeRef getEntryNode(const ::clang::CFG *F) { return &F->getEntry(); } 1549 1550 static nodes_iterator nodes_begin( const ::clang::CFG* F) { 1551 return F->nodes_begin(); 1552 } 1553 1554 static nodes_iterator nodes_end( const ::clang::CFG* F) { 1555 return F->nodes_end(); 1556 } 1557 1558 static unsigned size(const ::clang::CFG* F) { 1559 return F->size(); 1560 } 1561 }; 1562 1563 template <> struct GraphTraits<Inverse< ::clang::CFG *>> 1564 : public GraphTraits<Inverse< ::clang::CFGBlock *>> { 1565 using nodes_iterator = ::clang::CFG::iterator; 1566 1567 static NodeRef getEntryNode(::clang::CFG *F) { return &F->getExit(); } 1568 static nodes_iterator nodes_begin( ::clang::CFG* F) {return F->nodes_begin();} 1569 static nodes_iterator nodes_end( ::clang::CFG* F) { return F->nodes_end(); } 1570 }; 1571 1572 template <> struct GraphTraits<Inverse<const ::clang::CFG *>> 1573 : public GraphTraits<Inverse<const ::clang::CFGBlock *>> { 1574 using nodes_iterator = ::clang::CFG::const_iterator; 1575 1576 static NodeRef getEntryNode(const ::clang::CFG *F) { return &F->getExit(); } 1577 1578 static nodes_iterator nodes_begin(const ::clang::CFG* F) { 1579 return F->nodes_begin(); 1580 } 1581 1582 static nodes_iterator nodes_end(const ::clang::CFG* F) { 1583 return F->nodes_end(); 1584 } 1585 }; 1586 1587 } // namespace llvm 1588 1589 #endif // LLVM_CLANG_ANALYSIS_CFG_H 1590