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