16960ee6c7cc8a8883126d9861beecb51a4e4a475Ted Kremenek //===--- CFG.cpp - Classes for representing and building CFGs----*- C++ -*-===// 2fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek// 3fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek// The LLVM Compiler Infrastructure 4fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek// 50bc735ffcfb223c0186419547abaa5c84482663eChris Lattner// This file is distributed under the University of Illinois Open Source 60bc735ffcfb223c0186419547abaa5c84482663eChris Lattner// License. See LICENSE.TXT for details. 7fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek// 8fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek//===----------------------------------------------------------------------===// 9fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek// 10fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek// This file defines the CFG and CFGBuilder classes for representing and 11fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek// building Control-Flow Graphs (CFGs) from ASTs. 12fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek// 13fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek//===----------------------------------------------------------------------===// 14fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek 15e41611aa2237d06a0ef61db4528fb2883a8defcdTed Kremenek#include "clang/Analysis/CFG.h" 16478851c3ed6bd784e7377dffd8e57b200c1b9ba9Benjamin Kramer#include "clang/AST/ASTContext.h" 172fa67efeaf66a9332c30a026dc1c21bef6c33a6cBenjamin Kramer#include "clang/AST/Attr.h" 182fa67efeaf66a9332c30a026dc1c21bef6c33a6cBenjamin Kramer#include "clang/AST/CharUnits.h" 19b978a441c7d8bf59e7fede938e1f3b672573b443Mike Stump#include "clang/AST/DeclCXX.h" 2042a509f6a4f71bb805cc4abbb26722a34dffdddeTed Kremenek#include "clang/AST/PrettyPrinter.h" 212fa67efeaf66a9332c30a026dc1c21bef6c33a6cBenjamin Kramer#include "clang/AST/StmtVisitor.h" 227d0dcd2de023e2667a3f1f14daff9d087fab9bf7Jordan Rose#include "clang/Basic/Builtins.h" 236cb7c1a43b0c8f739d1f54b7fdae5ede86033496Benjamin Kramer#include "llvm/ADT/DenseMap.h" 24651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines#include <memory> 252fa67efeaf66a9332c30a026dc1c21bef6c33a6cBenjamin Kramer#include "llvm/ADT/SmallPtrSet.h" 262fa67efeaf66a9332c30a026dc1c21bef6c33a6cBenjamin Kramer#include "llvm/Support/Allocator.h" 272fa67efeaf66a9332c30a026dc1c21bef6c33a6cBenjamin Kramer#include "llvm/Support/Format.h" 282fa67efeaf66a9332c30a026dc1c21bef6c33a6cBenjamin Kramer#include "llvm/Support/GraphWriter.h" 292fa67efeaf66a9332c30a026dc1c21bef6c33a6cBenjamin Kramer#include "llvm/Support/SaveAndRestore.h" 3083c01da96f57cf732a5da9a83e2981241f205dc4Ted Kremenek 31fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenekusing namespace clang; 32fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek 33fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremeneknamespace { 34fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek 359c378f705405d37f49795d5e915989de774fe11fTed Kremenekstatic SourceLocation GetEndLoc(Decl *D) { 369c378f705405d37f49795d5e915989de774fe11fTed Kremenek if (VarDecl *VD = dyn_cast<VarDecl>(D)) 379c378f705405d37f49795d5e915989de774fe11fTed Kremenek if (Expr *Ex = VD->getInit()) 38c7eb9031159f30a63db960fad4640d779f1617c8Ted Kremenek return Ex->getSourceRange().getEnd(); 396d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump return D->getLocation(); 40c7eb9031159f30a63db960fad4640d779f1617c8Ted Kremenek} 41ad5a894df1841698c824381b414630799adc26caTed Kremenek 423179a45a0e91c1dcf3492222170cf4499531bb92Ted Kremenekclass CFGBuilder; 433179a45a0e91c1dcf3492222170cf4499531bb92Ted Kremenek 4494a3dcf146451eb6b0192873e267c4cb0f6147e8Zhanyong Wan/// The CFG builder uses a recursive algorithm to build the CFG. When 4594a3dcf146451eb6b0192873e267c4cb0f6147e8Zhanyong Wan/// we process an expression, sometimes we know that we must add the 4694a3dcf146451eb6b0192873e267c4cb0f6147e8Zhanyong Wan/// subexpressions as block-level expressions. For example: 4794a3dcf146451eb6b0192873e267c4cb0f6147e8Zhanyong Wan/// 4894a3dcf146451eb6b0192873e267c4cb0f6147e8Zhanyong Wan/// exp1 || exp2 4994a3dcf146451eb6b0192873e267c4cb0f6147e8Zhanyong Wan/// 5094a3dcf146451eb6b0192873e267c4cb0f6147e8Zhanyong Wan/// When processing the '||' expression, we know that exp1 and exp2 5194a3dcf146451eb6b0192873e267c4cb0f6147e8Zhanyong Wan/// need to be added as block-level expressions, even though they 5294a3dcf146451eb6b0192873e267c4cb0f6147e8Zhanyong Wan/// might not normally need to be. AddStmtChoice records this 5394a3dcf146451eb6b0192873e267c4cb0f6147e8Zhanyong Wan/// contextual information. If AddStmtChoice is 'NotAlwaysAdd', then 5494a3dcf146451eb6b0192873e267c4cb0f6147e8Zhanyong Wan/// the builder has an option not to add a subexpression as a 5594a3dcf146451eb6b0192873e267c4cb0f6147e8Zhanyong Wan/// block-level expression. 5694a3dcf146451eb6b0192873e267c4cb0f6147e8Zhanyong Wan/// 57852274d4257134906995cb252fb3dfd2d71deae8Ted Kremenekclass AddStmtChoice { 58852274d4257134906995cb252fb3dfd2d71deae8Ted Kremenekpublic: 59892697dd2287caf7c29aaaa82909b0e90b8b63feTed Kremenek enum Kind { NotAlwaysAdd = 0, AlwaysAdd = 1 }; 605ba290a12fb9390a77ea4dca3d98deb53022d182Ted Kremenek 6194a3dcf146451eb6b0192873e267c4cb0f6147e8Zhanyong Wan AddStmtChoice(Kind a_kind = NotAlwaysAdd) : kind(a_kind) {} 625ba290a12fb9390a77ea4dca3d98deb53022d182Ted Kremenek 633179a45a0e91c1dcf3492222170cf4499531bb92Ted Kremenek bool alwaysAdd(CFGBuilder &builder, 643179a45a0e91c1dcf3492222170cf4499531bb92Ted Kremenek const Stmt *stmt) const; 6594a3dcf146451eb6b0192873e267c4cb0f6147e8Zhanyong Wan 6694a3dcf146451eb6b0192873e267c4cb0f6147e8Zhanyong Wan /// Return a copy of this object, except with the 'always-add' bit 6794a3dcf146451eb6b0192873e267c4cb0f6147e8Zhanyong Wan /// set as specified. 6894a3dcf146451eb6b0192873e267c4cb0f6147e8Zhanyong Wan AddStmtChoice withAlwaysAdd(bool alwaysAdd) const { 693179a45a0e91c1dcf3492222170cf4499531bb92Ted Kremenek return AddStmtChoice(alwaysAdd ? AlwaysAdd : NotAlwaysAdd); 7094a3dcf146451eb6b0192873e267c4cb0f6147e8Zhanyong Wan } 7194a3dcf146451eb6b0192873e267c4cb0f6147e8Zhanyong Wan 72852274d4257134906995cb252fb3dfd2d71deae8Ted Kremenekprivate: 7394a3dcf146451eb6b0192873e267c4cb0f6147e8Zhanyong Wan Kind kind; 74852274d4257134906995cb252fb3dfd2d71deae8Ted Kremenek}; 756d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 76f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski/// LocalScope - Node in tree of local scopes created for C++ implicit 77f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski/// destructor calls generation. It contains list of automatic variables 78f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski/// declared in the scope and link to position in previous scope this scope 79f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski/// began in. 80f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski/// 81f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski/// The process of creating local scopes is as follows: 82f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski/// - Init CFGBuilder::ScopePos with invalid position (equivalent for null), 83f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski/// - Before processing statements in scope (e.g. CompoundStmt) create 84f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski/// LocalScope object using CFGBuilder::ScopePos as link to previous scope 85f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski/// and set CFGBuilder::ScopePos to the end of new scope, 8635387a0daf3a6a7f5fcfc232eb4c28f62a4a1957Marcin Swiderski/// - On every occurrence of VarDecl increase CFGBuilder::ScopePos if it points 87f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski/// at this VarDecl, 88f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski/// - For every normal (without jump) end of scope add to CFGBlock destructors 89f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski/// for objects in the current scope, 90f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski/// - For every jump add to CFGBlock destructors for objects 91f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski/// between CFGBuilder::ScopePos and local scope position saved for jump 92f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski/// target. Thanks to C++ restrictions on goto jumps we can be sure that 93f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski/// jump target position will be on the path to root from CFGBuilder::ScopePos 94f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski/// (adding any variable that doesn't need constructor to be called to 95f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski/// LocalScope can break this assumption), 96f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski/// 97f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderskiclass LocalScope { 98f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderskipublic: 99fe59b7472c06b36efb74fbb50bbdf464fa30c0d8Ted Kremenek typedef BumpVector<VarDecl*> AutomaticVarsTy; 100f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski 101f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski /// const_iterator - Iterates local scope backwards and jumps to previous 10235387a0daf3a6a7f5fcfc232eb4c28f62a4a1957Marcin Swiderski /// scope on reaching the beginning of currently iterated scope. 103f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski class const_iterator { 104f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski const LocalScope* Scope; 105f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski 106f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski /// VarIter is guaranteed to be greater then 0 for every valid iterator. 107f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski /// Invalid iterator (with null Scope) has VarIter equal to 0. 108f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski unsigned VarIter; 109f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski 110f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski public: 111f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski /// Create invalid iterator. Dereferencing invalid iterator is not allowed. 112f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski /// Incrementing invalid iterator is allowed and will result in invalid 113f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski /// iterator. 114f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski const_iterator() 1156bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines : Scope(nullptr), VarIter(0) {} 116f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski 117f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski /// Create valid iterator. In case when S.Prev is an invalid iterator and 118f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski /// I is equal to 0, this will create invalid iterator. 119f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski const_iterator(const LocalScope& S, unsigned I) 120f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski : Scope(&S), VarIter(I) { 121f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski // Iterator to "end" of scope is not allowed. Handle it by going up 122f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski // in scopes tree possibly up to invalid iterator in the root. 123f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski if (VarIter == 0 && Scope) 124f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski *this = Scope->Prev; 125f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski } 126f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski 1279c378f705405d37f49795d5e915989de774fe11fTed Kremenek VarDecl *const* operator->() const { 128f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski assert (Scope && "Dereferencing invalid iterator is not allowed"); 129f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski assert (VarIter != 0 && "Iterator has invalid value of VarIter member"); 130f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski return &Scope->Vars[VarIter - 1]; 131f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski } 1329c378f705405d37f49795d5e915989de774fe11fTed Kremenek VarDecl *operator*() const { 133f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski return *this->operator->(); 134f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski } 135f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski 1369c378f705405d37f49795d5e915989de774fe11fTed Kremenek const_iterator &operator++() { 137f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski if (!Scope) 138f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski return *this; 139f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski 140f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski assert (VarIter != 0 && "Iterator has invalid value of VarIter member"); 141f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski --VarIter; 142f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski if (VarIter == 0) 143f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski *this = Scope->Prev; 144f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski return *this; 145f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski } 14635387a0daf3a6a7f5fcfc232eb4c28f62a4a1957Marcin Swiderski const_iterator operator++(int) { 14735387a0daf3a6a7f5fcfc232eb4c28f62a4a1957Marcin Swiderski const_iterator P = *this; 14835387a0daf3a6a7f5fcfc232eb4c28f62a4a1957Marcin Swiderski ++*this; 14935387a0daf3a6a7f5fcfc232eb4c28f62a4a1957Marcin Swiderski return P; 15035387a0daf3a6a7f5fcfc232eb4c28f62a4a1957Marcin Swiderski } 151f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski 1529c378f705405d37f49795d5e915989de774fe11fTed Kremenek bool operator==(const const_iterator &rhs) const { 153f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski return Scope == rhs.Scope && VarIter == rhs.VarIter; 154f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski } 1559c378f705405d37f49795d5e915989de774fe11fTed Kremenek bool operator!=(const const_iterator &rhs) const { 156f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski return !(*this == rhs); 157f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski } 15835387a0daf3a6a7f5fcfc232eb4c28f62a4a1957Marcin Swiderski 1590e2c34f92f00628d48968dfea096d36381f494cbStephen Hines explicit operator bool() const { 16035387a0daf3a6a7f5fcfc232eb4c28f62a4a1957Marcin Swiderski return *this != const_iterator(); 16135387a0daf3a6a7f5fcfc232eb4c28f62a4a1957Marcin Swiderski } 16235387a0daf3a6a7f5fcfc232eb4c28f62a4a1957Marcin Swiderski 16335387a0daf3a6a7f5fcfc232eb4c28f62a4a1957Marcin Swiderski int distance(const_iterator L); 164f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski }; 165f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski 166f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski friend class const_iterator; 167f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski 168f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderskiprivate: 169fe59b7472c06b36efb74fbb50bbdf464fa30c0d8Ted Kremenek BumpVectorContext ctx; 170fe59b7472c06b36efb74fbb50bbdf464fa30c0d8Ted Kremenek 171f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski /// Automatic variables in order of declaration. 172f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski AutomaticVarsTy Vars; 173f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski /// Iterator to variable in previous scope that was declared just before 174f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski /// begin of this scope. 175f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski const_iterator Prev; 176f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski 177f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderskipublic: 178f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski /// Constructs empty scope linked to previous scope in specified place. 179fe59b7472c06b36efb74fbb50bbdf464fa30c0d8Ted Kremenek LocalScope(BumpVectorContext &ctx, const_iterator P) 180fe59b7472c06b36efb74fbb50bbdf464fa30c0d8Ted Kremenek : ctx(ctx), Vars(ctx, 4), Prev(P) {} 181f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski 182f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski /// Begin of scope in direction of CFG building (backwards). 183f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski const_iterator begin() const { return const_iterator(*this, Vars.size()); } 18435387a0daf3a6a7f5fcfc232eb4c28f62a4a1957Marcin Swiderski 1859c378f705405d37f49795d5e915989de774fe11fTed Kremenek void addVar(VarDecl *VD) { 186fe59b7472c06b36efb74fbb50bbdf464fa30c0d8Ted Kremenek Vars.push_back(VD, ctx); 18735387a0daf3a6a7f5fcfc232eb4c28f62a4a1957Marcin Swiderski } 188f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski}; 189f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski 19035387a0daf3a6a7f5fcfc232eb4c28f62a4a1957Marcin Swiderski/// distance - Calculates distance from this to L. L must be reachable from this 19135387a0daf3a6a7f5fcfc232eb4c28f62a4a1957Marcin Swiderski/// (with use of ++ operator). Cost of calculating the distance is linear w.r.t. 19235387a0daf3a6a7f5fcfc232eb4c28f62a4a1957Marcin Swiderski/// number of scopes between this and L. 19335387a0daf3a6a7f5fcfc232eb4c28f62a4a1957Marcin Swiderskiint LocalScope::const_iterator::distance(LocalScope::const_iterator L) { 19435387a0daf3a6a7f5fcfc232eb4c28f62a4a1957Marcin Swiderski int D = 0; 19535387a0daf3a6a7f5fcfc232eb4c28f62a4a1957Marcin Swiderski const_iterator F = *this; 19635387a0daf3a6a7f5fcfc232eb4c28f62a4a1957Marcin Swiderski while (F.Scope != L.Scope) { 1975290c80eba2c96aee32912adf77bea6eddb92026Ted Kremenek assert (F != const_iterator() 1985290c80eba2c96aee32912adf77bea6eddb92026Ted Kremenek && "L iterator is not reachable from F iterator."); 19935387a0daf3a6a7f5fcfc232eb4c28f62a4a1957Marcin Swiderski D += F.VarIter; 20035387a0daf3a6a7f5fcfc232eb4c28f62a4a1957Marcin Swiderski F = F.Scope->Prev; 20135387a0daf3a6a7f5fcfc232eb4c28f62a4a1957Marcin Swiderski } 20235387a0daf3a6a7f5fcfc232eb4c28f62a4a1957Marcin Swiderski D += F.VarIter - L.VarIter; 20335387a0daf3a6a7f5fcfc232eb4c28f62a4a1957Marcin Swiderski return D; 20435387a0daf3a6a7f5fcfc232eb4c28f62a4a1957Marcin Swiderski} 20535387a0daf3a6a7f5fcfc232eb4c28f62a4a1957Marcin Swiderski 20635387a0daf3a6a7f5fcfc232eb4c28f62a4a1957Marcin Swiderski/// BlockScopePosPair - Structure for specifying position in CFG during its 20735387a0daf3a6a7f5fcfc232eb4c28f62a4a1957Marcin Swiderski/// build process. It consists of CFGBlock that specifies position in CFG graph 20835387a0daf3a6a7f5fcfc232eb4c28f62a4a1957Marcin Swiderski/// and LocalScope::const_iterator that specifies position in LocalScope graph. 209f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderskistruct BlockScopePosPair { 2106bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines BlockScopePosPair() : block(nullptr) {} 2119c378f705405d37f49795d5e915989de774fe11fTed Kremenek BlockScopePosPair(CFGBlock *b, LocalScope::const_iterator scopePos) 2129ce5270f0aadaaf03a0cf705787f42ce9eb1194cTed Kremenek : block(b), scopePosition(scopePos) {} 213f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski 2149ce5270f0aadaaf03a0cf705787f42ce9eb1194cTed Kremenek CFGBlock *block; 2159ce5270f0aadaaf03a0cf705787f42ce9eb1194cTed Kremenek LocalScope::const_iterator scopePosition; 216f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski}; 217f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski 218e71f3d587844110d836c82250830b27b1651afdbTed Kremenek/// TryResult - a class representing a variant over the values 219e71f3d587844110d836c82250830b27b1651afdbTed Kremenek/// 'true', 'false', or 'unknown'. This is returned by tryEvaluateBool, 220e71f3d587844110d836c82250830b27b1651afdbTed Kremenek/// and is used by the CFGBuilder to decide if a branch condition 221e71f3d587844110d836c82250830b27b1651afdbTed Kremenek/// can be decided up front during CFG construction. 222e71f3d587844110d836c82250830b27b1651afdbTed Kremenekclass TryResult { 223e71f3d587844110d836c82250830b27b1651afdbTed Kremenek int X; 224e71f3d587844110d836c82250830b27b1651afdbTed Kremenekpublic: 225e71f3d587844110d836c82250830b27b1651afdbTed Kremenek TryResult(bool b) : X(b ? 1 : 0) {} 226e71f3d587844110d836c82250830b27b1651afdbTed Kremenek TryResult() : X(-1) {} 227e71f3d587844110d836c82250830b27b1651afdbTed Kremenek 228e71f3d587844110d836c82250830b27b1651afdbTed Kremenek bool isTrue() const { return X == 1; } 229e71f3d587844110d836c82250830b27b1651afdbTed Kremenek bool isFalse() const { return X == 0; } 230e71f3d587844110d836c82250830b27b1651afdbTed Kremenek bool isKnown() const { return X >= 0; } 231e71f3d587844110d836c82250830b27b1651afdbTed Kremenek void negate() { 232e71f3d587844110d836c82250830b27b1651afdbTed Kremenek assert(isKnown()); 233e71f3d587844110d836c82250830b27b1651afdbTed Kremenek X ^= 0x1; 234e71f3d587844110d836c82250830b27b1651afdbTed Kremenek } 235e71f3d587844110d836c82250830b27b1651afdbTed Kremenek}; 236e71f3d587844110d836c82250830b27b1651afdbTed Kremenek 237176edba5311f6eff0cad2631449885ddf4fbc9eaStephen HinesTryResult bothKnownTrue(TryResult R1, TryResult R2) { 238176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines if (!R1.isKnown() || !R2.isKnown()) 239176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines return TryResult(); 240176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines return TryResult(R1.isTrue() && R2.isTrue()); 241176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines} 242176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines 2435846720f08a6b225484bfe663599c2b057a99bc8Ted Kremenekclass reverse_children { 2445846720f08a6b225484bfe663599c2b057a99bc8Ted Kremenek llvm::SmallVector<Stmt *, 12> childrenBuf; 2455846720f08a6b225484bfe663599c2b057a99bc8Ted Kremenek ArrayRef<Stmt*> children; 2465846720f08a6b225484bfe663599c2b057a99bc8Ted Kremenekpublic: 2475846720f08a6b225484bfe663599c2b057a99bc8Ted Kremenek reverse_children(Stmt *S); 2485846720f08a6b225484bfe663599c2b057a99bc8Ted Kremenek 2495846720f08a6b225484bfe663599c2b057a99bc8Ted Kremenek typedef ArrayRef<Stmt*>::reverse_iterator iterator; 2505846720f08a6b225484bfe663599c2b057a99bc8Ted Kremenek iterator begin() const { return children.rbegin(); } 2515846720f08a6b225484bfe663599c2b057a99bc8Ted Kremenek iterator end() const { return children.rend(); } 2525846720f08a6b225484bfe663599c2b057a99bc8Ted Kremenek}; 2535846720f08a6b225484bfe663599c2b057a99bc8Ted Kremenek 2545846720f08a6b225484bfe663599c2b057a99bc8Ted Kremenek 2555846720f08a6b225484bfe663599c2b057a99bc8Ted Kremenekreverse_children::reverse_children(Stmt *S) { 2565846720f08a6b225484bfe663599c2b057a99bc8Ted Kremenek if (CallExpr *CE = dyn_cast<CallExpr>(S)) { 2575846720f08a6b225484bfe663599c2b057a99bc8Ted Kremenek children = CE->getRawSubExprs(); 2585846720f08a6b225484bfe663599c2b057a99bc8Ted Kremenek return; 2595846720f08a6b225484bfe663599c2b057a99bc8Ted Kremenek } 2605846720f08a6b225484bfe663599c2b057a99bc8Ted Kremenek switch (S->getStmtClass()) { 261b1855de3d61eab7d2f2e616ed59195f83e2a6dc0Ted Kremenek // Note: Fill in this switch with more cases we want to optimize. 2625846720f08a6b225484bfe663599c2b057a99bc8Ted Kremenek case Stmt::InitListExprClass: { 2635846720f08a6b225484bfe663599c2b057a99bc8Ted Kremenek InitListExpr *IE = cast<InitListExpr>(S); 2645846720f08a6b225484bfe663599c2b057a99bc8Ted Kremenek children = llvm::makeArrayRef(reinterpret_cast<Stmt**>(IE->getInits()), 2655846720f08a6b225484bfe663599c2b057a99bc8Ted Kremenek IE->getNumInits()); 2665846720f08a6b225484bfe663599c2b057a99bc8Ted Kremenek return; 2675846720f08a6b225484bfe663599c2b057a99bc8Ted Kremenek } 2685846720f08a6b225484bfe663599c2b057a99bc8Ted Kremenek default: 2695846720f08a6b225484bfe663599c2b057a99bc8Ted Kremenek break; 2705846720f08a6b225484bfe663599c2b057a99bc8Ted Kremenek } 2715846720f08a6b225484bfe663599c2b057a99bc8Ted Kremenek 2725846720f08a6b225484bfe663599c2b057a99bc8Ted Kremenek // Default case for all other statements. 2735846720f08a6b225484bfe663599c2b057a99bc8Ted Kremenek for (Stmt::child_range I = S->children(); I; ++I) { 2745846720f08a6b225484bfe663599c2b057a99bc8Ted Kremenek childrenBuf.push_back(*I); 2755846720f08a6b225484bfe663599c2b057a99bc8Ted Kremenek } 2765846720f08a6b225484bfe663599c2b057a99bc8Ted Kremenek 2775846720f08a6b225484bfe663599c2b057a99bc8Ted Kremenek // This needs to be done *after* childrenBuf has been populated. 2785846720f08a6b225484bfe663599c2b057a99bc8Ted Kremenek children = childrenBuf; 2795846720f08a6b225484bfe663599c2b057a99bc8Ted Kremenek} 2805846720f08a6b225484bfe663599c2b057a99bc8Ted Kremenek 281a34ea072371154c9042ce86321d17fbb4df1f84dTed Kremenek/// CFGBuilder - This class implements CFG construction from an AST. 282fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek/// The builder is stateful: an instance of the builder should be used to only 283fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek/// construct a single CFG. 284fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek/// 285fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek/// Example usage: 286fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek/// 287fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek/// CFGBuilder builder; 288fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek/// CFG* cfg = builder.BuildAST(stmt1); 289fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek/// 2906d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump/// CFG construction is done via a recursive walk of an AST. We actually parse 2916d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump/// the AST in reverse order so that the successor of a basic block is 2926d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump/// constructed prior to its predecessor. This allows us to nicely capture 2936d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump/// implicit fall-throughs without extra basic blocks. 294c310e933a9b023a280f3aa02e5a0c75398555e13Ted Kremenek/// 295ba5fb5a955c896815c439289fc51c03cf0635129Kovarththanan Rajaratnamclass CFGBuilder { 296f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski typedef BlockScopePosPair JumpTarget; 297f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski typedef BlockScopePosPair JumpSource; 298f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski 299e5af3ce53ec58995b09381ba645ab2117a46647bMike Stump ASTContext *Context; 300651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines std::unique_ptr<CFG> cfg; 301ee82d9bdc5025b82de8ce2a4ad4685e0a8b79da9Ted Kremenek 3029c378f705405d37f49795d5e915989de774fe11fTed Kremenek CFGBlock *Block; 3039c378f705405d37f49795d5e915989de774fe11fTed Kremenek CFGBlock *Succ; 304f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski JumpTarget ContinueJumpTarget; 305f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski JumpTarget BreakJumpTarget; 3069c378f705405d37f49795d5e915989de774fe11fTed Kremenek CFGBlock *SwitchTerminatedBlock; 3079c378f705405d37f49795d5e915989de774fe11fTed Kremenek CFGBlock *DefaultCaseBlock; 3089c378f705405d37f49795d5e915989de774fe11fTed Kremenek CFGBlock *TryTerminatedBlock; 309176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines 310f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski // Current position in local scope. 311f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski LocalScope::const_iterator ScopePos; 312f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski 313f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski // LabelMap records the mapping from Label expressions to their jump targets. 314ad8dcf4a9df0e24051dc31bf9e6f3cd138a34298Chris Lattner typedef llvm::DenseMap<LabelDecl*, JumpTarget> LabelMapTy; 3150cebe3e29b22d11f2c65ef28fcfb5f0431877266Ted Kremenek LabelMapTy LabelMap; 3166d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 3176d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump // A list of blocks that end with a "goto" that must be backpatched to their 3186d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump // resolved targets upon completion of CFG construction. 319f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski typedef std::vector<JumpSource> BackpatchBlocksTy; 3200cebe3e29b22d11f2c65ef28fcfb5f0431877266Ted Kremenek BackpatchBlocksTy BackpatchBlocks; 3216d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 32219bb356317952445b03ee341c02f6147083c9eeaTed Kremenek // A list of labels whose address has been taken (for indirect gotos). 323ad8dcf4a9df0e24051dc31bf9e6f3cd138a34298Chris Lattner typedef llvm::SmallPtrSet<LabelDecl*, 5> LabelSetTy; 32419bb356317952445b03ee341c02f6147083c9eeaTed Kremenek LabelSetTy AddressTakenLabels; 3256d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 32649b4ef364ba042f7db2ba567310fb49917ad0086Zhongxing Xu bool badCFG; 327b8ad5ee345fa1fdd1fa9253f2d01f69becc88a04Ted Kremenek const CFG::BuildOptions &BuildOpts; 328e71f3d587844110d836c82250830b27b1651afdbTed Kremenek 329e71f3d587844110d836c82250830b27b1651afdbTed Kremenek // State to track for building switch statements. 330e71f3d587844110d836c82250830b27b1651afdbTed Kremenek bool switchExclusivelyCovered; 3310498247f87ea0d716e0c2931fea812280649e33dTed Kremenek Expr::EvalResult *switchCond; 3320d28d360b5559abda755e50b855ba5e59727d9cdTed Kremenek 3330d28d360b5559abda755e50b855ba5e59727d9cdTed Kremenek CFG::BuildOptions::ForcedBlkExprs::value_type *cachedEntry; 334a8d459e8a68b1270b0c35fb73e8cc090b2b69e36Ted Kremenek const Stmt *lastLookup; 33549b4ef364ba042f7db2ba567310fb49917ad0086Zhongxing Xu 3368c6d360636dee25f1ce071c3656810c6632cb89dArgyrios Kyrtzidis // Caches boolean evaluations of expressions to avoid multiple re-evaluations 3378c6d360636dee25f1ce071c3656810c6632cb89dArgyrios Kyrtzidis // during construction of branches for chained logical operators. 3386955da2cad4bce19c541ddb85a6d965d77a1a4abNAKAMURA Takumi typedef llvm::DenseMap<Expr *, TryResult> CachedBoolEvalsTy; 3396955da2cad4bce19c541ddb85a6d965d77a1a4abNAKAMURA Takumi CachedBoolEvalsTy CachedBoolEvals; 3408c6d360636dee25f1ce071c3656810c6632cb89dArgyrios Kyrtzidis 3416d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stumppublic: 342b8ad5ee345fa1fdd1fa9253f2d01f69becc88a04Ted Kremenek explicit CFGBuilder(ASTContext *astContext, 343b8ad5ee345fa1fdd1fa9253f2d01f69becc88a04Ted Kremenek const CFG::BuildOptions &buildOpts) 344b8ad5ee345fa1fdd1fa9253f2d01f69becc88a04Ted Kremenek : Context(astContext), cfg(new CFG()), // crew a new CFG 3456bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines Block(nullptr), Succ(nullptr), 3466bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines SwitchTerminatedBlock(nullptr), DefaultCaseBlock(nullptr), 3476bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines TryTerminatedBlock(nullptr), badCFG(false), BuildOpts(buildOpts), 3486bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines switchExclusivelyCovered(false), switchCond(nullptr), 3496bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines cachedEntry(nullptr), lastLookup(nullptr) {} 3506d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 351d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek // buildCFG - Used by external clients to construct the CFG. 352176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines std::unique_ptr<CFG> buildCFG(const Decl *D, Stmt *Statement); 3536d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 3540d28d360b5559abda755e50b855ba5e59727d9cdTed Kremenek bool alwaysAdd(const Stmt *stmt); 3550d28d360b5559abda755e50b855ba5e59727d9cdTed Kremenek 3564f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenekprivate: 3574f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek // Visitors to walk an AST and construct the CFG. 358852274d4257134906995cb252fb3dfd2d71deae8Ted Kremenek CFGBlock *VisitAddrLabelExpr(AddrLabelExpr *A, AddStmtChoice asc); 359852274d4257134906995cb252fb3dfd2d71deae8Ted Kremenek CFGBlock *VisitBinaryOperator(BinaryOperator *B, AddStmtChoice asc); 3604f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek CFGBlock *VisitBreakStmt(BreakStmt *B); 361852274d4257134906995cb252fb3dfd2d71deae8Ted Kremenek CFGBlock *VisitCallExpr(CallExpr *C, AddStmtChoice asc); 3624f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek CFGBlock *VisitCaseStmt(CaseStmt *C); 363852274d4257134906995cb252fb3dfd2d71deae8Ted Kremenek CFGBlock *VisitChooseExpr(ChooseExpr *C, AddStmtChoice asc); 3643fc8ef574cdc09c613c329ee511852d219263c15Ted Kremenek CFGBlock *VisitCompoundStmt(CompoundStmt *C); 36556ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall CFGBlock *VisitConditionalOperator(AbstractConditionalOperator *C, 36656ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall AddStmtChoice asc); 3673fc8ef574cdc09c613c329ee511852d219263c15Ted Kremenek CFGBlock *VisitContinueStmt(ContinueStmt *C); 3686960ee6c7cc8a8883126d9861beecb51a4e4a475Ted Kremenek CFGBlock *VisitCXXBindTemporaryExpr(CXXBindTemporaryExpr *E, 3696960ee6c7cc8a8883126d9861beecb51a4e4a475Ted Kremenek AddStmtChoice asc); 3706960ee6c7cc8a8883126d9861beecb51a4e4a475Ted Kremenek CFGBlock *VisitCXXCatchStmt(CXXCatchStmt *S); 3716960ee6c7cc8a8883126d9861beecb51a4e4a475Ted Kremenek CFGBlock *VisitCXXConstructExpr(CXXConstructExpr *C, AddStmtChoice asc); 372651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines CFGBlock *VisitCXXNewExpr(CXXNewExpr *DE, AddStmtChoice asc); 37336d558d85653315edb389677e995ec9ccdbfbf3dJordan Rose CFGBlock *VisitCXXDeleteExpr(CXXDeleteExpr *DE, AddStmtChoice asc); 3746960ee6c7cc8a8883126d9861beecb51a4e4a475Ted Kremenek CFGBlock *VisitCXXForRangeStmt(CXXForRangeStmt *S); 3756960ee6c7cc8a8883126d9861beecb51a4e4a475Ted Kremenek CFGBlock *VisitCXXFunctionalCastExpr(CXXFunctionalCastExpr *E, 3766960ee6c7cc8a8883126d9861beecb51a4e4a475Ted Kremenek AddStmtChoice asc); 3776960ee6c7cc8a8883126d9861beecb51a4e4a475Ted Kremenek CFGBlock *VisitCXXTemporaryObjectExpr(CXXTemporaryObjectExpr *C, 3786960ee6c7cc8a8883126d9861beecb51a4e4a475Ted Kremenek AddStmtChoice asc); 3796960ee6c7cc8a8883126d9861beecb51a4e4a475Ted Kremenek CFGBlock *VisitCXXThrowExpr(CXXThrowExpr *T); 3806960ee6c7cc8a8883126d9861beecb51a4e4a475Ted Kremenek CFGBlock *VisitCXXTryStmt(CXXTryStmt *S); 3814f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek CFGBlock *VisitDeclStmt(DeclStmt *DS); 3829c378f705405d37f49795d5e915989de774fe11fTed Kremenek CFGBlock *VisitDeclSubExpr(DeclStmt *DS); 3833fc8ef574cdc09c613c329ee511852d219263c15Ted Kremenek CFGBlock *VisitDefaultStmt(DefaultStmt *D); 3843fc8ef574cdc09c613c329ee511852d219263c15Ted Kremenek CFGBlock *VisitDoStmt(DoStmt *D); 3856960ee6c7cc8a8883126d9861beecb51a4e4a475Ted Kremenek CFGBlock *VisitExprWithCleanups(ExprWithCleanups *E, AddStmtChoice asc); 3863fc8ef574cdc09c613c329ee511852d219263c15Ted Kremenek CFGBlock *VisitForStmt(ForStmt *F); 3879c378f705405d37f49795d5e915989de774fe11fTed Kremenek CFGBlock *VisitGotoStmt(GotoStmt *G); 3884f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek CFGBlock *VisitIfStmt(IfStmt *I); 389a725ed468585b881c43654eeb56b28554a84808aZhongxing Xu CFGBlock *VisitImplicitCastExpr(ImplicitCastExpr *E, AddStmtChoice asc); 3904f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek CFGBlock *VisitIndirectGotoStmt(IndirectGotoStmt *I); 3914f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek CFGBlock *VisitLabelStmt(LabelStmt *L); 3926960ee6c7cc8a8883126d9861beecb51a4e4a475Ted Kremenek CFGBlock *VisitLambdaExpr(LambdaExpr *E, AddStmtChoice asc); 3935c3ea5c57971317c35b120ef0a2a2c79bd171008Ted Kremenek CFGBlock *VisitLogicalOperator(BinaryOperator *B); 3943f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek std::pair<CFGBlock *, CFGBlock *> VisitLogicalOperator(BinaryOperator *B, 3953f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek Stmt *Term, 3963f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek CFGBlock *TrueBlock, 3973f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek CFGBlock *FalseBlock); 398115c1b9cc758d15f38e1d2ad4cf07b1cacfb3115Ted Kremenek CFGBlock *VisitMemberExpr(MemberExpr *M, AddStmtChoice asc); 3994f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek CFGBlock *VisitObjCAtCatchStmt(ObjCAtCatchStmt *S); 4004f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek CFGBlock *VisitObjCAtSynchronizedStmt(ObjCAtSynchronizedStmt *S); 4014f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek CFGBlock *VisitObjCAtThrowStmt(ObjCAtThrowStmt *S); 4024f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek CFGBlock *VisitObjCAtTryStmt(ObjCAtTryStmt *S); 4036960ee6c7cc8a8883126d9861beecb51a4e4a475Ted Kremenek CFGBlock *VisitObjCAutoreleasePoolStmt(ObjCAutoreleasePoolStmt *S); 4044f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek CFGBlock *VisitObjCForCollectionStmt(ObjCForCollectionStmt *S); 4054b9c2d235fb9449e249d74f48ecfec601650de93John McCall CFGBlock *VisitPseudoObjectExpr(PseudoObjectExpr *E); 4066960ee6c7cc8a8883126d9861beecb51a4e4a475Ted Kremenek CFGBlock *VisitReturnStmt(ReturnStmt *R); 407852274d4257134906995cb252fb3dfd2d71deae8Ted Kremenek CFGBlock *VisitStmtExpr(StmtExpr *S, AddStmtChoice asc); 4084f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek CFGBlock *VisitSwitchStmt(SwitchStmt *S); 4096960ee6c7cc8a8883126d9861beecb51a4e4a475Ted Kremenek CFGBlock *VisitUnaryExprOrTypeTraitExpr(UnaryExprOrTypeTraitExpr *E, 4106960ee6c7cc8a8883126d9861beecb51a4e4a475Ted Kremenek AddStmtChoice asc); 41199cae5b67b9711ca260e5b364a878a1a91183632Zhanyong Wan CFGBlock *VisitUnaryOperator(UnaryOperator *U, AddStmtChoice asc); 4124f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek CFGBlock *VisitWhileStmt(WhileStmt *W); 4134f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek 414852274d4257134906995cb252fb3dfd2d71deae8Ted Kremenek CFGBlock *Visit(Stmt *S, AddStmtChoice asc = AddStmtChoice::NotAlwaysAdd); 415852274d4257134906995cb252fb3dfd2d71deae8Ted Kremenek CFGBlock *VisitStmt(Stmt *S, AddStmtChoice asc); 4169c378f705405d37f49795d5e915989de774fe11fTed Kremenek CFGBlock *VisitChildren(Stmt *S); 41755331da3211151aa67277aa095b7d301342200d4Ted Kremenek CFGBlock *VisitNoRecurse(Expr *E, AddStmtChoice asc); 418cd7bf230a77c550115e4a78ee371fc49a7563692Mike Stump 419176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines /// When creating the CFG for temporary destructors, we want to mirror the 420176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines /// branch structure of the corresponding constructor calls. 421176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines /// Thus, while visiting a statement for temporary destructors, we keep a 422176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines /// context to keep track of the following information: 423176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines /// - whether a subexpression is executed unconditionally 424176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines /// - if a subexpression is executed conditionally, the first 425176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines /// CXXBindTemporaryExpr we encounter in that subexpression (which 426176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines /// corresponds to the last temporary destructor we have to call for this 427176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines /// subexpression) and the CFG block at that point (which will become the 428176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines /// successor block when inserting the decision point). 429176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines /// 430176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines /// That way, we can build the branch structure for temporary destructors as 431176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines /// follows: 432176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines /// 1. If a subexpression is executed unconditionally, we add the temporary 433176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines /// destructor calls to the current block. 434176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines /// 2. If a subexpression is executed conditionally, when we encounter a 435176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines /// CXXBindTemporaryExpr: 436176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines /// a) If it is the first temporary destructor call in the subexpression, 437176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines /// we remember the CXXBindTemporaryExpr and the current block in the 438176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines /// TempDtorContext; we start a new block, and insert the temporary 439176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines /// destructor call. 440176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines /// b) Otherwise, add the temporary destructor call to the current block. 441176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines /// 3. When we finished visiting a conditionally executed subexpression, 442176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines /// and we found at least one temporary constructor during the visitation 443176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines /// (2.a has executed), we insert a decision block that uses the 444176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines /// CXXBindTemporaryExpr as terminator, and branches to the current block 445176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines /// if the CXXBindTemporaryExpr was marked executed, and otherwise 446176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines /// branches to the stored successor. 447176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines struct TempDtorContext { 448176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines TempDtorContext() 449176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines : IsConditional(false), KnownExecuted(true), Succ(nullptr), 450176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines TerminatorExpr(nullptr) {} 451176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines 452176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines TempDtorContext(TryResult KnownExecuted) 453176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines : IsConditional(true), KnownExecuted(KnownExecuted), Succ(nullptr), 454176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines TerminatorExpr(nullptr) {} 455176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines 456176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines /// Returns whether we need to start a new branch for a temporary destructor 457176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines /// call. This is the case when the the temporary destructor is 458176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines /// conditionally executed, and it is the first one we encounter while 459176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines /// visiting a subexpression - other temporary destructors at the same level 460176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines /// will be added to the same block and are executed under the same 461176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines /// condition. 462176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines bool needsTempDtorBranch() const { 463176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines return IsConditional && !TerminatorExpr; 464176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines } 465176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines 466176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines /// Remember the successor S of a temporary destructor decision branch for 467176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines /// the corresponding CXXBindTemporaryExpr E. 468176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines void setDecisionPoint(CFGBlock *S, CXXBindTemporaryExpr *E) { 469176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines Succ = S; 470176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines TerminatorExpr = E; 471176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines } 472176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines 473176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines const bool IsConditional; 474176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines const TryResult KnownExecuted; 475176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines CFGBlock *Succ; 476176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines CXXBindTemporaryExpr *TerminatorExpr; 477176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines }; 478176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines 4798599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski // Visitors to walk an AST and generate destructors of temporaries in 4808599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski // full expression. 481176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines CFGBlock *VisitForTemporaryDtors(Stmt *E, bool BindToTemporary, 482176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines TempDtorContext &Context); 483176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines CFGBlock *VisitChildrenForTemporaryDtors(Stmt *E, TempDtorContext &Context); 484176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines CFGBlock *VisitBinaryOperatorForTemporaryDtors(BinaryOperator *E, 485176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines TempDtorContext &Context); 486176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines CFGBlock *VisitCXXBindTemporaryExprForTemporaryDtors( 487176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines CXXBindTemporaryExpr *E, bool BindToTemporary, TempDtorContext &Context); 488176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines CFGBlock *VisitConditionalOperatorForTemporaryDtors( 489176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines AbstractConditionalOperator *E, bool BindToTemporary, 490176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines TempDtorContext &Context); 491176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines void InsertTempDtorDecisionBlock(const TempDtorContext &Context, 492176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines CFGBlock *FalseSucc = nullptr); 4938599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski 494274f4334f6dd35239e5c3d4b86198f7f5804b059Ted Kremenek // NYS == Not Yet Supported 4959c378f705405d37f49795d5e915989de774fe11fTed Kremenek CFGBlock *NYS() { 4964102af916d52310c3deedd84d6fd5e2fd3c09bfeTed Kremenek badCFG = true; 4974102af916d52310c3deedd84d6fd5e2fd3c09bfeTed Kremenek return Block; 4984102af916d52310c3deedd84d6fd5e2fd3c09bfeTed Kremenek } 4996d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 5004f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek void autoCreateBlock() { if (!Block) Block = createBlock(); } 5014f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek CFGBlock *createBlock(bool add_successor = true); 502dba3fb5413437dc613734fa4ffac892b11a37d25Chandler Carruth CFGBlock *createNoReturnBlock(); 503d438b3dbdcde4df4f61a99054104643e6aadf78bZhongxing Xu 504df119892cf291847d6aebb117512225a8e67c0d5Zhongxing Xu CFGBlock *addStmt(Stmt *S) { 505df119892cf291847d6aebb117512225a8e67c0d5Zhongxing Xu return Visit(S, AddStmtChoice::AlwaysAdd); 506852274d4257134906995cb252fb3dfd2d71deae8Ted Kremenek } 507cbb67480094b3bcb5b715acd827cbad55e2a204cSean Hunt CFGBlock *addInitializer(CXXCtorInitializer *I); 5086a16a306f6226030f8d38ae7e32082888fa937a1Zhongxing Xu void addAutomaticObjDtors(LocalScope::const_iterator B, 5099c378f705405d37f49795d5e915989de774fe11fTed Kremenek LocalScope::const_iterator E, Stmt *S); 5107c625d8ffc20b92fff9e1690cd2484fcb6498183Marcin Swiderski void addImplicitDtorsForDestructor(const CXXDestructorDecl *DD); 511239a7c42df78abc7fd5611d806d5e199fec994d1Marcin Swiderski 512239a7c42df78abc7fd5611d806d5e199fec994d1Marcin Swiderski // Local scopes creation. 513239a7c42df78abc7fd5611d806d5e199fec994d1Marcin Swiderski LocalScope* createOrReuseLocalScope(LocalScope* Scope); 514239a7c42df78abc7fd5611d806d5e199fec994d1Marcin Swiderski 5159c378f705405d37f49795d5e915989de774fe11fTed Kremenek void addLocalScopeForStmt(Stmt *S); 5166bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines LocalScope* addLocalScopeForDeclStmt(DeclStmt *DS, 5176bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines LocalScope* Scope = nullptr); 5186bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines LocalScope* addLocalScopeForVarDecl(VarDecl *VD, LocalScope* Scope = nullptr); 519239a7c42df78abc7fd5611d806d5e199fec994d1Marcin Swiderski 5209c378f705405d37f49795d5e915989de774fe11fTed Kremenek void addLocalScopeAndDtors(Stmt *S); 521ad5a894df1841698c824381b414630799adc26caTed Kremenek 522239a7c42df78abc7fd5611d806d5e199fec994d1Marcin Swiderski // Interface to CFGBlock - adding CFGElements. 523d40066b0fb883839a9100e5455e33190b9b8abacTed Kremenek void appendStmt(CFGBlock *B, const Stmt *S) { 52474fb1a493cf5d2dd0fb51a4eadf74e85e10a3457Ted Kremenek if (alwaysAdd(S) && cachedEntry) 5250d28d360b5559abda755e50b855ba5e59727d9cdTed Kremenek cachedEntry->second = B; 5260d28d360b5559abda755e50b855ba5e59727d9cdTed Kremenek 527ac73ea8c12772fd0dcec71b83c193a2837de7f8bJordy Rose // All block-level expressions should have already been IgnoreParens()ed. 528ac73ea8c12772fd0dcec71b83c193a2837de7f8bJordy Rose assert(!isa<Expr>(S) || cast<Expr>(S)->IgnoreParens() == S); 529d40066b0fb883839a9100e5455e33190b9b8abacTed Kremenek B->appendStmt(const_cast<Stmt*>(S), cfg->getBumpVectorContext()); 530ee82d9bdc5025b82de8ce2a4ad4685e0a8b79da9Ted Kremenek } 531cbb67480094b3bcb5b715acd827cbad55e2a204cSean Hunt void appendInitializer(CFGBlock *B, CXXCtorInitializer *I) { 53282bc3fd823d85ee3ef9a641c0975b6ad25f55047Marcin Swiderski B->appendInitializer(I, cfg->getBumpVectorContext()); 53382bc3fd823d85ee3ef9a641c0975b6ad25f55047Marcin Swiderski } 534651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines void appendNewAllocator(CFGBlock *B, CXXNewExpr *NE) { 535651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines B->appendNewAllocator(NE, cfg->getBumpVectorContext()); 536651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 5377c625d8ffc20b92fff9e1690cd2484fcb6498183Marcin Swiderski void appendBaseDtor(CFGBlock *B, const CXXBaseSpecifier *BS) { 5387c625d8ffc20b92fff9e1690cd2484fcb6498183Marcin Swiderski B->appendBaseDtor(BS, cfg->getBumpVectorContext()); 5397c625d8ffc20b92fff9e1690cd2484fcb6498183Marcin Swiderski } 5407c625d8ffc20b92fff9e1690cd2484fcb6498183Marcin Swiderski void appendMemberDtor(CFGBlock *B, FieldDecl *FD) { 5417c625d8ffc20b92fff9e1690cd2484fcb6498183Marcin Swiderski B->appendMemberDtor(FD, cfg->getBumpVectorContext()); 5427c625d8ffc20b92fff9e1690cd2484fcb6498183Marcin Swiderski } 5438599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski void appendTemporaryDtor(CFGBlock *B, CXXBindTemporaryExpr *E) { 5448599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski B->appendTemporaryDtor(E, cfg->getBumpVectorContext()); 5458599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski } 546c8cfc74bdcc999828bc232294d937fb191940d5bChandler Carruth void appendAutomaticObjDtor(CFGBlock *B, VarDecl *VD, Stmt *S) { 547c8cfc74bdcc999828bc232294d937fb191940d5bChandler Carruth B->appendAutomaticObjDtor(VD, S, cfg->getBumpVectorContext()); 548c8cfc74bdcc999828bc232294d937fb191940d5bChandler Carruth } 549ad5a894df1841698c824381b414630799adc26caTed Kremenek 55036d558d85653315edb389677e995ec9ccdbfbf3dJordan Rose void appendDeleteDtor(CFGBlock *B, CXXRecordDecl *RD, CXXDeleteExpr *DE) { 55136d558d85653315edb389677e995ec9ccdbfbf3dJordan Rose B->appendDeleteDtor(RD, DE, cfg->getBumpVectorContext()); 55236d558d85653315edb389677e995ec9ccdbfbf3dJordan Rose } 55336d558d85653315edb389677e995ec9ccdbfbf3dJordan Rose 5549c378f705405d37f49795d5e915989de774fe11fTed Kremenek void prependAutomaticObjDtorsWithTerminator(CFGBlock *Blk, 55553de134e7b4686eed40bc031438d8a4560a2cda4Marcin Swiderski LocalScope::const_iterator B, LocalScope::const_iterator E); 55653de134e7b4686eed40bc031438d8a4560a2cda4Marcin Swiderski 557651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines void addSuccessor(CFGBlock *B, CFGBlock *S, bool IsReachable = true) { 558651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines B->addSuccessor(CFGBlock::AdjacentBlock(S, IsReachable), 559651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines cfg->getBumpVectorContext()); 560651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 561651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 562651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines /// Add a reachable successor to a block, with the alternate variant that is 563651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines /// unreachable. 564651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines void addSuccessor(CFGBlock *B, CFGBlock *ReachableBlock, CFGBlock *AltBlock) { 565651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines B->addSuccessor(CFGBlock::AdjacentBlock(ReachableBlock, AltBlock), 566651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines cfg->getBumpVectorContext()); 567ee82d9bdc5025b82de8ce2a4ad4685e0a8b79da9Ted Kremenek } 5681eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 5696bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines /// \brief Find a relational comparison with an expression evaluating to a 5706bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines /// boolean and a constant other than 0 and 1. 5716bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines /// e.g. if ((x < y) == 10) 5726bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines TryResult checkIncorrectRelationalOperator(const BinaryOperator *B) { 5736bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines const Expr *LHSExpr = B->getLHS()->IgnoreParens(); 5746bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines const Expr *RHSExpr = B->getRHS()->IgnoreParens(); 5756bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 5766bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines const IntegerLiteral *IntLiteral = dyn_cast<IntegerLiteral>(LHSExpr); 5776bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines const Expr *BoolExpr = RHSExpr; 5786bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines bool IntFirst = true; 5796bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (!IntLiteral) { 5806bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines IntLiteral = dyn_cast<IntegerLiteral>(RHSExpr); 5816bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines BoolExpr = LHSExpr; 5826bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines IntFirst = false; 5836bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } 5846bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 5856bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (!IntLiteral || !BoolExpr->isKnownToHaveBooleanValue()) 5866bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return TryResult(); 5876bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 5886bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines llvm::APInt IntValue = IntLiteral->getValue(); 5896bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if ((IntValue == 1) || (IntValue == 0)) 5906bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return TryResult(); 5916bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 5926bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines bool IntLarger = IntLiteral->getType()->isUnsignedIntegerType() || 5936bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines !IntValue.isNegative(); 5946bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 5956bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines BinaryOperatorKind Bok = B->getOpcode(); 5966bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (Bok == BO_GT || Bok == BO_GE) { 5976bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines // Always true for 10 > bool and bool > -1 5986bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines // Always false for -1 > bool and bool > 10 5996bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return TryResult(IntFirst == IntLarger); 6006bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } else { 6016bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines // Always true for -1 < bool and bool < 10 6026bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines // Always false for 10 < bool and bool < -1 6036bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return TryResult(IntFirst != IntLarger); 6046bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } 6056bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } 6066bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 6076bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines /// Find an incorrect equality comparison. Either with an expression 6086bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines /// evaluating to a boolean and a constant other than 0 and 1. 6096bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines /// e.g. if (!x == 10) or a bitwise and/or operation that always evaluates to 6106bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines /// true/false e.q. (x & 8) == 4. 6116bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines TryResult checkIncorrectEqualityOperator(const BinaryOperator *B) { 6126bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines const Expr *LHSExpr = B->getLHS()->IgnoreParens(); 6136bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines const Expr *RHSExpr = B->getRHS()->IgnoreParens(); 6146bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 6156bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines const IntegerLiteral *IntLiteral = dyn_cast<IntegerLiteral>(LHSExpr); 6166bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines const Expr *BoolExpr = RHSExpr; 6176bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 6186bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (!IntLiteral) { 6196bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines IntLiteral = dyn_cast<IntegerLiteral>(RHSExpr); 6206bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines BoolExpr = LHSExpr; 6216bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } 6226bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 6236bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (!IntLiteral) 6246bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return TryResult(); 6256bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 6266bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines const BinaryOperator *BitOp = dyn_cast<BinaryOperator>(BoolExpr); 6276bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (BitOp && (BitOp->getOpcode() == BO_And || 6286bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines BitOp->getOpcode() == BO_Or)) { 6296bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines const Expr *LHSExpr2 = BitOp->getLHS()->IgnoreParens(); 6306bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines const Expr *RHSExpr2 = BitOp->getRHS()->IgnoreParens(); 6316bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 6326bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines const IntegerLiteral *IntLiteral2 = dyn_cast<IntegerLiteral>(LHSExpr2); 6336bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 6346bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (!IntLiteral2) 6356bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines IntLiteral2 = dyn_cast<IntegerLiteral>(RHSExpr2); 6366bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 6376bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (!IntLiteral2) 6386bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return TryResult(); 6396bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 6406bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines llvm::APInt L1 = IntLiteral->getValue(); 6416bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines llvm::APInt L2 = IntLiteral2->getValue(); 6426bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if ((BitOp->getOpcode() == BO_And && (L2 & L1) != L1) || 6436bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines (BitOp->getOpcode() == BO_Or && (L2 | L1) != L1)) { 6446bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (BuildOpts.Observer) 6456bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines BuildOpts.Observer->compareBitwiseEquality(B, 6466bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines B->getOpcode() != BO_EQ); 6476bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines TryResult(B->getOpcode() != BO_EQ); 6486bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } 6496bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } else if (BoolExpr->isKnownToHaveBooleanValue()) { 6506bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines llvm::APInt IntValue = IntLiteral->getValue(); 6516bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if ((IntValue == 1) || (IntValue == 0)) { 6526bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return TryResult(); 6536bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } 6546bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return TryResult(B->getOpcode() != BO_EQ); 6556bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } 6566bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 6576bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return TryResult(); 6586bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } 6596bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 6606bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines TryResult analyzeLogicOperatorCondition(BinaryOperatorKind Relation, 6616bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines const llvm::APSInt &Value1, 6626bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines const llvm::APSInt &Value2) { 6636bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines assert(Value1.isSigned() == Value2.isSigned()); 6646bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines switch (Relation) { 6656bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines default: 6666bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return TryResult(); 6676bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines case BO_EQ: 6686bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return TryResult(Value1 == Value2); 6696bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines case BO_NE: 6706bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return TryResult(Value1 != Value2); 6716bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines case BO_LT: 6726bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return TryResult(Value1 < Value2); 6736bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines case BO_LE: 6746bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return TryResult(Value1 <= Value2); 6756bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines case BO_GT: 6766bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return TryResult(Value1 > Value2); 6776bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines case BO_GE: 6786bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return TryResult(Value1 >= Value2); 6796bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } 6806bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } 6816bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 6826bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines /// \brief Find a pair of comparison expressions with or without parentheses 6836bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines /// with a shared variable and constants and a logical operator between them 6846bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines /// that always evaluates to either true or false. 6856bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines /// e.g. if (x != 3 || x != 4) 6866bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines TryResult checkIncorrectLogicOperator(const BinaryOperator *B) { 6876bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines assert(B->isLogicalOp()); 6886bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines const BinaryOperator *LHS = 6896bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines dyn_cast<BinaryOperator>(B->getLHS()->IgnoreParens()); 6906bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines const BinaryOperator *RHS = 6916bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines dyn_cast<BinaryOperator>(B->getRHS()->IgnoreParens()); 6926bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (!LHS || !RHS) 6936bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return TryResult(); 6946bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 6956bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (!LHS->isComparisonOp() || !RHS->isComparisonOp()) 6966bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return TryResult(); 6976bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 6986bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines BinaryOperatorKind BO1 = LHS->getOpcode(); 6996bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines const DeclRefExpr *Decl1 = 7006bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines dyn_cast<DeclRefExpr>(LHS->getLHS()->IgnoreParenImpCasts()); 7016bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines const IntegerLiteral *Literal1 = 7026bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines dyn_cast<IntegerLiteral>(LHS->getRHS()->IgnoreParens()); 7036bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (!Decl1 && !Literal1) { 7046bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (BO1 == BO_GT) 7056bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines BO1 = BO_LT; 7066bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines else if (BO1 == BO_GE) 7076bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines BO1 = BO_LE; 7086bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines else if (BO1 == BO_LT) 7096bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines BO1 = BO_GT; 7106bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines else if (BO1 == BO_LE) 7116bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines BO1 = BO_GE; 7126bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines Decl1 = dyn_cast<DeclRefExpr>(LHS->getRHS()->IgnoreParenImpCasts()); 7136bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines Literal1 = dyn_cast<IntegerLiteral>(LHS->getLHS()->IgnoreParens()); 7146bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } 7156bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 7166bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (!Decl1 || !Literal1) 7176bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return TryResult(); 7186bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 7196bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines BinaryOperatorKind BO2 = RHS->getOpcode(); 7206bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines const DeclRefExpr *Decl2 = 7216bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines dyn_cast<DeclRefExpr>(RHS->getLHS()->IgnoreParenImpCasts()); 7226bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines const IntegerLiteral *Literal2 = 7236bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines dyn_cast<IntegerLiteral>(RHS->getRHS()->IgnoreParens()); 7246bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (!Decl2 && !Literal2) { 7256bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (BO2 == BO_GT) 7266bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines BO2 = BO_LT; 7276bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines else if (BO2 == BO_GE) 7286bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines BO2 = BO_LE; 7296bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines else if (BO2 == BO_LT) 7306bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines BO2 = BO_GT; 7316bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines else if (BO2 == BO_LE) 7326bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines BO2 = BO_GE; 7336bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines Decl2 = dyn_cast<DeclRefExpr>(RHS->getRHS()->IgnoreParenImpCasts()); 7346bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines Literal2 = dyn_cast<IntegerLiteral>(RHS->getLHS()->IgnoreParens()); 7356bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } 7366bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 7376bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (!Decl2 || !Literal2) 7386bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return TryResult(); 7396bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 7406bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines // Check that it is the same variable on both sides. 7416bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (Decl1->getDecl() != Decl2->getDecl()) 7426bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return TryResult(); 7436bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 7446bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines llvm::APSInt L1, L2; 7456bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 7466bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (!Literal1->EvaluateAsInt(L1, *Context) || 7476bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines !Literal2->EvaluateAsInt(L2, *Context)) 7486bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return TryResult(); 7496bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 7506bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines // Can't compare signed with unsigned or with different bit width. 7516bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (L1.isSigned() != L2.isSigned() || L1.getBitWidth() != L2.getBitWidth()) 7526bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return TryResult(); 7536bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 7546bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines // Values that will be used to determine if result of logical 7556bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines // operator is always true/false 7566bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines const llvm::APSInt Values[] = { 7576bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines // Value less than both Value1 and Value2 7586bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines llvm::APSInt::getMinValue(L1.getBitWidth(), L1.isUnsigned()), 7596bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines // L1 7606bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines L1, 7616bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines // Value between Value1 and Value2 7626bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines ((L1 < L2) ? L1 : L2) + llvm::APSInt(llvm::APInt(L1.getBitWidth(), 1), 7636bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines L1.isUnsigned()), 7646bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines // L2 7656bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines L2, 7666bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines // Value greater than both Value1 and Value2 7676bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines llvm::APSInt::getMaxValue(L1.getBitWidth(), L1.isUnsigned()), 7686bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines }; 7696bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 7706bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines // Check whether expression is always true/false by evaluating the following 7716bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines // * variable x is less than the smallest literal. 7726bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines // * variable x is equal to the smallest literal. 7736bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines // * Variable x is between smallest and largest literal. 7746bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines // * Variable x is equal to the largest literal. 7756bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines // * Variable x is greater than largest literal. 7766bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines bool AlwaysTrue = true, AlwaysFalse = true; 7776bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines for (unsigned int ValueIndex = 0; 7786bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines ValueIndex < sizeof(Values) / sizeof(Values[0]); 7796bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines ++ValueIndex) { 7806bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines llvm::APSInt Value = Values[ValueIndex]; 7816bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines TryResult Res1, Res2; 7826bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines Res1 = analyzeLogicOperatorCondition(BO1, Value, L1); 7836bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines Res2 = analyzeLogicOperatorCondition(BO2, Value, L2); 7846bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 7856bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (!Res1.isKnown() || !Res2.isKnown()) 7866bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return TryResult(); 7876bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 7886bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (B->getOpcode() == BO_LAnd) { 7896bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines AlwaysTrue &= (Res1.isTrue() && Res2.isTrue()); 7906bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines AlwaysFalse &= !(Res1.isTrue() && Res2.isTrue()); 7916bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } else { 7926bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines AlwaysTrue &= (Res1.isTrue() || Res2.isTrue()); 7936bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines AlwaysFalse &= !(Res1.isTrue() || Res2.isTrue()); 7946bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } 7956bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } 7966bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 7976bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (AlwaysTrue || AlwaysFalse) { 7986bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (BuildOpts.Observer) 7996bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines BuildOpts.Observer->compareAlwaysTrue(B, AlwaysTrue); 8006bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return TryResult(AlwaysTrue); 8016bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } 8026bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return TryResult(); 8036bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } 8046bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 805e71f3d587844110d836c82250830b27b1651afdbTed Kremenek /// Try and evaluate an expression to an integer constant. 806e71f3d587844110d836c82250830b27b1651afdbTed Kremenek bool tryEvaluate(Expr *S, Expr::EvalResult &outResult) { 807e71f3d587844110d836c82250830b27b1651afdbTed Kremenek if (!BuildOpts.PruneTriviallyFalseEdges) 808e71f3d587844110d836c82250830b27b1651afdbTed Kremenek return false; 809e71f3d587844110d836c82250830b27b1651afdbTed Kremenek return !S->isTypeDependent() && 810f8adeefa9e9882bff402e092024dd457f8574673Ted Kremenek !S->isValueDependent() && 81151f4708c00110940ca3f337961915f2ca1668375Richard Smith S->EvaluateAsRValue(outResult, *Context); 812e71f3d587844110d836c82250830b27b1651afdbTed Kremenek } 8131eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 8140a3ed3143b00f237decb1288c1ff574ae09eba4eTed Kremenek /// tryEvaluateBool - Try and evaluate the Stmt and return 0 or 1 81500998a068e50945118f334c98af05ed44d7c22a6Mike Stump /// if we can evaluate to a known value, otherwise return -1. 8160a3ed3143b00f237decb1288c1ff574ae09eba4eTed Kremenek TryResult tryEvaluateBool(Expr *S) { 81785df96c1f04867e26ba069aa0cc6a4cd6a01292eRichard Smith if (!BuildOpts.PruneTriviallyFalseEdges || 8188c6d360636dee25f1ce071c3656810c6632cb89dArgyrios Kyrtzidis S->isTypeDependent() || S->isValueDependent()) 819e71f3d587844110d836c82250830b27b1651afdbTed Kremenek return TryResult(); 8208c6d360636dee25f1ce071c3656810c6632cb89dArgyrios Kyrtzidis 8218c6d360636dee25f1ce071c3656810c6632cb89dArgyrios Kyrtzidis if (BinaryOperator *Bop = dyn_cast<BinaryOperator>(S)) { 8228c6d360636dee25f1ce071c3656810c6632cb89dArgyrios Kyrtzidis if (Bop->isLogicalOp()) { 8238c6d360636dee25f1ce071c3656810c6632cb89dArgyrios Kyrtzidis // Check the cache first. 8246955da2cad4bce19c541ddb85a6d965d77a1a4abNAKAMURA Takumi CachedBoolEvalsTy::iterator I = CachedBoolEvals.find(S); 8256955da2cad4bce19c541ddb85a6d965d77a1a4abNAKAMURA Takumi if (I != CachedBoolEvals.end()) 8268c6d360636dee25f1ce071c3656810c6632cb89dArgyrios Kyrtzidis return I->second; // already in map; 8279260f618e72f7c70dc76312f95d679f0ed03858cNAKAMURA Takumi 8289260f618e72f7c70dc76312f95d679f0ed03858cNAKAMURA Takumi // Retrieve result at first, or the map might be updated. 8299260f618e72f7c70dc76312f95d679f0ed03858cNAKAMURA Takumi TryResult Result = evaluateAsBooleanConditionNoCache(S); 8309260f618e72f7c70dc76312f95d679f0ed03858cNAKAMURA Takumi CachedBoolEvals[S] = Result; // update or insert 8319260f618e72f7c70dc76312f95d679f0ed03858cNAKAMURA Takumi return Result; 8328c6d360636dee25f1ce071c3656810c6632cb89dArgyrios Kyrtzidis } 8333d1125b27e8006385a830f5b3748b7b44d227b4cTed Kremenek else { 8343d1125b27e8006385a830f5b3748b7b44d227b4cTed Kremenek switch (Bop->getOpcode()) { 8353d1125b27e8006385a830f5b3748b7b44d227b4cTed Kremenek default: break; 8363d1125b27e8006385a830f5b3748b7b44d227b4cTed Kremenek // For 'x & 0' and 'x * 0', we can determine that 8373d1125b27e8006385a830f5b3748b7b44d227b4cTed Kremenek // the value is always false. 8383d1125b27e8006385a830f5b3748b7b44d227b4cTed Kremenek case BO_Mul: 8393d1125b27e8006385a830f5b3748b7b44d227b4cTed Kremenek case BO_And: { 8403d1125b27e8006385a830f5b3748b7b44d227b4cTed Kremenek // If either operand is zero, we know the value 8413d1125b27e8006385a830f5b3748b7b44d227b4cTed Kremenek // must be false. 8423d1125b27e8006385a830f5b3748b7b44d227b4cTed Kremenek llvm::APSInt IntVal; 8433d1125b27e8006385a830f5b3748b7b44d227b4cTed Kremenek if (Bop->getLHS()->EvaluateAsInt(IntVal, *Context)) { 8443ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar if (!IntVal.getBoolValue()) { 8453d1125b27e8006385a830f5b3748b7b44d227b4cTed Kremenek return TryResult(false); 8463d1125b27e8006385a830f5b3748b7b44d227b4cTed Kremenek } 8473d1125b27e8006385a830f5b3748b7b44d227b4cTed Kremenek } 8483d1125b27e8006385a830f5b3748b7b44d227b4cTed Kremenek if (Bop->getRHS()->EvaluateAsInt(IntVal, *Context)) { 8493ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar if (!IntVal.getBoolValue()) { 8503d1125b27e8006385a830f5b3748b7b44d227b4cTed Kremenek return TryResult(false); 8513d1125b27e8006385a830f5b3748b7b44d227b4cTed Kremenek } 8523d1125b27e8006385a830f5b3748b7b44d227b4cTed Kremenek } 8533d1125b27e8006385a830f5b3748b7b44d227b4cTed Kremenek } 8543d1125b27e8006385a830f5b3748b7b44d227b4cTed Kremenek break; 8553d1125b27e8006385a830f5b3748b7b44d227b4cTed Kremenek } 8563d1125b27e8006385a830f5b3748b7b44d227b4cTed Kremenek } 8578c6d360636dee25f1ce071c3656810c6632cb89dArgyrios Kyrtzidis } 8588c6d360636dee25f1ce071c3656810c6632cb89dArgyrios Kyrtzidis 8598c6d360636dee25f1ce071c3656810c6632cb89dArgyrios Kyrtzidis return evaluateAsBooleanConditionNoCache(S); 8608c6d360636dee25f1ce071c3656810c6632cb89dArgyrios Kyrtzidis } 8618c6d360636dee25f1ce071c3656810c6632cb89dArgyrios Kyrtzidis 8628c6d360636dee25f1ce071c3656810c6632cb89dArgyrios Kyrtzidis /// \brief Evaluate as boolean \param E without using the cache. 8638c6d360636dee25f1ce071c3656810c6632cb89dArgyrios Kyrtzidis TryResult evaluateAsBooleanConditionNoCache(Expr *E) { 8648c6d360636dee25f1ce071c3656810c6632cb89dArgyrios Kyrtzidis if (BinaryOperator *Bop = dyn_cast<BinaryOperator>(E)) { 8658c6d360636dee25f1ce071c3656810c6632cb89dArgyrios Kyrtzidis if (Bop->isLogicalOp()) { 8668c6d360636dee25f1ce071c3656810c6632cb89dArgyrios Kyrtzidis TryResult LHS = tryEvaluateBool(Bop->getLHS()); 8678c6d360636dee25f1ce071c3656810c6632cb89dArgyrios Kyrtzidis if (LHS.isKnown()) { 8688c6d360636dee25f1ce071c3656810c6632cb89dArgyrios Kyrtzidis // We were able to evaluate the LHS, see if we can get away with not 8698c6d360636dee25f1ce071c3656810c6632cb89dArgyrios Kyrtzidis // evaluating the RHS: 0 && X -> 0, 1 || X -> 1 8708c6d360636dee25f1ce071c3656810c6632cb89dArgyrios Kyrtzidis if (LHS.isTrue() == (Bop->getOpcode() == BO_LOr)) 8718c6d360636dee25f1ce071c3656810c6632cb89dArgyrios Kyrtzidis return LHS.isTrue(); 8728c6d360636dee25f1ce071c3656810c6632cb89dArgyrios Kyrtzidis 8738c6d360636dee25f1ce071c3656810c6632cb89dArgyrios Kyrtzidis TryResult RHS = tryEvaluateBool(Bop->getRHS()); 8748c6d360636dee25f1ce071c3656810c6632cb89dArgyrios Kyrtzidis if (RHS.isKnown()) { 8758c6d360636dee25f1ce071c3656810c6632cb89dArgyrios Kyrtzidis if (Bop->getOpcode() == BO_LOr) 8768c6d360636dee25f1ce071c3656810c6632cb89dArgyrios Kyrtzidis return LHS.isTrue() || RHS.isTrue(); 8778c6d360636dee25f1ce071c3656810c6632cb89dArgyrios Kyrtzidis else 8788c6d360636dee25f1ce071c3656810c6632cb89dArgyrios Kyrtzidis return LHS.isTrue() && RHS.isTrue(); 8798c6d360636dee25f1ce071c3656810c6632cb89dArgyrios Kyrtzidis } 8808c6d360636dee25f1ce071c3656810c6632cb89dArgyrios Kyrtzidis } else { 8818c6d360636dee25f1ce071c3656810c6632cb89dArgyrios Kyrtzidis TryResult RHS = tryEvaluateBool(Bop->getRHS()); 8828c6d360636dee25f1ce071c3656810c6632cb89dArgyrios Kyrtzidis if (RHS.isKnown()) { 8838c6d360636dee25f1ce071c3656810c6632cb89dArgyrios Kyrtzidis // We can't evaluate the LHS; however, sometimes the result 8848c6d360636dee25f1ce071c3656810c6632cb89dArgyrios Kyrtzidis // is determined by the RHS: X && 0 -> 0, X || 1 -> 1. 8858c6d360636dee25f1ce071c3656810c6632cb89dArgyrios Kyrtzidis if (RHS.isTrue() == (Bop->getOpcode() == BO_LOr)) 8868c6d360636dee25f1ce071c3656810c6632cb89dArgyrios Kyrtzidis return RHS.isTrue(); 8876bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } else { 8886bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines TryResult BopRes = checkIncorrectLogicOperator(Bop); 8896bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (BopRes.isKnown()) 8906bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return BopRes.isTrue(); 8918c6d360636dee25f1ce071c3656810c6632cb89dArgyrios Kyrtzidis } 8928c6d360636dee25f1ce071c3656810c6632cb89dArgyrios Kyrtzidis } 8938c6d360636dee25f1ce071c3656810c6632cb89dArgyrios Kyrtzidis 8948c6d360636dee25f1ce071c3656810c6632cb89dArgyrios Kyrtzidis return TryResult(); 8956bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } else if (Bop->isEqualityOp()) { 8966bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines TryResult BopRes = checkIncorrectEqualityOperator(Bop); 8976bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (BopRes.isKnown()) 8986bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return BopRes.isTrue(); 8996bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } else if (Bop->isRelationalOp()) { 9006bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines TryResult BopRes = checkIncorrectRelationalOperator(Bop); 9016bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (BopRes.isKnown()) 9026bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return BopRes.isTrue(); 9038c6d360636dee25f1ce071c3656810c6632cb89dArgyrios Kyrtzidis } 9048c6d360636dee25f1ce071c3656810c6632cb89dArgyrios Kyrtzidis } 9058c6d360636dee25f1ce071c3656810c6632cb89dArgyrios Kyrtzidis 9068c6d360636dee25f1ce071c3656810c6632cb89dArgyrios Kyrtzidis bool Result; 9078c6d360636dee25f1ce071c3656810c6632cb89dArgyrios Kyrtzidis if (E->EvaluateAsBooleanCondition(Result, *Context)) 9088c6d360636dee25f1ce071c3656810c6632cb89dArgyrios Kyrtzidis return Result; 9098c6d360636dee25f1ce071c3656810c6632cb89dArgyrios Kyrtzidis 9108c6d360636dee25f1ce071c3656810c6632cb89dArgyrios Kyrtzidis return TryResult(); 91100998a068e50945118f334c98af05ed44d7c22a6Mike Stump } 912e71f3d587844110d836c82250830b27b1651afdbTed Kremenek 913d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek}; 9146d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 9150d28d360b5559abda755e50b855ba5e59727d9cdTed Kremenekinline bool AddStmtChoice::alwaysAdd(CFGBuilder &builder, 9160d28d360b5559abda755e50b855ba5e59727d9cdTed Kremenek const Stmt *stmt) const { 9170d28d360b5559abda755e50b855ba5e59727d9cdTed Kremenek return builder.alwaysAdd(stmt) || kind == AlwaysAdd; 9180d28d360b5559abda755e50b855ba5e59727d9cdTed Kremenek} 919a8d459e8a68b1270b0c35fb73e8cc090b2b69e36Ted Kremenek 9200d28d360b5559abda755e50b855ba5e59727d9cdTed Kremenekbool CFGBuilder::alwaysAdd(const Stmt *stmt) { 92174fb1a493cf5d2dd0fb51a4eadf74e85e10a3457Ted Kremenek bool shouldAdd = BuildOpts.alwaysAdd(stmt); 92274fb1a493cf5d2dd0fb51a4eadf74e85e10a3457Ted Kremenek 9230d28d360b5559abda755e50b855ba5e59727d9cdTed Kremenek if (!BuildOpts.forcedBlkExprs) 92474fb1a493cf5d2dd0fb51a4eadf74e85e10a3457Ted Kremenek return shouldAdd; 925a8d459e8a68b1270b0c35fb73e8cc090b2b69e36Ted Kremenek 926a8d459e8a68b1270b0c35fb73e8cc090b2b69e36Ted Kremenek if (lastLookup == stmt) { 927a8d459e8a68b1270b0c35fb73e8cc090b2b69e36Ted Kremenek if (cachedEntry) { 928a8d459e8a68b1270b0c35fb73e8cc090b2b69e36Ted Kremenek assert(cachedEntry->first == stmt); 929a8d459e8a68b1270b0c35fb73e8cc090b2b69e36Ted Kremenek return true; 930a8d459e8a68b1270b0c35fb73e8cc090b2b69e36Ted Kremenek } 93174fb1a493cf5d2dd0fb51a4eadf74e85e10a3457Ted Kremenek return shouldAdd; 932a8d459e8a68b1270b0c35fb73e8cc090b2b69e36Ted Kremenek } 9330d28d360b5559abda755e50b855ba5e59727d9cdTed Kremenek 934a8d459e8a68b1270b0c35fb73e8cc090b2b69e36Ted Kremenek lastLookup = stmt; 935a8d459e8a68b1270b0c35fb73e8cc090b2b69e36Ted Kremenek 936a8d459e8a68b1270b0c35fb73e8cc090b2b69e36Ted Kremenek // Perform the lookup! 9370d28d360b5559abda755e50b855ba5e59727d9cdTed Kremenek CFG::BuildOptions::ForcedBlkExprs *fb = *BuildOpts.forcedBlkExprs; 9380d28d360b5559abda755e50b855ba5e59727d9cdTed Kremenek 939a8d459e8a68b1270b0c35fb73e8cc090b2b69e36Ted Kremenek if (!fb) { 940a8d459e8a68b1270b0c35fb73e8cc090b2b69e36Ted Kremenek // No need to update 'cachedEntry', since it will always be null. 9416bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines assert(!cachedEntry); 94274fb1a493cf5d2dd0fb51a4eadf74e85e10a3457Ted Kremenek return shouldAdd; 943a8d459e8a68b1270b0c35fb73e8cc090b2b69e36Ted Kremenek } 9440d28d360b5559abda755e50b855ba5e59727d9cdTed Kremenek 9450d28d360b5559abda755e50b855ba5e59727d9cdTed Kremenek CFG::BuildOptions::ForcedBlkExprs::iterator itr = fb->find(stmt); 946a8d459e8a68b1270b0c35fb73e8cc090b2b69e36Ted Kremenek if (itr == fb->end()) { 9476bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines cachedEntry = nullptr; 94874fb1a493cf5d2dd0fb51a4eadf74e85e10a3457Ted Kremenek return shouldAdd; 949a8d459e8a68b1270b0c35fb73e8cc090b2b69e36Ted Kremenek } 950a8d459e8a68b1270b0c35fb73e8cc090b2b69e36Ted Kremenek 9510d28d360b5559abda755e50b855ba5e59727d9cdTed Kremenek cachedEntry = &*itr; 9520d28d360b5559abda755e50b855ba5e59727d9cdTed Kremenek return true; 9533179a45a0e91c1dcf3492222170cf4499531bb92Ted Kremenek} 9543179a45a0e91c1dcf3492222170cf4499531bb92Ted Kremenek 955898574e7496ba8fd76290079d3a9d06954992734Douglas Gregor// FIXME: Add support for dependent-sized array types in C++? 956898574e7496ba8fd76290079d3a9d06954992734Douglas Gregor// Does it even make sense to build a CFG for an uninstantiated template? 957f4c7371fb1d3cebcfb40abad4537bb82515704eaJohn McCallstatic const VariableArrayType *FindVA(const Type *t) { 958f4c7371fb1d3cebcfb40abad4537bb82515704eaJohn McCall while (const ArrayType *vt = dyn_cast<ArrayType>(t)) { 959f4c7371fb1d3cebcfb40abad4537bb82515704eaJohn McCall if (const VariableArrayType *vat = dyn_cast<VariableArrayType>(vt)) 960610a09e409bea151a42dd907768f1e0c4b103f1fTed Kremenek if (vat->getSizeExpr()) 961610a09e409bea151a42dd907768f1e0c4b103f1fTed Kremenek return vat; 9626d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 963610a09e409bea151a42dd907768f1e0c4b103f1fTed Kremenek t = vt->getElementType().getTypePtr(); 964610a09e409bea151a42dd907768f1e0c4b103f1fTed Kremenek } 9656d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 9666bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return nullptr; 967610a09e409bea151a42dd907768f1e0c4b103f1fTed Kremenek} 9686d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 9696d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump/// BuildCFG - Constructs a CFG from an AST (a Stmt*). The AST can represent an 9706d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump/// arbitrary statement. Examples include a single expression or a function 9716d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump/// body (compound statement). The ownership of the returned CFG is 9726d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump/// transferred to the caller. If CFG construction fails, this method returns 9736d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump/// NULL. 974176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hinesstd::unique_ptr<CFG> CFGBuilder::buildCFG(const Decl *D, Stmt *Statement) { 9750ba497be27170c2a23c0217366f97eeecefa1ed8Ted Kremenek assert(cfg.get()); 9764f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek if (!Statement) 9776bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return nullptr; 978d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek 9796d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump // Create an empty block that will serve as the exit block for the CFG. Since 9806d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump // this is the first block added to the CFG, it will be implicitly registered 9816d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump // as the exit block. 98249af7cb8a3aca79783e7a0708b97a8f856f0da22Ted Kremenek Succ = createBlock(); 983ee82d9bdc5025b82de8ce2a4ad4685e0a8b79da9Ted Kremenek assert(Succ == &cfg->getExit()); 9846bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines Block = nullptr; // the EXIT block is empty. Create all other blocks lazily. 9856d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 9867c625d8ffc20b92fff9e1690cd2484fcb6498183Marcin Swiderski if (BuildOpts.AddImplicitDtors) 9877c625d8ffc20b92fff9e1690cd2484fcb6498183Marcin Swiderski if (const CXXDestructorDecl *DD = dyn_cast_or_null<CXXDestructorDecl>(D)) 9887c625d8ffc20b92fff9e1690cd2484fcb6498183Marcin Swiderski addImplicitDtorsForDestructor(DD); 9897c625d8ffc20b92fff9e1690cd2484fcb6498183Marcin Swiderski 990d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek // Visit the statements and create the CFG. 9911b3b7cb15cbd02b7283bbf3ce7c0e9b0da30ef9dZhongxing Xu CFGBlock *B = addStmt(Statement); 9921b3b7cb15cbd02b7283bbf3ce7c0e9b0da30ef9dZhongxing Xu 9931b3b7cb15cbd02b7283bbf3ce7c0e9b0da30ef9dZhongxing Xu if (badCFG) 9946bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return nullptr; 9951b3b7cb15cbd02b7283bbf3ce7c0e9b0da30ef9dZhongxing Xu 99682bc3fd823d85ee3ef9a641c0975b6ad25f55047Marcin Swiderski // For C++ constructor add initializers to CFG. 997b978a441c7d8bf59e7fede938e1f3b672573b443Mike Stump if (const CXXConstructorDecl *CD = dyn_cast_or_null<CXXConstructorDecl>(D)) { 99882bc3fd823d85ee3ef9a641c0975b6ad25f55047Marcin Swiderski for (CXXConstructorDecl::init_const_reverse_iterator I = CD->init_rbegin(), 99982bc3fd823d85ee3ef9a641c0975b6ad25f55047Marcin Swiderski E = CD->init_rend(); I != E; ++I) { 100082bc3fd823d85ee3ef9a641c0975b6ad25f55047Marcin Swiderski B = addInitializer(*I); 100182bc3fd823d85ee3ef9a641c0975b6ad25f55047Marcin Swiderski if (badCFG) 10026bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return nullptr; 100382bc3fd823d85ee3ef9a641c0975b6ad25f55047Marcin Swiderski } 1004b978a441c7d8bf59e7fede938e1f3b672573b443Mike Stump } 10056d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 100682bc3fd823d85ee3ef9a641c0975b6ad25f55047Marcin Swiderski if (B) 100782bc3fd823d85ee3ef9a641c0975b6ad25f55047Marcin Swiderski Succ = B; 100882bc3fd823d85ee3ef9a641c0975b6ad25f55047Marcin Swiderski 10091b3b7cb15cbd02b7283bbf3ce7c0e9b0da30ef9dZhongxing Xu // Backpatch the gotos whose label -> block mappings we didn't know when we 10101b3b7cb15cbd02b7283bbf3ce7c0e9b0da30ef9dZhongxing Xu // encountered them. 10111b3b7cb15cbd02b7283bbf3ce7c0e9b0da30ef9dZhongxing Xu for (BackpatchBlocksTy::iterator I = BackpatchBlocks.begin(), 10121b3b7cb15cbd02b7283bbf3ce7c0e9b0da30ef9dZhongxing Xu E = BackpatchBlocks.end(); I != E; ++I ) { 1013c3daac59e26b63c08208de2fbaceb1ff01be3492Daniel Dunbar 10149c378f705405d37f49795d5e915989de774fe11fTed Kremenek CFGBlock *B = I->block; 10158343f8e00a222ca09dde536c77313e3e6e03ad59Rafael Espindola const GotoStmt *G = cast<GotoStmt>(B->getTerminator()); 10161b3b7cb15cbd02b7283bbf3ce7c0e9b0da30ef9dZhongxing Xu LabelMapTy::iterator LI = LabelMap.find(G->getLabel()); 10176d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 10181b3b7cb15cbd02b7283bbf3ce7c0e9b0da30ef9dZhongxing Xu // If there is no target for the goto, then we are looking at an 10191b3b7cb15cbd02b7283bbf3ce7c0e9b0da30ef9dZhongxing Xu // incomplete AST. Handle this by not registering a successor. 10201b3b7cb15cbd02b7283bbf3ce7c0e9b0da30ef9dZhongxing Xu if (LI == LabelMap.end()) continue; 1021d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek 1022f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski JumpTarget JT = LI->second; 10239ce5270f0aadaaf03a0cf705787f42ce9eb1194cTed Kremenek prependAutomaticObjDtorsWithTerminator(B, I->scopePosition, 10249ce5270f0aadaaf03a0cf705787f42ce9eb1194cTed Kremenek JT.scopePosition); 10259ce5270f0aadaaf03a0cf705787f42ce9eb1194cTed Kremenek addSuccessor(B, JT.block); 10261b3b7cb15cbd02b7283bbf3ce7c0e9b0da30ef9dZhongxing Xu } 10276d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 10281b3b7cb15cbd02b7283bbf3ce7c0e9b0da30ef9dZhongxing Xu // Add successors to the Indirect Goto Dispatch block (if we have one). 10299c378f705405d37f49795d5e915989de774fe11fTed Kremenek if (CFGBlock *B = cfg->getIndirectGotoBlock()) 10301b3b7cb15cbd02b7283bbf3ce7c0e9b0da30ef9dZhongxing Xu for (LabelSetTy::iterator I = AddressTakenLabels.begin(), 10311b3b7cb15cbd02b7283bbf3ce7c0e9b0da30ef9dZhongxing Xu E = AddressTakenLabels.end(); I != E; ++I ) { 10321b3b7cb15cbd02b7283bbf3ce7c0e9b0da30ef9dZhongxing Xu 10331b3b7cb15cbd02b7283bbf3ce7c0e9b0da30ef9dZhongxing Xu // Lookup the target block. 10341b3b7cb15cbd02b7283bbf3ce7c0e9b0da30ef9dZhongxing Xu LabelMapTy::iterator LI = LabelMap.find(*I); 10351b3b7cb15cbd02b7283bbf3ce7c0e9b0da30ef9dZhongxing Xu 10361b3b7cb15cbd02b7283bbf3ce7c0e9b0da30ef9dZhongxing Xu // If there is no target block that contains label, then we are looking 10371b3b7cb15cbd02b7283bbf3ce7c0e9b0da30ef9dZhongxing Xu // at an incomplete AST. Handle this by not registering a successor. 10381b3b7cb15cbd02b7283bbf3ce7c0e9b0da30ef9dZhongxing Xu if (LI == LabelMap.end()) continue; 10391b3b7cb15cbd02b7283bbf3ce7c0e9b0da30ef9dZhongxing Xu 10409ce5270f0aadaaf03a0cf705787f42ce9eb1194cTed Kremenek addSuccessor(B, LI->second.block); 1041c3daac59e26b63c08208de2fbaceb1ff01be3492Daniel Dunbar } 10426d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 10436d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump // Create an empty entry block that has no predecessors. 1044322f58d3830da13b419646c071e3ab801518a09cTed Kremenek cfg->setEntry(createBlock()); 10456d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 1046176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines return std::move(cfg); 1047d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek} 10486d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 1049d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek/// createBlock - Used to lazily create blocks that are connected 1050d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek/// to the current (global) succcessor. 10519c378f705405d37f49795d5e915989de774fe11fTed KremenekCFGBlock *CFGBuilder::createBlock(bool add_successor) { 10529c378f705405d37f49795d5e915989de774fe11fTed Kremenek CFGBlock *B = cfg->createBlock(); 10534f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek if (add_successor && Succ) 10540a3ed3143b00f237decb1288c1ff574ae09eba4eTed Kremenek addSuccessor(B, Succ); 1055d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek return B; 1056d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek} 10576d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 1058dba3fb5413437dc613734fa4ffac892b11a37d25Chandler Carruth/// createNoReturnBlock - Used to create a block is a 'noreturn' point in the 1059dba3fb5413437dc613734fa4ffac892b11a37d25Chandler Carruth/// CFG. It is *not* connected to the current (global) successor, and instead 1060dba3fb5413437dc613734fa4ffac892b11a37d25Chandler Carruth/// directly tied to the exit block in order to be reachable. 1061dba3fb5413437dc613734fa4ffac892b11a37d25Chandler CarruthCFGBlock *CFGBuilder::createNoReturnBlock() { 1062dba3fb5413437dc613734fa4ffac892b11a37d25Chandler Carruth CFGBlock *B = createBlock(false); 106383754162f698a5dafad93fb89be0953651a604d0Chandler Carruth B->setHasNoReturnElement(); 1064651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines addSuccessor(B, &cfg->getExit(), Succ); 1065dba3fb5413437dc613734fa4ffac892b11a37d25Chandler Carruth return B; 1066dba3fb5413437dc613734fa4ffac892b11a37d25Chandler Carruth} 1067dba3fb5413437dc613734fa4ffac892b11a37d25Chandler Carruth 106882bc3fd823d85ee3ef9a641c0975b6ad25f55047Marcin Swiderski/// addInitializer - Add C++ base or member initializer element to CFG. 1069cbb67480094b3bcb5b715acd827cbad55e2a204cSean HuntCFGBlock *CFGBuilder::addInitializer(CXXCtorInitializer *I) { 107082bc3fd823d85ee3ef9a641c0975b6ad25f55047Marcin Swiderski if (!BuildOpts.AddInitializers) 107182bc3fd823d85ee3ef9a641c0975b6ad25f55047Marcin Swiderski return Block; 107282bc3fd823d85ee3ef9a641c0975b6ad25f55047Marcin Swiderski 10738599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski bool HasTemporaries = false; 107482bc3fd823d85ee3ef9a641c0975b6ad25f55047Marcin Swiderski 10758599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski // Destructors of temporaries in initialization expression should be called 10768599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski // after initialization finishes. 10778599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski Expr *Init = I->getInit(); 10788599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski if (Init) { 10794765fa05b5652fcc4356371c2f481d0ea9a1b007John McCall HasTemporaries = isa<ExprWithCleanups>(Init); 108082bc3fd823d85ee3ef9a641c0975b6ad25f55047Marcin Swiderski 10815a1ffe98b04120846a15f7105905b5f363b08635Jordan Rose if (BuildOpts.AddTemporaryDtors && HasTemporaries) { 10828599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski // Generate destructors for temporaries in initialization expression. 1083176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines TempDtorContext Context; 10844765fa05b5652fcc4356371c2f481d0ea9a1b007John McCall VisitForTemporaryDtors(cast<ExprWithCleanups>(Init)->getSubExpr(), 1085176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines /*BindToTemporary=*/false, Context); 10868599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski } 108782bc3fd823d85ee3ef9a641c0975b6ad25f55047Marcin Swiderski } 10888599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski 10898599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski autoCreateBlock(); 10908599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski appendInitializer(Block, I); 10918599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski 10928599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski if (Init) { 1093892697dd2287caf7c29aaaa82909b0e90b8b63feTed Kremenek if (HasTemporaries) { 10948599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski // For expression with temporaries go directly to subexpression to omit 10958599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski // generating destructors for the second time. 1096892697dd2287caf7c29aaaa82909b0e90b8b63feTed Kremenek return Visit(cast<ExprWithCleanups>(Init)->getSubExpr()); 1097892697dd2287caf7c29aaaa82909b0e90b8b63feTed Kremenek } 1098892697dd2287caf7c29aaaa82909b0e90b8b63feTed Kremenek return Visit(Init); 10998599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski } 11008599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski 110182bc3fd823d85ee3ef9a641c0975b6ad25f55047Marcin Swiderski return Block; 110282bc3fd823d85ee3ef9a641c0975b6ad25f55047Marcin Swiderski} 110382bc3fd823d85ee3ef9a641c0975b6ad25f55047Marcin Swiderski 11042d9eb21325a0854e86de7344f54a8e6cef2a97adDouglas Gregor/// \brief Retrieve the type of the temporary object whose lifetime was 11052d9eb21325a0854e86de7344f54a8e6cef2a97adDouglas Gregor/// extended by a local reference with the given initializer. 11062d9eb21325a0854e86de7344f54a8e6cef2a97adDouglas Gregorstatic QualType getReferenceInitTemporaryType(ASTContext &Context, 11072d9eb21325a0854e86de7344f54a8e6cef2a97adDouglas Gregor const Expr *Init) { 11082d9eb21325a0854e86de7344f54a8e6cef2a97adDouglas Gregor while (true) { 11092d9eb21325a0854e86de7344f54a8e6cef2a97adDouglas Gregor // Skip parentheses. 11102d9eb21325a0854e86de7344f54a8e6cef2a97adDouglas Gregor Init = Init->IgnoreParens(); 11112d9eb21325a0854e86de7344f54a8e6cef2a97adDouglas Gregor 11122d9eb21325a0854e86de7344f54a8e6cef2a97adDouglas Gregor // Skip through cleanups. 11132d9eb21325a0854e86de7344f54a8e6cef2a97adDouglas Gregor if (const ExprWithCleanups *EWC = dyn_cast<ExprWithCleanups>(Init)) { 11142d9eb21325a0854e86de7344f54a8e6cef2a97adDouglas Gregor Init = EWC->getSubExpr(); 11152d9eb21325a0854e86de7344f54a8e6cef2a97adDouglas Gregor continue; 11162d9eb21325a0854e86de7344f54a8e6cef2a97adDouglas Gregor } 11172d9eb21325a0854e86de7344f54a8e6cef2a97adDouglas Gregor 11182d9eb21325a0854e86de7344f54a8e6cef2a97adDouglas Gregor // Skip through the temporary-materialization expression. 11192d9eb21325a0854e86de7344f54a8e6cef2a97adDouglas Gregor if (const MaterializeTemporaryExpr *MTE 11202d9eb21325a0854e86de7344f54a8e6cef2a97adDouglas Gregor = dyn_cast<MaterializeTemporaryExpr>(Init)) { 11212d9eb21325a0854e86de7344f54a8e6cef2a97adDouglas Gregor Init = MTE->GetTemporaryExpr(); 11222d9eb21325a0854e86de7344f54a8e6cef2a97adDouglas Gregor continue; 11232d9eb21325a0854e86de7344f54a8e6cef2a97adDouglas Gregor } 11242d9eb21325a0854e86de7344f54a8e6cef2a97adDouglas Gregor 11252d9eb21325a0854e86de7344f54a8e6cef2a97adDouglas Gregor // Skip derived-to-base and no-op casts. 11262d9eb21325a0854e86de7344f54a8e6cef2a97adDouglas Gregor if (const CastExpr *CE = dyn_cast<CastExpr>(Init)) { 11272d9eb21325a0854e86de7344f54a8e6cef2a97adDouglas Gregor if ((CE->getCastKind() == CK_DerivedToBase || 11282d9eb21325a0854e86de7344f54a8e6cef2a97adDouglas Gregor CE->getCastKind() == CK_UncheckedDerivedToBase || 11292d9eb21325a0854e86de7344f54a8e6cef2a97adDouglas Gregor CE->getCastKind() == CK_NoOp) && 11302d9eb21325a0854e86de7344f54a8e6cef2a97adDouglas Gregor Init->getType()->isRecordType()) { 11312d9eb21325a0854e86de7344f54a8e6cef2a97adDouglas Gregor Init = CE->getSubExpr(); 11322d9eb21325a0854e86de7344f54a8e6cef2a97adDouglas Gregor continue; 11332d9eb21325a0854e86de7344f54a8e6cef2a97adDouglas Gregor } 11342d9eb21325a0854e86de7344f54a8e6cef2a97adDouglas Gregor } 11352d9eb21325a0854e86de7344f54a8e6cef2a97adDouglas Gregor 11362d9eb21325a0854e86de7344f54a8e6cef2a97adDouglas Gregor // Skip member accesses into rvalues. 11372d9eb21325a0854e86de7344f54a8e6cef2a97adDouglas Gregor if (const MemberExpr *ME = dyn_cast<MemberExpr>(Init)) { 11382d9eb21325a0854e86de7344f54a8e6cef2a97adDouglas Gregor if (!ME->isArrow() && ME->getBase()->isRValue()) { 11392d9eb21325a0854e86de7344f54a8e6cef2a97adDouglas Gregor Init = ME->getBase(); 11402d9eb21325a0854e86de7344f54a8e6cef2a97adDouglas Gregor continue; 11412d9eb21325a0854e86de7344f54a8e6cef2a97adDouglas Gregor } 11422d9eb21325a0854e86de7344f54a8e6cef2a97adDouglas Gregor } 11432d9eb21325a0854e86de7344f54a8e6cef2a97adDouglas Gregor 11442d9eb21325a0854e86de7344f54a8e6cef2a97adDouglas Gregor break; 11452d9eb21325a0854e86de7344f54a8e6cef2a97adDouglas Gregor } 11462d9eb21325a0854e86de7344f54a8e6cef2a97adDouglas Gregor 11472d9eb21325a0854e86de7344f54a8e6cef2a97adDouglas Gregor return Init->getType(); 11482d9eb21325a0854e86de7344f54a8e6cef2a97adDouglas Gregor} 11492d9eb21325a0854e86de7344f54a8e6cef2a97adDouglas Gregor 1150239a7c42df78abc7fd5611d806d5e199fec994d1Marcin Swiderski/// addAutomaticObjDtors - Add to current block automatic objects destructors 1151239a7c42df78abc7fd5611d806d5e199fec994d1Marcin Swiderski/// for objects in range of local scope positions. Use S as trigger statement 1152239a7c42df78abc7fd5611d806d5e199fec994d1Marcin Swiderski/// for destructors. 11536a16a306f6226030f8d38ae7e32082888fa937a1Zhongxing Xuvoid CFGBuilder::addAutomaticObjDtors(LocalScope::const_iterator B, 11549c378f705405d37f49795d5e915989de774fe11fTed Kremenek LocalScope::const_iterator E, Stmt *S) { 1155239a7c42df78abc7fd5611d806d5e199fec994d1Marcin Swiderski if (!BuildOpts.AddImplicitDtors) 11566a16a306f6226030f8d38ae7e32082888fa937a1Zhongxing Xu return; 11576a16a306f6226030f8d38ae7e32082888fa937a1Zhongxing Xu 1158239a7c42df78abc7fd5611d806d5e199fec994d1Marcin Swiderski if (B == E) 11596a16a306f6226030f8d38ae7e32082888fa937a1Zhongxing Xu return; 1160239a7c42df78abc7fd5611d806d5e199fec994d1Marcin Swiderski 1161c8cfc74bdcc999828bc232294d937fb191940d5bChandler Carruth // We need to append the destructors in reverse order, but any one of them 1162c8cfc74bdcc999828bc232294d937fb191940d5bChandler Carruth // may be a no-return destructor which changes the CFG. As a result, buffer 1163c8cfc74bdcc999828bc232294d937fb191940d5bChandler Carruth // this sequence up and replay them in reverse order when appending onto the 1164c8cfc74bdcc999828bc232294d937fb191940d5bChandler Carruth // CFGBlock(s). 1165c8cfc74bdcc999828bc232294d937fb191940d5bChandler Carruth SmallVector<VarDecl*, 10> Decls; 1166c8cfc74bdcc999828bc232294d937fb191940d5bChandler Carruth Decls.reserve(B.distance(E)); 1167c8cfc74bdcc999828bc232294d937fb191940d5bChandler Carruth for (LocalScope::const_iterator I = B; I != E; ++I) 1168c8cfc74bdcc999828bc232294d937fb191940d5bChandler Carruth Decls.push_back(*I); 1169c8cfc74bdcc999828bc232294d937fb191940d5bChandler Carruth 1170c8cfc74bdcc999828bc232294d937fb191940d5bChandler Carruth for (SmallVectorImpl<VarDecl*>::reverse_iterator I = Decls.rbegin(), 1171c8cfc74bdcc999828bc232294d937fb191940d5bChandler Carruth E = Decls.rend(); 1172c8cfc74bdcc999828bc232294d937fb191940d5bChandler Carruth I != E; ++I) { 1173c8cfc74bdcc999828bc232294d937fb191940d5bChandler Carruth // If this destructor is marked as a no-return destructor, we need to 1174c8cfc74bdcc999828bc232294d937fb191940d5bChandler Carruth // create a new block for the destructor which does not have as a successor 1175c8cfc74bdcc999828bc232294d937fb191940d5bChandler Carruth // anything built thus far: control won't flow out of this block. 117688237bf587581026dcfc8386abf055cb201aa487Ted Kremenek QualType Ty = (*I)->getType(); 117788237bf587581026dcfc8386abf055cb201aa487Ted Kremenek if (Ty->isReferenceType()) { 11782d9eb21325a0854e86de7344f54a8e6cef2a97adDouglas Gregor Ty = getReferenceInitTemporaryType(*Context, (*I)->getInit()); 11792d9eb21325a0854e86de7344f54a8e6cef2a97adDouglas Gregor } 118088237bf587581026dcfc8386abf055cb201aa487Ted Kremenek Ty = Context->getBaseElementType(Ty); 118188237bf587581026dcfc8386abf055cb201aa487Ted Kremenek 1182c8cfc74bdcc999828bc232294d937fb191940d5bChandler Carruth const CXXDestructorDecl *Dtor = Ty->getAsCXXRecordDecl()->getDestructor(); 1183cd8ab51a44e80625d84126780b0d85a7732e25afRichard Smith if (Dtor->isNoReturn()) 1184dba3fb5413437dc613734fa4ffac892b11a37d25Chandler Carruth Block = createNoReturnBlock(); 1185dba3fb5413437dc613734fa4ffac892b11a37d25Chandler Carruth else 1186c8cfc74bdcc999828bc232294d937fb191940d5bChandler Carruth autoCreateBlock(); 1187c8cfc74bdcc999828bc232294d937fb191940d5bChandler Carruth 1188c8cfc74bdcc999828bc232294d937fb191940d5bChandler Carruth appendAutomaticObjDtor(Block, *I, S); 1189c8cfc74bdcc999828bc232294d937fb191940d5bChandler Carruth } 1190239a7c42df78abc7fd5611d806d5e199fec994d1Marcin Swiderski} 1191239a7c42df78abc7fd5611d806d5e199fec994d1Marcin Swiderski 11927c625d8ffc20b92fff9e1690cd2484fcb6498183Marcin Swiderski/// addImplicitDtorsForDestructor - Add implicit destructors generated for 11937c625d8ffc20b92fff9e1690cd2484fcb6498183Marcin Swiderski/// base and member objects in destructor. 11947c625d8ffc20b92fff9e1690cd2484fcb6498183Marcin Swiderskivoid CFGBuilder::addImplicitDtorsForDestructor(const CXXDestructorDecl *DD) { 11957c625d8ffc20b92fff9e1690cd2484fcb6498183Marcin Swiderski assert (BuildOpts.AddImplicitDtors 11967c625d8ffc20b92fff9e1690cd2484fcb6498183Marcin Swiderski && "Can be called only when dtors should be added"); 11977c625d8ffc20b92fff9e1690cd2484fcb6498183Marcin Swiderski const CXXRecordDecl *RD = DD->getParent(); 11987c625d8ffc20b92fff9e1690cd2484fcb6498183Marcin Swiderski 11997c625d8ffc20b92fff9e1690cd2484fcb6498183Marcin Swiderski // At the end destroy virtual base objects. 1200651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines for (const auto &VI : RD->vbases()) { 1201651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines const CXXRecordDecl *CD = VI.getType()->getAsCXXRecordDecl(); 12027c625d8ffc20b92fff9e1690cd2484fcb6498183Marcin Swiderski if (!CD->hasTrivialDestructor()) { 12037c625d8ffc20b92fff9e1690cd2484fcb6498183Marcin Swiderski autoCreateBlock(); 1204651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines appendBaseDtor(Block, &VI); 12057c625d8ffc20b92fff9e1690cd2484fcb6498183Marcin Swiderski } 12067c625d8ffc20b92fff9e1690cd2484fcb6498183Marcin Swiderski } 12077c625d8ffc20b92fff9e1690cd2484fcb6498183Marcin Swiderski 12087c625d8ffc20b92fff9e1690cd2484fcb6498183Marcin Swiderski // Before virtual bases destroy direct base objects. 1209651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines for (const auto &BI : RD->bases()) { 1210651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (!BI.isVirtual()) { 1211651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines const CXXRecordDecl *CD = BI.getType()->getAsCXXRecordDecl(); 121223661d3e348c5f44ae89b6848bbc331829bb46f2David Blaikie if (!CD->hasTrivialDestructor()) { 121323661d3e348c5f44ae89b6848bbc331829bb46f2David Blaikie autoCreateBlock(); 1214651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines appendBaseDtor(Block, &BI); 121523661d3e348c5f44ae89b6848bbc331829bb46f2David Blaikie } 121623661d3e348c5f44ae89b6848bbc331829bb46f2David Blaikie } 12177c625d8ffc20b92fff9e1690cd2484fcb6498183Marcin Swiderski } 12187c625d8ffc20b92fff9e1690cd2484fcb6498183Marcin Swiderski 12197c625d8ffc20b92fff9e1690cd2484fcb6498183Marcin Swiderski // First destroy member objects. 1220651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines for (auto *FI : RD->fields()) { 12218c5e5d6d8a316af5a9842169f541cac49717887dMarcin Swiderski // Check for constant size array. Set type to array element type. 12228c5e5d6d8a316af5a9842169f541cac49717887dMarcin Swiderski QualType QT = FI->getType(); 12238c5e5d6d8a316af5a9842169f541cac49717887dMarcin Swiderski if (const ConstantArrayType *AT = Context->getAsConstantArrayType(QT)) { 12248c5e5d6d8a316af5a9842169f541cac49717887dMarcin Swiderski if (AT->getSize() == 0) 12258c5e5d6d8a316af5a9842169f541cac49717887dMarcin Swiderski continue; 12268c5e5d6d8a316af5a9842169f541cac49717887dMarcin Swiderski QT = AT->getElementType(); 12278c5e5d6d8a316af5a9842169f541cac49717887dMarcin Swiderski } 12288c5e5d6d8a316af5a9842169f541cac49717887dMarcin Swiderski 12298c5e5d6d8a316af5a9842169f541cac49717887dMarcin Swiderski if (const CXXRecordDecl *CD = QT->getAsCXXRecordDecl()) 12307c625d8ffc20b92fff9e1690cd2484fcb6498183Marcin Swiderski if (!CD->hasTrivialDestructor()) { 12317c625d8ffc20b92fff9e1690cd2484fcb6498183Marcin Swiderski autoCreateBlock(); 1232651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines appendMemberDtor(Block, FI); 12337c625d8ffc20b92fff9e1690cd2484fcb6498183Marcin Swiderski } 12347c625d8ffc20b92fff9e1690cd2484fcb6498183Marcin Swiderski } 12357c625d8ffc20b92fff9e1690cd2484fcb6498183Marcin Swiderski} 12367c625d8ffc20b92fff9e1690cd2484fcb6498183Marcin Swiderski 1237239a7c42df78abc7fd5611d806d5e199fec994d1Marcin Swiderski/// createOrReuseLocalScope - If Scope is NULL create new LocalScope. Either 1238239a7c42df78abc7fd5611d806d5e199fec994d1Marcin Swiderski/// way return valid LocalScope object. 1239239a7c42df78abc7fd5611d806d5e199fec994d1Marcin SwiderskiLocalScope* CFGBuilder::createOrReuseLocalScope(LocalScope* Scope) { 1240239a7c42df78abc7fd5611d806d5e199fec994d1Marcin Swiderski if (!Scope) { 1241fe59b7472c06b36efb74fbb50bbdf464fa30c0d8Ted Kremenek llvm::BumpPtrAllocator &alloc = cfg->getAllocator(); 1242fe59b7472c06b36efb74fbb50bbdf464fa30c0d8Ted Kremenek Scope = alloc.Allocate<LocalScope>(); 1243fe59b7472c06b36efb74fbb50bbdf464fa30c0d8Ted Kremenek BumpVectorContext ctx(alloc); 1244fe59b7472c06b36efb74fbb50bbdf464fa30c0d8Ted Kremenek new (Scope) LocalScope(ctx, ScopePos); 1245239a7c42df78abc7fd5611d806d5e199fec994d1Marcin Swiderski } 1246239a7c42df78abc7fd5611d806d5e199fec994d1Marcin Swiderski return Scope; 1247239a7c42df78abc7fd5611d806d5e199fec994d1Marcin Swiderski} 1248239a7c42df78abc7fd5611d806d5e199fec994d1Marcin Swiderski 1249239a7c42df78abc7fd5611d806d5e199fec994d1Marcin Swiderski/// addLocalScopeForStmt - Add LocalScope to local scopes tree for statement 125002acdfaeb3f3805b65e4707e5dff096209adb367Zhongxing Xu/// that should create implicit scope (e.g. if/else substatements). 12519c378f705405d37f49795d5e915989de774fe11fTed Kremenekvoid CFGBuilder::addLocalScopeForStmt(Stmt *S) { 1252239a7c42df78abc7fd5611d806d5e199fec994d1Marcin Swiderski if (!BuildOpts.AddImplicitDtors) 125302acdfaeb3f3805b65e4707e5dff096209adb367Zhongxing Xu return; 125402acdfaeb3f3805b65e4707e5dff096209adb367Zhongxing Xu 12556bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines LocalScope *Scope = nullptr; 1256239a7c42df78abc7fd5611d806d5e199fec994d1Marcin Swiderski 1257239a7c42df78abc7fd5611d806d5e199fec994d1Marcin Swiderski // For compound statement we will be creating explicit scope. 1258ad8dcf4a9df0e24051dc31bf9e6f3cd138a34298Chris Lattner if (CompoundStmt *CS = dyn_cast<CompoundStmt>(S)) { 1259651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines for (auto *BI : CS->body()) { 1260651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Stmt *SI = BI->stripLabelLikeStatements(); 1261ad8dcf4a9df0e24051dc31bf9e6f3cd138a34298Chris Lattner if (DeclStmt *DS = dyn_cast<DeclStmt>(SI)) 1262239a7c42df78abc7fd5611d806d5e199fec994d1Marcin Swiderski Scope = addLocalScopeForDeclStmt(DS, Scope); 1263239a7c42df78abc7fd5611d806d5e199fec994d1Marcin Swiderski } 126402acdfaeb3f3805b65e4707e5dff096209adb367Zhongxing Xu return; 1265239a7c42df78abc7fd5611d806d5e199fec994d1Marcin Swiderski } 1266239a7c42df78abc7fd5611d806d5e199fec994d1Marcin Swiderski 1267239a7c42df78abc7fd5611d806d5e199fec994d1Marcin Swiderski // For any other statement scope will be implicit and as such will be 1268239a7c42df78abc7fd5611d806d5e199fec994d1Marcin Swiderski // interesting only for DeclStmt. 1269a1364be341550d71dff27dd8de0c6872ba6c707eChandler Carruth if (DeclStmt *DS = dyn_cast<DeclStmt>(S->stripLabelLikeStatements())) 1270b6edff55db4ff240d56d33594d68a711e4b1e24aZhongxing Xu addLocalScopeForDeclStmt(DS); 1271239a7c42df78abc7fd5611d806d5e199fec994d1Marcin Swiderski} 1272239a7c42df78abc7fd5611d806d5e199fec994d1Marcin Swiderski 1273239a7c42df78abc7fd5611d806d5e199fec994d1Marcin Swiderski/// addLocalScopeForDeclStmt - Add LocalScope for declaration statement. Will 1274239a7c42df78abc7fd5611d806d5e199fec994d1Marcin Swiderski/// reuse Scope if not NULL. 12759c378f705405d37f49795d5e915989de774fe11fTed KremenekLocalScope* CFGBuilder::addLocalScopeForDeclStmt(DeclStmt *DS, 1276b6edff55db4ff240d56d33594d68a711e4b1e24aZhongxing Xu LocalScope* Scope) { 1277239a7c42df78abc7fd5611d806d5e199fec994d1Marcin Swiderski if (!BuildOpts.AddImplicitDtors) 1278239a7c42df78abc7fd5611d806d5e199fec994d1Marcin Swiderski return Scope; 1279239a7c42df78abc7fd5611d806d5e199fec994d1Marcin Swiderski 1280651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines for (auto *DI : DS->decls()) 1281651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (VarDecl *VD = dyn_cast<VarDecl>(DI)) 1282239a7c42df78abc7fd5611d806d5e199fec994d1Marcin Swiderski Scope = addLocalScopeForVarDecl(VD, Scope); 1283239a7c42df78abc7fd5611d806d5e199fec994d1Marcin Swiderski return Scope; 1284239a7c42df78abc7fd5611d806d5e199fec994d1Marcin Swiderski} 1285239a7c42df78abc7fd5611d806d5e199fec994d1Marcin Swiderski 1286239a7c42df78abc7fd5611d806d5e199fec994d1Marcin Swiderski/// addLocalScopeForVarDecl - Add LocalScope for variable declaration. It will 1287239a7c42df78abc7fd5611d806d5e199fec994d1Marcin Swiderski/// create add scope for automatic objects and temporary objects bound to 1288239a7c42df78abc7fd5611d806d5e199fec994d1Marcin Swiderski/// const reference. Will reuse Scope if not NULL. 12899c378f705405d37f49795d5e915989de774fe11fTed KremenekLocalScope* CFGBuilder::addLocalScopeForVarDecl(VarDecl *VD, 1290b6edff55db4ff240d56d33594d68a711e4b1e24aZhongxing Xu LocalScope* Scope) { 1291239a7c42df78abc7fd5611d806d5e199fec994d1Marcin Swiderski if (!BuildOpts.AddImplicitDtors) 1292239a7c42df78abc7fd5611d806d5e199fec994d1Marcin Swiderski return Scope; 1293239a7c42df78abc7fd5611d806d5e199fec994d1Marcin Swiderski 1294239a7c42df78abc7fd5611d806d5e199fec994d1Marcin Swiderski // Check if variable is local. 1295239a7c42df78abc7fd5611d806d5e199fec994d1Marcin Swiderski switch (VD->getStorageClass()) { 1296239a7c42df78abc7fd5611d806d5e199fec994d1Marcin Swiderski case SC_None: 1297239a7c42df78abc7fd5611d806d5e199fec994d1Marcin Swiderski case SC_Auto: 1298239a7c42df78abc7fd5611d806d5e199fec994d1Marcin Swiderski case SC_Register: 1299239a7c42df78abc7fd5611d806d5e199fec994d1Marcin Swiderski break; 1300239a7c42df78abc7fd5611d806d5e199fec994d1Marcin Swiderski default: return Scope; 1301239a7c42df78abc7fd5611d806d5e199fec994d1Marcin Swiderski } 1302239a7c42df78abc7fd5611d806d5e199fec994d1Marcin Swiderski 1303239a7c42df78abc7fd5611d806d5e199fec994d1Marcin Swiderski // Check for const references bound to temporary. Set type to pointee. 1304239a7c42df78abc7fd5611d806d5e199fec994d1Marcin Swiderski QualType QT = VD->getType(); 13052d9eb21325a0854e86de7344f54a8e6cef2a97adDouglas Gregor if (QT.getTypePtr()->isReferenceType()) { 130649bab4c0046e8300c79e79b7ca9a479696c7e87aRichard Smith // Attempt to determine whether this declaration lifetime-extends a 130749bab4c0046e8300c79e79b7ca9a479696c7e87aRichard Smith // temporary. 130849bab4c0046e8300c79e79b7ca9a479696c7e87aRichard Smith // 130949bab4c0046e8300c79e79b7ca9a479696c7e87aRichard Smith // FIXME: This is incorrect. Non-reference declarations can lifetime-extend 131049bab4c0046e8300c79e79b7ca9a479696c7e87aRichard Smith // temporaries, and a single declaration can extend multiple temporaries. 131149bab4c0046e8300c79e79b7ca9a479696c7e87aRichard Smith // We should look at the storage duration on each nested 131249bab4c0046e8300c79e79b7ca9a479696c7e87aRichard Smith // MaterializeTemporaryExpr instead. 131349bab4c0046e8300c79e79b7ca9a479696c7e87aRichard Smith const Expr *Init = VD->getInit(); 131449bab4c0046e8300c79e79b7ca9a479696c7e87aRichard Smith if (!Init) 131549bab4c0046e8300c79e79b7ca9a479696c7e87aRichard Smith return Scope; 131649bab4c0046e8300c79e79b7ca9a479696c7e87aRichard Smith if (const ExprWithCleanups *EWC = dyn_cast<ExprWithCleanups>(Init)) 131749bab4c0046e8300c79e79b7ca9a479696c7e87aRichard Smith Init = EWC->getSubExpr(); 131849bab4c0046e8300c79e79b7ca9a479696c7e87aRichard Smith if (!isa<MaterializeTemporaryExpr>(Init)) 1319239a7c42df78abc7fd5611d806d5e199fec994d1Marcin Swiderski return Scope; 13202d9eb21325a0854e86de7344f54a8e6cef2a97adDouglas Gregor 132149bab4c0046e8300c79e79b7ca9a479696c7e87aRichard Smith // Lifetime-extending a temporary. 132249bab4c0046e8300c79e79b7ca9a479696c7e87aRichard Smith QT = getReferenceInitTemporaryType(*Context, Init); 1323239a7c42df78abc7fd5611d806d5e199fec994d1Marcin Swiderski } 1324239a7c42df78abc7fd5611d806d5e199fec994d1Marcin Swiderski 1325b1c52870b8c2feaa7cd112295368bec53af490a0Marcin Swiderski // Check for constant size array. Set type to array element type. 13262d9eb21325a0854e86de7344f54a8e6cef2a97adDouglas Gregor while (const ConstantArrayType *AT = Context->getAsConstantArrayType(QT)) { 1327b1c52870b8c2feaa7cd112295368bec53af490a0Marcin Swiderski if (AT->getSize() == 0) 1328b1c52870b8c2feaa7cd112295368bec53af490a0Marcin Swiderski return Scope; 1329b1c52870b8c2feaa7cd112295368bec53af490a0Marcin Swiderski QT = AT->getElementType(); 1330b1c52870b8c2feaa7cd112295368bec53af490a0Marcin Swiderski } 13314e493e0dbac2aaac04c041f3d7dee9eccfb97689Zhongxing Xu 1332b1c52870b8c2feaa7cd112295368bec53af490a0Marcin Swiderski // Check if type is a C++ class with non-trivial destructor. 13339c378f705405d37f49795d5e915989de774fe11fTed Kremenek if (const CXXRecordDecl *CD = QT->getAsCXXRecordDecl()) 133423661d3e348c5f44ae89b6848bbc331829bb46f2David Blaikie if (!CD->hasTrivialDestructor()) { 13354e493e0dbac2aaac04c041f3d7dee9eccfb97689Zhongxing Xu // Add the variable to scope 13364e493e0dbac2aaac04c041f3d7dee9eccfb97689Zhongxing Xu Scope = createOrReuseLocalScope(Scope); 13374e493e0dbac2aaac04c041f3d7dee9eccfb97689Zhongxing Xu Scope->addVar(VD); 13384e493e0dbac2aaac04c041f3d7dee9eccfb97689Zhongxing Xu ScopePos = Scope->begin(); 13394e493e0dbac2aaac04c041f3d7dee9eccfb97689Zhongxing Xu } 1340239a7c42df78abc7fd5611d806d5e199fec994d1Marcin Swiderski return Scope; 1341239a7c42df78abc7fd5611d806d5e199fec994d1Marcin Swiderski} 1342239a7c42df78abc7fd5611d806d5e199fec994d1Marcin Swiderski 1343239a7c42df78abc7fd5611d806d5e199fec994d1Marcin Swiderski/// addLocalScopeAndDtors - For given statement add local scope for it and 1344239a7c42df78abc7fd5611d806d5e199fec994d1Marcin Swiderski/// add destructors that will cleanup the scope. Will reuse Scope if not NULL. 13459c378f705405d37f49795d5e915989de774fe11fTed Kremenekvoid CFGBuilder::addLocalScopeAndDtors(Stmt *S) { 1346239a7c42df78abc7fd5611d806d5e199fec994d1Marcin Swiderski if (!BuildOpts.AddImplicitDtors) 1347239a7c42df78abc7fd5611d806d5e199fec994d1Marcin Swiderski return; 1348239a7c42df78abc7fd5611d806d5e199fec994d1Marcin Swiderski 1349239a7c42df78abc7fd5611d806d5e199fec994d1Marcin Swiderski LocalScope::const_iterator scopeBeginPos = ScopePos; 135002acdfaeb3f3805b65e4707e5dff096209adb367Zhongxing Xu addLocalScopeForStmt(S); 1351239a7c42df78abc7fd5611d806d5e199fec994d1Marcin Swiderski addAutomaticObjDtors(ScopePos, scopeBeginPos, S); 1352239a7c42df78abc7fd5611d806d5e199fec994d1Marcin Swiderski} 1353239a7c42df78abc7fd5611d806d5e199fec994d1Marcin Swiderski 135453de134e7b4686eed40bc031438d8a4560a2cda4Marcin Swiderski/// prependAutomaticObjDtorsWithTerminator - Prepend destructor CFGElements for 135553de134e7b4686eed40bc031438d8a4560a2cda4Marcin Swiderski/// variables with automatic storage duration to CFGBlock's elements vector. 135653de134e7b4686eed40bc031438d8a4560a2cda4Marcin Swiderski/// Elements will be prepended to physical beginning of the vector which 135753de134e7b4686eed40bc031438d8a4560a2cda4Marcin Swiderski/// happens to be logical end. Use blocks terminator as statement that specifies 135853de134e7b4686eed40bc031438d8a4560a2cda4Marcin Swiderski/// destructors call site. 1359c8cfc74bdcc999828bc232294d937fb191940d5bChandler Carruth/// FIXME: This mechanism for adding automatic destructors doesn't handle 1360c8cfc74bdcc999828bc232294d937fb191940d5bChandler Carruth/// no-return destructors properly. 13619c378f705405d37f49795d5e915989de774fe11fTed Kremenekvoid CFGBuilder::prependAutomaticObjDtorsWithTerminator(CFGBlock *Blk, 136253de134e7b4686eed40bc031438d8a4560a2cda4Marcin Swiderski LocalScope::const_iterator B, LocalScope::const_iterator E) { 1363c8cfc74bdcc999828bc232294d937fb191940d5bChandler Carruth BumpVectorContext &C = cfg->getBumpVectorContext(); 1364c8cfc74bdcc999828bc232294d937fb191940d5bChandler Carruth CFGBlock::iterator InsertPos 1365c8cfc74bdcc999828bc232294d937fb191940d5bChandler Carruth = Blk->beginAutomaticObjDtorsInsert(Blk->end(), B.distance(E), C); 1366c8cfc74bdcc999828bc232294d937fb191940d5bChandler Carruth for (LocalScope::const_iterator I = B; I != E; ++I) 1367c8cfc74bdcc999828bc232294d937fb191940d5bChandler Carruth InsertPos = Blk->insertAutomaticObjDtor(InsertPos, *I, 1368c8cfc74bdcc999828bc232294d937fb191940d5bChandler Carruth Blk->getTerminator()); 136953de134e7b4686eed40bc031438d8a4560a2cda4Marcin Swiderski} 137053de134e7b4686eed40bc031438d8a4560a2cda4Marcin Swiderski 13714f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek/// Visit - Walk the subtree of a statement and add extra 13726d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump/// blocks for ternary operators, &&, and ||. We also process "," and 13736d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump/// DeclStmts (which may contain nested control-flow). 13749c378f705405d37f49795d5e915989de774fe11fTed KremenekCFGBlock *CFGBuilder::Visit(Stmt * S, AddStmtChoice asc) { 1375f42e3371079de333c3822a060c008bf6680677c8Ted Kremenek if (!S) { 1376f42e3371079de333c3822a060c008bf6680677c8Ted Kremenek badCFG = true; 13776bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return nullptr; 1378f42e3371079de333c3822a060c008bf6680677c8Ted Kremenek } 1379ac73ea8c12772fd0dcec71b83c193a2837de7f8bJordy Rose 1380ac73ea8c12772fd0dcec71b83c193a2837de7f8bJordy Rose if (Expr *E = dyn_cast<Expr>(S)) 1381ac73ea8c12772fd0dcec71b83c193a2837de7f8bJordy Rose S = E->IgnoreParens(); 1382ac73ea8c12772fd0dcec71b83c193a2837de7f8bJordy Rose 13834f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek switch (S->getStmtClass()) { 13844f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek default: 1385852274d4257134906995cb252fb3dfd2d71deae8Ted Kremenek return VisitStmt(S, asc); 13864f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek 13874f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek case Stmt::AddrLabelExprClass: 1388852274d4257134906995cb252fb3dfd2d71deae8Ted Kremenek return VisitAddrLabelExpr(cast<AddrLabelExpr>(S), asc); 13891eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 139056ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall case Stmt::BinaryConditionalOperatorClass: 139156ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall return VisitConditionalOperator(cast<BinaryConditionalOperator>(S), asc); 139256ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall 13934f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek case Stmt::BinaryOperatorClass: 1394852274d4257134906995cb252fb3dfd2d71deae8Ted Kremenek return VisitBinaryOperator(cast<BinaryOperator>(S), asc); 13951eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 13964f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek case Stmt::BlockExprClass: 139755331da3211151aa67277aa095b7d301342200d4Ted Kremenek return VisitNoRecurse(cast<Expr>(S), asc); 13984f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek 13994f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek case Stmt::BreakStmtClass: 14004f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek return VisitBreakStmt(cast<BreakStmt>(S)); 14011eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 14024f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek case Stmt::CallExprClass: 1403a427f1d8f0848997029d1bdc0c5c137f982f775dTed Kremenek case Stmt::CXXOperatorCallExprClass: 14041de85338543dd6228eb518185e385d94d377f4cbJohn McCall case Stmt::CXXMemberCallExprClass: 14059fcce65e7e1307b5b8da9be13e4092d6bb94dc1dRichard Smith case Stmt::UserDefinedLiteralClass: 1406852274d4257134906995cb252fb3dfd2d71deae8Ted Kremenek return VisitCallExpr(cast<CallExpr>(S), asc); 14071eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 14084f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek case Stmt::CaseStmtClass: 14094f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek return VisitCaseStmt(cast<CaseStmt>(S)); 14104f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek 14114f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek case Stmt::ChooseExprClass: 1412852274d4257134906995cb252fb3dfd2d71deae8Ted Kremenek return VisitChooseExpr(cast<ChooseExpr>(S), asc); 14131eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 14144f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek case Stmt::CompoundStmtClass: 14154f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek return VisitCompoundStmt(cast<CompoundStmt>(S)); 14161eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 14174f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek case Stmt::ConditionalOperatorClass: 1418852274d4257134906995cb252fb3dfd2d71deae8Ted Kremenek return VisitConditionalOperator(cast<ConditionalOperator>(S), asc); 14191eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 14204f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek case Stmt::ContinueStmtClass: 14214f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek return VisitContinueStmt(cast<ContinueStmt>(S)); 14221eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1423021c8afbab95c71fbdd95c0b5cea36fd316281f9Ted Kremenek case Stmt::CXXCatchStmtClass: 1424021c8afbab95c71fbdd95c0b5cea36fd316281f9Ted Kremenek return VisitCXXCatchStmt(cast<CXXCatchStmt>(S)); 1425021c8afbab95c71fbdd95c0b5cea36fd316281f9Ted Kremenek 14264765fa05b5652fcc4356371c2f481d0ea9a1b007John McCall case Stmt::ExprWithCleanupsClass: 14274765fa05b5652fcc4356371c2f481d0ea9a1b007John McCall return VisitExprWithCleanups(cast<ExprWithCleanups>(S), asc); 142847e331ed28c2536bec227c5e2fa094ab3d46eed1Ted Kremenek 1429b66529d04727dc686b97ea3d937fc9785792f505Jordan Rose case Stmt::CXXDefaultArgExprClass: 1430c3bf52ced9652f555aa0767bb822ec4c64546212Richard Smith case Stmt::CXXDefaultInitExprClass: 1431b66529d04727dc686b97ea3d937fc9785792f505Jordan Rose // FIXME: The expression inside a CXXDefaultArgExpr is owned by the 1432b66529d04727dc686b97ea3d937fc9785792f505Jordan Rose // called function's declaration, not by the caller. If we simply add 1433b66529d04727dc686b97ea3d937fc9785792f505Jordan Rose // this expression to the CFG, we could end up with the same Expr 1434b66529d04727dc686b97ea3d937fc9785792f505Jordan Rose // appearing multiple times. 1435b66529d04727dc686b97ea3d937fc9785792f505Jordan Rose // PR13385 / <rdar://problem/12156507> 1436c3bf52ced9652f555aa0767bb822ec4c64546212Richard Smith // 1437c3bf52ced9652f555aa0767bb822ec4c64546212Richard Smith // It's likewise possible for multiple CXXDefaultInitExprs for the same 1438c3bf52ced9652f555aa0767bb822ec4c64546212Richard Smith // expression to be used in the same function (through aggregate 1439c3bf52ced9652f555aa0767bb822ec4c64546212Richard Smith // initialization). 1440b66529d04727dc686b97ea3d937fc9785792f505Jordan Rose return VisitStmt(S, asc); 1441b66529d04727dc686b97ea3d937fc9785792f505Jordan Rose 1442a725ed468585b881c43654eeb56b28554a84808aZhongxing Xu case Stmt::CXXBindTemporaryExprClass: 1443a725ed468585b881c43654eeb56b28554a84808aZhongxing Xu return VisitCXXBindTemporaryExpr(cast<CXXBindTemporaryExpr>(S), asc); 1444a725ed468585b881c43654eeb56b28554a84808aZhongxing Xu 144581bc7d07b701042371a5723b6f394cd2482ed7beZhongxing Xu case Stmt::CXXConstructExprClass: 144681bc7d07b701042371a5723b6f394cd2482ed7beZhongxing Xu return VisitCXXConstructExpr(cast<CXXConstructExpr>(S), asc); 144781bc7d07b701042371a5723b6f394cd2482ed7beZhongxing Xu 1448651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines case Stmt::CXXNewExprClass: 1449651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return VisitCXXNewExpr(cast<CXXNewExpr>(S), asc); 1450651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 145136d558d85653315edb389677e995ec9ccdbfbf3dJordan Rose case Stmt::CXXDeleteExprClass: 145236d558d85653315edb389677e995ec9ccdbfbf3dJordan Rose return VisitCXXDeleteExpr(cast<CXXDeleteExpr>(S), asc); 145336d558d85653315edb389677e995ec9ccdbfbf3dJordan Rose 1454a725ed468585b881c43654eeb56b28554a84808aZhongxing Xu case Stmt::CXXFunctionalCastExprClass: 1455a725ed468585b881c43654eeb56b28554a84808aZhongxing Xu return VisitCXXFunctionalCastExpr(cast<CXXFunctionalCastExpr>(S), asc); 1456a725ed468585b881c43654eeb56b28554a84808aZhongxing Xu 145781bc7d07b701042371a5723b6f394cd2482ed7beZhongxing Xu case Stmt::CXXTemporaryObjectExprClass: 145881bc7d07b701042371a5723b6f394cd2482ed7beZhongxing Xu return VisitCXXTemporaryObjectExpr(cast<CXXTemporaryObjectExpr>(S), asc); 145981bc7d07b701042371a5723b6f394cd2482ed7beZhongxing Xu 1460021c8afbab95c71fbdd95c0b5cea36fd316281f9Ted Kremenek case Stmt::CXXThrowExprClass: 1461021c8afbab95c71fbdd95c0b5cea36fd316281f9Ted Kremenek return VisitCXXThrowExpr(cast<CXXThrowExpr>(S)); 1462ad5a894df1841698c824381b414630799adc26caTed Kremenek 1463021c8afbab95c71fbdd95c0b5cea36fd316281f9Ted Kremenek case Stmt::CXXTryStmtClass: 1464021c8afbab95c71fbdd95c0b5cea36fd316281f9Ted Kremenek return VisitCXXTryStmt(cast<CXXTryStmt>(S)); 1465ad5a894df1841698c824381b414630799adc26caTed Kremenek 1466ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith case Stmt::CXXForRangeStmtClass: 1467ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith return VisitCXXForRangeStmt(cast<CXXForRangeStmt>(S)); 1468ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith 14694f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek case Stmt::DeclStmtClass: 14704f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek return VisitDeclStmt(cast<DeclStmt>(S)); 14711eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 14724f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek case Stmt::DefaultStmtClass: 14734f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek return VisitDefaultStmt(cast<DefaultStmt>(S)); 14741eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 14754f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek case Stmt::DoStmtClass: 14764f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek return VisitDoStmt(cast<DoStmt>(S)); 14771eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 14784f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek case Stmt::ForStmtClass: 14794f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek return VisitForStmt(cast<ForStmt>(S)); 14801eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 14814f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek case Stmt::GotoStmtClass: 14824f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek return VisitGotoStmt(cast<GotoStmt>(S)); 14831eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 14844f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek case Stmt::IfStmtClass: 14854f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek return VisitIfStmt(cast<IfStmt>(S)); 14861eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1487892697dd2287caf7c29aaaa82909b0e90b8b63feTed Kremenek case Stmt::ImplicitCastExprClass: 1488892697dd2287caf7c29aaaa82909b0e90b8b63feTed Kremenek return VisitImplicitCastExpr(cast<ImplicitCastExpr>(S), asc); 1489a725ed468585b881c43654eeb56b28554a84808aZhongxing Xu 14904f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek case Stmt::IndirectGotoStmtClass: 14914f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek return VisitIndirectGotoStmt(cast<IndirectGotoStmt>(S)); 14921eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 14934f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek case Stmt::LabelStmtClass: 14944f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek return VisitLabelStmt(cast<LabelStmt>(S)); 14951eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 149683748e2f41ea0ac7c954946feb5da9ccc6ab8becTed Kremenek case Stmt::LambdaExprClass: 149783748e2f41ea0ac7c954946feb5da9ccc6ab8becTed Kremenek return VisitLambdaExpr(cast<LambdaExpr>(S), asc); 149883748e2f41ea0ac7c954946feb5da9ccc6ab8becTed Kremenek 1499115c1b9cc758d15f38e1d2ad4cf07b1cacfb3115Ted Kremenek case Stmt::MemberExprClass: 1500115c1b9cc758d15f38e1d2ad4cf07b1cacfb3115Ted Kremenek return VisitMemberExpr(cast<MemberExpr>(S), asc); 1501115c1b9cc758d15f38e1d2ad4cf07b1cacfb3115Ted Kremenek 15026a9065a39ab15383082b914af28759da1652db18Ted Kremenek case Stmt::NullStmtClass: 15036a9065a39ab15383082b914af28759da1652db18Ted Kremenek return Block; 15046a9065a39ab15383082b914af28759da1652db18Ted Kremenek 15054f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek case Stmt::ObjCAtCatchStmtClass: 15061eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump return VisitObjCAtCatchStmt(cast<ObjCAtCatchStmt>(S)); 15071eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 15088e282c332f8ad51dedf86a185a4dcb78ef93fb51Ted Kremenek case Stmt::ObjCAutoreleasePoolStmtClass: 15098e282c332f8ad51dedf86a185a4dcb78ef93fb51Ted Kremenek return VisitObjCAutoreleasePoolStmt(cast<ObjCAutoreleasePoolStmt>(S)); 15108e282c332f8ad51dedf86a185a4dcb78ef93fb51Ted Kremenek 15114f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek case Stmt::ObjCAtSynchronizedStmtClass: 15124f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek return VisitObjCAtSynchronizedStmt(cast<ObjCAtSynchronizedStmt>(S)); 15131eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 15144f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek case Stmt::ObjCAtThrowStmtClass: 15154f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek return VisitObjCAtThrowStmt(cast<ObjCAtThrowStmt>(S)); 15161eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 15174f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek case Stmt::ObjCAtTryStmtClass: 15184f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek return VisitObjCAtTryStmt(cast<ObjCAtTryStmt>(S)); 15191eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 15204f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek case Stmt::ObjCForCollectionStmtClass: 15214f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek return VisitObjCForCollectionStmt(cast<ObjCForCollectionStmt>(S)); 15221eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 15236a9065a39ab15383082b914af28759da1652db18Ted Kremenek case Stmt::OpaqueValueExprClass: 15244f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek return Block; 15251eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 15264b9c2d235fb9449e249d74f48ecfec601650de93John McCall case Stmt::PseudoObjectExprClass: 15274b9c2d235fb9449e249d74f48ecfec601650de93John McCall return VisitPseudoObjectExpr(cast<PseudoObjectExpr>(S)); 15284b9c2d235fb9449e249d74f48ecfec601650de93John McCall 15294f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek case Stmt::ReturnStmtClass: 15304f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek return VisitReturnStmt(cast<ReturnStmt>(S)); 15311eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1532f4e3cfbe8abd124be6341ef5d714819b4fbd9082Peter Collingbourne case Stmt::UnaryExprOrTypeTraitExprClass: 1533f4e3cfbe8abd124be6341ef5d714819b4fbd9082Peter Collingbourne return VisitUnaryExprOrTypeTraitExpr(cast<UnaryExprOrTypeTraitExpr>(S), 1534f4e3cfbe8abd124be6341ef5d714819b4fbd9082Peter Collingbourne asc); 15351eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 15364f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek case Stmt::StmtExprClass: 1537852274d4257134906995cb252fb3dfd2d71deae8Ted Kremenek return VisitStmtExpr(cast<StmtExpr>(S), asc); 15381eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 15394f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek case Stmt::SwitchStmtClass: 15404f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek return VisitSwitchStmt(cast<SwitchStmt>(S)); 15411eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 154299cae5b67b9711ca260e5b364a878a1a91183632Zhanyong Wan case Stmt::UnaryOperatorClass: 154399cae5b67b9711ca260e5b364a878a1a91183632Zhanyong Wan return VisitUnaryOperator(cast<UnaryOperator>(S), asc); 154499cae5b67b9711ca260e5b364a878a1a91183632Zhanyong Wan 15454f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek case Stmt::WhileStmtClass: 15464f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek return VisitWhileStmt(cast<WhileStmt>(S)); 15474f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek } 15484f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek} 15491eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1550852274d4257134906995cb252fb3dfd2d71deae8Ted KremenekCFGBlock *CFGBuilder::VisitStmt(Stmt *S, AddStmtChoice asc) { 15513179a45a0e91c1dcf3492222170cf4499531bb92Ted Kremenek if (asc.alwaysAdd(*this, S)) { 15524f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek autoCreateBlock(); 1553247e9665d897a7bbbf60c1c0d3b6609c4504a961Ted Kremenek appendStmt(Block, S); 15546d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump } 15551eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 15564f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek return VisitChildren(S); 15574f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek} 15586d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 15594f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek/// VisitChildren - Visit the children of a Stmt. 15605846720f08a6b225484bfe663599c2b057a99bc8Ted KremenekCFGBlock *CFGBuilder::VisitChildren(Stmt *S) { 15615846720f08a6b225484bfe663599c2b057a99bc8Ted Kremenek CFGBlock *B = Block; 15626b12da9f89b7863e6fc995312355b94197b75657Ted Kremenek 15635846720f08a6b225484bfe663599c2b057a99bc8Ted Kremenek // Visit the children in their reverse order so that they appear in 15645846720f08a6b225484bfe663599c2b057a99bc8Ted Kremenek // left-to-right (natural) order in the CFG. 15655846720f08a6b225484bfe663599c2b057a99bc8Ted Kremenek reverse_children RChildren(S); 15665846720f08a6b225484bfe663599c2b057a99bc8Ted Kremenek for (reverse_children::iterator I = RChildren.begin(), E = RChildren.end(); 15675846720f08a6b225484bfe663599c2b057a99bc8Ted Kremenek I != E; ++I) { 15685846720f08a6b225484bfe663599c2b057a99bc8Ted Kremenek if (Stmt *Child = *I) 15695846720f08a6b225484bfe663599c2b057a99bc8Ted Kremenek if (CFGBlock *R = Visit(Child)) 15705846720f08a6b225484bfe663599c2b057a99bc8Ted Kremenek B = R; 15715846720f08a6b225484bfe663599c2b057a99bc8Ted Kremenek } 15725846720f08a6b225484bfe663599c2b057a99bc8Ted Kremenek return B; 15734f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek} 15741eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1575852274d4257134906995cb252fb3dfd2d71deae8Ted KremenekCFGBlock *CFGBuilder::VisitAddrLabelExpr(AddrLabelExpr *A, 1576852274d4257134906995cb252fb3dfd2d71deae8Ted Kremenek AddStmtChoice asc) { 15774f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek AddressTakenLabels.insert(A->getLabel()); 15786d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 15793179a45a0e91c1dcf3492222170cf4499531bb92Ted Kremenek if (asc.alwaysAdd(*this, A)) { 15804f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek autoCreateBlock(); 1581247e9665d897a7bbbf60c1c0d3b6609c4504a961Ted Kremenek appendStmt(Block, A); 15826d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump } 15836d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 15844f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek return Block; 15854f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek} 15861eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 158799cae5b67b9711ca260e5b364a878a1a91183632Zhanyong WanCFGBlock *CFGBuilder::VisitUnaryOperator(UnaryOperator *U, 1588892697dd2287caf7c29aaaa82909b0e90b8b63feTed Kremenek AddStmtChoice asc) { 15893179a45a0e91c1dcf3492222170cf4499531bb92Ted Kremenek if (asc.alwaysAdd(*this, U)) { 159099cae5b67b9711ca260e5b364a878a1a91183632Zhanyong Wan autoCreateBlock(); 1591247e9665d897a7bbbf60c1c0d3b6609c4504a961Ted Kremenek appendStmt(Block, U); 159299cae5b67b9711ca260e5b364a878a1a91183632Zhanyong Wan } 159399cae5b67b9711ca260e5b364a878a1a91183632Zhanyong Wan 1594892697dd2287caf7c29aaaa82909b0e90b8b63feTed Kremenek return Visit(U->getSubExpr(), AddStmtChoice()); 159599cae5b67b9711ca260e5b364a878a1a91183632Zhanyong Wan} 159699cae5b67b9711ca260e5b364a878a1a91183632Zhanyong Wan 15975c3ea5c57971317c35b120ef0a2a2c79bd171008Ted KremenekCFGBlock *CFGBuilder::VisitLogicalOperator(BinaryOperator *B) { 15985c3ea5c57971317c35b120ef0a2a2c79bd171008Ted Kremenek CFGBlock *ConfluenceBlock = Block ? Block : createBlock(); 15995c3ea5c57971317c35b120ef0a2a2c79bd171008Ted Kremenek appendStmt(ConfluenceBlock, B); 16001eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 16015c3ea5c57971317c35b120ef0a2a2c79bd171008Ted Kremenek if (badCFG) 16026bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return nullptr; 16031eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 16046bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return VisitLogicalOperator(B, nullptr, ConfluenceBlock, 16056bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines ConfluenceBlock).first; 16063f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek} 1607862b24f8e9b1a3b332399591e48b303f57f01d0aTed Kremenek 16083f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenekstd::pair<CFGBlock*, CFGBlock*> 16093f635c08b2d0b2d5bafb38da09589cb238407faaTed KremenekCFGBuilder::VisitLogicalOperator(BinaryOperator *B, 16103f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek Stmt *Term, 16113f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek CFGBlock *TrueBlock, 16123f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek CFGBlock *FalseBlock) { 16133f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek 16143f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek // Introspect the RHS. If it is a nested logical operation, we recursively 16153f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek // build the CFG using this function. Otherwise, resort to default 16163f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek // CFG construction behavior. 16173f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek Expr *RHS = B->getRHS()->IgnoreParens(); 16183f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek CFGBlock *RHSBlock, *ExitBlock; 16193f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek 16203f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek do { 16213f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek if (BinaryOperator *B_RHS = dyn_cast<BinaryOperator>(RHS)) 16223f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek if (B_RHS->isLogicalOp()) { 1623651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines std::tie(RHSBlock, ExitBlock) = 16243f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek VisitLogicalOperator(B_RHS, Term, TrueBlock, FalseBlock); 16253f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek break; 16263f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek } 16271eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 16283f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek // The RHS is not a nested logical operation. Don't push the terminator 16293f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek // down further, but instead visit RHS and construct the respective 16303f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek // pieces of the CFG, and link up the RHSBlock with the terminator 16313f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek // we have been provided. 16323f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek ExitBlock = RHSBlock = createBlock(false); 16333f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek 16343f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek if (!Term) { 16353f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek assert(TrueBlock == FalseBlock); 16363f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek addSuccessor(RHSBlock, TrueBlock); 16373f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek } 16383f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek else { 16393f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek RHSBlock->setTerminator(Term); 16403f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek TryResult KnownVal = tryEvaluateBool(RHS); 16416bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (!KnownVal.isKnown()) 16426bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines KnownVal = tryEvaluateBool(B); 1643651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines addSuccessor(RHSBlock, TrueBlock, !KnownVal.isFalse()); 1644651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines addSuccessor(RHSBlock, FalseBlock, !KnownVal.isTrue()); 16453f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek } 16463f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek 16473f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek Block = RHSBlock; 16483f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek RHSBlock = addStmt(RHS); 16495c3ea5c57971317c35b120ef0a2a2c79bd171008Ted Kremenek } 16503f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek while (false); 16513f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek 16523f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek if (badCFG) 16536bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return std::make_pair(nullptr, nullptr); 16548c6d360636dee25f1ce071c3656810c6632cb89dArgyrios Kyrtzidis 16555c3ea5c57971317c35b120ef0a2a2c79bd171008Ted Kremenek // Generate the blocks for evaluating the LHS. 16563f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek Expr *LHS = B->getLHS()->IgnoreParens(); 16573f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek 16583f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek if (BinaryOperator *B_LHS = dyn_cast<BinaryOperator>(LHS)) 16593f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek if (B_LHS->isLogicalOp()) { 16603f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek if (B->getOpcode() == BO_LOr) 16613f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek FalseBlock = RHSBlock; 16623f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek else 16633f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek TrueBlock = RHSBlock; 16643f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek 16653f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek // For the LHS, treat 'B' as the terminator that we want to sink 16663f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek // into the nested branch. The RHS always gets the top-most 16673f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek // terminator. 16683f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek return VisitLogicalOperator(B_LHS, B, TrueBlock, FalseBlock); 16693f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek } 16703f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek 16713f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek // Create the block evaluating the LHS. 16723f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek // This contains the '&&' or '||' as the terminator. 16733f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek CFGBlock *LHSBlock = createBlock(false); 16743f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek LHSBlock->setTerminator(B); 16753f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek 16765c3ea5c57971317c35b120ef0a2a2c79bd171008Ted Kremenek Block = LHSBlock; 16773f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek CFGBlock *EntryLHSBlock = addStmt(LHS); 16783f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek 16793f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek if (badCFG) 16806bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return std::make_pair(nullptr, nullptr); 16815c3ea5c57971317c35b120ef0a2a2c79bd171008Ted Kremenek 16825c3ea5c57971317c35b120ef0a2a2c79bd171008Ted Kremenek // See if this is a known constant. 16833f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek TryResult KnownVal = tryEvaluateBool(LHS); 16845c3ea5c57971317c35b120ef0a2a2c79bd171008Ted Kremenek 16855c3ea5c57971317c35b120ef0a2a2c79bd171008Ted Kremenek // Now link the LHSBlock with RHSBlock. 16865c3ea5c57971317c35b120ef0a2a2c79bd171008Ted Kremenek if (B->getOpcode() == BO_LOr) { 1687651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines addSuccessor(LHSBlock, TrueBlock, !KnownVal.isFalse()); 1688651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines addSuccessor(LHSBlock, RHSBlock, !KnownVal.isTrue()); 16895c3ea5c57971317c35b120ef0a2a2c79bd171008Ted Kremenek } else { 16905c3ea5c57971317c35b120ef0a2a2c79bd171008Ted Kremenek assert(B->getOpcode() == BO_LAnd); 1691651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines addSuccessor(LHSBlock, RHSBlock, !KnownVal.isFalse()); 1692651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines addSuccessor(LHSBlock, FalseBlock, !KnownVal.isTrue()); 16935c3ea5c57971317c35b120ef0a2a2c79bd171008Ted Kremenek } 169400998a068e50945118f334c98af05ed44d7c22a6Mike Stump 16953f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek return std::make_pair(EntryLHSBlock, ExitBlock); 16965c3ea5c57971317c35b120ef0a2a2c79bd171008Ted Kremenek} 16971eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 16983f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek 16995c3ea5c57971317c35b120ef0a2a2c79bd171008Ted KremenekCFGBlock *CFGBuilder::VisitBinaryOperator(BinaryOperator *B, 17005c3ea5c57971317c35b120ef0a2a2c79bd171008Ted Kremenek AddStmtChoice asc) { 17015c3ea5c57971317c35b120ef0a2a2c79bd171008Ted Kremenek // && or || 17025c3ea5c57971317c35b120ef0a2a2c79bd171008Ted Kremenek if (B->isLogicalOp()) 17035c3ea5c57971317c35b120ef0a2a2c79bd171008Ted Kremenek return VisitLogicalOperator(B); 170436f327c309b1fb6b82f1987190f0be74000b14c1Zhanyong Wan 170536f327c309b1fb6b82f1987190f0be74000b14c1Zhanyong Wan if (B->getOpcode() == BO_Comma) { // , 17066dc534ecc19a045ebcfe93eefa45da509968e888Ted Kremenek autoCreateBlock(); 1707247e9665d897a7bbbf60c1c0d3b6609c4504a961Ted Kremenek appendStmt(Block, B); 17084f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek addStmt(B->getRHS()); 17094f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek return addStmt(B->getLHS()); 17106d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump } 171136f327c309b1fb6b82f1987190f0be74000b14c1Zhanyong Wan 171236f327c309b1fb6b82f1987190f0be74000b14c1Zhanyong Wan if (B->isAssignmentOp()) { 17133179a45a0e91c1dcf3492222170cf4499531bb92Ted Kremenek if (asc.alwaysAdd(*this, B)) { 1714fc61d94fbdbcd2b423976e21f24d423fcd442486Zhongxing Xu autoCreateBlock(); 1715247e9665d897a7bbbf60c1c0d3b6609c4504a961Ted Kremenek appendStmt(Block, B); 1716fc61d94fbdbcd2b423976e21f24d423fcd442486Zhongxing Xu } 1717892697dd2287caf7c29aaaa82909b0e90b8b63feTed Kremenek Visit(B->getLHS()); 1718e1667190dff025936a21e5eb43889ac93b570468Marcin Swiderski return Visit(B->getRHS()); 1719fc61d94fbdbcd2b423976e21f24d423fcd442486Zhongxing Xu } 17201eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 17213179a45a0e91c1dcf3492222170cf4499531bb92Ted Kremenek if (asc.alwaysAdd(*this, B)) { 1722e1667190dff025936a21e5eb43889ac93b570468Marcin Swiderski autoCreateBlock(); 1723247e9665d897a7bbbf60c1c0d3b6609c4504a961Ted Kremenek appendStmt(Block, B); 1724e1667190dff025936a21e5eb43889ac93b570468Marcin Swiderski } 1725e1667190dff025936a21e5eb43889ac93b570468Marcin Swiderski 1726a1898ddd5d0e46330898930b9185b628b5cede63Zhongxing Xu CFGBlock *RBlock = Visit(B->getRHS()); 1727a1898ddd5d0e46330898930b9185b628b5cede63Zhongxing Xu CFGBlock *LBlock = Visit(B->getLHS()); 1728a1898ddd5d0e46330898930b9185b628b5cede63Zhongxing Xu // If visiting RHS causes us to finish 'Block', e.g. the RHS is a StmtExpr 1729a1898ddd5d0e46330898930b9185b628b5cede63Zhongxing Xu // containing a DoStmt, and the LHS doesn't create a new block, then we should 1730a1898ddd5d0e46330898930b9185b628b5cede63Zhongxing Xu // return RBlock. Otherwise we'll incorrectly return NULL. 1731a1898ddd5d0e46330898930b9185b628b5cede63Zhongxing Xu return (LBlock ? LBlock : RBlock); 17324f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek} 17336d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 173455331da3211151aa67277aa095b7d301342200d4Ted KremenekCFGBlock *CFGBuilder::VisitNoRecurse(Expr *E, AddStmtChoice asc) { 17353179a45a0e91c1dcf3492222170cf4499531bb92Ted Kremenek if (asc.alwaysAdd(*this, E)) { 1736721903eca33f6115296083aed17685eaa73d3e8cTed Kremenek autoCreateBlock(); 1737247e9665d897a7bbbf60c1c0d3b6609c4504a961Ted Kremenek appendStmt(Block, E); 1738721903eca33f6115296083aed17685eaa73d3e8cTed Kremenek } 1739721903eca33f6115296083aed17685eaa73d3e8cTed Kremenek return Block; 17404f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek} 1741cd7bf230a77c550115e4a78ee371fc49a7563692Mike Stump 17424f88063677a2d990a44bb0d5f8437d2498b91d7fTed KremenekCFGBlock *CFGBuilder::VisitBreakStmt(BreakStmt *B) { 17434f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek // "break" is a control-flow statement. Thus we stop processing the current 17444f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek // block. 1745d438b3dbdcde4df4f61a99054104643e6aadf78bZhongxing Xu if (badCFG) 17466bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return nullptr; 17471eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 17484f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek // Now create a new block that ends with the break statement. 17494f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek Block = createBlock(false); 17504f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek Block->setTerminator(B); 17511eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 17524f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek // If there is no target for the break, then we are looking at an incomplete 17534f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek // AST. This means that the CFG cannot be constructed. 17549ce5270f0aadaaf03a0cf705787f42ce9eb1194cTed Kremenek if (BreakJumpTarget.block) { 17559ce5270f0aadaaf03a0cf705787f42ce9eb1194cTed Kremenek addAutomaticObjDtors(ScopePos, BreakJumpTarget.scopePosition, B); 17569ce5270f0aadaaf03a0cf705787f42ce9eb1194cTed Kremenek addSuccessor(Block, BreakJumpTarget.block); 1757f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski } else 17584f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek badCFG = true; 17591eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 17601eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 17614f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek return Block; 17624f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek} 17631eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 17648026f6d82f7fa544bc0453714fe94bca62a1196eSebastian Redlstatic bool CanThrow(Expr *E, ASTContext &Ctx) { 17654c45aa1b00b91847acfb082acfaced3ffa294d1dMike Stump QualType Ty = E->getType(); 17664c45aa1b00b91847acfb082acfaced3ffa294d1dMike Stump if (Ty->isFunctionPointerType()) 17674c45aa1b00b91847acfb082acfaced3ffa294d1dMike Stump Ty = Ty->getAs<PointerType>()->getPointeeType(); 17684c45aa1b00b91847acfb082acfaced3ffa294d1dMike Stump else if (Ty->isBlockPointerType()) 17694c45aa1b00b91847acfb082acfaced3ffa294d1dMike Stump Ty = Ty->getAs<BlockPointerType>()->getPointeeType(); 1770ad5a894df1841698c824381b414630799adc26caTed Kremenek 17714c45aa1b00b91847acfb082acfaced3ffa294d1dMike Stump const FunctionType *FT = Ty->getAs<FunctionType>(); 17724c45aa1b00b91847acfb082acfaced3ffa294d1dMike Stump if (FT) { 17734c45aa1b00b91847acfb082acfaced3ffa294d1dMike Stump if (const FunctionProtoType *Proto = dyn_cast<FunctionProtoType>(FT)) 1774b9d0b76e42fd2d4cdfd135220302458d03ad09feRichard Smith if (!isUnresolvedExceptionSpec(Proto->getExceptionSpecType()) && 1775e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith Proto->isNothrow(Ctx)) 17764c45aa1b00b91847acfb082acfaced3ffa294d1dMike Stump return false; 17774c45aa1b00b91847acfb082acfaced3ffa294d1dMike Stump } 17784c45aa1b00b91847acfb082acfaced3ffa294d1dMike Stump return true; 17794c45aa1b00b91847acfb082acfaced3ffa294d1dMike Stump} 17804c45aa1b00b91847acfb082acfaced3ffa294d1dMike Stump 1781852274d4257134906995cb252fb3dfd2d71deae8Ted KremenekCFGBlock *CFGBuilder::VisitCallExpr(CallExpr *C, AddStmtChoice asc) { 17821de85338543dd6228eb518185e385d94d377f4cbJohn McCall // Compute the callee type. 17831de85338543dd6228eb518185e385d94d377f4cbJohn McCall QualType calleeType = C->getCallee()->getType(); 17841de85338543dd6228eb518185e385d94d377f4cbJohn McCall if (calleeType == Context->BoundMemberTy) { 17851de85338543dd6228eb518185e385d94d377f4cbJohn McCall QualType boundType = Expr::findBoundMemberType(C->getCallee()); 17861de85338543dd6228eb518185e385d94d377f4cbJohn McCall 17871de85338543dd6228eb518185e385d94d377f4cbJohn McCall // We should only get a null bound type if processing a dependent 17881de85338543dd6228eb518185e385d94d377f4cbJohn McCall // CFG. Recover by assuming nothing. 17891de85338543dd6228eb518185e385d94d377f4cbJohn McCall if (!boundType.isNull()) calleeType = boundType; 17902455636163fdd18581d7fdae816433f886d88213Mike Stump } 17912455636163fdd18581d7fdae816433f886d88213Mike Stump 17921de85338543dd6228eb518185e385d94d377f4cbJohn McCall // If this is a call to a no-return function, this stops the block here. 17931de85338543dd6228eb518185e385d94d377f4cbJohn McCall bool NoReturn = getFunctionExtInfo(*calleeType).getNoReturn(); 17941de85338543dd6228eb518185e385d94d377f4cbJohn McCall 17954c45aa1b00b91847acfb082acfaced3ffa294d1dMike Stump bool AddEHEdge = false; 1796079bd72439448b78629a28da6b1f8abe2cdeaf4dMike Stump 1797079bd72439448b78629a28da6b1f8abe2cdeaf4dMike Stump // Languages without exceptions are assumed to not throw. 17984e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie if (Context->getLangOpts().Exceptions) { 17996c52c7850bccb6991470668429a1e1edf01b0873Ted Kremenek if (BuildOpts.AddEHEdges) 18004c45aa1b00b91847acfb082acfaced3ffa294d1dMike Stump AddEHEdge = true; 1801079bd72439448b78629a28da6b1f8abe2cdeaf4dMike Stump } 1802079bd72439448b78629a28da6b1f8abe2cdeaf4dMike Stump 18037d0dcd2de023e2667a3f1f14daff9d087fab9bf7Jordan Rose // If this is a call to a builtin function, it might not actually evaluate 18047d0dcd2de023e2667a3f1f14daff9d087fab9bf7Jordan Rose // its arguments. Don't add them to the CFG if this is the case. 18057d0dcd2de023e2667a3f1f14daff9d087fab9bf7Jordan Rose bool OmitArguments = false; 18067d0dcd2de023e2667a3f1f14daff9d087fab9bf7Jordan Rose 1807079bd72439448b78629a28da6b1f8abe2cdeaf4dMike Stump if (FunctionDecl *FD = C->getDirectCallee()) { 1808cd8ab51a44e80625d84126780b0d85a7732e25afRichard Smith if (FD->isNoReturn()) 18092455636163fdd18581d7fdae816433f886d88213Mike Stump NoReturn = true; 1810079bd72439448b78629a28da6b1f8abe2cdeaf4dMike Stump if (FD->hasAttr<NoThrowAttr>()) 18114c45aa1b00b91847acfb082acfaced3ffa294d1dMike Stump AddEHEdge = false; 18127d0dcd2de023e2667a3f1f14daff9d087fab9bf7Jordan Rose if (FD->getBuiltinID() == Builtin::BI__builtin_object_size) 18137d0dcd2de023e2667a3f1f14daff9d087fab9bf7Jordan Rose OmitArguments = true; 1814079bd72439448b78629a28da6b1f8abe2cdeaf4dMike Stump } 18152455636163fdd18581d7fdae816433f886d88213Mike Stump 18168026f6d82f7fa544bc0453714fe94bca62a1196eSebastian Redl if (!CanThrow(C->getCallee(), *Context)) 18174c45aa1b00b91847acfb082acfaced3ffa294d1dMike Stump AddEHEdge = false; 18184c45aa1b00b91847acfb082acfaced3ffa294d1dMike Stump 18197d0dcd2de023e2667a3f1f14daff9d087fab9bf7Jordan Rose if (OmitArguments) { 18207d0dcd2de023e2667a3f1f14daff9d087fab9bf7Jordan Rose assert(!NoReturn && "noreturn calls with unevaluated args not implemented"); 18217d0dcd2de023e2667a3f1f14daff9d087fab9bf7Jordan Rose assert(!AddEHEdge && "EH calls with unevaluated args not implemented"); 18227d0dcd2de023e2667a3f1f14daff9d087fab9bf7Jordan Rose autoCreateBlock(); 18237d0dcd2de023e2667a3f1f14daff9d087fab9bf7Jordan Rose appendStmt(Block, C); 18247d0dcd2de023e2667a3f1f14daff9d087fab9bf7Jordan Rose return Visit(C->getCallee()); 18257d0dcd2de023e2667a3f1f14daff9d087fab9bf7Jordan Rose } 18267d0dcd2de023e2667a3f1f14daff9d087fab9bf7Jordan Rose 18277d0dcd2de023e2667a3f1f14daff9d087fab9bf7Jordan Rose if (!NoReturn && !AddEHEdge) { 182894a3dcf146451eb6b0192873e267c4cb0f6147e8Zhanyong Wan return VisitStmt(C, asc.withAlwaysAdd(true)); 18297d0dcd2de023e2667a3f1f14daff9d087fab9bf7Jordan Rose } 18301eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1831079bd72439448b78629a28da6b1f8abe2cdeaf4dMike Stump if (Block) { 1832079bd72439448b78629a28da6b1f8abe2cdeaf4dMike Stump Succ = Block; 1833d438b3dbdcde4df4f61a99054104643e6aadf78bZhongxing Xu if (badCFG) 18346bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return nullptr; 1835079bd72439448b78629a28da6b1f8abe2cdeaf4dMike Stump } 18361eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1837dba3fb5413437dc613734fa4ffac892b11a37d25Chandler Carruth if (NoReturn) 1838dba3fb5413437dc613734fa4ffac892b11a37d25Chandler Carruth Block = createNoReturnBlock(); 1839dba3fb5413437dc613734fa4ffac892b11a37d25Chandler Carruth else 1840dba3fb5413437dc613734fa4ffac892b11a37d25Chandler Carruth Block = createBlock(); 1841dba3fb5413437dc613734fa4ffac892b11a37d25Chandler Carruth 1842247e9665d897a7bbbf60c1c0d3b6609c4504a961Ted Kremenek appendStmt(Block, C); 18432455636163fdd18581d7fdae816433f886d88213Mike Stump 18444c45aa1b00b91847acfb082acfaced3ffa294d1dMike Stump if (AddEHEdge) { 1845079bd72439448b78629a28da6b1f8abe2cdeaf4dMike Stump // Add exceptional edges. 1846079bd72439448b78629a28da6b1f8abe2cdeaf4dMike Stump if (TryTerminatedBlock) 18470a3ed3143b00f237decb1288c1ff574ae09eba4eTed Kremenek addSuccessor(Block, TryTerminatedBlock); 1848079bd72439448b78629a28da6b1f8abe2cdeaf4dMike Stump else 18490a3ed3143b00f237decb1288c1ff574ae09eba4eTed Kremenek addSuccessor(Block, &cfg->getExit()); 1850079bd72439448b78629a28da6b1f8abe2cdeaf4dMike Stump } 18511eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 18522455636163fdd18581d7fdae816433f886d88213Mike Stump return VisitChildren(C); 1853d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek} 1854d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek 1855852274d4257134906995cb252fb3dfd2d71deae8Ted KremenekCFGBlock *CFGBuilder::VisitChooseExpr(ChooseExpr *C, 1856852274d4257134906995cb252fb3dfd2d71deae8Ted Kremenek AddStmtChoice asc) { 18579c378f705405d37f49795d5e915989de774fe11fTed Kremenek CFGBlock *ConfluenceBlock = Block ? Block : createBlock(); 1858247e9665d897a7bbbf60c1c0d3b6609c4504a961Ted Kremenek appendStmt(ConfluenceBlock, C); 1859d438b3dbdcde4df4f61a99054104643e6aadf78bZhongxing Xu if (badCFG) 18606bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return nullptr; 18611eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 186294a3dcf146451eb6b0192873e267c4cb0f6147e8Zhanyong Wan AddStmtChoice alwaysAdd = asc.withAlwaysAdd(true); 18633fc8ef574cdc09c613c329ee511852d219263c15Ted Kremenek Succ = ConfluenceBlock; 18646bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines Block = nullptr; 18659c378f705405d37f49795d5e915989de774fe11fTed Kremenek CFGBlock *LHSBlock = Visit(C->getLHS(), alwaysAdd); 1866d438b3dbdcde4df4f61a99054104643e6aadf78bZhongxing Xu if (badCFG) 18676bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return nullptr; 18681eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 18693fc8ef574cdc09c613c329ee511852d219263c15Ted Kremenek Succ = ConfluenceBlock; 18706bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines Block = nullptr; 18719c378f705405d37f49795d5e915989de774fe11fTed Kremenek CFGBlock *RHSBlock = Visit(C->getRHS(), alwaysAdd); 1872d438b3dbdcde4df4f61a99054104643e6aadf78bZhongxing Xu if (badCFG) 18736bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return nullptr; 18741eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 18753fc8ef574cdc09c613c329ee511852d219263c15Ted Kremenek Block = createBlock(false); 187600998a068e50945118f334c98af05ed44d7c22a6Mike Stump // See if this is a known constant. 18770a3ed3143b00f237decb1288c1ff574ae09eba4eTed Kremenek const TryResult& KnownVal = tryEvaluateBool(C->getCond()); 18786bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines addSuccessor(Block, KnownVal.isFalse() ? nullptr : LHSBlock); 18796bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines addSuccessor(Block, KnownVal.isTrue() ? nullptr : RHSBlock); 18803fc8ef574cdc09c613c329ee511852d219263c15Ted Kremenek Block->setTerminator(C); 18811eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump return addStmt(C->getCond()); 18823fc8ef574cdc09c613c329ee511852d219263c15Ted Kremenek} 18831eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 18841eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 18859c378f705405d37f49795d5e915989de774fe11fTed KremenekCFGBlock *CFGBuilder::VisitCompoundStmt(CompoundStmt *C) { 1886fcb72ac985c26372315fabc08d43d6f66ff906b4Marcin Swiderski addLocalScopeAndDtors(C); 18879c378f705405d37f49795d5e915989de774fe11fTed Kremenek CFGBlock *LastBlock = Block; 18884f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek 18894f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek for (CompoundStmt::reverse_body_iterator I=C->body_rbegin(), E=C->body_rend(); 18904f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek I != E; ++I ) { 1891334c19566104d3333cf662f0017088a18eddfa81Ted Kremenek // If we hit a segment of code just containing ';' (NullStmts), we can 1892334c19566104d3333cf662f0017088a18eddfa81Ted Kremenek // get a null block back. In such cases, just use the LastBlock 1893334c19566104d3333cf662f0017088a18eddfa81Ted Kremenek if (CFGBlock *newBlock = addStmt(*I)) 1894334c19566104d3333cf662f0017088a18eddfa81Ted Kremenek LastBlock = newBlock; 18951eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1896e8d6d2b9a2c5d3f0e7e0f88f54f1711bbc6c6f78Ted Kremenek if (badCFG) 18976bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return nullptr; 18981eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump } 1899079bd72439448b78629a28da6b1f8abe2cdeaf4dMike Stump 19004f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek return LastBlock; 19014f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek} 19021eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 190356ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCallCFGBlock *CFGBuilder::VisitConditionalOperator(AbstractConditionalOperator *C, 1904852274d4257134906995cb252fb3dfd2d71deae8Ted Kremenek AddStmtChoice asc) { 190556ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall const BinaryConditionalOperator *BCO = dyn_cast<BinaryConditionalOperator>(C); 19066bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines const OpaqueValueExpr *opaqueValue = (BCO ? BCO->getOpaqueValue() : nullptr); 190756ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall 1908f34bb2eaa87aa28bcc8b6ff0dfc696cd75605b11Ted Kremenek // Create the confluence block that will "merge" the results of the ternary 1909f34bb2eaa87aa28bcc8b6ff0dfc696cd75605b11Ted Kremenek // expression. 19109c378f705405d37f49795d5e915989de774fe11fTed Kremenek CFGBlock *ConfluenceBlock = Block ? Block : createBlock(); 1911247e9665d897a7bbbf60c1c0d3b6609c4504a961Ted Kremenek appendStmt(ConfluenceBlock, C); 1912d438b3dbdcde4df4f61a99054104643e6aadf78bZhongxing Xu if (badCFG) 19136bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return nullptr; 19141eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 191594a3dcf146451eb6b0192873e267c4cb0f6147e8Zhanyong Wan AddStmtChoice alwaysAdd = asc.withAlwaysAdd(true); 1916115c1b9cc758d15f38e1d2ad4cf07b1cacfb3115Ted Kremenek 1917f34bb2eaa87aa28bcc8b6ff0dfc696cd75605b11Ted Kremenek // Create a block for the LHS expression if there is an LHS expression. A 1918f34bb2eaa87aa28bcc8b6ff0dfc696cd75605b11Ted Kremenek // GCC extension allows LHS to be NULL, causing the condition to be the 1919f34bb2eaa87aa28bcc8b6ff0dfc696cd75605b11Ted Kremenek // value that is returned instead. 1920f34bb2eaa87aa28bcc8b6ff0dfc696cd75605b11Ted Kremenek // e.g: x ?: y is shorthand for: x ? x : y; 1921f34bb2eaa87aa28bcc8b6ff0dfc696cd75605b11Ted Kremenek Succ = ConfluenceBlock; 19226bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines Block = nullptr; 19236bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines CFGBlock *LHSBlock = nullptr; 192456ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall const Expr *trueExpr = C->getTrueExpr(); 192556ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall if (trueExpr != opaqueValue) { 192656ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall LHSBlock = Visit(C->getTrueExpr(), alwaysAdd); 1927d438b3dbdcde4df4f61a99054104643e6aadf78bZhongxing Xu if (badCFG) 19286bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return nullptr; 19296bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines Block = nullptr; 1930f34bb2eaa87aa28bcc8b6ff0dfc696cd75605b11Ted Kremenek } 1931f226d18f0f49394cec460699f4268e32bd0ce833Ted Kremenek else 1932f226d18f0f49394cec460699f4268e32bd0ce833Ted Kremenek LHSBlock = ConfluenceBlock; 19331eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1934f34bb2eaa87aa28bcc8b6ff0dfc696cd75605b11Ted Kremenek // Create the block for the RHS expression. 1935f34bb2eaa87aa28bcc8b6ff0dfc696cd75605b11Ted Kremenek Succ = ConfluenceBlock; 19369c378f705405d37f49795d5e915989de774fe11fTed Kremenek CFGBlock *RHSBlock = Visit(C->getFalseExpr(), alwaysAdd); 1937d438b3dbdcde4df4f61a99054104643e6aadf78bZhongxing Xu if (badCFG) 19386bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return nullptr; 19391eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 194056df4a9e0461d4dfb2a740cb6b0ce531d6c82538Richard Smith // If the condition is a logical '&&' or '||', build a more accurate CFG. 194156df4a9e0461d4dfb2a740cb6b0ce531d6c82538Richard Smith if (BinaryOperator *Cond = 194256df4a9e0461d4dfb2a740cb6b0ce531d6c82538Richard Smith dyn_cast<BinaryOperator>(C->getCond()->IgnoreParens())) 194356df4a9e0461d4dfb2a740cb6b0ce531d6c82538Richard Smith if (Cond->isLogicalOp()) 194456df4a9e0461d4dfb2a740cb6b0ce531d6c82538Richard Smith return VisitLogicalOperator(Cond, C, LHSBlock, RHSBlock).first; 194556df4a9e0461d4dfb2a740cb6b0ce531d6c82538Richard Smith 1946f34bb2eaa87aa28bcc8b6ff0dfc696cd75605b11Ted Kremenek // Create the block that will contain the condition. 1947f34bb2eaa87aa28bcc8b6ff0dfc696cd75605b11Ted Kremenek Block = createBlock(false); 19481eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 194900998a068e50945118f334c98af05ed44d7c22a6Mike Stump // See if this is a known constant. 19500a3ed3143b00f237decb1288c1ff574ae09eba4eTed Kremenek const TryResult& KnownVal = tryEvaluateBool(C->getCond()); 1951651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines addSuccessor(Block, LHSBlock, !KnownVal.isFalse()); 1952651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines addSuccessor(Block, RHSBlock, !KnownVal.isTrue()); 1953f34bb2eaa87aa28bcc8b6ff0dfc696cd75605b11Ted Kremenek Block->setTerminator(C); 195456ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall Expr *condExpr = C->getCond(); 1955d40baf6a77f6353a93f181da5d1347d3730aad37John McCall 1956f226d18f0f49394cec460699f4268e32bd0ce833Ted Kremenek if (opaqueValue) { 1957f226d18f0f49394cec460699f4268e32bd0ce833Ted Kremenek // Run the condition expression if it's not trivially expressed in 1958f226d18f0f49394cec460699f4268e32bd0ce833Ted Kremenek // terms of the opaque value (or if there is no opaque value). 1959f226d18f0f49394cec460699f4268e32bd0ce833Ted Kremenek if (condExpr != opaqueValue) 1960f226d18f0f49394cec460699f4268e32bd0ce833Ted Kremenek addStmt(condExpr); 1961d40baf6a77f6353a93f181da5d1347d3730aad37John McCall 1962f226d18f0f49394cec460699f4268e32bd0ce833Ted Kremenek // Before that, run the common subexpression if there was one. 1963f226d18f0f49394cec460699f4268e32bd0ce833Ted Kremenek // At least one of this or the above will be run. 1964f226d18f0f49394cec460699f4268e32bd0ce833Ted Kremenek return addStmt(BCO->getCommon()); 1965f226d18f0f49394cec460699f4268e32bd0ce833Ted Kremenek } 1966f226d18f0f49394cec460699f4268e32bd0ce833Ted Kremenek 1967f226d18f0f49394cec460699f4268e32bd0ce833Ted Kremenek return addStmt(condExpr); 1968f34bb2eaa87aa28bcc8b6ff0dfc696cd75605b11Ted Kremenek} 1969f34bb2eaa87aa28bcc8b6ff0dfc696cd75605b11Ted Kremenek 19704f88063677a2d990a44bb0d5f8437d2498b91d7fTed KremenekCFGBlock *CFGBuilder::VisitDeclStmt(DeclStmt *DS) { 1971bc869de349227707a07ccc783344d255cf37ec16Ted Kremenek // Check if the Decl is for an __label__. If so, elide it from the 1972bc869de349227707a07ccc783344d255cf37ec16Ted Kremenek // CFG entirely. 1973bc869de349227707a07ccc783344d255cf37ec16Ted Kremenek if (isa<LabelDecl>(*DS->decl_begin())) 1974bc869de349227707a07ccc783344d255cf37ec16Ted Kremenek return Block; 1975bc869de349227707a07ccc783344d255cf37ec16Ted Kremenek 197629c9e62f412c9db3ee238db2472390685a6303f3Ted Kremenek // This case also handles static_asserts. 19778599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski if (DS->isSingleDecl()) 19788599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski return VisitDeclSubExpr(DS); 19791eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 19806bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines CFGBlock *B = nullptr; 19811eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1982fd8b43596478b779b6777cb3a595e69d7856c378Jordan Rose // Build an individual DeclStmt for each decl. 1983fd8b43596478b779b6777cb3a595e69d7856c378Jordan Rose for (DeclStmt::reverse_decl_iterator I = DS->decl_rbegin(), 1984fd8b43596478b779b6777cb3a595e69d7856c378Jordan Rose E = DS->decl_rend(); 1985fd8b43596478b779b6777cb3a595e69d7856c378Jordan Rose I != E; ++I) { 19864f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek // Get the alignment of the new DeclStmt, padding out to >=8 bytes. 19874f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek unsigned A = llvm::AlignOf<DeclStmt>::Alignment < 8 19884f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek ? 8 : llvm::AlignOf<DeclStmt>::Alignment; 19891eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 19904f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek // Allocate the DeclStmt using the BumpPtrAllocator. It will get 19914f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek // automatically freed with the CFG. 19924f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek DeclGroupRef DG(*I); 19934f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek Decl *D = *I; 19941eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump void *Mem = cfg->getAllocator().Allocate(sizeof(DeclStmt), A); 19954f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek DeclStmt *DSNew = new (Mem) DeclStmt(DG, D->getLocation(), GetEndLoc(D)); 199649a246f4fad959888bb0164c624c3c2b03078e91Jordan Rose cfg->addSyntheticDeclStmt(DSNew, DS); 19971eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 19984f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek // Append the fake DeclStmt to block. 19998599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski B = VisitDeclSubExpr(DSNew); 20004f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek } 20011eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 20021eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump return B; 20034f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek} 20041eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 20054f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek/// VisitDeclSubExpr - Utility method to add block-level expressions for 20068599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski/// DeclStmts and initializers in them. 20079c378f705405d37f49795d5e915989de774fe11fTed KremenekCFGBlock *CFGBuilder::VisitDeclSubExpr(DeclStmt *DS) { 20088599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski assert(DS->isSingleDecl() && "Can handle single declarations only."); 20098599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski VarDecl *VD = dyn_cast<VarDecl>(DS->getSingleDecl()); 20101eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 20118599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski if (!VD) { 20122794bc0e3757992194dd587d0f6a253ec72afc9aJordan Rose // Of everything that can be declared in a DeclStmt, only VarDecls impact 20132794bc0e3757992194dd587d0f6a253ec72afc9aJordan Rose // runtime semantics. 20144f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek return Block; 20158599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski } 20161eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 20178599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski bool HasTemporaries = false; 20188599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski 2019fbd4b5dc7febd1d8b4fa64ab00a29d72b44bec7bTed Kremenek // Guard static initializers under a branch. 20206bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines CFGBlock *blockAfterStaticInit = nullptr; 20215062bb22706c8f2ceec5815533ff5a88d169d098Ted Kremenek 20225062bb22706c8f2ceec5815533ff5a88d169d098Ted Kremenek if (BuildOpts.AddStaticInitBranches && VD->isStaticLocal()) { 20235062bb22706c8f2ceec5815533ff5a88d169d098Ted Kremenek // For static variables, we need to create a branch to track 20245062bb22706c8f2ceec5815533ff5a88d169d098Ted Kremenek // whether or not they are initialized. 20255062bb22706c8f2ceec5815533ff5a88d169d098Ted Kremenek if (Block) { 20265062bb22706c8f2ceec5815533ff5a88d169d098Ted Kremenek Succ = Block; 20276bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines Block = nullptr; 20285062bb22706c8f2ceec5815533ff5a88d169d098Ted Kremenek if (badCFG) 20296bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return nullptr; 20305062bb22706c8f2ceec5815533ff5a88d169d098Ted Kremenek } 20315062bb22706c8f2ceec5815533ff5a88d169d098Ted Kremenek blockAfterStaticInit = Succ; 20325062bb22706c8f2ceec5815533ff5a88d169d098Ted Kremenek } 2033fbd4b5dc7febd1d8b4fa64ab00a29d72b44bec7bTed Kremenek 20348599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski // Destructors of temporaries in initialization expression should be called 20358599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski // after initialization finishes. 20364f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek Expr *Init = VD->getInit(); 20378599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski if (Init) { 20384765fa05b5652fcc4356371c2f481d0ea9a1b007John McCall HasTemporaries = isa<ExprWithCleanups>(Init); 20398599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski 20405a1ffe98b04120846a15f7105905b5f363b08635Jordan Rose if (BuildOpts.AddTemporaryDtors && HasTemporaries) { 20418599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski // Generate destructors for temporaries in initialization expression. 2042176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines TempDtorContext Context; 20434765fa05b5652fcc4356371c2f481d0ea9a1b007John McCall VisitForTemporaryDtors(cast<ExprWithCleanups>(Init)->getSubExpr(), 2044176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines /*BindToTemporary=*/false, Context); 20458599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski } 20468599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski } 20478599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski 20488599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski autoCreateBlock(); 2049892697dd2287caf7c29aaaa82909b0e90b8b63feTed Kremenek appendStmt(Block, DS); 2050550f2234fc9218914c325041067052342dfce553Ted Kremenek 2051550f2234fc9218914c325041067052342dfce553Ted Kremenek // Keep track of the last non-null block, as 'Block' can be nulled out 2052550f2234fc9218914c325041067052342dfce553Ted Kremenek // if the initializer expression is something like a 'while' in a 2053550f2234fc9218914c325041067052342dfce553Ted Kremenek // statement-expression. 2054550f2234fc9218914c325041067052342dfce553Ted Kremenek CFGBlock *LastBlock = Block; 20551eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 20564f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek if (Init) { 2057550f2234fc9218914c325041067052342dfce553Ted Kremenek if (HasTemporaries) { 20588599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski // For expression with temporaries go directly to subexpression to omit 20598599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski // generating destructors for the second time. 2060550f2234fc9218914c325041067052342dfce553Ted Kremenek ExprWithCleanups *EC = cast<ExprWithCleanups>(Init); 2061550f2234fc9218914c325041067052342dfce553Ted Kremenek if (CFGBlock *newBlock = Visit(EC->getSubExpr())) 2062550f2234fc9218914c325041067052342dfce553Ted Kremenek LastBlock = newBlock; 2063550f2234fc9218914c325041067052342dfce553Ted Kremenek } 2064550f2234fc9218914c325041067052342dfce553Ted Kremenek else { 2065550f2234fc9218914c325041067052342dfce553Ted Kremenek if (CFGBlock *newBlock = Visit(Init)) 2066550f2234fc9218914c325041067052342dfce553Ted Kremenek LastBlock = newBlock; 2067550f2234fc9218914c325041067052342dfce553Ted Kremenek } 20684f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek } 20691eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 20704f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek // If the type of VD is a VLA, then we must process its size expressions. 2071f4c7371fb1d3cebcfb40abad4537bb82515704eaJohn McCall for (const VariableArrayType* VA = FindVA(VD->getType().getTypePtr()); 20726bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines VA != nullptr; VA = FindVA(VA->getElementType().getTypePtr())) { 20738f81acfa95a5d2a22fc875c1a10901eaa30b8405Ted Kremenek if (CFGBlock *newBlock = addStmt(VA->getSizeExpr())) 20748f81acfa95a5d2a22fc875c1a10901eaa30b8405Ted Kremenek LastBlock = newBlock; 20758f81acfa95a5d2a22fc875c1a10901eaa30b8405Ted Kremenek } 20761eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 2077fcb72ac985c26372315fabc08d43d6f66ff906b4Marcin Swiderski // Remove variable from local scope. 2078fcb72ac985c26372315fabc08d43d6f66ff906b4Marcin Swiderski if (ScopePos && VD == *ScopePos) 2079fcb72ac985c26372315fabc08d43d6f66ff906b4Marcin Swiderski ++ScopePos; 2080fcb72ac985c26372315fabc08d43d6f66ff906b4Marcin Swiderski 20810f5c5c60e9806d13f0907cd99d7204ffab0e08f7Ted Kremenek CFGBlock *B = LastBlock; 20825062bb22706c8f2ceec5815533ff5a88d169d098Ted Kremenek if (blockAfterStaticInit) { 2083fbd4b5dc7febd1d8b4fa64ab00a29d72b44bec7bTed Kremenek Succ = B; 20840f5c5c60e9806d13f0907cd99d7204ffab0e08f7Ted Kremenek Block = createBlock(false); 20850f5c5c60e9806d13f0907cd99d7204ffab0e08f7Ted Kremenek Block->setTerminator(DS); 20865062bb22706c8f2ceec5815533ff5a88d169d098Ted Kremenek addSuccessor(Block, blockAfterStaticInit); 20870f5c5c60e9806d13f0907cd99d7204ffab0e08f7Ted Kremenek addSuccessor(Block, B); 20880f5c5c60e9806d13f0907cd99d7204ffab0e08f7Ted Kremenek B = Block; 2089fbd4b5dc7febd1d8b4fa64ab00a29d72b44bec7bTed Kremenek } 2090fbd4b5dc7febd1d8b4fa64ab00a29d72b44bec7bTed Kremenek 2091fbd4b5dc7febd1d8b4fa64ab00a29d72b44bec7bTed Kremenek return B; 2092d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek} 2093fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek 20949c378f705405d37f49795d5e915989de774fe11fTed KremenekCFGBlock *CFGBuilder::VisitIfStmt(IfStmt *I) { 20956d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump // We may see an if statement in the middle of a basic block, or it may be the 20966d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump // first statement we are processing. In either case, we create a new basic 20976d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump // block. First, we create the blocks for the then...else statements, and 20986d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump // then we create the block containing the if statement. If we were in the 20996c2497248bc4f7fd8e5fb0a206d20abbf0e16645Ted Kremenek // middle of a block, we stop processing that block. That block is then the 21006c2497248bc4f7fd8e5fb0a206d20abbf0e16645Ted Kremenek // implicit successor for the "then" and "else" clauses. 21016d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 210204e046cbf7153fc261d730d460f081322d5c42f6Marcin Swiderski // Save local scope position because in case of condition variable ScopePos 210304e046cbf7153fc261d730d460f081322d5c42f6Marcin Swiderski // won't be restored when traversing AST. 210404e046cbf7153fc261d730d460f081322d5c42f6Marcin Swiderski SaveAndRestore<LocalScope::const_iterator> save_scope_pos(ScopePos); 210504e046cbf7153fc261d730d460f081322d5c42f6Marcin Swiderski 210604e046cbf7153fc261d730d460f081322d5c42f6Marcin Swiderski // Create local scope for possible condition variable. 210704e046cbf7153fc261d730d460f081322d5c42f6Marcin Swiderski // Store scope position. Add implicit destructor. 21089c378f705405d37f49795d5e915989de774fe11fTed Kremenek if (VarDecl *VD = I->getConditionVariable()) { 210904e046cbf7153fc261d730d460f081322d5c42f6Marcin Swiderski LocalScope::const_iterator BeginScopePos = ScopePos; 211004e046cbf7153fc261d730d460f081322d5c42f6Marcin Swiderski addLocalScopeForVarDecl(VD); 211104e046cbf7153fc261d730d460f081322d5c42f6Marcin Swiderski addAutomaticObjDtors(ScopePos, BeginScopePos, I); 211204e046cbf7153fc261d730d460f081322d5c42f6Marcin Swiderski } 211304e046cbf7153fc261d730d460f081322d5c42f6Marcin Swiderski 2114fc8f0e14ad142ed811e90fbd9a30e419e301c717Chris Lattner // The block we were processing is now finished. Make it the successor 21156d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump // block. 21166d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump if (Block) { 2117d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek Succ = Block; 2118d438b3dbdcde4df4f61a99054104643e6aadf78bZhongxing Xu if (badCFG) 21196bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return nullptr; 2120c310e933a9b023a280f3aa02e5a0c75398555e13Ted Kremenek } 21216d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 2122b6f1d782e0dc5fad138a17e6aa0ff6f9bc4788c6Ted Kremenek // Process the false branch. 21239c378f705405d37f49795d5e915989de774fe11fTed Kremenek CFGBlock *ElseBlock = Succ; 21246d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 21259c378f705405d37f49795d5e915989de774fe11fTed Kremenek if (Stmt *Else = I->getElse()) { 2126d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek SaveAndRestore<CFGBlock*> sv(Succ); 21276d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 2128d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek // NULL out Block so that the recursive call to Visit will 21296d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump // create a new basic block. 21306bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines Block = nullptr; 213104e046cbf7153fc261d730d460f081322d5c42f6Marcin Swiderski 213204e046cbf7153fc261d730d460f081322d5c42f6Marcin Swiderski // If branch is not a compound statement create implicit scope 213304e046cbf7153fc261d730d460f081322d5c42f6Marcin Swiderski // and add destructors. 213404e046cbf7153fc261d730d460f081322d5c42f6Marcin Swiderski if (!isa<CompoundStmt>(Else)) 213504e046cbf7153fc261d730d460f081322d5c42f6Marcin Swiderski addLocalScopeAndDtors(Else); 213604e046cbf7153fc261d730d460f081322d5c42f6Marcin Swiderski 21374f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek ElseBlock = addStmt(Else); 21386d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 2139b6f7b72047b3fd3f96a5040e1e4d520a9dea01cdTed Kremenek if (!ElseBlock) // Can occur when the Else body has all NullStmts. 2140b6f7b72047b3fd3f96a5040e1e4d520a9dea01cdTed Kremenek ElseBlock = sv.get(); 21414e8df2eb7072db8f66572c3db31a2a08b12a752eTed Kremenek else if (Block) { 2142d438b3dbdcde4df4f61a99054104643e6aadf78bZhongxing Xu if (badCFG) 21436bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return nullptr; 21444e8df2eb7072db8f66572c3db31a2a08b12a752eTed Kremenek } 2145c310e933a9b023a280f3aa02e5a0c75398555e13Ted Kremenek } 21466d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 2147b6f1d782e0dc5fad138a17e6aa0ff6f9bc4788c6Ted Kremenek // Process the true branch. 21489c378f705405d37f49795d5e915989de774fe11fTed Kremenek CFGBlock *ThenBlock; 2149d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek { 21509c378f705405d37f49795d5e915989de774fe11fTed Kremenek Stmt *Then = I->getThen(); 21516db0ad32fa0987ff76d4c41393991ef4b6895ea3Ted Kremenek assert(Then); 2152d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek SaveAndRestore<CFGBlock*> sv(Succ); 21536bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines Block = nullptr; 215404e046cbf7153fc261d730d460f081322d5c42f6Marcin Swiderski 215504e046cbf7153fc261d730d460f081322d5c42f6Marcin Swiderski // If branch is not a compound statement create implicit scope 215604e046cbf7153fc261d730d460f081322d5c42f6Marcin Swiderski // and add destructors. 215704e046cbf7153fc261d730d460f081322d5c42f6Marcin Swiderski if (!isa<CompoundStmt>(Then)) 215804e046cbf7153fc261d730d460f081322d5c42f6Marcin Swiderski addLocalScopeAndDtors(Then); 215904e046cbf7153fc261d730d460f081322d5c42f6Marcin Swiderski 21604f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek ThenBlock = addStmt(Then); 21616d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 2162dbdf7949a7a50f5a65055a3e95f6432ecc541056Ted Kremenek if (!ThenBlock) { 2163dbdf7949a7a50f5a65055a3e95f6432ecc541056Ted Kremenek // We can reach here if the "then" body has all NullStmts. 2164dbdf7949a7a50f5a65055a3e95f6432ecc541056Ted Kremenek // Create an empty block so we can distinguish between true and false 2165dbdf7949a7a50f5a65055a3e95f6432ecc541056Ted Kremenek // branches in path-sensitive analyses. 2166dbdf7949a7a50f5a65055a3e95f6432ecc541056Ted Kremenek ThenBlock = createBlock(false); 21670a3ed3143b00f237decb1288c1ff574ae09eba4eTed Kremenek addSuccessor(ThenBlock, sv.get()); 21686d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump } else if (Block) { 2169d438b3dbdcde4df4f61a99054104643e6aadf78bZhongxing Xu if (badCFG) 21706bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return nullptr; 21716d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump } 21720cebe3e29b22d11f2c65ef28fcfb5f0431877266Ted Kremenek } 2173d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek 21743f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek // Specially handle "if (expr1 || ...)" and "if (expr1 && ...)" by 21753f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek // having these handle the actual control-flow jump. Note that 21763f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek // if we introduce a condition variable, e.g. "if (int x = exp1 || exp2)" 21773f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek // we resort to the old control-flow behavior. This special handling 21783f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek // removes infeasible paths from the control-flow graph by having the 21793f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek // control-flow transfer of '&&' or '||' go directly into the then/else 21803f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek // blocks directly. 21813f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek if (!I->getConditionVariable()) 218256df4a9e0461d4dfb2a740cb6b0ce531d6c82538Richard Smith if (BinaryOperator *Cond = 218356df4a9e0461d4dfb2a740cb6b0ce531d6c82538Richard Smith dyn_cast<BinaryOperator>(I->getCond()->IgnoreParens())) 21843f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek if (Cond->isLogicalOp()) 21853f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek return VisitLogicalOperator(Cond, I, ThenBlock, ElseBlock).first; 21863f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek 21876d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump // Now create a new block containing the if statement. 2188d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek Block = createBlock(false); 21896d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 2190d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek // Set the terminator of the new block to the If statement. 2191d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek Block->setTerminator(I); 21926d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 219300998a068e50945118f334c98af05ed44d7c22a6Mike Stump // See if this is a known constant. 21940a3ed3143b00f237decb1288c1ff574ae09eba4eTed Kremenek const TryResult &KnownVal = tryEvaluateBool(I->getCond()); 219500998a068e50945118f334c98af05ed44d7c22a6Mike Stump 2196651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // Add the successors. If we know that specific branches are 2197651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // unreachable, inform addSuccessor() of that knowledge. 2198651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines addSuccessor(Block, ThenBlock, /* isReachable = */ !KnownVal.isFalse()); 2199651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines addSuccessor(Block, ElseBlock, /* isReachable = */ !KnownVal.isTrue()); 22006d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 22016d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump // Add the condition as the last statement in the new block. This may create 22026d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump // new blocks as the condition may contain control-flow. Any newly created 22036d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump // blocks will be pointed to be "Block". 22048f81acfa95a5d2a22fc875c1a10901eaa30b8405Ted Kremenek CFGBlock *LastBlock = addStmt(I->getCond()); 2205ad5a894df1841698c824381b414630799adc26caTed Kremenek 22066bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines // Finally, if the IfStmt contains a condition variable, add it and its 22076bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines // initializer to the CFG. 22086bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (const DeclStmt* DS = I->getConditionVariableDeclStmt()) { 22096bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines autoCreateBlock(); 22106bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines LastBlock = addStmt(const_cast<DeclStmt *>(DS)); 221161dfbecd8e6181b2ba42ffb5feede27a2bab3b8aTed Kremenek } 2212ad5a894df1841698c824381b414630799adc26caTed Kremenek 22138f81acfa95a5d2a22fc875c1a10901eaa30b8405Ted Kremenek return LastBlock; 2214d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek} 22156d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 22166d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 22179c378f705405d37f49795d5e915989de774fe11fTed KremenekCFGBlock *CFGBuilder::VisitReturnStmt(ReturnStmt *R) { 22186c2497248bc4f7fd8e5fb0a206d20abbf0e16645Ted Kremenek // If we were in the middle of a block we stop processing that block. 2219d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek // 22206d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump // NOTE: If a "return" appears in the middle of a block, this means that the 22216d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump // code afterwards is DEAD (unreachable). We still keep a basic block 22226d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump // for that code; a simple "mark-and-sweep" from the entry block will be 22236d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump // able to report such dead blocks. 2224d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek 2225d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek // Create the new block. 2226d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek Block = createBlock(false); 22276d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 2228fcb72ac985c26372315fabc08d43d6f66ff906b4Marcin Swiderski addAutomaticObjDtors(ScopePos, LocalScope::const_iterator(), R); 22291ae74842cd1be37a8d99d0865623ef16432d3b67Pavel Labath 22301ae74842cd1be37a8d99d0865623ef16432d3b67Pavel Labath // If the one of the destructors does not return, we already have the Exit 22311ae74842cd1be37a8d99d0865623ef16432d3b67Pavel Labath // block as a successor. 22321ae74842cd1be37a8d99d0865623ef16432d3b67Pavel Labath if (!Block->hasNoReturnElement()) 22331ae74842cd1be37a8d99d0865623ef16432d3b67Pavel Labath addSuccessor(Block, &cfg->getExit()); 22346d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 22356d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump // Add the return statement to the block. This may create new blocks if R 22366d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump // contains control-flow (short-circuit operations). 2237852274d4257134906995cb252fb3dfd2d71deae8Ted Kremenek return VisitStmt(R, AddStmtChoice::AlwaysAdd); 2238d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek} 22390cebe3e29b22d11f2c65ef28fcfb5f0431877266Ted Kremenek 22409c378f705405d37f49795d5e915989de774fe11fTed KremenekCFGBlock *CFGBuilder::VisitLabelStmt(LabelStmt *L) { 2241d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek // Get the block of the labeled statement. Add it to our map. 22424f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek addStmt(L->getSubStmt()); 2243ad8dcf4a9df0e24051dc31bf9e6f3cd138a34298Chris Lattner CFGBlock *LabelBlock = Block; 22446d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 22454f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek if (!LabelBlock) // This can happen when the body is empty, i.e. 22464f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek LabelBlock = createBlock(); // scopes that only contains NullStmts. 22476d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 2248ad8dcf4a9df0e24051dc31bf9e6f3cd138a34298Chris Lattner assert(LabelMap.find(L->getDecl()) == LabelMap.end() && 2249ad8dcf4a9df0e24051dc31bf9e6f3cd138a34298Chris Lattner "label already in map"); 2250ad8dcf4a9df0e24051dc31bf9e6f3cd138a34298Chris Lattner LabelMap[L->getDecl()] = JumpTarget(LabelBlock, ScopePos); 22516d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 22526d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump // Labels partition blocks, so this is the end of the basic block we were 22536d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump // processing (L is the block's label). Because this is label (and we have 22546d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump // already processed the substatement) there is no extra control-flow to worry 22556d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump // about. 22569cffe7366ea3beb33c2d58f43a8c3a04c1873e11Ted Kremenek LabelBlock->setLabel(L); 2257d438b3dbdcde4df4f61a99054104643e6aadf78bZhongxing Xu if (badCFG) 22586bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return nullptr; 22596d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 22606d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump // We set Block to NULL to allow lazy creation of a new block (if necessary); 22616bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines Block = nullptr; 22626d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 2263d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek // This block is now the implicit successor of other blocks. 2264d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek Succ = LabelBlock; 22656d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 2266d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek return LabelBlock; 2267d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek} 226831dcd3c8c4df5a656f58f50ea73afc177c101c67Ted Kremenek 226983748e2f41ea0ac7c954946feb5da9ccc6ab8becTed KremenekCFGBlock *CFGBuilder::VisitLambdaExpr(LambdaExpr *E, AddStmtChoice asc) { 227083748e2f41ea0ac7c954946feb5da9ccc6ab8becTed Kremenek CFGBlock *LastBlock = VisitNoRecurse(E, asc); 227183748e2f41ea0ac7c954946feb5da9ccc6ab8becTed Kremenek for (LambdaExpr::capture_init_iterator it = E->capture_init_begin(), 227283748e2f41ea0ac7c954946feb5da9ccc6ab8becTed Kremenek et = E->capture_init_end(); it != et; ++it) { 227383748e2f41ea0ac7c954946feb5da9ccc6ab8becTed Kremenek if (Expr *Init = *it) { 227483748e2f41ea0ac7c954946feb5da9ccc6ab8becTed Kremenek CFGBlock *Tmp = Visit(Init); 22756bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (Tmp) 227683748e2f41ea0ac7c954946feb5da9ccc6ab8becTed Kremenek LastBlock = Tmp; 227783748e2f41ea0ac7c954946feb5da9ccc6ab8becTed Kremenek } 227883748e2f41ea0ac7c954946feb5da9ccc6ab8becTed Kremenek } 227983748e2f41ea0ac7c954946feb5da9ccc6ab8becTed Kremenek return LastBlock; 228083748e2f41ea0ac7c954946feb5da9ccc6ab8becTed Kremenek} 228183748e2f41ea0ac7c954946feb5da9ccc6ab8becTed Kremenek 22829c378f705405d37f49795d5e915989de774fe11fTed KremenekCFGBlock *CFGBuilder::VisitGotoStmt(GotoStmt *G) { 22836d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump // Goto is a control-flow statement. Thus we stop processing the current 22846d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump // block and create a new one. 22854f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek 2286d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek Block = createBlock(false); 2287d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek Block->setTerminator(G); 22886d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 22896d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump // If we already know the mapping to the label block add the successor now. 2290d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek LabelMapTy::iterator I = LabelMap.find(G->getLabel()); 22916d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 2292d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek if (I == LabelMap.end()) 2293d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek // We will need to backpatch this block later. 2294f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski BackpatchBlocks.push_back(JumpSource(Block, ScopePos)); 2295f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski else { 2296f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski JumpTarget JT = I->second; 22979ce5270f0aadaaf03a0cf705787f42ce9eb1194cTed Kremenek addAutomaticObjDtors(ScopePos, JT.scopePosition, G); 22989ce5270f0aadaaf03a0cf705787f42ce9eb1194cTed Kremenek addSuccessor(Block, JT.block); 2299f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski } 2300d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek 23016d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump return Block; 2302d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek} 2303d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek 23049c378f705405d37f49795d5e915989de774fe11fTed KremenekCFGBlock *CFGBuilder::VisitForStmt(ForStmt *F) { 23056bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines CFGBlock *LoopSuccessor = nullptr; 23066d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 230747575f1f775f5f250be4f395fa694a7274a65f33Marcin Swiderski // Save local scope position because in case of condition variable ScopePos 230847575f1f775f5f250be4f395fa694a7274a65f33Marcin Swiderski // won't be restored when traversing AST. 230947575f1f775f5f250be4f395fa694a7274a65f33Marcin Swiderski SaveAndRestore<LocalScope::const_iterator> save_scope_pos(ScopePos); 231047575f1f775f5f250be4f395fa694a7274a65f33Marcin Swiderski 231147575f1f775f5f250be4f395fa694a7274a65f33Marcin Swiderski // Create local scope for init statement and possible condition variable. 231247575f1f775f5f250be4f395fa694a7274a65f33Marcin Swiderski // Add destructor for init statement and condition variable. 231347575f1f775f5f250be4f395fa694a7274a65f33Marcin Swiderski // Store scope position for continue statement. 23149c378f705405d37f49795d5e915989de774fe11fTed Kremenek if (Stmt *Init = F->getInit()) 231547575f1f775f5f250be4f395fa694a7274a65f33Marcin Swiderski addLocalScopeForStmt(Init); 2316f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski LocalScope::const_iterator LoopBeginScopePos = ScopePos; 2317f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski 23189c378f705405d37f49795d5e915989de774fe11fTed Kremenek if (VarDecl *VD = F->getConditionVariable()) 231947575f1f775f5f250be4f395fa694a7274a65f33Marcin Swiderski addLocalScopeForVarDecl(VD); 232047575f1f775f5f250be4f395fa694a7274a65f33Marcin Swiderski LocalScope::const_iterator ContinueScopePos = ScopePos; 232147575f1f775f5f250be4f395fa694a7274a65f33Marcin Swiderski 232247575f1f775f5f250be4f395fa694a7274a65f33Marcin Swiderski addAutomaticObjDtors(ScopePos, save_scope_pos.get(), F); 232347575f1f775f5f250be4f395fa694a7274a65f33Marcin Swiderski 2324fefb9f7009702befaf715e7a8debc9505c3c8634Mike Stump // "for" is a control-flow statement. Thus we stop processing the current 2325fefb9f7009702befaf715e7a8debc9505c3c8634Mike Stump // block. 2326d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek if (Block) { 2327d438b3dbdcde4df4f61a99054104643e6aadf78bZhongxing Xu if (badCFG) 23286bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return nullptr; 2329d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek LoopSuccessor = Block; 23304f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek } else 23314f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek LoopSuccessor = Succ; 23326d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 23333f64a0e3be2c9408f8256bd3aa9f0ce9e268982cTed Kremenek // Save the current value for the break targets. 23343f64a0e3be2c9408f8256bd3aa9f0ce9e268982cTed Kremenek // All breaks should go to the code following the loop. 2335f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski SaveAndRestore<JumpTarget> save_break(BreakJumpTarget); 233647575f1f775f5f250be4f395fa694a7274a65f33Marcin Swiderski BreakJumpTarget = JumpTarget(LoopSuccessor, ScopePos); 23373f64a0e3be2c9408f8256bd3aa9f0ce9e268982cTed Kremenek 23386bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines CFGBlock *BodyBlock = nullptr, *TransitionBlock = nullptr; 233900998a068e50945118f334c98af05ed44d7c22a6Mike Stump 2340d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek // Now create the loop body. 2341d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek { 23426db0ad32fa0987ff76d4c41393991ef4b6895ea3Ted Kremenek assert(F->getBody()); 23436d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 23443f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek // Save the current values for Block, Succ, continue and break targets. 23453f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek SaveAndRestore<CFGBlock*> save_Block(Block), save_Succ(Succ); 23463f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek SaveAndRestore<JumpTarget> save_continue(ContinueJumpTarget); 23476d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 23483f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek // Create an empty block to represent the transition block for looping back 23493f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek // to the head of the loop. If we have increment code, it will 23503f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek // go in this block as well. 23513f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek Block = Succ = TransitionBlock = createBlock(false); 23523f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek TransitionBlock->setLoopTarget(F); 23536d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 23549c378f705405d37f49795d5e915989de774fe11fTed Kremenek if (Stmt *I = F->getInc()) { 23556d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump // Generate increment code in its own basic block. This is the target of 23566d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump // continue statements. 23574f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek Succ = addStmt(I); 2358e933450535ab077b95e59f929a4ccb25b6f360e6Ted Kremenek } 23596d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 23603575f84e459033d6427b84b4b795b22c85c4d27dTed Kremenek // Finish up the increment (or empty) block if it hasn't been already. 23613575f84e459033d6427b84b4b795b22c85c4d27dTed Kremenek if (Block) { 23623575f84e459033d6427b84b4b795b22c85c4d27dTed Kremenek assert(Block == Succ); 2363d438b3dbdcde4df4f61a99054104643e6aadf78bZhongxing Xu if (badCFG) 23646bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return nullptr; 23656bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines Block = nullptr; 23663575f84e459033d6427b84b4b795b22c85c4d27dTed Kremenek } 23676d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 23683f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek // The starting block for the loop increment is the block that should 23693f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek // represent the 'loop target' for looping back to the start of the loop. 23703f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek ContinueJumpTarget = JumpTarget(Succ, ContinueScopePos); 23713f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek ContinueJumpTarget.block->setLoopTarget(F); 23726d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 23733f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek // Loop body should end with destructor of Condition variable (if any). 23743f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek addAutomaticObjDtors(ScopePos, LoopBeginScopePos, F); 23753575f84e459033d6427b84b4b795b22c85c4d27dTed Kremenek 237647575f1f775f5f250be4f395fa694a7274a65f33Marcin Swiderski // If body is not a compound statement create implicit scope 237747575f1f775f5f250be4f395fa694a7274a65f33Marcin Swiderski // and add destructors. 237847575f1f775f5f250be4f395fa694a7274a65f33Marcin Swiderski if (!isa<CompoundStmt>(F->getBody())) 237947575f1f775f5f250be4f395fa694a7274a65f33Marcin Swiderski addLocalScopeAndDtors(F->getBody()); 238047575f1f775f5f250be4f395fa694a7274a65f33Marcin Swiderski 23816d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump // Now populate the body block, and in the process create new blocks as we 23826d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump // walk the body of the loop. 23833f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek BodyBlock = addStmt(F->getBody()); 2384af603f742491dc4707138c0293d295171fdd51baTed Kremenek 23853f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek if (!BodyBlock) { 23863f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek // In the case of "for (...;...;...);" we can have a null BodyBlock. 23873f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek // Use the continue jump target as the proxy for the body. 23883f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek BodyBlock = ContinueJumpTarget.block; 23893f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek } 2390d438b3dbdcde4df4f61a99054104643e6aadf78bZhongxing Xu else if (badCFG) 23916bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return nullptr; 23923f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek } 23933f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek 23943f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek // Because of short-circuit evaluation, the condition of the loop can span 23953f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek // multiple basic blocks. Thus we need the "Entry" and "Exit" blocks that 23963f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek // evaluate the condition. 23976bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines CFGBlock *EntryConditionBlock = nullptr, *ExitConditionBlock = nullptr; 23983f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek 23993f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek do { 24003f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek Expr *C = F->getCond(); 24013f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek 24023f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek // Specially handle logical operators, which have a slightly 24033f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek // more optimal CFG representation. 240456df4a9e0461d4dfb2a740cb6b0ce531d6c82538Richard Smith if (BinaryOperator *Cond = 24056bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines dyn_cast_or_null<BinaryOperator>(C ? C->IgnoreParens() : nullptr)) 24063f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek if (Cond->isLogicalOp()) { 2407651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines std::tie(EntryConditionBlock, ExitConditionBlock) = 24083f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek VisitLogicalOperator(Cond, F, BodyBlock, LoopSuccessor); 24093f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek break; 24103f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek } 24116d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 24123f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek // The default case when not handling logical operators. 24133f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek EntryConditionBlock = ExitConditionBlock = createBlock(false); 24143f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek ExitConditionBlock->setTerminator(F); 24153f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek 24163f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek // See if this is a known constant. 24173f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek TryResult KnownVal(true); 24183f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek 24193f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek if (C) { 24203f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek // Now add the actual condition to the condition block. 24213f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek // Because the condition itself may contain control-flow, new blocks may 24223f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek // be created. Thus we update "Succ" after adding the condition. 24233f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek Block = ExitConditionBlock; 24243f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek EntryConditionBlock = addStmt(C); 24253f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek 24263f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek // If this block contains a condition variable, add both the condition 24273f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek // variable and initializer to the CFG. 24283f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek if (VarDecl *VD = F->getConditionVariable()) { 24293f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek if (Expr *Init = VD->getInit()) { 24303f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek autoCreateBlock(); 24313f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek appendStmt(Block, F->getConditionVariableDeclStmt()); 24323f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek EntryConditionBlock = addStmt(Init); 24333f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek assert(Block == EntryConditionBlock); 24343f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek } 24353f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek } 24363f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek 24373f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek if (Block && badCFG) 24386bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return nullptr; 24393f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek 24403f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek KnownVal = tryEvaluateBool(C); 24413f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek } 24423f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek 24433f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek // Add the loop body entry as a successor to the condition. 24446bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines addSuccessor(ExitConditionBlock, KnownVal.isFalse() ? nullptr : BodyBlock); 24453f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek // Link up the condition block with the code that follows the loop. (the 24463f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek // false branch). 24476bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines addSuccessor(ExitConditionBlock, 24486bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines KnownVal.isTrue() ? nullptr : LoopSuccessor); 24496d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 24503f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek } while (false); 24513f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek 24523f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek // Link up the loop-back block to the entry condition block. 24533f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek addSuccessor(TransitionBlock, EntryConditionBlock); 24543f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek 24553f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek // The condition block is the implicit successor for any code above the loop. 24563f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek Succ = EntryConditionBlock; 24576d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 2458d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek // If the loop contains initialization, create a new block for those 24596d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump // statements. This block can also contain statements that precede the loop. 24609c378f705405d37f49795d5e915989de774fe11fTed Kremenek if (Stmt *I = F->getInit()) { 2461d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek Block = createBlock(); 246249af7cb8a3aca79783e7a0708b97a8f856f0da22Ted Kremenek return addStmt(I); 24632bac4ea765a4a6e1f6149964663f62d4bca6743bTed Kremenek } 246436f327c309b1fb6b82f1987190f0be74000b14c1Zhanyong Wan 246536f327c309b1fb6b82f1987190f0be74000b14c1Zhanyong Wan // There is no loop initialization. We are thus basically a while loop. 246636f327c309b1fb6b82f1987190f0be74000b14c1Zhanyong Wan // NULL out Block to force lazy block construction. 24676bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines Block = nullptr; 246836f327c309b1fb6b82f1987190f0be74000b14c1Zhanyong Wan Succ = EntryConditionBlock; 246936f327c309b1fb6b82f1987190f0be74000b14c1Zhanyong Wan return EntryConditionBlock; 2470d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek} 2471d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek 2472115c1b9cc758d15f38e1d2ad4cf07b1cacfb3115Ted KremenekCFGBlock *CFGBuilder::VisitMemberExpr(MemberExpr *M, AddStmtChoice asc) { 24733179a45a0e91c1dcf3492222170cf4499531bb92Ted Kremenek if (asc.alwaysAdd(*this, M)) { 2474115c1b9cc758d15f38e1d2ad4cf07b1cacfb3115Ted Kremenek autoCreateBlock(); 2475247e9665d897a7bbbf60c1c0d3b6609c4504a961Ted Kremenek appendStmt(Block, M); 2476115c1b9cc758d15f38e1d2ad4cf07b1cacfb3115Ted Kremenek } 2477892697dd2287caf7c29aaaa82909b0e90b8b63feTed Kremenek return Visit(M->getBase()); 2478115c1b9cc758d15f38e1d2ad4cf07b1cacfb3115Ted Kremenek} 2479115c1b9cc758d15f38e1d2ad4cf07b1cacfb3115Ted Kremenek 24809c378f705405d37f49795d5e915989de774fe11fTed KremenekCFGBlock *CFGBuilder::VisitObjCForCollectionStmt(ObjCForCollectionStmt *S) { 2481514de5a21645900c92cf4f4f7313d6f66945d134Ted Kremenek // Objective-C fast enumeration 'for' statements: 2482514de5a21645900c92cf4f4f7313d6f66945d134Ted Kremenek // http://developer.apple.com/documentation/Cocoa/Conceptual/ObjectiveC 2483514de5a21645900c92cf4f4f7313d6f66945d134Ted Kremenek // 2484514de5a21645900c92cf4f4f7313d6f66945d134Ted Kremenek // for ( Type newVariable in collection_expression ) { statements } 2485514de5a21645900c92cf4f4f7313d6f66945d134Ted Kremenek // 2486514de5a21645900c92cf4f4f7313d6f66945d134Ted Kremenek // becomes: 2487514de5a21645900c92cf4f4f7313d6f66945d134Ted Kremenek // 2488514de5a21645900c92cf4f4f7313d6f66945d134Ted Kremenek // prologue: 2489514de5a21645900c92cf4f4f7313d6f66945d134Ted Kremenek // 1. collection_expression 2490514de5a21645900c92cf4f4f7313d6f66945d134Ted Kremenek // T. jump to loop_entry 2491514de5a21645900c92cf4f4f7313d6f66945d134Ted Kremenek // loop_entry: 24924cb3a855df3b3f8d551565cae9f43939a301ea89Ted Kremenek // 1. side-effects of element expression 2493514de5a21645900c92cf4f4f7313d6f66945d134Ted Kremenek // 1. ObjCForCollectionStmt [performs binding to newVariable] 2494514de5a21645900c92cf4f4f7313d6f66945d134Ted Kremenek // T. ObjCForCollectionStmt TB, FB [jumps to TB if newVariable != nil] 2495514de5a21645900c92cf4f4f7313d6f66945d134Ted Kremenek // TB: 2496514de5a21645900c92cf4f4f7313d6f66945d134Ted Kremenek // statements 2497514de5a21645900c92cf4f4f7313d6f66945d134Ted Kremenek // T. jump to loop_entry 2498514de5a21645900c92cf4f4f7313d6f66945d134Ted Kremenek // FB: 2499514de5a21645900c92cf4f4f7313d6f66945d134Ted Kremenek // what comes after 2500514de5a21645900c92cf4f4f7313d6f66945d134Ted Kremenek // 2501514de5a21645900c92cf4f4f7313d6f66945d134Ted Kremenek // and 2502514de5a21645900c92cf4f4f7313d6f66945d134Ted Kremenek // 2503514de5a21645900c92cf4f4f7313d6f66945d134Ted Kremenek // Type existingItem; 2504514de5a21645900c92cf4f4f7313d6f66945d134Ted Kremenek // for ( existingItem in expression ) { statements } 2505514de5a21645900c92cf4f4f7313d6f66945d134Ted Kremenek // 2506514de5a21645900c92cf4f4f7313d6f66945d134Ted Kremenek // becomes: 2507514de5a21645900c92cf4f4f7313d6f66945d134Ted Kremenek // 25086d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump // the same with newVariable replaced with existingItem; the binding works 25096d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump // the same except that for one ObjCForCollectionStmt::getElement() returns 25106d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump // a DeclStmt and the other returns a DeclRefExpr. 2511514de5a21645900c92cf4f4f7313d6f66945d134Ted Kremenek // 25126d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 25136bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines CFGBlock *LoopSuccessor = nullptr; 25146d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 2515514de5a21645900c92cf4f4f7313d6f66945d134Ted Kremenek if (Block) { 2516d438b3dbdcde4df4f61a99054104643e6aadf78bZhongxing Xu if (badCFG) 25176bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return nullptr; 2518514de5a21645900c92cf4f4f7313d6f66945d134Ted Kremenek LoopSuccessor = Block; 25196bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines Block = nullptr; 25204f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek } else 25214f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek LoopSuccessor = Succ; 25226d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 25234cb3a855df3b3f8d551565cae9f43939a301ea89Ted Kremenek // Build the condition blocks. 25249c378f705405d37f49795d5e915989de774fe11fTed Kremenek CFGBlock *ExitConditionBlock = createBlock(false); 25256d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 25264cb3a855df3b3f8d551565cae9f43939a301ea89Ted Kremenek // Set the terminator for the "exit" condition block. 25276d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump ExitConditionBlock->setTerminator(S); 25286d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 25296d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump // The last statement in the block should be the ObjCForCollectionStmt, which 25306d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump // performs the actual binding to 'element' and determines if there are any 25316d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump // more items in the collection. 2532892697dd2287caf7c29aaaa82909b0e90b8b63feTed Kremenek appendStmt(ExitConditionBlock, S); 25334cb3a855df3b3f8d551565cae9f43939a301ea89Ted Kremenek Block = ExitConditionBlock; 25346d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 25354cb3a855df3b3f8d551565cae9f43939a301ea89Ted Kremenek // Walk the 'element' expression to see if there are any side-effects. We 2536fc8f0e14ad142ed811e90fbd9a30e419e301c717Chris Lattner // generate new blocks as necessary. We DON'T add the statement by default to 25376d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump // the CFG unless it contains control-flow. 2538012614ecf78442368ec82ee30efb3bc047b413e6Ted Kremenek CFGBlock *EntryConditionBlock = Visit(S->getElement(), 2539012614ecf78442368ec82ee30efb3bc047b413e6Ted Kremenek AddStmtChoice::NotAlwaysAdd); 25406d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump if (Block) { 2541d438b3dbdcde4df4f61a99054104643e6aadf78bZhongxing Xu if (badCFG) 25426bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return nullptr; 25436bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines Block = nullptr; 25444e8df2eb7072db8f66572c3db31a2a08b12a752eTed Kremenek } 25456d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 25466d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump // The condition block is the implicit successor for the loop body as well as 25476d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump // any code above the loop. 25484cb3a855df3b3f8d551565cae9f43939a301ea89Ted Kremenek Succ = EntryConditionBlock; 25496d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 25504cb3a855df3b3f8d551565cae9f43939a301ea89Ted Kremenek // Now create the true branch. 25516d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump { 25524cb3a855df3b3f8d551565cae9f43939a301ea89Ted Kremenek // Save the current values for Succ, continue and break targets. 25534c98b1f67cdf385e05a86d54201b319cf1f1c042Anna Zaks SaveAndRestore<CFGBlock*> save_Block(Block), save_Succ(Succ); 2554f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski SaveAndRestore<JumpTarget> save_continue(ContinueJumpTarget), 25554c98b1f67cdf385e05a86d54201b319cf1f1c042Anna Zaks save_break(BreakJumpTarget); 25564c98b1f67cdf385e05a86d54201b319cf1f1c042Anna Zaks 25574c98b1f67cdf385e05a86d54201b319cf1f1c042Anna Zaks // Add an intermediate block between the BodyBlock and the 25584c98b1f67cdf385e05a86d54201b319cf1f1c042Anna Zaks // EntryConditionBlock to represent the "loop back" transition, for looping 25594c98b1f67cdf385e05a86d54201b319cf1f1c042Anna Zaks // back to the head of the loop. 25606bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines CFGBlock *LoopBackBlock = nullptr; 25614c98b1f67cdf385e05a86d54201b319cf1f1c042Anna Zaks Succ = LoopBackBlock = createBlock(); 25624c98b1f67cdf385e05a86d54201b319cf1f1c042Anna Zaks LoopBackBlock->setLoopTarget(S); 25634c98b1f67cdf385e05a86d54201b319cf1f1c042Anna Zaks 2564f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski BreakJumpTarget = JumpTarget(LoopSuccessor, ScopePos); 25654c98b1f67cdf385e05a86d54201b319cf1f1c042Anna Zaks ContinueJumpTarget = JumpTarget(Succ, ScopePos); 25666d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 25679c378f705405d37f49795d5e915989de774fe11fTed Kremenek CFGBlock *BodyBlock = addStmt(S->getBody()); 25686d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 25694cb3a855df3b3f8d551565cae9f43939a301ea89Ted Kremenek if (!BodyBlock) 25704c98b1f67cdf385e05a86d54201b319cf1f1c042Anna Zaks BodyBlock = ContinueJumpTarget.block; // can happen for "for (X in Y) ;" 25714e8df2eb7072db8f66572c3db31a2a08b12a752eTed Kremenek else if (Block) { 2572d438b3dbdcde4df4f61a99054104643e6aadf78bZhongxing Xu if (badCFG) 25736bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return nullptr; 25744e8df2eb7072db8f66572c3db31a2a08b12a752eTed Kremenek } 25756d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 25764cb3a855df3b3f8d551565cae9f43939a301ea89Ted Kremenek // This new body block is a successor to our "exit" condition block. 25770a3ed3143b00f237decb1288c1ff574ae09eba4eTed Kremenek addSuccessor(ExitConditionBlock, BodyBlock); 25784cb3a855df3b3f8d551565cae9f43939a301ea89Ted Kremenek } 25796d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 25804cb3a855df3b3f8d551565cae9f43939a301ea89Ted Kremenek // Link up the condition block with the code that follows the loop. 25814cb3a855df3b3f8d551565cae9f43939a301ea89Ted Kremenek // (the false branch). 25820a3ed3143b00f237decb1288c1ff574ae09eba4eTed Kremenek addSuccessor(ExitConditionBlock, LoopSuccessor); 25834cb3a855df3b3f8d551565cae9f43939a301ea89Ted Kremenek 2584514de5a21645900c92cf4f4f7313d6f66945d134Ted Kremenek // Now create a prologue block to contain the collection expression. 25854cb3a855df3b3f8d551565cae9f43939a301ea89Ted Kremenek Block = createBlock(); 2586514de5a21645900c92cf4f4f7313d6f66945d134Ted Kremenek return addStmt(S->getCollection()); 25876d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump} 25886d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 25898e282c332f8ad51dedf86a185a4dcb78ef93fb51Ted KremenekCFGBlock *CFGBuilder::VisitObjCAutoreleasePoolStmt(ObjCAutoreleasePoolStmt *S) { 25908e282c332f8ad51dedf86a185a4dcb78ef93fb51Ted Kremenek // Inline the body. 25918e282c332f8ad51dedf86a185a4dcb78ef93fb51Ted Kremenek return addStmt(S->getSubStmt()); 25928e282c332f8ad51dedf86a185a4dcb78ef93fb51Ted Kremenek // TODO: consider adding cleanups for the end of @autoreleasepool scope. 25938e282c332f8ad51dedf86a185a4dcb78ef93fb51Ted Kremenek} 25948e282c332f8ad51dedf86a185a4dcb78ef93fb51Ted Kremenek 25959c378f705405d37f49795d5e915989de774fe11fTed KremenekCFGBlock *CFGBuilder::VisitObjCAtSynchronizedStmt(ObjCAtSynchronizedStmt *S) { 2596b3b0b3624e462c2940f65b86e773bfc300005203Ted Kremenek // FIXME: Add locking 'primitives' to CFG for @synchronized. 25976d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 2598b3b0b3624e462c2940f65b86e773bfc300005203Ted Kremenek // Inline the body. 25994f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek CFGBlock *SyncBlock = addStmt(S->getSynchBody()); 26006d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 2601da5348eda7bb45d715561249dec9833d51dfda67Ted Kremenek // The sync body starts its own basic block. This makes it a little easier 2602da5348eda7bb45d715561249dec9833d51dfda67Ted Kremenek // for diagnostic clients. 2603da5348eda7bb45d715561249dec9833d51dfda67Ted Kremenek if (SyncBlock) { 2604d438b3dbdcde4df4f61a99054104643e6aadf78bZhongxing Xu if (badCFG) 26056bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return nullptr; 26066d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 26076bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines Block = nullptr; 2608fadebbafe622752c3c6565b53ce8cd42bbbbd90cTed Kremenek Succ = SyncBlock; 2609da5348eda7bb45d715561249dec9833d51dfda67Ted Kremenek } 26106d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 26114beaa9f51b2da57c64740cef2bd1c2fdb0c325d5Ted Kremenek // Add the @synchronized to the CFG. 26124beaa9f51b2da57c64740cef2bd1c2fdb0c325d5Ted Kremenek autoCreateBlock(); 2613247e9665d897a7bbbf60c1c0d3b6609c4504a961Ted Kremenek appendStmt(Block, S); 26144beaa9f51b2da57c64740cef2bd1c2fdb0c325d5Ted Kremenek 2615b3b0b3624e462c2940f65b86e773bfc300005203Ted Kremenek // Inline the sync expression. 26164f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek return addStmt(S->getSynchExpr()); 2617b3b0b3624e462c2940f65b86e773bfc300005203Ted Kremenek} 26186d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 26199c378f705405d37f49795d5e915989de774fe11fTed KremenekCFGBlock *CFGBuilder::VisitObjCAtTryStmt(ObjCAtTryStmt *S) { 26204f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek // FIXME 262190658ec72542df44eb462c69056184d2946bdbceTed Kremenek return NYS(); 2622e31c0d206b872b056dc42c3af21b11d5de4edfd9Ted Kremenek} 2623514de5a21645900c92cf4f4f7313d6f66945d134Ted Kremenek 26244b9c2d235fb9449e249d74f48ecfec601650de93John McCallCFGBlock *CFGBuilder::VisitPseudoObjectExpr(PseudoObjectExpr *E) { 26254b9c2d235fb9449e249d74f48ecfec601650de93John McCall autoCreateBlock(); 26264b9c2d235fb9449e249d74f48ecfec601650de93John McCall 26274b9c2d235fb9449e249d74f48ecfec601650de93John McCall // Add the PseudoObject as the last thing. 26284b9c2d235fb9449e249d74f48ecfec601650de93John McCall appendStmt(Block, E); 26294b9c2d235fb9449e249d74f48ecfec601650de93John McCall 26304b9c2d235fb9449e249d74f48ecfec601650de93John McCall CFGBlock *lastBlock = Block; 26314b9c2d235fb9449e249d74f48ecfec601650de93John McCall 26324b9c2d235fb9449e249d74f48ecfec601650de93John McCall // Before that, evaluate all of the semantics in order. In 26334b9c2d235fb9449e249d74f48ecfec601650de93John McCall // CFG-land, that means appending them in reverse order. 26344b9c2d235fb9449e249d74f48ecfec601650de93John McCall for (unsigned i = E->getNumSemanticExprs(); i != 0; ) { 26354b9c2d235fb9449e249d74f48ecfec601650de93John McCall Expr *Semantic = E->getSemanticExpr(--i); 26364b9c2d235fb9449e249d74f48ecfec601650de93John McCall 26374b9c2d235fb9449e249d74f48ecfec601650de93John McCall // If the semantic is an opaque value, we're being asked to bind 26384b9c2d235fb9449e249d74f48ecfec601650de93John McCall // it to its source expression. 26394b9c2d235fb9449e249d74f48ecfec601650de93John McCall if (OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(Semantic)) 26404b9c2d235fb9449e249d74f48ecfec601650de93John McCall Semantic = OVE->getSourceExpr(); 26414b9c2d235fb9449e249d74f48ecfec601650de93John McCall 26424b9c2d235fb9449e249d74f48ecfec601650de93John McCall if (CFGBlock *B = Visit(Semantic)) 26434b9c2d235fb9449e249d74f48ecfec601650de93John McCall lastBlock = B; 26444b9c2d235fb9449e249d74f48ecfec601650de93John McCall } 26454b9c2d235fb9449e249d74f48ecfec601650de93John McCall 26464b9c2d235fb9449e249d74f48ecfec601650de93John McCall return lastBlock; 26474b9c2d235fb9449e249d74f48ecfec601650de93John McCall} 26484b9c2d235fb9449e249d74f48ecfec601650de93John McCall 26499c378f705405d37f49795d5e915989de774fe11fTed KremenekCFGBlock *CFGBuilder::VisitWhileStmt(WhileStmt *W) { 26506bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines CFGBlock *LoopSuccessor = nullptr; 26516d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 265205adedcb5e199e377e35f576288caf5ceed40136Marcin Swiderski // Save local scope position because in case of condition variable ScopePos 265305adedcb5e199e377e35f576288caf5ceed40136Marcin Swiderski // won't be restored when traversing AST. 265405adedcb5e199e377e35f576288caf5ceed40136Marcin Swiderski SaveAndRestore<LocalScope::const_iterator> save_scope_pos(ScopePos); 265505adedcb5e199e377e35f576288caf5ceed40136Marcin Swiderski 265605adedcb5e199e377e35f576288caf5ceed40136Marcin Swiderski // Create local scope for possible condition variable. 265705adedcb5e199e377e35f576288caf5ceed40136Marcin Swiderski // Store scope position for continue statement. 2658f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski LocalScope::const_iterator LoopBeginScopePos = ScopePos; 26599c378f705405d37f49795d5e915989de774fe11fTed Kremenek if (VarDecl *VD = W->getConditionVariable()) { 266005adedcb5e199e377e35f576288caf5ceed40136Marcin Swiderski addLocalScopeForVarDecl(VD); 266105adedcb5e199e377e35f576288caf5ceed40136Marcin Swiderski addAutomaticObjDtors(ScopePos, LoopBeginScopePos, W); 266205adedcb5e199e377e35f576288caf5ceed40136Marcin Swiderski } 2663f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski 2664fefb9f7009702befaf715e7a8debc9505c3c8634Mike Stump // "while" is a control-flow statement. Thus we stop processing the current 2665fefb9f7009702befaf715e7a8debc9505c3c8634Mike Stump // block. 2666d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek if (Block) { 2667d438b3dbdcde4df4f61a99054104643e6aadf78bZhongxing Xu if (badCFG) 26686bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return nullptr; 2669d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek LoopSuccessor = Block; 26706bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines Block = nullptr; 26713f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek } else { 26724f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek LoopSuccessor = Succ; 267349af7cb8a3aca79783e7a0708b97a8f856f0da22Ted Kremenek } 26746d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 26756bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines CFGBlock *BodyBlock = nullptr, *TransitionBlock = nullptr; 267600998a068e50945118f334c98af05ed44d7c22a6Mike Stump 2677d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek // Process the loop body. 2678d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek { 2679f6e8541dd884029b85483a319ce7d32f3e476dccTed Kremenek assert(W->getBody()); 2680d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek 26813f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek // Save the current values for Block, Succ, continue and break targets. 2682f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski SaveAndRestore<CFGBlock*> save_Block(Block), save_Succ(Succ); 2683f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski SaveAndRestore<JumpTarget> save_continue(ContinueJumpTarget), 26843f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek save_break(BreakJumpTarget); 2685f6e8541dd884029b85483a319ce7d32f3e476dccTed Kremenek 26866d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump // Create an empty block to represent the transition block for looping back 26876d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump // to the head of the loop. 26883f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek Succ = TransitionBlock = createBlock(false); 26893f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek TransitionBlock->setLoopTarget(W); 2690f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski ContinueJumpTarget = JumpTarget(Succ, LoopBeginScopePos); 26916d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 2692d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek // All breaks should go to the code following the loop. 269305adedcb5e199e377e35f576288caf5ceed40136Marcin Swiderski BreakJumpTarget = JumpTarget(LoopSuccessor, ScopePos); 26946d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 269505adedcb5e199e377e35f576288caf5ceed40136Marcin Swiderski // Loop body should end with destructor of Condition variable (if any). 269605adedcb5e199e377e35f576288caf5ceed40136Marcin Swiderski addAutomaticObjDtors(ScopePos, LoopBeginScopePos, W); 269705adedcb5e199e377e35f576288caf5ceed40136Marcin Swiderski 269805adedcb5e199e377e35f576288caf5ceed40136Marcin Swiderski // If body is not a compound statement create implicit scope 269905adedcb5e199e377e35f576288caf5ceed40136Marcin Swiderski // and add destructors. 270005adedcb5e199e377e35f576288caf5ceed40136Marcin Swiderski if (!isa<CompoundStmt>(W->getBody())) 270105adedcb5e199e377e35f576288caf5ceed40136Marcin Swiderski addLocalScopeAndDtors(W->getBody()); 270205adedcb5e199e377e35f576288caf5ceed40136Marcin Swiderski 2703d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek // Create the body. The returned block is the entry to the loop body. 27043f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek BodyBlock = addStmt(W->getBody()); 27056d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 2706af603f742491dc4707138c0293d295171fdd51baTed Kremenek if (!BodyBlock) 27079ce5270f0aadaaf03a0cf705787f42ce9eb1194cTed Kremenek BodyBlock = ContinueJumpTarget.block; // can happen for "while(...) ;" 27083f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek else if (Block && badCFG) 27096bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return nullptr; 27103f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek } 27113f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek 27123f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek // Because of short-circuit evaluation, the condition of the loop can span 27133f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek // multiple basic blocks. Thus we need the "Entry" and "Exit" blocks that 27143f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek // evaluate the condition. 27156bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines CFGBlock *EntryConditionBlock = nullptr, *ExitConditionBlock = nullptr; 27163f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek 27173f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek do { 27183f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek Expr *C = W->getCond(); 27193f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek 27203f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek // Specially handle logical operators, which have a slightly 27213f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek // more optimal CFG representation. 272256df4a9e0461d4dfb2a740cb6b0ce531d6c82538Richard Smith if (BinaryOperator *Cond = dyn_cast<BinaryOperator>(C->IgnoreParens())) 27233f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek if (Cond->isLogicalOp()) { 2724651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines std::tie(EntryConditionBlock, ExitConditionBlock) = 2725651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines VisitLogicalOperator(Cond, W, BodyBlock, LoopSuccessor); 27263f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek break; 27273f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek } 27283f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek 27293f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek // The default case when not handling logical operators. 2730857f5681f5e2bbb482f41f461add502b556c712aTed Kremenek ExitConditionBlock = createBlock(false); 27313f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek ExitConditionBlock->setTerminator(W); 27323f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek 27333f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek // Now add the actual condition to the condition block. 27343f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek // Because the condition itself may contain control-flow, new blocks may 27353f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek // be created. Thus we update "Succ" after adding the condition. 27363f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek Block = ExitConditionBlock; 27373f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek Block = EntryConditionBlock = addStmt(C); 27383f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek 27393f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek // If this block contains a condition variable, add both the condition 27403f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek // variable and initializer to the CFG. 27413f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek if (VarDecl *VD = W->getConditionVariable()) { 27423f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek if (Expr *Init = VD->getInit()) { 27433f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek autoCreateBlock(); 27443f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek appendStmt(Block, W->getConditionVariableDeclStmt()); 27453f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek EntryConditionBlock = addStmt(Init); 27463f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek assert(Block == EntryConditionBlock); 27473f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek } 27484e8df2eb7072db8f66572c3db31a2a08b12a752eTed Kremenek } 27496d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 27503f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek if (Block && badCFG) 27516bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return nullptr; 27523f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek 27533f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek // See if this is a known constant. 27543f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek const TryResult& KnownVal = tryEvaluateBool(C); 27553f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek 2756941fde8019d47c694b8483db45d5878818fa69d1Ted Kremenek // Add the loop body entry as a successor to the condition. 27576bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines addSuccessor(ExitConditionBlock, KnownVal.isFalse() ? nullptr : BodyBlock); 27583f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek // Link up the condition block with the code that follows the loop. (the 27593f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek // false branch). 27606bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines addSuccessor(ExitConditionBlock, 27616bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines KnownVal.isTrue() ? nullptr : LoopSuccessor); 27623f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek 27633f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek } while(false); 27646d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 27653f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek // Link up the loop-back block to the entry condition block. 27663f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek addSuccessor(TransitionBlock, EntryConditionBlock); 27676d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 27686d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump // There can be no more statements in the condition block since we loop back 27696d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump // to this block. NULL out Block to force lazy creation of another block. 27706bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines Block = nullptr; 27716d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 27724ec010a6ccf4db2ab2ef9e68942642d50f7f193cTed Kremenek // Return the condition block, which is the dominating block for the loop. 27735482713d70ecbfe608940018046aa248b3d03443Ted Kremenek Succ = EntryConditionBlock; 277449af7cb8a3aca79783e7a0708b97a8f856f0da22Ted Kremenek return EntryConditionBlock; 2775d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek} 27761eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 27771eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 27789c378f705405d37f49795d5e915989de774fe11fTed KremenekCFGBlock *CFGBuilder::VisitObjCAtCatchStmt(ObjCAtCatchStmt *S) { 27794f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek // FIXME: For now we pretend that @catch and the code it contains does not 27804f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek // exit. 27814f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek return Block; 27824f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek} 27836d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 27849c378f705405d37f49795d5e915989de774fe11fTed KremenekCFGBlock *CFGBuilder::VisitObjCAtThrowStmt(ObjCAtThrowStmt *S) { 27852fda504dccd79f91ac9a7d82acecfbab3eaa1719Ted Kremenek // FIXME: This isn't complete. We basically treat @throw like a return 27862fda504dccd79f91ac9a7d82acecfbab3eaa1719Ted Kremenek // statement. 27876d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 27886c2497248bc4f7fd8e5fb0a206d20abbf0e16645Ted Kremenek // If we were in the middle of a block we stop processing that block. 2789d438b3dbdcde4df4f61a99054104643e6aadf78bZhongxing Xu if (badCFG) 27906bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return nullptr; 27916d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 27922fda504dccd79f91ac9a7d82acecfbab3eaa1719Ted Kremenek // Create the new block. 27932fda504dccd79f91ac9a7d82acecfbab3eaa1719Ted Kremenek Block = createBlock(false); 27946d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 27952fda504dccd79f91ac9a7d82acecfbab3eaa1719Ted Kremenek // The Exit block is the only successor. 27960a3ed3143b00f237decb1288c1ff574ae09eba4eTed Kremenek addSuccessor(Block, &cfg->getExit()); 27976d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 27986d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump // Add the statement to the block. This may create new blocks if S contains 27996d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump // control-flow (short-circuit operations). 2800852274d4257134906995cb252fb3dfd2d71deae8Ted Kremenek return VisitStmt(S, AddStmtChoice::AlwaysAdd); 28012fda504dccd79f91ac9a7d82acecfbab3eaa1719Ted Kremenek} 2802989d52d469df0c202f7de82f54407066c7db2e63Ted Kremenek 28039c378f705405d37f49795d5e915989de774fe11fTed KremenekCFGBlock *CFGBuilder::VisitCXXThrowExpr(CXXThrowExpr *T) { 28046c2497248bc4f7fd8e5fb0a206d20abbf0e16645Ted Kremenek // If we were in the middle of a block we stop processing that block. 2805d438b3dbdcde4df4f61a99054104643e6aadf78bZhongxing Xu if (badCFG) 28066bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return nullptr; 28070979d80615df97c675423de631c1b884819f4712Mike Stump 28080979d80615df97c675423de631c1b884819f4712Mike Stump // Create the new block. 28090979d80615df97c675423de631c1b884819f4712Mike Stump Block = createBlock(false); 28100979d80615df97c675423de631c1b884819f4712Mike Stump 28115d1d20227878cd03db8b2dd23efd4cedfe874feeMike Stump if (TryTerminatedBlock) 28125d1d20227878cd03db8b2dd23efd4cedfe874feeMike Stump // The current try statement is the only successor. 28130a3ed3143b00f237decb1288c1ff574ae09eba4eTed Kremenek addSuccessor(Block, TryTerminatedBlock); 2814ad5a894df1841698c824381b414630799adc26caTed Kremenek else 28155d1d20227878cd03db8b2dd23efd4cedfe874feeMike Stump // otherwise the Exit block is the only successor. 28160a3ed3143b00f237decb1288c1ff574ae09eba4eTed Kremenek addSuccessor(Block, &cfg->getExit()); 28170979d80615df97c675423de631c1b884819f4712Mike Stump 28180979d80615df97c675423de631c1b884819f4712Mike Stump // Add the statement to the block. This may create new blocks if S contains 28190979d80615df97c675423de631c1b884819f4712Mike Stump // control-flow (short-circuit operations). 2820852274d4257134906995cb252fb3dfd2d71deae8Ted Kremenek return VisitStmt(T, AddStmtChoice::AlwaysAdd); 28210979d80615df97c675423de631c1b884819f4712Mike Stump} 28220979d80615df97c675423de631c1b884819f4712Mike Stump 28239c378f705405d37f49795d5e915989de774fe11fTed KremenekCFGBlock *CFGBuilder::VisitDoStmt(DoStmt *D) { 28246bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines CFGBlock *LoopSuccessor = nullptr; 28256d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 28268f9893a2beeacd5149bd2d3d4c6e130516915068Mike Stump // "do...while" is a control-flow statement. Thus we stop processing the 28278f9893a2beeacd5149bd2d3d4c6e130516915068Mike Stump // current block. 2828d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek if (Block) { 2829d438b3dbdcde4df4f61a99054104643e6aadf78bZhongxing Xu if (badCFG) 28306bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return nullptr; 2831d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek LoopSuccessor = Block; 28324f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek } else 28334f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek LoopSuccessor = Succ; 28346d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 28356d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump // Because of short-circuit evaluation, the condition of the loop can span 28366d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump // multiple basic blocks. Thus we need the "Entry" and "Exit" blocks that 28376d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump // evaluate the condition. 28389c378f705405d37f49795d5e915989de774fe11fTed Kremenek CFGBlock *ExitConditionBlock = createBlock(false); 28399c378f705405d37f49795d5e915989de774fe11fTed Kremenek CFGBlock *EntryConditionBlock = ExitConditionBlock; 28406d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 284149af7cb8a3aca79783e7a0708b97a8f856f0da22Ted Kremenek // Set the terminator for the "exit" condition block. 28426d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump ExitConditionBlock->setTerminator(D); 28436d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 28446d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump // Now add the actual condition to the condition block. Because the condition 28456d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump // itself may contain control-flow, new blocks may be created. 28469c378f705405d37f49795d5e915989de774fe11fTed Kremenek if (Stmt *C = D->getCond()) { 284749af7cb8a3aca79783e7a0708b97a8f856f0da22Ted Kremenek Block = ExitConditionBlock; 284849af7cb8a3aca79783e7a0708b97a8f856f0da22Ted Kremenek EntryConditionBlock = addStmt(C); 28494e8df2eb7072db8f66572c3db31a2a08b12a752eTed Kremenek if (Block) { 2850d438b3dbdcde4df4f61a99054104643e6aadf78bZhongxing Xu if (badCFG) 28516bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return nullptr; 28524e8df2eb7072db8f66572c3db31a2a08b12a752eTed Kremenek } 285349af7cb8a3aca79783e7a0708b97a8f856f0da22Ted Kremenek } 28546d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 28555482713d70ecbfe608940018046aa248b3d03443Ted Kremenek // The condition block is the implicit successor for the loop body. 285649af7cb8a3aca79783e7a0708b97a8f856f0da22Ted Kremenek Succ = EntryConditionBlock; 285749af7cb8a3aca79783e7a0708b97a8f856f0da22Ted Kremenek 285800998a068e50945118f334c98af05ed44d7c22a6Mike Stump // See if this is a known constant. 28590a3ed3143b00f237decb1288c1ff574ae09eba4eTed Kremenek const TryResult &KnownVal = tryEvaluateBool(D->getCond()); 286000998a068e50945118f334c98af05ed44d7c22a6Mike Stump 2861d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek // Process the loop body. 28626bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines CFGBlock *BodyBlock = nullptr; 2863d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek { 28646db0ad32fa0987ff76d4c41393991ef4b6895ea3Ted Kremenek assert(D->getBody()); 28656d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 2866d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek // Save the current values for Block, Succ, and continue and break targets 2867f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski SaveAndRestore<CFGBlock*> save_Block(Block), save_Succ(Succ); 2868f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski SaveAndRestore<JumpTarget> save_continue(ContinueJumpTarget), 2869f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski save_break(BreakJumpTarget); 28706d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 2871d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek // All continues within this loop should go to the condition block 2872f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski ContinueJumpTarget = JumpTarget(EntryConditionBlock, ScopePos); 28736d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 2874d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek // All breaks should go to the code following the loop. 2875f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski BreakJumpTarget = JumpTarget(LoopSuccessor, ScopePos); 28766d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 2877d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek // NULL out Block to force lazy instantiation of blocks for the body. 28786bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines Block = nullptr; 28796d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 288005adedcb5e199e377e35f576288caf5ceed40136Marcin Swiderski // If body is not a compound statement create implicit scope 288105adedcb5e199e377e35f576288caf5ceed40136Marcin Swiderski // and add destructors. 288205adedcb5e199e377e35f576288caf5ceed40136Marcin Swiderski if (!isa<CompoundStmt>(D->getBody())) 288305adedcb5e199e377e35f576288caf5ceed40136Marcin Swiderski addLocalScopeAndDtors(D->getBody()); 288405adedcb5e199e377e35f576288caf5ceed40136Marcin Swiderski 2885d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek // Create the body. The returned block is the entry to the loop body. 28864f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek BodyBlock = addStmt(D->getBody()); 28876d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 2888af603f742491dc4707138c0293d295171fdd51baTed Kremenek if (!BodyBlock) 2889a9d996dbeb719200c4a9d86f68166a237583025fTed Kremenek BodyBlock = EntryConditionBlock; // can happen for "do ; while(...)" 28904e8df2eb7072db8f66572c3db31a2a08b12a752eTed Kremenek else if (Block) { 2891d438b3dbdcde4df4f61a99054104643e6aadf78bZhongxing Xu if (badCFG) 28926bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return nullptr; 28934e8df2eb7072db8f66572c3db31a2a08b12a752eTed Kremenek } 28946d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 2895d173dc7825e999edab836f8215a82a96eae7c738Ted Kremenek if (!KnownVal.isFalse()) { 2896d173dc7825e999edab836f8215a82a96eae7c738Ted Kremenek // Add an intermediate block between the BodyBlock and the 2897d173dc7825e999edab836f8215a82a96eae7c738Ted Kremenek // ExitConditionBlock to represent the "loop back" transition. Create an 2898d173dc7825e999edab836f8215a82a96eae7c738Ted Kremenek // empty block to represent the transition block for looping back to the 2899d173dc7825e999edab836f8215a82a96eae7c738Ted Kremenek // head of the loop. 2900d173dc7825e999edab836f8215a82a96eae7c738Ted Kremenek // FIXME: Can we do this more efficiently without adding another block? 29016bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines Block = nullptr; 2902d173dc7825e999edab836f8215a82a96eae7c738Ted Kremenek Succ = BodyBlock; 2903d173dc7825e999edab836f8215a82a96eae7c738Ted Kremenek CFGBlock *LoopBackBlock = createBlock(); 2904d173dc7825e999edab836f8215a82a96eae7c738Ted Kremenek LoopBackBlock->setLoopTarget(D); 2905d173dc7825e999edab836f8215a82a96eae7c738Ted Kremenek 2906d173dc7825e999edab836f8215a82a96eae7c738Ted Kremenek // Add the loop body entry as a successor to the condition. 29070a3ed3143b00f237decb1288c1ff574ae09eba4eTed Kremenek addSuccessor(ExitConditionBlock, LoopBackBlock); 2908d173dc7825e999edab836f8215a82a96eae7c738Ted Kremenek } 2909d173dc7825e999edab836f8215a82a96eae7c738Ted Kremenek else 29106bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines addSuccessor(ExitConditionBlock, nullptr); 2911b5c13b0f4e438391b31dacb87641be7a1b990b57Ted Kremenek } 29126d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 2913941fde8019d47c694b8483db45d5878818fa69d1Ted Kremenek // Link up the condition block with the code that follows the loop. 2914941fde8019d47c694b8483db45d5878818fa69d1Ted Kremenek // (the false branch). 29156bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines addSuccessor(ExitConditionBlock, KnownVal.isTrue() ? nullptr : LoopSuccessor); 29166d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 29176d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump // There can be no more statements in the body block(s) since we loop back to 29186d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump // the body. NULL out Block to force lazy creation of another block. 29196bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines Block = nullptr; 29206d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 2921d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek // Return the loop body, which is the dominating block for the loop. 29225482713d70ecbfe608940018046aa248b3d03443Ted Kremenek Succ = BodyBlock; 2923d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek return BodyBlock; 2924d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek} 2925d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek 29269c378f705405d37f49795d5e915989de774fe11fTed KremenekCFGBlock *CFGBuilder::VisitContinueStmt(ContinueStmt *C) { 2927d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek // "continue" is a control-flow statement. Thus we stop processing the 2928d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek // current block. 2929d438b3dbdcde4df4f61a99054104643e6aadf78bZhongxing Xu if (badCFG) 29306bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return nullptr; 29316d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 2932d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek // Now create a new block that ends with the continue statement. 2933d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek Block = createBlock(false); 2934d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek Block->setTerminator(C); 29356d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 2936d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek // If there is no target for the continue, then we are looking at an 2937235c5ed8bee5bbcb45de1707d6988635e49b10b8Ted Kremenek // incomplete AST. This means the CFG cannot be constructed. 29389ce5270f0aadaaf03a0cf705787f42ce9eb1194cTed Kremenek if (ContinueJumpTarget.block) { 29399ce5270f0aadaaf03a0cf705787f42ce9eb1194cTed Kremenek addAutomaticObjDtors(ScopePos, ContinueJumpTarget.scopePosition, C); 29409ce5270f0aadaaf03a0cf705787f42ce9eb1194cTed Kremenek addSuccessor(Block, ContinueJumpTarget.block); 2941f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski } else 2942235c5ed8bee5bbcb45de1707d6988635e49b10b8Ted Kremenek badCFG = true; 29436d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 2944d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek return Block; 2945d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek} 29461eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 2947f4e3cfbe8abd124be6341ef5d714819b4fbd9082Peter CollingbourneCFGBlock *CFGBuilder::VisitUnaryExprOrTypeTraitExpr(UnaryExprOrTypeTraitExpr *E, 2948f4e3cfbe8abd124be6341ef5d714819b4fbd9082Peter Collingbourne AddStmtChoice asc) { 294913fc08a323b29dd97a46def1e3a15bf082476efaTed Kremenek 29503179a45a0e91c1dcf3492222170cf4499531bb92Ted Kremenek if (asc.alwaysAdd(*this, E)) { 295113fc08a323b29dd97a46def1e3a15bf082476efaTed Kremenek autoCreateBlock(); 2952892697dd2287caf7c29aaaa82909b0e90b8b63feTed Kremenek appendStmt(Block, E); 295313fc08a323b29dd97a46def1e3a15bf082476efaTed Kremenek } 29541eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 29554f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek // VLA types have expressions that must be evaluated. 295697e50714c262cc421f960303171d2c1afbc9bb4fTed Kremenek CFGBlock *lastBlock = Block; 295797e50714c262cc421f960303171d2c1afbc9bb4fTed Kremenek 29584f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek if (E->isArgumentType()) { 2959f4c7371fb1d3cebcfb40abad4537bb82515704eaJohn McCall for (const VariableArrayType *VA =FindVA(E->getArgumentType().getTypePtr()); 29606bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines VA != nullptr; VA = FindVA(VA->getElementType().getTypePtr())) 296197e50714c262cc421f960303171d2c1afbc9bb4fTed Kremenek lastBlock = addStmt(VA->getSizeExpr()); 2962f91a5b008d1a63630ae483247204c2651e512fa1Ted Kremenek } 296397e50714c262cc421f960303171d2c1afbc9bb4fTed Kremenek return lastBlock; 2964d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek} 29651eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 29664f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek/// VisitStmtExpr - Utility method to handle (nested) statement 29674f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek/// expressions (a GCC extension). 29689c378f705405d37f49795d5e915989de774fe11fTed KremenekCFGBlock *CFGBuilder::VisitStmtExpr(StmtExpr *SE, AddStmtChoice asc) { 29693179a45a0e91c1dcf3492222170cf4499531bb92Ted Kremenek if (asc.alwaysAdd(*this, SE)) { 297013fc08a323b29dd97a46def1e3a15bf082476efaTed Kremenek autoCreateBlock(); 2971892697dd2287caf7c29aaaa82909b0e90b8b63feTed Kremenek appendStmt(Block, SE); 297213fc08a323b29dd97a46def1e3a15bf082476efaTed Kremenek } 29734f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek return VisitCompoundStmt(SE->getSubStmt()); 29744f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek} 2975d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek 29769c378f705405d37f49795d5e915989de774fe11fTed KremenekCFGBlock *CFGBuilder::VisitSwitchStmt(SwitchStmt *Terminator) { 29776d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump // "switch" is a control-flow statement. Thus we stop processing the current 29786d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump // block. 29796bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines CFGBlock *SwitchSuccessor = nullptr; 29806d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 29818ae6058cecba902c0069c24bdc9c26d475559291Marcin Swiderski // Save local scope position because in case of condition variable ScopePos 29828ae6058cecba902c0069c24bdc9c26d475559291Marcin Swiderski // won't be restored when traversing AST. 29838ae6058cecba902c0069c24bdc9c26d475559291Marcin Swiderski SaveAndRestore<LocalScope::const_iterator> save_scope_pos(ScopePos); 29848ae6058cecba902c0069c24bdc9c26d475559291Marcin Swiderski 29858ae6058cecba902c0069c24bdc9c26d475559291Marcin Swiderski // Create local scope for possible condition variable. 29868ae6058cecba902c0069c24bdc9c26d475559291Marcin Swiderski // Store scope position. Add implicit destructor. 29879c378f705405d37f49795d5e915989de774fe11fTed Kremenek if (VarDecl *VD = Terminator->getConditionVariable()) { 29888ae6058cecba902c0069c24bdc9c26d475559291Marcin Swiderski LocalScope::const_iterator SwitchBeginScopePos = ScopePos; 29898ae6058cecba902c0069c24bdc9c26d475559291Marcin Swiderski addLocalScopeForVarDecl(VD); 29908ae6058cecba902c0069c24bdc9c26d475559291Marcin Swiderski addAutomaticObjDtors(ScopePos, SwitchBeginScopePos, Terminator); 29918ae6058cecba902c0069c24bdc9c26d475559291Marcin Swiderski } 29928ae6058cecba902c0069c24bdc9c26d475559291Marcin Swiderski 2993d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek if (Block) { 2994d438b3dbdcde4df4f61a99054104643e6aadf78bZhongxing Xu if (badCFG) 29956bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return nullptr; 2996d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek SwitchSuccessor = Block; 29976d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump } else SwitchSuccessor = Succ; 2998d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek 2999d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek // Save the current "switch" context. 3000d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek SaveAndRestore<CFGBlock*> save_switch(SwitchTerminatedBlock), 3001eef5a9ac59f4f8b868ef0657ccf6bec81b4fe37aTed Kremenek save_default(DefaultCaseBlock); 3002f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski SaveAndRestore<JumpTarget> save_break(BreakJumpTarget); 3003eef5a9ac59f4f8b868ef0657ccf6bec81b4fe37aTed Kremenek 30046d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump // Set the "default" case to be the block after the switch statement. If the 30056d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump // switch statement contains a "default:", this value will be overwritten with 30066d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump // the block for that code. 3007eef5a9ac59f4f8b868ef0657ccf6bec81b4fe37aTed Kremenek DefaultCaseBlock = SwitchSuccessor; 30086d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 3009d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek // Create a new block that will contain the switch statement. 3010d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek SwitchTerminatedBlock = createBlock(false); 30116d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 3012d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek // Now process the switch body. The code after the switch is the implicit 3013d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek // successor. 3014d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek Succ = SwitchSuccessor; 3015f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski BreakJumpTarget = JumpTarget(SwitchSuccessor, ScopePos); 30166d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 30176d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump // When visiting the body, the case statements should automatically get linked 30186d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump // up to the switch. We also don't keep a pointer to the body, since all 30196d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump // control-flow from the switch goes to case/default statements. 30206db0ad32fa0987ff76d4c41393991ef4b6895ea3Ted Kremenek assert(Terminator->getBody() && "switch must contain a non-NULL body"); 30216bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines Block = nullptr; 30228ae6058cecba902c0069c24bdc9c26d475559291Marcin Swiderski 3023e71f3d587844110d836c82250830b27b1651afdbTed Kremenek // For pruning unreachable case statements, save the current state 3024e71f3d587844110d836c82250830b27b1651afdbTed Kremenek // for tracking the condition value. 3025e71f3d587844110d836c82250830b27b1651afdbTed Kremenek SaveAndRestore<bool> save_switchExclusivelyCovered(switchExclusivelyCovered, 3026e71f3d587844110d836c82250830b27b1651afdbTed Kremenek false); 30270498247f87ea0d716e0c2931fea812280649e33dTed Kremenek 3028e71f3d587844110d836c82250830b27b1651afdbTed Kremenek // Determine if the switch condition can be explicitly evaluated. 3029e71f3d587844110d836c82250830b27b1651afdbTed Kremenek assert(Terminator->getCond() && "switch condition must be non-NULL"); 30300498247f87ea0d716e0c2931fea812280649e33dTed Kremenek Expr::EvalResult result; 3031e9cd9c0016f103fd45d41d136d5d1084aa42eb75Ted Kremenek bool b = tryEvaluate(Terminator->getCond(), result); 3032e9cd9c0016f103fd45d41d136d5d1084aa42eb75Ted Kremenek SaveAndRestore<Expr::EvalResult*> save_switchCond(switchCond, 30336bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines b ? &result : nullptr); 30340498247f87ea0d716e0c2931fea812280649e33dTed Kremenek 30358ae6058cecba902c0069c24bdc9c26d475559291Marcin Swiderski // If body is not a compound statement create implicit scope 30368ae6058cecba902c0069c24bdc9c26d475559291Marcin Swiderski // and add destructors. 30378ae6058cecba902c0069c24bdc9c26d475559291Marcin Swiderski if (!isa<CompoundStmt>(Terminator->getBody())) 30388ae6058cecba902c0069c24bdc9c26d475559291Marcin Swiderski addLocalScopeAndDtors(Terminator->getBody()); 30398ae6058cecba902c0069c24bdc9c26d475559291Marcin Swiderski 3040d438b3dbdcde4df4f61a99054104643e6aadf78bZhongxing Xu addStmt(Terminator->getBody()); 30414e8df2eb7072db8f66572c3db31a2a08b12a752eTed Kremenek if (Block) { 3042d438b3dbdcde4df4f61a99054104643e6aadf78bZhongxing Xu if (badCFG) 30436bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return nullptr; 30444e8df2eb7072db8f66572c3db31a2a08b12a752eTed Kremenek } 304549af7cb8a3aca79783e7a0708b97a8f856f0da22Ted Kremenek 30466d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump // If we have no "default:" case, the default transition is to the code 3047432c478fe0fec3946610d5dc7905daf5fbadf47bTed Kremenek // following the switch body. Moreover, take into account if all the 3048432c478fe0fec3946610d5dc7905daf5fbadf47bTed Kremenek // cases of a switch are covered (e.g., switching on an enum value). 30492a1551fa14728891bf8e325d3eb686ed404cd8b2David Majnemer // 30502a1551fa14728891bf8e325d3eb686ed404cd8b2David Majnemer // Note: We add a successor to a switch that is considered covered yet has no 30512a1551fa14728891bf8e325d3eb686ed404cd8b2David Majnemer // case statements if the enumeration has no enumerators. 30522a1551fa14728891bf8e325d3eb686ed404cd8b2David Majnemer bool SwitchAlwaysHasSuccessor = false; 30532a1551fa14728891bf8e325d3eb686ed404cd8b2David Majnemer SwitchAlwaysHasSuccessor |= switchExclusivelyCovered; 30542a1551fa14728891bf8e325d3eb686ed404cd8b2David Majnemer SwitchAlwaysHasSuccessor |= Terminator->isAllEnumCasesCovered() && 30552a1551fa14728891bf8e325d3eb686ed404cd8b2David Majnemer Terminator->getSwitchCaseList(); 3056651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines addSuccessor(SwitchTerminatedBlock, DefaultCaseBlock, 3057651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines !SwitchAlwaysHasSuccessor); 30586d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 305949af7cb8a3aca79783e7a0708b97a8f856f0da22Ted Kremenek // Add the terminator and condition in the switch block. 3060411cdee0b490f79428c9eb977f25199eb7d21cd8Ted Kremenek SwitchTerminatedBlock->setTerminator(Terminator); 3061d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek Block = SwitchTerminatedBlock; 30628f81acfa95a5d2a22fc875c1a10901eaa30b8405Ted Kremenek CFGBlock *LastBlock = addStmt(Terminator->getCond()); 3063ad5a894df1841698c824381b414630799adc26caTed Kremenek 30646b501ebaf172b28d6d7e1737db27f915175ad3c8Ted Kremenek // Finally, if the SwitchStmt contains a condition variable, add both the 30656b501ebaf172b28d6d7e1737db27f915175ad3c8Ted Kremenek // SwitchStmt and the condition variable initialization to the CFG. 30666b501ebaf172b28d6d7e1737db27f915175ad3c8Ted Kremenek if (VarDecl *VD = Terminator->getConditionVariable()) { 30676b501ebaf172b28d6d7e1737db27f915175ad3c8Ted Kremenek if (Expr *Init = VD->getInit()) { 30686b501ebaf172b28d6d7e1737db27f915175ad3c8Ted Kremenek autoCreateBlock(); 3069d40066b0fb883839a9100e5455e33190b9b8abacTed Kremenek appendStmt(Block, Terminator->getConditionVariableDeclStmt()); 30708f81acfa95a5d2a22fc875c1a10901eaa30b8405Ted Kremenek LastBlock = addStmt(Init); 30716b501ebaf172b28d6d7e1737db27f915175ad3c8Ted Kremenek } 30726b501ebaf172b28d6d7e1737db27f915175ad3c8Ted Kremenek } 3073ad5a894df1841698c824381b414630799adc26caTed Kremenek 30748f81acfa95a5d2a22fc875c1a10901eaa30b8405Ted Kremenek return LastBlock; 3075d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek} 3076e71f3d587844110d836c82250830b27b1651afdbTed Kremenek 3077e71f3d587844110d836c82250830b27b1651afdbTed Kremenekstatic bool shouldAddCase(bool &switchExclusivelyCovered, 3078e9cd9c0016f103fd45d41d136d5d1084aa42eb75Ted Kremenek const Expr::EvalResult *switchCond, 3079e71f3d587844110d836c82250830b27b1651afdbTed Kremenek const CaseStmt *CS, 3080e71f3d587844110d836c82250830b27b1651afdbTed Kremenek ASTContext &Ctx) { 3081e9cd9c0016f103fd45d41d136d5d1084aa42eb75Ted Kremenek if (!switchCond) 3082e9cd9c0016f103fd45d41d136d5d1084aa42eb75Ted Kremenek return true; 3083e9cd9c0016f103fd45d41d136d5d1084aa42eb75Ted Kremenek 3084e71f3d587844110d836c82250830b27b1651afdbTed Kremenek bool addCase = false; 30850498247f87ea0d716e0c2931fea812280649e33dTed Kremenek 3086e71f3d587844110d836c82250830b27b1651afdbTed Kremenek if (!switchExclusivelyCovered) { 3087e9cd9c0016f103fd45d41d136d5d1084aa42eb75Ted Kremenek if (switchCond->Val.isInt()) { 3088e71f3d587844110d836c82250830b27b1651afdbTed Kremenek // Evaluate the LHS of the case value. 308985df96c1f04867e26ba069aa0cc6a4cd6a01292eRichard Smith const llvm::APSInt &lhsInt = CS->getLHS()->EvaluateKnownConstInt(Ctx); 3090e9cd9c0016f103fd45d41d136d5d1084aa42eb75Ted Kremenek const llvm::APSInt &condInt = switchCond->Val.getInt(); 3091e71f3d587844110d836c82250830b27b1651afdbTed Kremenek 3092e71f3d587844110d836c82250830b27b1651afdbTed Kremenek if (condInt == lhsInt) { 3093e71f3d587844110d836c82250830b27b1651afdbTed Kremenek addCase = true; 3094e71f3d587844110d836c82250830b27b1651afdbTed Kremenek switchExclusivelyCovered = true; 3095e71f3d587844110d836c82250830b27b1651afdbTed Kremenek } 3096e71f3d587844110d836c82250830b27b1651afdbTed Kremenek else if (condInt < lhsInt) { 3097e71f3d587844110d836c82250830b27b1651afdbTed Kremenek if (const Expr *RHS = CS->getRHS()) { 3098e71f3d587844110d836c82250830b27b1651afdbTed Kremenek // Evaluate the RHS of the case value. 309985df96c1f04867e26ba069aa0cc6a4cd6a01292eRichard Smith const llvm::APSInt &V2 = RHS->EvaluateKnownConstInt(Ctx); 310085df96c1f04867e26ba069aa0cc6a4cd6a01292eRichard Smith if (V2 <= condInt) { 3101e71f3d587844110d836c82250830b27b1651afdbTed Kremenek addCase = true; 3102e71f3d587844110d836c82250830b27b1651afdbTed Kremenek switchExclusivelyCovered = true; 3103e71f3d587844110d836c82250830b27b1651afdbTed Kremenek } 3104e71f3d587844110d836c82250830b27b1651afdbTed Kremenek } 3105e71f3d587844110d836c82250830b27b1651afdbTed Kremenek } 3106e71f3d587844110d836c82250830b27b1651afdbTed Kremenek } 3107e71f3d587844110d836c82250830b27b1651afdbTed Kremenek else 3108e71f3d587844110d836c82250830b27b1651afdbTed Kremenek addCase = true; 3109e71f3d587844110d836c82250830b27b1651afdbTed Kremenek } 3110e71f3d587844110d836c82250830b27b1651afdbTed Kremenek return addCase; 3111e71f3d587844110d836c82250830b27b1651afdbTed Kremenek} 3112d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek 31139c378f705405d37f49795d5e915989de774fe11fTed KremenekCFGBlock *CFGBuilder::VisitCaseStmt(CaseStmt *CS) { 31146d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump // CaseStmts are essentially labels, so they are the first statement in a 31156d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump // block. 31166bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines CFGBlock *TopBlock = nullptr, *LastBlock = nullptr; 31170498247f87ea0d716e0c2931fea812280649e33dTed Kremenek 31180fc67e2d619088945ac71e9d2590d5158650885dTed Kremenek if (Stmt *Sub = CS->getSubStmt()) { 31190fc67e2d619088945ac71e9d2590d5158650885dTed Kremenek // For deeply nested chains of CaseStmts, instead of doing a recursion 31200fc67e2d619088945ac71e9d2590d5158650885dTed Kremenek // (which can blow out the stack), manually unroll and create blocks 31210fc67e2d619088945ac71e9d2590d5158650885dTed Kremenek // along the way. 31220fc67e2d619088945ac71e9d2590d5158650885dTed Kremenek while (isa<CaseStmt>(Sub)) { 31230a3ed3143b00f237decb1288c1ff574ae09eba4eTed Kremenek CFGBlock *currentBlock = createBlock(false); 31240a3ed3143b00f237decb1288c1ff574ae09eba4eTed Kremenek currentBlock->setLabel(CS); 31250fc67e2d619088945ac71e9d2590d5158650885dTed Kremenek 31260fc67e2d619088945ac71e9d2590d5158650885dTed Kremenek if (TopBlock) 31270a3ed3143b00f237decb1288c1ff574ae09eba4eTed Kremenek addSuccessor(LastBlock, currentBlock); 31280fc67e2d619088945ac71e9d2590d5158650885dTed Kremenek else 31290a3ed3143b00f237decb1288c1ff574ae09eba4eTed Kremenek TopBlock = currentBlock; 31300fc67e2d619088945ac71e9d2590d5158650885dTed Kremenek 3131e71f3d587844110d836c82250830b27b1651afdbTed Kremenek addSuccessor(SwitchTerminatedBlock, 3132e9cd9c0016f103fd45d41d136d5d1084aa42eb75Ted Kremenek shouldAddCase(switchExclusivelyCovered, switchCond, 3133e71f3d587844110d836c82250830b27b1651afdbTed Kremenek CS, *Context) 31346bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines ? currentBlock : nullptr); 31350fc67e2d619088945ac71e9d2590d5158650885dTed Kremenek 3136e71f3d587844110d836c82250830b27b1651afdbTed Kremenek LastBlock = currentBlock; 31370fc67e2d619088945ac71e9d2590d5158650885dTed Kremenek CS = cast<CaseStmt>(Sub); 31380fc67e2d619088945ac71e9d2590d5158650885dTed Kremenek Sub = CS->getSubStmt(); 31390fc67e2d619088945ac71e9d2590d5158650885dTed Kremenek } 314029ccaa186ac27bcb414c5acb069f6438b27dd5e7Ted Kremenek 31410fc67e2d619088945ac71e9d2590d5158650885dTed Kremenek addStmt(Sub); 31420fc67e2d619088945ac71e9d2590d5158650885dTed Kremenek } 31431eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 31449c378f705405d37f49795d5e915989de774fe11fTed Kremenek CFGBlock *CaseBlock = Block; 31454f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek if (!CaseBlock) 31464f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek CaseBlock = createBlock(); 31476d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 31486d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump // Cases statements partition blocks, so this is the top of the basic block we 31496d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump // were processing (the "case XXX:" is the label). 31504f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek CaseBlock->setLabel(CS); 31514f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek 3152d438b3dbdcde4df4f61a99054104643e6aadf78bZhongxing Xu if (badCFG) 31536bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return nullptr; 31546d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 31556d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump // Add this block to the list of successors for the block with the switch 31566d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump // statement. 31574f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek assert(SwitchTerminatedBlock); 3158651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines addSuccessor(SwitchTerminatedBlock, CaseBlock, 3159e9cd9c0016f103fd45d41d136d5d1084aa42eb75Ted Kremenek shouldAddCase(switchExclusivelyCovered, switchCond, 3160651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines CS, *Context)); 31616d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 3162d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek // We set Block to NULL to allow lazy creation of a new block (if necessary) 31636bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines Block = nullptr; 31646d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 31650fc67e2d619088945ac71e9d2590d5158650885dTed Kremenek if (TopBlock) { 31660a3ed3143b00f237decb1288c1ff574ae09eba4eTed Kremenek addSuccessor(LastBlock, CaseBlock); 31670fc67e2d619088945ac71e9d2590d5158650885dTed Kremenek Succ = TopBlock; 316836f327c309b1fb6b82f1987190f0be74000b14c1Zhanyong Wan } else { 31690fc67e2d619088945ac71e9d2590d5158650885dTed Kremenek // This block is now the implicit successor of other blocks. 31700fc67e2d619088945ac71e9d2590d5158650885dTed Kremenek Succ = CaseBlock; 31710fc67e2d619088945ac71e9d2590d5158650885dTed Kremenek } 31726d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 31730fc67e2d619088945ac71e9d2590d5158650885dTed Kremenek return Succ; 3174d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek} 31756d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 31769c378f705405d37f49795d5e915989de774fe11fTed KremenekCFGBlock *CFGBuilder::VisitDefaultStmt(DefaultStmt *Terminator) { 31774f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek if (Terminator->getSubStmt()) 31784f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek addStmt(Terminator->getSubStmt()); 31791eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 3180eef5a9ac59f4f8b868ef0657ccf6bec81b4fe37aTed Kremenek DefaultCaseBlock = Block; 31814f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek 31824f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek if (!DefaultCaseBlock) 31834f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek DefaultCaseBlock = createBlock(); 31846d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 31856d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump // Default statements partition blocks, so this is the top of the basic block 31866d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump // we were processing (the "default:" is the label). 3187411cdee0b490f79428c9eb977f25199eb7d21cd8Ted Kremenek DefaultCaseBlock->setLabel(Terminator); 31881eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 3189d438b3dbdcde4df4f61a99054104643e6aadf78bZhongxing Xu if (badCFG) 31906bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return nullptr; 3191eef5a9ac59f4f8b868ef0657ccf6bec81b4fe37aTed Kremenek 31926d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump // Unlike case statements, we don't add the default block to the successors 31936d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump // for the switch statement immediately. This is done when we finish 31946d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump // processing the switch statement. This allows for the default case 31956d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump // (including a fall-through to the code after the switch statement) to always 31966d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump // be the last successor of a switch-terminated block. 31976d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 3198eef5a9ac59f4f8b868ef0657ccf6bec81b4fe37aTed Kremenek // We set Block to NULL to allow lazy creation of a new block (if necessary) 31996bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines Block = nullptr; 32006d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 3201eef5a9ac59f4f8b868ef0657ccf6bec81b4fe37aTed Kremenek // This block is now the implicit successor of other blocks. 3202eef5a9ac59f4f8b868ef0657ccf6bec81b4fe37aTed Kremenek Succ = DefaultCaseBlock; 32036d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 32046d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump return DefaultCaseBlock; 3205295222c1f0926d84de77f076e79903523eeb5dbfTed Kremenek} 3206d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek 32075d1d20227878cd03db8b2dd23efd4cedfe874feeMike StumpCFGBlock *CFGBuilder::VisitCXXTryStmt(CXXTryStmt *Terminator) { 32085d1d20227878cd03db8b2dd23efd4cedfe874feeMike Stump // "try"/"catch" is a control-flow statement. Thus we stop processing the 32095d1d20227878cd03db8b2dd23efd4cedfe874feeMike Stump // current block. 32106bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines CFGBlock *TrySuccessor = nullptr; 32115d1d20227878cd03db8b2dd23efd4cedfe874feeMike Stump 32125d1d20227878cd03db8b2dd23efd4cedfe874feeMike Stump if (Block) { 3213d438b3dbdcde4df4f61a99054104643e6aadf78bZhongxing Xu if (badCFG) 32146bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return nullptr; 32155d1d20227878cd03db8b2dd23efd4cedfe874feeMike Stump TrySuccessor = Block; 32165d1d20227878cd03db8b2dd23efd4cedfe874feeMike Stump } else TrySuccessor = Succ; 32175d1d20227878cd03db8b2dd23efd4cedfe874feeMike Stump 3218a1f93631a84621d77aeb627691da85a8991af188Mike Stump CFGBlock *PrevTryTerminatedBlock = TryTerminatedBlock; 32195d1d20227878cd03db8b2dd23efd4cedfe874feeMike Stump 32205d1d20227878cd03db8b2dd23efd4cedfe874feeMike Stump // Create a new block that will contain the try statement. 3221f00cca5e05bb9ea51a3a21c8014ff9f3508d46e9Mike Stump CFGBlock *NewTryTerminatedBlock = createBlock(false); 32225d1d20227878cd03db8b2dd23efd4cedfe874feeMike Stump // Add the terminator in the try block. 3223f00cca5e05bb9ea51a3a21c8014ff9f3508d46e9Mike Stump NewTryTerminatedBlock->setTerminator(Terminator); 32245d1d20227878cd03db8b2dd23efd4cedfe874feeMike Stump 3225a1f93631a84621d77aeb627691da85a8991af188Mike Stump bool HasCatchAll = false; 32265d1d20227878cd03db8b2dd23efd4cedfe874feeMike Stump for (unsigned h = 0; h <Terminator->getNumHandlers(); ++h) { 32275d1d20227878cd03db8b2dd23efd4cedfe874feeMike Stump // The code after the try is the implicit successor. 32285d1d20227878cd03db8b2dd23efd4cedfe874feeMike Stump Succ = TrySuccessor; 32295d1d20227878cd03db8b2dd23efd4cedfe874feeMike Stump CXXCatchStmt *CS = Terminator->getHandler(h); 32306bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (CS->getExceptionDecl() == nullptr) { 3231a1f93631a84621d77aeb627691da85a8991af188Mike Stump HasCatchAll = true; 3232a1f93631a84621d77aeb627691da85a8991af188Mike Stump } 32336bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines Block = nullptr; 32345d1d20227878cd03db8b2dd23efd4cedfe874feeMike Stump CFGBlock *CatchBlock = VisitCXXCatchStmt(CS); 32356bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (!CatchBlock) 32366bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return nullptr; 32375d1d20227878cd03db8b2dd23efd4cedfe874feeMike Stump // Add this block to the list of successors for the block with the try 32385d1d20227878cd03db8b2dd23efd4cedfe874feeMike Stump // statement. 32390a3ed3143b00f237decb1288c1ff574ae09eba4eTed Kremenek addSuccessor(NewTryTerminatedBlock, CatchBlock); 32405d1d20227878cd03db8b2dd23efd4cedfe874feeMike Stump } 3241a1f93631a84621d77aeb627691da85a8991af188Mike Stump if (!HasCatchAll) { 3242a1f93631a84621d77aeb627691da85a8991af188Mike Stump if (PrevTryTerminatedBlock) 32430a3ed3143b00f237decb1288c1ff574ae09eba4eTed Kremenek addSuccessor(NewTryTerminatedBlock, PrevTryTerminatedBlock); 3244a1f93631a84621d77aeb627691da85a8991af188Mike Stump else 32450a3ed3143b00f237decb1288c1ff574ae09eba4eTed Kremenek addSuccessor(NewTryTerminatedBlock, &cfg->getExit()); 3246a1f93631a84621d77aeb627691da85a8991af188Mike Stump } 32475d1d20227878cd03db8b2dd23efd4cedfe874feeMike Stump 32485d1d20227878cd03db8b2dd23efd4cedfe874feeMike Stump // The code after the try is the implicit successor. 32495d1d20227878cd03db8b2dd23efd4cedfe874feeMike Stump Succ = TrySuccessor; 32505d1d20227878cd03db8b2dd23efd4cedfe874feeMike Stump 3251f00cca5e05bb9ea51a3a21c8014ff9f3508d46e9Mike Stump // Save the current "try" context. 3252f0e71aede7ccf3e311feac6a414c431f7a0fc3c8Ted Kremenek SaveAndRestore<CFGBlock*> save_try(TryTerminatedBlock, NewTryTerminatedBlock); 3253f0e71aede7ccf3e311feac6a414c431f7a0fc3c8Ted Kremenek cfg->addTryDispatchBlock(TryTerminatedBlock); 3254f00cca5e05bb9ea51a3a21c8014ff9f3508d46e9Mike Stump 32556db0ad32fa0987ff76d4c41393991ef4b6895ea3Ted Kremenek assert(Terminator->getTryBlock() && "try must contain a non-NULL body"); 32566bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines Block = nullptr; 32578f81acfa95a5d2a22fc875c1a10901eaa30b8405Ted Kremenek return addStmt(Terminator->getTryBlock()); 32585d1d20227878cd03db8b2dd23efd4cedfe874feeMike Stump} 32595d1d20227878cd03db8b2dd23efd4cedfe874feeMike Stump 32609c378f705405d37f49795d5e915989de774fe11fTed KremenekCFGBlock *CFGBuilder::VisitCXXCatchStmt(CXXCatchStmt *CS) { 32615d1d20227878cd03db8b2dd23efd4cedfe874feeMike Stump // CXXCatchStmt are treated like labels, so they are the first statement in a 32625d1d20227878cd03db8b2dd23efd4cedfe874feeMike Stump // block. 32635d1d20227878cd03db8b2dd23efd4cedfe874feeMike Stump 32640e97bcbee9d5f7735edecbccfb5031a2f065f286Marcin Swiderski // Save local scope position because in case of exception variable ScopePos 32650e97bcbee9d5f7735edecbccfb5031a2f065f286Marcin Swiderski // won't be restored when traversing AST. 32660e97bcbee9d5f7735edecbccfb5031a2f065f286Marcin Swiderski SaveAndRestore<LocalScope::const_iterator> save_scope_pos(ScopePos); 32670e97bcbee9d5f7735edecbccfb5031a2f065f286Marcin Swiderski 32680e97bcbee9d5f7735edecbccfb5031a2f065f286Marcin Swiderski // Create local scope for possible exception variable. 32690e97bcbee9d5f7735edecbccfb5031a2f065f286Marcin Swiderski // Store scope position. Add implicit destructor. 32709c378f705405d37f49795d5e915989de774fe11fTed Kremenek if (VarDecl *VD = CS->getExceptionDecl()) { 32710e97bcbee9d5f7735edecbccfb5031a2f065f286Marcin Swiderski LocalScope::const_iterator BeginScopePos = ScopePos; 32720e97bcbee9d5f7735edecbccfb5031a2f065f286Marcin Swiderski addLocalScopeForVarDecl(VD); 32730e97bcbee9d5f7735edecbccfb5031a2f065f286Marcin Swiderski addAutomaticObjDtors(ScopePos, BeginScopePos, CS); 32740e97bcbee9d5f7735edecbccfb5031a2f065f286Marcin Swiderski } 32750e97bcbee9d5f7735edecbccfb5031a2f065f286Marcin Swiderski 32765d1d20227878cd03db8b2dd23efd4cedfe874feeMike Stump if (CS->getHandlerBlock()) 32775d1d20227878cd03db8b2dd23efd4cedfe874feeMike Stump addStmt(CS->getHandlerBlock()); 32785d1d20227878cd03db8b2dd23efd4cedfe874feeMike Stump 32799c378f705405d37f49795d5e915989de774fe11fTed Kremenek CFGBlock *CatchBlock = Block; 32805d1d20227878cd03db8b2dd23efd4cedfe874feeMike Stump if (!CatchBlock) 32815d1d20227878cd03db8b2dd23efd4cedfe874feeMike Stump CatchBlock = createBlock(); 3282337e4dbc6859589b8878146a88bebf754e916702Ted Kremenek 3283337e4dbc6859589b8878146a88bebf754e916702Ted Kremenek // CXXCatchStmt is more than just a label. They have semantic meaning 3284337e4dbc6859589b8878146a88bebf754e916702Ted Kremenek // as well, as they implicitly "initialize" the catch variable. Add 3285337e4dbc6859589b8878146a88bebf754e916702Ted Kremenek // it to the CFG as a CFGElement so that the control-flow of these 3286337e4dbc6859589b8878146a88bebf754e916702Ted Kremenek // semantics gets captured. 3287337e4dbc6859589b8878146a88bebf754e916702Ted Kremenek appendStmt(CatchBlock, CS); 3288337e4dbc6859589b8878146a88bebf754e916702Ted Kremenek 3289337e4dbc6859589b8878146a88bebf754e916702Ted Kremenek // Also add the CXXCatchStmt as a label, to mirror handling of regular 3290337e4dbc6859589b8878146a88bebf754e916702Ted Kremenek // labels. 32915d1d20227878cd03db8b2dd23efd4cedfe874feeMike Stump CatchBlock->setLabel(CS); 32925d1d20227878cd03db8b2dd23efd4cedfe874feeMike Stump 3293337e4dbc6859589b8878146a88bebf754e916702Ted Kremenek // Bail out if the CFG is bad. 3294d438b3dbdcde4df4f61a99054104643e6aadf78bZhongxing Xu if (badCFG) 32956bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return nullptr; 32965d1d20227878cd03db8b2dd23efd4cedfe874feeMike Stump 32975d1d20227878cd03db8b2dd23efd4cedfe874feeMike Stump // We set Block to NULL to allow lazy creation of a new block (if necessary) 32986bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines Block = nullptr; 32995d1d20227878cd03db8b2dd23efd4cedfe874feeMike Stump 33005d1d20227878cd03db8b2dd23efd4cedfe874feeMike Stump return CatchBlock; 33015d1d20227878cd03db8b2dd23efd4cedfe874feeMike Stump} 33025d1d20227878cd03db8b2dd23efd4cedfe874feeMike Stump 33039c378f705405d37f49795d5e915989de774fe11fTed KremenekCFGBlock *CFGBuilder::VisitCXXForRangeStmt(CXXForRangeStmt *S) { 3304ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith // C++0x for-range statements are specified as [stmt.ranged]: 3305ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith // 3306ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith // { 3307ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith // auto && __range = range-init; 3308ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith // for ( auto __begin = begin-expr, 3309ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith // __end = end-expr; 3310ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith // __begin != __end; 3311ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith // ++__begin ) { 3312ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith // for-range-declaration = *__begin; 3313ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith // statement 3314ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith // } 3315ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith // } 3316ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith 3317ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith // Save local scope position before the addition of the implicit variables. 3318ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith SaveAndRestore<LocalScope::const_iterator> save_scope_pos(ScopePos); 3319ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith 3320ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith // Create local scopes and destructors for range, begin and end variables. 3321ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith if (Stmt *Range = S->getRangeStmt()) 3322ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith addLocalScopeForStmt(Range); 3323ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith if (Stmt *BeginEnd = S->getBeginEndStmt()) 3324ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith addLocalScopeForStmt(BeginEnd); 3325ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith addAutomaticObjDtors(ScopePos, save_scope_pos.get(), S); 3326ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith 3327ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith LocalScope::const_iterator ContinueScopePos = ScopePos; 3328ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith 3329ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith // "for" is a control-flow statement. Thus we stop processing the current 3330ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith // block. 33316bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines CFGBlock *LoopSuccessor = nullptr; 3332ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith if (Block) { 3333ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith if (badCFG) 33346bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return nullptr; 3335ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith LoopSuccessor = Block; 3336ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith } else 3337ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith LoopSuccessor = Succ; 3338ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith 3339ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith // Save the current value for the break targets. 3340ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith // All breaks should go to the code following the loop. 3341ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith SaveAndRestore<JumpTarget> save_break(BreakJumpTarget); 3342ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith BreakJumpTarget = JumpTarget(LoopSuccessor, ScopePos); 3343ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith 3344ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith // The block for the __begin != __end expression. 33459c378f705405d37f49795d5e915989de774fe11fTed Kremenek CFGBlock *ConditionBlock = createBlock(false); 3346ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith ConditionBlock->setTerminator(S); 3347ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith 3348ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith // Now add the actual condition to the condition block. 3349ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith if (Expr *C = S->getCond()) { 3350ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith Block = ConditionBlock; 3351ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith CFGBlock *BeginConditionBlock = addStmt(C); 3352ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith if (badCFG) 33536bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return nullptr; 3354ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith assert(BeginConditionBlock == ConditionBlock && 3355ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith "condition block in for-range was unexpectedly complex"); 3356ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith (void)BeginConditionBlock; 3357ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith } 3358ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith 3359ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith // The condition block is the implicit successor for the loop body as well as 3360ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith // any code above the loop. 3361ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith Succ = ConditionBlock; 3362ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith 3363ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith // See if this is a known constant. 3364ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith TryResult KnownVal(true); 3365ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith 3366ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith if (S->getCond()) 3367ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith KnownVal = tryEvaluateBool(S->getCond()); 3368ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith 3369ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith // Now create the loop body. 3370ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith { 3371ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith assert(S->getBody()); 3372ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith 3373ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith // Save the current values for Block, Succ, and continue targets. 3374ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith SaveAndRestore<CFGBlock*> save_Block(Block), save_Succ(Succ); 3375ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith SaveAndRestore<JumpTarget> save_continue(ContinueJumpTarget); 3376ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith 3377ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith // Generate increment code in its own basic block. This is the target of 3378ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith // continue statements. 33796bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines Block = nullptr; 3380ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith Succ = addStmt(S->getInc()); 3381ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith ContinueJumpTarget = JumpTarget(Succ, ContinueScopePos); 3382ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith 3383ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith // The starting block for the loop increment is the block that should 3384ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith // represent the 'loop target' for looping back to the start of the loop. 3385ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith ContinueJumpTarget.block->setLoopTarget(S); 3386ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith 3387ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith // Finish up the increment block and prepare to start the loop body. 3388ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith assert(Block); 3389ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith if (badCFG) 33906bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return nullptr; 33916bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines Block = nullptr; 3392ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith 3393ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith // Add implicit scope and dtors for loop variable. 3394ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith addLocalScopeAndDtors(S->getLoopVarStmt()); 3395ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith 3396ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith // Populate a new block to contain the loop body and loop variable. 33978f81acfa95a5d2a22fc875c1a10901eaa30b8405Ted Kremenek addStmt(S->getBody()); 3398ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith if (badCFG) 33996bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return nullptr; 34008f81acfa95a5d2a22fc875c1a10901eaa30b8405Ted Kremenek CFGBlock *LoopVarStmtBlock = addStmt(S->getLoopVarStmt()); 3401ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith if (badCFG) 34026bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return nullptr; 34036bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 3404ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith // This new body block is a successor to our condition block. 34056bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines addSuccessor(ConditionBlock, 34066bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines KnownVal.isFalse() ? nullptr : LoopVarStmtBlock); 3407ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith } 3408ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith 3409ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith // Link up the condition block with the code that follows the loop (the 3410ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith // false branch). 34116bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines addSuccessor(ConditionBlock, KnownVal.isTrue() ? nullptr : LoopSuccessor); 3412ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith 3413ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith // Add the initialization statements. 3414ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith Block = createBlock(); 3415b403d6d746239095a2c7bac958c924d92434e2b4Richard Smith addStmt(S->getBeginEndStmt()); 3416b403d6d746239095a2c7bac958c924d92434e2b4Richard Smith return addStmt(S->getRangeStmt()); 3417ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith} 3418ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith 34194765fa05b5652fcc4356371c2f481d0ea9a1b007John McCallCFGBlock *CFGBuilder::VisitExprWithCleanups(ExprWithCleanups *E, 34208599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski AddStmtChoice asc) { 34215a1ffe98b04120846a15f7105905b5f363b08635Jordan Rose if (BuildOpts.AddTemporaryDtors) { 34228599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski // If adding implicit destructors visit the full expression for adding 34238599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski // destructors of temporaries. 3424176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines TempDtorContext Context; 3425176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines VisitForTemporaryDtors(E->getSubExpr(), false, Context); 34268599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski 34278599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski // Full expression has to be added as CFGStmt so it will be sequenced 34288599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski // before destructors of it's temporaries. 342994a3dcf146451eb6b0192873e267c4cb0f6147e8Zhanyong Wan asc = asc.withAlwaysAdd(true); 34308599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski } 34318599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski return Visit(E->getSubExpr(), asc); 34328599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski} 34338599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski 3434a725ed468585b881c43654eeb56b28554a84808aZhongxing XuCFGBlock *CFGBuilder::VisitCXXBindTemporaryExpr(CXXBindTemporaryExpr *E, 3435a725ed468585b881c43654eeb56b28554a84808aZhongxing Xu AddStmtChoice asc) { 34363179a45a0e91c1dcf3492222170cf4499531bb92Ted Kremenek if (asc.alwaysAdd(*this, E)) { 3437a725ed468585b881c43654eeb56b28554a84808aZhongxing Xu autoCreateBlock(); 3438247e9665d897a7bbbf60c1c0d3b6609c4504a961Ted Kremenek appendStmt(Block, E); 3439a725ed468585b881c43654eeb56b28554a84808aZhongxing Xu 3440a725ed468585b881c43654eeb56b28554a84808aZhongxing Xu // We do not want to propagate the AlwaysAdd property. 344194a3dcf146451eb6b0192873e267c4cb0f6147e8Zhanyong Wan asc = asc.withAlwaysAdd(false); 3442a725ed468585b881c43654eeb56b28554a84808aZhongxing Xu } 3443a725ed468585b881c43654eeb56b28554a84808aZhongxing Xu return Visit(E->getSubExpr(), asc); 3444a725ed468585b881c43654eeb56b28554a84808aZhongxing Xu} 3445a725ed468585b881c43654eeb56b28554a84808aZhongxing Xu 344681bc7d07b701042371a5723b6f394cd2482ed7beZhongxing XuCFGBlock *CFGBuilder::VisitCXXConstructExpr(CXXConstructExpr *C, 344781bc7d07b701042371a5723b6f394cd2482ed7beZhongxing Xu AddStmtChoice asc) { 344881bc7d07b701042371a5723b6f394cd2482ed7beZhongxing Xu autoCreateBlock(); 344997a72c35a62304c3781aa280e28cb97a59afd585Zhongxing Xu appendStmt(Block, C); 345094a3dcf146451eb6b0192873e267c4cb0f6147e8Zhanyong Wan 345181bc7d07b701042371a5723b6f394cd2482ed7beZhongxing Xu return VisitChildren(C); 345281bc7d07b701042371a5723b6f394cd2482ed7beZhongxing Xu} 345381bc7d07b701042371a5723b6f394cd2482ed7beZhongxing Xu 3454651f13cea278ec967336033dd032faef0e9fc2ecStephen HinesCFGBlock *CFGBuilder::VisitCXXNewExpr(CXXNewExpr *NE, 3455651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines AddStmtChoice asc) { 3456651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 3457651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines autoCreateBlock(); 3458651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines appendStmt(Block, NE); 3459651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 3460651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (NE->getInitializer()) 3461651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Block = Visit(NE->getInitializer()); 3462651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (BuildOpts.AddCXXNewAllocator) 3463651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines appendNewAllocator(Block, NE); 3464651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (NE->isArray()) 3465651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Block = Visit(NE->getArraySize()); 3466651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines for (CXXNewExpr::arg_iterator I = NE->placement_arg_begin(), 3467651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines E = NE->placement_arg_end(); I != E; ++I) 3468651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Block = Visit(*I); 3469651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return Block; 3470651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines} 347136d558d85653315edb389677e995ec9ccdbfbf3dJordan Rose 347236d558d85653315edb389677e995ec9ccdbfbf3dJordan RoseCFGBlock *CFGBuilder::VisitCXXDeleteExpr(CXXDeleteExpr *DE, 347336d558d85653315edb389677e995ec9ccdbfbf3dJordan Rose AddStmtChoice asc) { 347436d558d85653315edb389677e995ec9ccdbfbf3dJordan Rose autoCreateBlock(); 347536d558d85653315edb389677e995ec9ccdbfbf3dJordan Rose appendStmt(Block, DE); 347636d558d85653315edb389677e995ec9ccdbfbf3dJordan Rose QualType DTy = DE->getDestroyedType(); 347736d558d85653315edb389677e995ec9ccdbfbf3dJordan Rose DTy = DTy.getNonReferenceType(); 347836d558d85653315edb389677e995ec9ccdbfbf3dJordan Rose CXXRecordDecl *RD = Context->getBaseElementType(DTy)->getAsCXXRecordDecl(); 347936d558d85653315edb389677e995ec9ccdbfbf3dJordan Rose if (RD) { 3480a7be2f4c745120d6ee5adfd19ef259919bdc3f7fMatt Beaumont-Gay if (RD->isCompleteDefinition() && !RD->hasTrivialDestructor()) 348136d558d85653315edb389677e995ec9ccdbfbf3dJordan Rose appendDeleteDtor(Block, RD, DE); 348236d558d85653315edb389677e995ec9ccdbfbf3dJordan Rose } 348336d558d85653315edb389677e995ec9ccdbfbf3dJordan Rose 348436d558d85653315edb389677e995ec9ccdbfbf3dJordan Rose return VisitChildren(DE); 348536d558d85653315edb389677e995ec9ccdbfbf3dJordan Rose} 348636d558d85653315edb389677e995ec9ccdbfbf3dJordan Rose 3487a725ed468585b881c43654eeb56b28554a84808aZhongxing XuCFGBlock *CFGBuilder::VisitCXXFunctionalCastExpr(CXXFunctionalCastExpr *E, 3488a725ed468585b881c43654eeb56b28554a84808aZhongxing Xu AddStmtChoice asc) { 34893179a45a0e91c1dcf3492222170cf4499531bb92Ted Kremenek if (asc.alwaysAdd(*this, E)) { 3490a725ed468585b881c43654eeb56b28554a84808aZhongxing Xu autoCreateBlock(); 3491247e9665d897a7bbbf60c1c0d3b6609c4504a961Ted Kremenek appendStmt(Block, E); 3492a725ed468585b881c43654eeb56b28554a84808aZhongxing Xu // We do not want to propagate the AlwaysAdd property. 349394a3dcf146451eb6b0192873e267c4cb0f6147e8Zhanyong Wan asc = asc.withAlwaysAdd(false); 3494a725ed468585b881c43654eeb56b28554a84808aZhongxing Xu } 3495a725ed468585b881c43654eeb56b28554a84808aZhongxing Xu return Visit(E->getSubExpr(), asc); 3496a725ed468585b881c43654eeb56b28554a84808aZhongxing Xu} 3497a725ed468585b881c43654eeb56b28554a84808aZhongxing Xu 349881bc7d07b701042371a5723b6f394cd2482ed7beZhongxing XuCFGBlock *CFGBuilder::VisitCXXTemporaryObjectExpr(CXXTemporaryObjectExpr *C, 349981bc7d07b701042371a5723b6f394cd2482ed7beZhongxing Xu AddStmtChoice asc) { 350081bc7d07b701042371a5723b6f394cd2482ed7beZhongxing Xu autoCreateBlock(); 3501247e9665d897a7bbbf60c1c0d3b6609c4504a961Ted Kremenek appendStmt(Block, C); 350281bc7d07b701042371a5723b6f394cd2482ed7beZhongxing Xu return VisitChildren(C); 350381bc7d07b701042371a5723b6f394cd2482ed7beZhongxing Xu} 350481bc7d07b701042371a5723b6f394cd2482ed7beZhongxing Xu 3505a725ed468585b881c43654eeb56b28554a84808aZhongxing XuCFGBlock *CFGBuilder::VisitImplicitCastExpr(ImplicitCastExpr *E, 3506a725ed468585b881c43654eeb56b28554a84808aZhongxing Xu AddStmtChoice asc) { 35073179a45a0e91c1dcf3492222170cf4499531bb92Ted Kremenek if (asc.alwaysAdd(*this, E)) { 3508a725ed468585b881c43654eeb56b28554a84808aZhongxing Xu autoCreateBlock(); 3509247e9665d897a7bbbf60c1c0d3b6609c4504a961Ted Kremenek appendStmt(Block, E); 3510a725ed468585b881c43654eeb56b28554a84808aZhongxing Xu } 3511892697dd2287caf7c29aaaa82909b0e90b8b63feTed Kremenek return Visit(E->getSubExpr(), AddStmtChoice()); 3512a725ed468585b881c43654eeb56b28554a84808aZhongxing Xu} 3513a725ed468585b881c43654eeb56b28554a84808aZhongxing Xu 35149c378f705405d37f49795d5e915989de774fe11fTed KremenekCFGBlock *CFGBuilder::VisitIndirectGotoStmt(IndirectGotoStmt *I) { 35156d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump // Lazily create the indirect-goto dispatch block if there isn't one already. 35169c378f705405d37f49795d5e915989de774fe11fTed Kremenek CFGBlock *IBlock = cfg->getIndirectGotoBlock(); 35176d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 351819bb356317952445b03ee341c02f6147083c9eeaTed Kremenek if (!IBlock) { 351919bb356317952445b03ee341c02f6147083c9eeaTed Kremenek IBlock = createBlock(false); 352019bb356317952445b03ee341c02f6147083c9eeaTed Kremenek cfg->setIndirectGotoBlock(IBlock); 352119bb356317952445b03ee341c02f6147083c9eeaTed Kremenek } 35226d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 352319bb356317952445b03ee341c02f6147083c9eeaTed Kremenek // IndirectGoto is a control-flow statement. Thus we stop processing the 352419bb356317952445b03ee341c02f6147083c9eeaTed Kremenek // current block and create a new one. 3525d438b3dbdcde4df4f61a99054104643e6aadf78bZhongxing Xu if (badCFG) 35266bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return nullptr; 35274f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek 352819bb356317952445b03ee341c02f6147083c9eeaTed Kremenek Block = createBlock(false); 352919bb356317952445b03ee341c02f6147083c9eeaTed Kremenek Block->setTerminator(I); 35300a3ed3143b00f237decb1288c1ff574ae09eba4eTed Kremenek addSuccessor(Block, IBlock); 353119bb356317952445b03ee341c02f6147083c9eeaTed Kremenek return addStmt(I->getTarget()); 353219bb356317952445b03ee341c02f6147083c9eeaTed Kremenek} 353319bb356317952445b03ee341c02f6147083c9eeaTed Kremenek 3534176edba5311f6eff0cad2631449885ddf4fbc9eaStephen HinesCFGBlock *CFGBuilder::VisitForTemporaryDtors(Stmt *E, bool BindToTemporary, 3535176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines TempDtorContext &Context) { 35365a1ffe98b04120846a15f7105905b5f363b08635Jordan Rose assert(BuildOpts.AddImplicitDtors && BuildOpts.AddTemporaryDtors); 35375a1ffe98b04120846a15f7105905b5f363b08635Jordan Rose 35388599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin SwiderskitryAgain: 35398599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski if (!E) { 35408599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski badCFG = true; 35416bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return nullptr; 35428599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski } 35438599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski switch (E->getStmtClass()) { 35448599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski default: 3545176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines return VisitChildrenForTemporaryDtors(E, Context); 35468599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski 35478599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski case Stmt::BinaryOperatorClass: 3548176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines return VisitBinaryOperatorForTemporaryDtors(cast<BinaryOperator>(E), 3549176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines Context); 35508599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski 35518599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski case Stmt::CXXBindTemporaryExprClass: 35528599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski return VisitCXXBindTemporaryExprForTemporaryDtors( 3553176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines cast<CXXBindTemporaryExpr>(E), BindToTemporary, Context); 35548599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski 355556ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall case Stmt::BinaryConditionalOperatorClass: 35568599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski case Stmt::ConditionalOperatorClass: 35578599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski return VisitConditionalOperatorForTemporaryDtors( 3558176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines cast<AbstractConditionalOperator>(E), BindToTemporary, Context); 35598599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski 35608599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski case Stmt::ImplicitCastExprClass: 35618599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski // For implicit cast we want BindToTemporary to be passed further. 35628599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski E = cast<CastExpr>(E)->getSubExpr(); 35638599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski goto tryAgain; 35648599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski 3565176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines case Stmt::CXXFunctionalCastExprClass: 3566176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines // For functional cast we want BindToTemporary to be passed further. 3567176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines E = cast<CXXFunctionalCastExpr>(E)->getSubExpr(); 3568176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines goto tryAgain; 3569176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines 35708599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski case Stmt::ParenExprClass: 35718599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski E = cast<ParenExpr>(E)->getSubExpr(); 35728599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski goto tryAgain; 3573176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines 3574176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines case Stmt::MaterializeTemporaryExprClass: { 3575176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines const MaterializeTemporaryExpr* MTE = cast<MaterializeTemporaryExpr>(E); 3576176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines BindToTemporary = (MTE->getStorageDuration() != SD_FullExpression); 3577176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines SmallVector<const Expr *, 2> CommaLHSs; 3578176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines SmallVector<SubobjectAdjustment, 2> Adjustments; 3579176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines // Find the expression whose lifetime needs to be extended. 3580176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines E = const_cast<Expr *>( 3581176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines cast<MaterializeTemporaryExpr>(E) 3582176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines ->GetTemporaryExpr() 3583176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines ->skipRValueSubobjectAdjustments(CommaLHSs, Adjustments)); 3584176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines // Visit the skipped comma operator left-hand sides for other temporaries. 3585176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines for (const Expr *CommaLHS : CommaLHSs) { 3586176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines VisitForTemporaryDtors(const_cast<Expr *>(CommaLHS), 3587176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines /*BindToTemporary=*/false, Context); 3588176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines } 3589176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines goto tryAgain; 3590176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines } 3591176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines 3592176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines case Stmt::BlockExprClass: 3593176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines // Don't recurse into blocks; their subexpressions don't get evaluated 3594176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines // here. 3595176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines return Block; 3596176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines 3597176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines case Stmt::LambdaExprClass: { 3598176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines // For lambda expressions, only recurse into the capture initializers, 3599176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines // and not the body. 3600176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines auto *LE = cast<LambdaExpr>(E); 3601176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines CFGBlock *B = Block; 3602176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines for (Expr *Init : LE->capture_inits()) { 3603176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines if (CFGBlock *R = VisitForTemporaryDtors( 3604176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines Init, /*BindToTemporary=*/false, Context)) 3605176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines B = R; 3606176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines } 3607176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines return B; 3608176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines } 3609176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines 3610176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines case Stmt::CXXDefaultArgExprClass: 3611176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines E = cast<CXXDefaultArgExpr>(E)->getExpr(); 3612176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines goto tryAgain; 3613176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines 3614176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines case Stmt::CXXDefaultInitExprClass: 3615176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines E = cast<CXXDefaultInitExpr>(E)->getExpr(); 361603e80030515c800d1ab44125b9052dfffd1bd04cDouglas Gregor goto tryAgain; 36178599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski } 36188599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski} 36198599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski 3620176edba5311f6eff0cad2631449885ddf4fbc9eaStephen HinesCFGBlock *CFGBuilder::VisitChildrenForTemporaryDtors(Stmt *E, 3621176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines TempDtorContext &Context) { 3622176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines if (isa<LambdaExpr>(E)) { 3623176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines // Do not visit the children of lambdas; they have their own CFGs. 3624176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines return Block; 3625176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines } 3626176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines 36278599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski // When visiting children for destructors we want to visit them in reverse 36285846720f08a6b225484bfe663599c2b057a99bc8Ted Kremenek // order that they will appear in the CFG. Because the CFG is built 36295846720f08a6b225484bfe663599c2b057a99bc8Ted Kremenek // bottom-up, this means we visit them in their natural order, which 36305846720f08a6b225484bfe663599c2b057a99bc8Ted Kremenek // reverses them in the CFG. 36318599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski CFGBlock *B = Block; 36325846720f08a6b225484bfe663599c2b057a99bc8Ted Kremenek for (Stmt::child_range I = E->children(); I; ++I) { 36335846720f08a6b225484bfe663599c2b057a99bc8Ted Kremenek if (Stmt *Child = *I) 3634176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines if (CFGBlock *R = VisitForTemporaryDtors(Child, false, Context)) 36355846720f08a6b225484bfe663599c2b057a99bc8Ted Kremenek B = R; 36368599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski } 36378599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski return B; 36388599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski} 36398599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski 3640176edba5311f6eff0cad2631449885ddf4fbc9eaStephen HinesCFGBlock *CFGBuilder::VisitBinaryOperatorForTemporaryDtors( 3641176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines BinaryOperator *E, TempDtorContext &Context) { 36428599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski if (E->isLogicalOp()) { 3643176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines VisitForTemporaryDtors(E->getLHS(), false, Context); 3644176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines TryResult RHSExecuted = tryEvaluateBool(E->getLHS()); 3645176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines if (RHSExecuted.isKnown() && E->getOpcode() == BO_LOr) 3646176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines RHSExecuted.negate(); 3647176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines 3648176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines // We do not know at CFG-construction time whether the right-hand-side was 3649176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines // executed, thus we add a branch node that depends on the temporary 3650176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines // constructor call. 3651176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines TempDtorContext RHSContext( 3652176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines bothKnownTrue(Context.KnownExecuted, RHSExecuted)); 3653176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines VisitForTemporaryDtors(E->getRHS(), false, RHSContext); 3654176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines InsertTempDtorDecisionBlock(RHSContext); 36558599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski 3656176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines return Block; 36578599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski } 36588599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski 365936f327c309b1fb6b82f1987190f0be74000b14c1Zhanyong Wan if (E->isAssignmentOp()) { 36608599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski // For assignment operator (=) LHS expression is visited 36618599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski // before RHS expression. For destructors visit them in reverse order. 3662176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines CFGBlock *RHSBlock = VisitForTemporaryDtors(E->getRHS(), false, Context); 3663176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines CFGBlock *LHSBlock = VisitForTemporaryDtors(E->getLHS(), false, Context); 36648599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski return LHSBlock ? LHSBlock : RHSBlock; 36658599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski } 36668599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski 36678599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski // For any other binary operator RHS expression is visited before 36688599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski // LHS expression (order of children). For destructors visit them in reverse 36698599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski // order. 3670176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines CFGBlock *LHSBlock = VisitForTemporaryDtors(E->getLHS(), false, Context); 3671176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines CFGBlock *RHSBlock = VisitForTemporaryDtors(E->getRHS(), false, Context); 36728599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski return RHSBlock ? RHSBlock : LHSBlock; 36738599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski} 36748599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski 36758599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin SwiderskiCFGBlock *CFGBuilder::VisitCXXBindTemporaryExprForTemporaryDtors( 3676176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines CXXBindTemporaryExpr *E, bool BindToTemporary, TempDtorContext &Context) { 36778599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski // First add destructors for temporaries in subexpression. 3678176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines CFGBlock *B = VisitForTemporaryDtors(E->getSubExpr(), false, Context); 3679249c9458e2cc5b671634baefe8517d7598883a20Zhongxing Xu if (!BindToTemporary) { 36808599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski // If lifetime of temporary is not prolonged (by assigning to constant 36818599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski // reference) add destructor for it. 3682c8cfc74bdcc999828bc232294d937fb191940d5bChandler Carruth 3683c8cfc74bdcc999828bc232294d937fb191940d5bChandler Carruth const CXXDestructorDecl *Dtor = E->getTemporary()->getDestructor(); 3684176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines 3685651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (Dtor->isNoReturn()) { 3686176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines // If the destructor is marked as a no-return destructor, we need to 3687176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines // create a new block for the destructor which does not have as a 3688176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines // successor anything built thus far. Control won't flow out of this 3689176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines // block. 3690176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines if (B) Succ = B; 3691dba3fb5413437dc613734fa4ffac892b11a37d25Chandler Carruth Block = createNoReturnBlock(); 3692176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines } else if (Context.needsTempDtorBranch()) { 3693176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines // If we need to introduce a branch, we add a new block that we will hook 3694176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines // up to a decision block later. 3695176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines if (B) Succ = B; 3696176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines Block = createBlock(); 3697651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } else { 3698c8cfc74bdcc999828bc232294d937fb191940d5bChandler Carruth autoCreateBlock(); 3699651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 3700176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines if (Context.needsTempDtorBranch()) { 3701176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines Context.setDecisionPoint(Succ, E); 3702176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines } 37038599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski appendTemporaryDtor(Block, E); 3704176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines 37058599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski B = Block; 37068599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski } 37078599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski return B; 37088599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski} 37098599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski 3710176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hinesvoid CFGBuilder::InsertTempDtorDecisionBlock(const TempDtorContext &Context, 3711176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines CFGBlock *FalseSucc) { 3712176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines if (!Context.TerminatorExpr) { 3713176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines // If no temporary was found, we do not need to insert a decision point. 3714176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines return; 37158599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski } 3716176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines assert(Context.TerminatorExpr); 3717176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines CFGBlock *Decision = createBlock(false); 3718176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines Decision->setTerminator(CFGTerminator(Context.TerminatorExpr, true)); 3719176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines addSuccessor(Decision, Block, !Context.KnownExecuted.isFalse()); 3720176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines addSuccessor(Decision, FalseSucc ? FalseSucc : Context.Succ, 3721176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines !Context.KnownExecuted.isTrue()); 3722176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines Block = Decision; 3723176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines} 37248599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski 3725176edba5311f6eff0cad2631449885ddf4fbc9eaStephen HinesCFGBlock *CFGBuilder::VisitConditionalOperatorForTemporaryDtors( 3726176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines AbstractConditionalOperator *E, bool BindToTemporary, 3727176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines TempDtorContext &Context) { 3728176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines VisitForTemporaryDtors(E->getCond(), false, Context); 3729176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines CFGBlock *ConditionBlock = Block; 3730176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines CFGBlock *ConditionSucc = Succ; 3731176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines TryResult ConditionVal = tryEvaluateBool(E->getCond()); 3732176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines TryResult NegatedVal = ConditionVal; 3733176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines if (NegatedVal.isKnown()) NegatedVal.negate(); 3734176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines 3735176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines TempDtorContext TrueContext( 3736176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines bothKnownTrue(Context.KnownExecuted, ConditionVal)); 3737176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines VisitForTemporaryDtors(E->getTrueExpr(), BindToTemporary, TrueContext); 3738176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines CFGBlock *TrueBlock = Block; 3739176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines 3740176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines Block = ConditionBlock; 3741176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines Succ = ConditionSucc; 3742176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines TempDtorContext FalseContext( 3743176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines bothKnownTrue(Context.KnownExecuted, NegatedVal)); 3744176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines VisitForTemporaryDtors(E->getFalseExpr(), BindToTemporary, FalseContext); 3745176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines 3746176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines if (TrueContext.TerminatorExpr && FalseContext.TerminatorExpr) { 3747176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines InsertTempDtorDecisionBlock(FalseContext, TrueBlock); 3748176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines } else if (TrueContext.TerminatorExpr) { 3749176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines Block = TrueBlock; 3750176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines InsertTempDtorDecisionBlock(TrueContext); 37518599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski } else { 3752176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines InsertTempDtorDecisionBlock(FalseContext); 37538599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski } 37548599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski return Block; 37558599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski} 37568599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski 3757befef2f69759d7338e2b7c5ce6c8b6f47fe6e667Ted Kremenek} // end anonymous namespace 3758026473c2175424a039f51ca8949937268721b965Ted Kremenek 37596d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump/// createBlock - Constructs and adds a new CFGBlock to the CFG. The block has 37606d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump/// no successors or predecessors. If this is the first block created in the 37616d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump/// CFG, it is automatically set to be the Entry and Exit of the CFG. 37629c378f705405d37f49795d5e915989de774fe11fTed KremenekCFGBlock *CFG::createBlock() { 3763026473c2175424a039f51ca8949937268721b965Ted Kremenek bool first_block = begin() == end(); 3764026473c2175424a039f51ca8949937268721b965Ted Kremenek 3765026473c2175424a039f51ca8949937268721b965Ted Kremenek // Create the block. 3766ee82d9bdc5025b82de8ce2a4ad4685e0a8b79da9Ted Kremenek CFGBlock *Mem = getAllocator().Allocate<CFGBlock>(); 376702f34c5003b2c5067675f89ffce0a84c28faf722Anna Zaks new (Mem) CFGBlock(NumBlockIDs++, BlkBVC, this); 3768ee82d9bdc5025b82de8ce2a4ad4685e0a8b79da9Ted Kremenek Blocks.push_back(Mem, BlkBVC); 3769026473c2175424a039f51ca8949937268721b965Ted Kremenek 3770026473c2175424a039f51ca8949937268721b965Ted Kremenek // If this is the first block, set it as the Entry and Exit. 3771ee82d9bdc5025b82de8ce2a4ad4685e0a8b79da9Ted Kremenek if (first_block) 3772ee82d9bdc5025b82de8ce2a4ad4685e0a8b79da9Ted Kremenek Entry = Exit = &back(); 3773026473c2175424a039f51ca8949937268721b965Ted Kremenek 3774026473c2175424a039f51ca8949937268721b965Ted Kremenek // Return the block. 3775ee82d9bdc5025b82de8ce2a4ad4685e0a8b79da9Ted Kremenek return &back(); 3776026473c2175424a039f51ca8949937268721b965Ted Kremenek} 3777026473c2175424a039f51ca8949937268721b965Ted Kremenek 3778176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines/// buildCFG - Constructs a CFG from an AST. 3779176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hinesstd::unique_ptr<CFG> CFG::buildCFG(const Decl *D, Stmt *Statement, 3780176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines ASTContext *C, const BuildOptions &BO) { 3781b8ad5ee345fa1fdd1fa9253f2d01f69becc88a04Ted Kremenek CFGBuilder Builder(C, BO); 3782b8ad5ee345fa1fdd1fa9253f2d01f69becc88a04Ted Kremenek return Builder.buildCFG(D, Statement); 3783fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek} 3784fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek 3785c5aff4497e5bfd7523e00b87560c1a5aa65136ccTed Kremenekconst CXXDestructorDecl * 3786c5aff4497e5bfd7523e00b87560c1a5aa65136ccTed KremenekCFGImplicitDtor::getDestructorDecl(ASTContext &astContext) const { 3787c9f8f5a726bbb562e4b2d4b19d66e6202dcb2657Ted Kremenek switch (getKind()) { 3788c9f8f5a726bbb562e4b2d4b19d66e6202dcb2657Ted Kremenek case CFGElement::Statement: 3789c9f8f5a726bbb562e4b2d4b19d66e6202dcb2657Ted Kremenek case CFGElement::Initializer: 3790651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines case CFGElement::NewAllocator: 3791c9f8f5a726bbb562e4b2d4b19d66e6202dcb2657Ted Kremenek llvm_unreachable("getDestructorDecl should only be used with " 3792c9f8f5a726bbb562e4b2d4b19d66e6202dcb2657Ted Kremenek "ImplicitDtors"); 3793c9f8f5a726bbb562e4b2d4b19d66e6202dcb2657Ted Kremenek case CFGElement::AutomaticObjectDtor: { 3794fdf6a279c9a75c778eba382d9a156697092982a1David Blaikie const VarDecl *var = castAs<CFGAutomaticObjDtor>().getVarDecl(); 3795c9f8f5a726bbb562e4b2d4b19d66e6202dcb2657Ted Kremenek QualType ty = var->getType(); 3796697d42db6cba7a5994d955ce31be2c097902cf0cTed Kremenek ty = ty.getNonReferenceType(); 37974cf225382a8b061dce41733c962d62b6db9721f8Ted Kremenek while (const ArrayType *arrayType = astContext.getAsArrayType(ty)) { 3798c5aff4497e5bfd7523e00b87560c1a5aa65136ccTed Kremenek ty = arrayType->getElementType(); 3799c5aff4497e5bfd7523e00b87560c1a5aa65136ccTed Kremenek } 3800c9f8f5a726bbb562e4b2d4b19d66e6202dcb2657Ted Kremenek const RecordType *recordType = ty->getAs<RecordType>(); 3801c9f8f5a726bbb562e4b2d4b19d66e6202dcb2657Ted Kremenek const CXXRecordDecl *classDecl = 3802697d42db6cba7a5994d955ce31be2c097902cf0cTed Kremenek cast<CXXRecordDecl>(recordType->getDecl()); 3803c9f8f5a726bbb562e4b2d4b19d66e6202dcb2657Ted Kremenek return classDecl->getDestructor(); 3804c9f8f5a726bbb562e4b2d4b19d66e6202dcb2657Ted Kremenek } 380536d558d85653315edb389677e995ec9ccdbfbf3dJordan Rose case CFGElement::DeleteDtor: { 380636d558d85653315edb389677e995ec9ccdbfbf3dJordan Rose const CXXDeleteExpr *DE = castAs<CFGDeleteDtor>().getDeleteExpr(); 380736d558d85653315edb389677e995ec9ccdbfbf3dJordan Rose QualType DTy = DE->getDestroyedType(); 380836d558d85653315edb389677e995ec9ccdbfbf3dJordan Rose DTy = DTy.getNonReferenceType(); 380936d558d85653315edb389677e995ec9ccdbfbf3dJordan Rose const CXXRecordDecl *classDecl = 381036d558d85653315edb389677e995ec9ccdbfbf3dJordan Rose astContext.getBaseElementType(DTy)->getAsCXXRecordDecl(); 381136d558d85653315edb389677e995ec9ccdbfbf3dJordan Rose return classDecl->getDestructor(); 381236d558d85653315edb389677e995ec9ccdbfbf3dJordan Rose } 3813c9f8f5a726bbb562e4b2d4b19d66e6202dcb2657Ted Kremenek case CFGElement::TemporaryDtor: { 3814c9f8f5a726bbb562e4b2d4b19d66e6202dcb2657Ted Kremenek const CXXBindTemporaryExpr *bindExpr = 3815fdf6a279c9a75c778eba382d9a156697092982a1David Blaikie castAs<CFGTemporaryDtor>().getBindTemporaryExpr(); 3816c9f8f5a726bbb562e4b2d4b19d66e6202dcb2657Ted Kremenek const CXXTemporary *temp = bindExpr->getTemporary(); 3817c9f8f5a726bbb562e4b2d4b19d66e6202dcb2657Ted Kremenek return temp->getDestructor(); 3818c9f8f5a726bbb562e4b2d4b19d66e6202dcb2657Ted Kremenek } 3819c9f8f5a726bbb562e4b2d4b19d66e6202dcb2657Ted Kremenek case CFGElement::BaseDtor: 3820c9f8f5a726bbb562e4b2d4b19d66e6202dcb2657Ted Kremenek case CFGElement::MemberDtor: 3821c9f8f5a726bbb562e4b2d4b19d66e6202dcb2657Ted Kremenek 3822c9f8f5a726bbb562e4b2d4b19d66e6202dcb2657Ted Kremenek // Not yet supported. 38236bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return nullptr; 3824c9f8f5a726bbb562e4b2d4b19d66e6202dcb2657Ted Kremenek } 3825697d42db6cba7a5994d955ce31be2c097902cf0cTed Kremenek llvm_unreachable("getKind() returned bogus value"); 3826c9f8f5a726bbb562e4b2d4b19d66e6202dcb2657Ted Kremenek} 3827c9f8f5a726bbb562e4b2d4b19d66e6202dcb2657Ted Kremenek 3828c5aff4497e5bfd7523e00b87560c1a5aa65136ccTed Kremenekbool CFGImplicitDtor::isNoReturn(ASTContext &astContext) const { 3829cd8ab51a44e80625d84126780b0d85a7732e25afRichard Smith if (const CXXDestructorDecl *DD = getDestructorDecl(astContext)) 3830cd8ab51a44e80625d84126780b0d85a7732e25afRichard Smith return DD->isNoReturn(); 3831c9f8f5a726bbb562e4b2d4b19d66e6202dcb2657Ted Kremenek return false; 38323c0349e87cdbd7316d06d2411d86ee1086e717a5Ted Kremenek} 38333c0349e87cdbd7316d06d2411d86ee1086e717a5Ted Kremenek 383463f5887f316fb52d243fcbb3631c039de6c4b993Ted Kremenek//===----------------------------------------------------------------------===// 3835651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CFGBlock operations. 3836ee7f84d509c6382491673883598eb9ed2d3a6a8bTed Kremenek//===----------------------------------------------------------------------===// 3837ee7f84d509c6382491673883598eb9ed2d3a6a8bTed Kremenek 3838651f13cea278ec967336033dd032faef0e9fc2ecStephen HinesCFGBlock::AdjacentBlock::AdjacentBlock(CFGBlock *B, bool IsReachable) 38396bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines : ReachableBlock(IsReachable ? B : nullptr), 38406bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines UnreachableBlock(!IsReachable ? B : nullptr, 3841651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines B && IsReachable ? AB_Normal : AB_Unreachable) {} 3842651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 3843651f13cea278ec967336033dd032faef0e9fc2ecStephen HinesCFGBlock::AdjacentBlock::AdjacentBlock(CFGBlock *B, CFGBlock *AlternateBlock) 3844651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines : ReachableBlock(B), 38456bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines UnreachableBlock(B == AlternateBlock ? nullptr : AlternateBlock, 3846651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines B == AlternateBlock ? AB_Alternate : AB_Normal) {} 3847651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 3848651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesvoid CFGBlock::addSuccessor(AdjacentBlock Succ, 3849651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines BumpVectorContext &C) { 3850651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (CFGBlock *B = Succ.getReachableBlock()) 3851651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines B->Preds.push_back(AdjacentBlock(this, Succ.isReachable()), C); 3852651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 3853651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (CFGBlock *UnreachableB = Succ.getPossiblyUnreachableBlock()) 3854651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines UnreachableB->Preds.push_back(AdjacentBlock(this, false), C); 3855651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 3856651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Succs.push_back(Succ, C); 3857651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines} 3858651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 3859ee7f84d509c6382491673883598eb9ed2d3a6a8bTed Kremenekbool CFGBlock::FilterEdge(const CFGBlock::FilterOptions &F, 3860be39a566a914df8561d7a1e9654708297f0908c1Ted Kremenek const CFGBlock *From, const CFGBlock *To) { 3861ee7f84d509c6382491673883598eb9ed2d3a6a8bTed Kremenek 3862651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (F.IgnoreNullPredecessors && !From) 3863651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return true; 3864651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 3865651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (To && From && F.IgnoreDefaultsWithCoveredEnums) { 3866ee7f84d509c6382491673883598eb9ed2d3a6a8bTed Kremenek // If the 'To' has no label or is labeled but the label isn't a 3867ee7f84d509c6382491673883598eb9ed2d3a6a8bTed Kremenek // CaseStmt then filter this edge. 3868ee7f84d509c6382491673883598eb9ed2d3a6a8bTed Kremenek if (const SwitchStmt *S = 38696e40035988965340555c942d6e7afb6c7527beb1Ted Kremenek dyn_cast_or_null<SwitchStmt>(From->getTerminator().getStmt())) { 3870ee7f84d509c6382491673883598eb9ed2d3a6a8bTed Kremenek if (S->isAllEnumCasesCovered()) { 38716e40035988965340555c942d6e7afb6c7527beb1Ted Kremenek const Stmt *L = To->getLabel(); 38726e40035988965340555c942d6e7afb6c7527beb1Ted Kremenek if (!L || !isa<CaseStmt>(L)) 38736e40035988965340555c942d6e7afb6c7527beb1Ted Kremenek return true; 3874ee7f84d509c6382491673883598eb9ed2d3a6a8bTed Kremenek } 3875ee7f84d509c6382491673883598eb9ed2d3a6a8bTed Kremenek } 3876ee7f84d509c6382491673883598eb9ed2d3a6a8bTed Kremenek } 3877ee7f84d509c6382491673883598eb9ed2d3a6a8bTed Kremenek 3878ee7f84d509c6382491673883598eb9ed2d3a6a8bTed Kremenek return false; 3879ee7f84d509c6382491673883598eb9ed2d3a6a8bTed Kremenek} 3880ee7f84d509c6382491673883598eb9ed2d3a6a8bTed Kremenek 3881ee7f84d509c6382491673883598eb9ed2d3a6a8bTed Kremenek//===----------------------------------------------------------------------===// 38827dba8607e59096014b7139ff20ef00870041d518Ted Kremenek// CFG pretty printing 38837dba8607e59096014b7139ff20ef00870041d518Ted Kremenek//===----------------------------------------------------------------------===// 38847dba8607e59096014b7139ff20ef00870041d518Ted Kremenek 388542a509f6a4f71bb805cc4abbb26722a34dffdddeTed Kremeneknamespace { 38862bac4ea765a4a6e1f6149964663f62d4bca6743bTed Kremenek 3887ba5fb5a955c896815c439289fc51c03cf0635129Kovarththanan Rajaratnamclass StmtPrinterHelper : public PrinterHelper { 38883c0349e87cdbd7316d06d2411d86ee1086e717a5Ted Kremenek typedef llvm::DenseMap<const Stmt*,std::pair<unsigned,unsigned> > StmtMapTy; 38893c0349e87cdbd7316d06d2411d86ee1086e717a5Ted Kremenek typedef llvm::DenseMap<const Decl*,std::pair<unsigned,unsigned> > DeclMapTy; 389042a509f6a4f71bb805cc4abbb26722a34dffdddeTed Kremenek StmtMapTy StmtMap; 38911cff132e48e0ccc253c34e5a2fb12718bd4e7d2eMarcin Swiderski DeclMapTy DeclMap; 38920a3ed3143b00f237decb1288c1ff574ae09eba4eTed Kremenek signed currentBlock; 389366c486f275531df6362b3511fc3af6563561801bTed Kremenek unsigned currStmt; 3894e4f2142d00fa5fdb580c4e2413da91882d955381Chris Lattner const LangOptions &LangOpts; 389542a509f6a4f71bb805cc4abbb26722a34dffdddeTed Kremenekpublic: 38961c29bba6da40bbe59fb1f81c4cd5ab5471554ffeTed Kremenek 3897e4f2142d00fa5fdb580c4e2413da91882d955381Chris Lattner StmtPrinterHelper(const CFG* cfg, const LangOptions &LO) 389866c486f275531df6362b3511fc3af6563561801bTed Kremenek : currentBlock(0), currStmt(0), LangOpts(LO) 38993c0349e87cdbd7316d06d2411d86ee1086e717a5Ted Kremenek { 390042a509f6a4f71bb805cc4abbb26722a34dffdddeTed Kremenek for (CFG::const_iterator I = cfg->begin(), E = cfg->end(); I != E; ++I ) { 390142a509f6a4f71bb805cc4abbb26722a34dffdddeTed Kremenek unsigned j = 1; 3902ee82d9bdc5025b82de8ce2a4ad4685e0a8b79da9Ted Kremenek for (CFGBlock::const_iterator BI = (*I)->begin(), BEnd = (*I)->end() ; 39031cff132e48e0ccc253c34e5a2fb12718bd4e7d2eMarcin Swiderski BI != BEnd; ++BI, ++j ) { 3904b07805485c603be3d8011f72611465324c9e664bDavid Blaikie if (Optional<CFGStmt> SE = BI->getAs<CFGStmt>()) { 3905b07805485c603be3d8011f72611465324c9e664bDavid Blaikie const Stmt *stmt= SE->getStmt(); 39061cff132e48e0ccc253c34e5a2fb12718bd4e7d2eMarcin Swiderski std::pair<unsigned, unsigned> P((*I)->getBlockID(), j); 39073c0349e87cdbd7316d06d2411d86ee1086e717a5Ted Kremenek StmtMap[stmt] = P; 39083c0349e87cdbd7316d06d2411d86ee1086e717a5Ted Kremenek 39093c0349e87cdbd7316d06d2411d86ee1086e717a5Ted Kremenek switch (stmt->getStmtClass()) { 39103c0349e87cdbd7316d06d2411d86ee1086e717a5Ted Kremenek case Stmt::DeclStmtClass: 39113c0349e87cdbd7316d06d2411d86ee1086e717a5Ted Kremenek DeclMap[cast<DeclStmt>(stmt)->getSingleDecl()] = P; 39123c0349e87cdbd7316d06d2411d86ee1086e717a5Ted Kremenek break; 39133c0349e87cdbd7316d06d2411d86ee1086e717a5Ted Kremenek case Stmt::IfStmtClass: { 39143c0349e87cdbd7316d06d2411d86ee1086e717a5Ted Kremenek const VarDecl *var = cast<IfStmt>(stmt)->getConditionVariable(); 39153c0349e87cdbd7316d06d2411d86ee1086e717a5Ted Kremenek if (var) 39163c0349e87cdbd7316d06d2411d86ee1086e717a5Ted Kremenek DeclMap[var] = P; 39173c0349e87cdbd7316d06d2411d86ee1086e717a5Ted Kremenek break; 39183c0349e87cdbd7316d06d2411d86ee1086e717a5Ted Kremenek } 39193c0349e87cdbd7316d06d2411d86ee1086e717a5Ted Kremenek case Stmt::ForStmtClass: { 39203c0349e87cdbd7316d06d2411d86ee1086e717a5Ted Kremenek const VarDecl *var = cast<ForStmt>(stmt)->getConditionVariable(); 39213c0349e87cdbd7316d06d2411d86ee1086e717a5Ted Kremenek if (var) 39223c0349e87cdbd7316d06d2411d86ee1086e717a5Ted Kremenek DeclMap[var] = P; 39233c0349e87cdbd7316d06d2411d86ee1086e717a5Ted Kremenek break; 39243c0349e87cdbd7316d06d2411d86ee1086e717a5Ted Kremenek } 39253c0349e87cdbd7316d06d2411d86ee1086e717a5Ted Kremenek case Stmt::WhileStmtClass: { 39263c0349e87cdbd7316d06d2411d86ee1086e717a5Ted Kremenek const VarDecl *var = 39273c0349e87cdbd7316d06d2411d86ee1086e717a5Ted Kremenek cast<WhileStmt>(stmt)->getConditionVariable(); 39283c0349e87cdbd7316d06d2411d86ee1086e717a5Ted Kremenek if (var) 39293c0349e87cdbd7316d06d2411d86ee1086e717a5Ted Kremenek DeclMap[var] = P; 39303c0349e87cdbd7316d06d2411d86ee1086e717a5Ted Kremenek break; 39313c0349e87cdbd7316d06d2411d86ee1086e717a5Ted Kremenek } 39323c0349e87cdbd7316d06d2411d86ee1086e717a5Ted Kremenek case Stmt::SwitchStmtClass: { 39333c0349e87cdbd7316d06d2411d86ee1086e717a5Ted Kremenek const VarDecl *var = 39343c0349e87cdbd7316d06d2411d86ee1086e717a5Ted Kremenek cast<SwitchStmt>(stmt)->getConditionVariable(); 39353c0349e87cdbd7316d06d2411d86ee1086e717a5Ted Kremenek if (var) 39363c0349e87cdbd7316d06d2411d86ee1086e717a5Ted Kremenek DeclMap[var] = P; 39373c0349e87cdbd7316d06d2411d86ee1086e717a5Ted Kremenek break; 39383c0349e87cdbd7316d06d2411d86ee1086e717a5Ted Kremenek } 39393c0349e87cdbd7316d06d2411d86ee1086e717a5Ted Kremenek case Stmt::CXXCatchStmtClass: { 39403c0349e87cdbd7316d06d2411d86ee1086e717a5Ted Kremenek const VarDecl *var = 39413c0349e87cdbd7316d06d2411d86ee1086e717a5Ted Kremenek cast<CXXCatchStmt>(stmt)->getExceptionDecl(); 39423c0349e87cdbd7316d06d2411d86ee1086e717a5Ted Kremenek if (var) 39433c0349e87cdbd7316d06d2411d86ee1086e717a5Ted Kremenek DeclMap[var] = P; 39443c0349e87cdbd7316d06d2411d86ee1086e717a5Ted Kremenek break; 39453c0349e87cdbd7316d06d2411d86ee1086e717a5Ted Kremenek } 39463c0349e87cdbd7316d06d2411d86ee1086e717a5Ted Kremenek default: 39473c0349e87cdbd7316d06d2411d86ee1086e717a5Ted Kremenek break; 39481cff132e48e0ccc253c34e5a2fb12718bd4e7d2eMarcin Swiderski } 39491cff132e48e0ccc253c34e5a2fb12718bd4e7d2eMarcin Swiderski } 395042a509f6a4f71bb805cc4abbb26722a34dffdddeTed Kremenek } 3951b36cd3e1757fb4fcd9509f35558c847b04bef35fZhongxing Xu } 3952fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek } 39536d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 395433337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar ~StmtPrinterHelper() override {} 39556d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 3956e4f2142d00fa5fdb580c4e2413da91882d955381Chris Lattner const LangOptions &getLangOpts() const { return LangOpts; } 39570a3ed3143b00f237decb1288c1ff574ae09eba4eTed Kremenek void setBlockID(signed i) { currentBlock = i; } 395866c486f275531df6362b3511fc3af6563561801bTed Kremenek void setStmtID(unsigned i) { currStmt = i; } 39596d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 3960651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines bool handledStmt(Stmt *S, raw_ostream &OS) override { 39611cff132e48e0ccc253c34e5a2fb12718bd4e7d2eMarcin Swiderski StmtMapTy::iterator I = StmtMap.find(S); 3962fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek 396342a509f6a4f71bb805cc4abbb26722a34dffdddeTed Kremenek if (I == StmtMap.end()) 396442a509f6a4f71bb805cc4abbb26722a34dffdddeTed Kremenek return false; 39656d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 39660a3ed3143b00f237decb1288c1ff574ae09eba4eTed Kremenek if (currentBlock >= 0 && I->second.first == (unsigned) currentBlock 396766c486f275531df6362b3511fc3af6563561801bTed Kremenek && I->second.second == currStmt) { 396842a509f6a4f71bb805cc4abbb26722a34dffdddeTed Kremenek return false; 39693fa1e4b27300a4ea4cf273182d4b6427ef87f3f8Ted Kremenek } 39706d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 39713fa1e4b27300a4ea4cf273182d4b6427ef87f3f8Ted Kremenek OS << "[B" << I->second.first << "." << I->second.second << "]"; 39721c29bba6da40bbe59fb1f81c4cd5ab5471554ffeTed Kremenek return true; 397342a509f6a4f71bb805cc4abbb26722a34dffdddeTed Kremenek } 39741cff132e48e0ccc253c34e5a2fb12718bd4e7d2eMarcin Swiderski 39759c378f705405d37f49795d5e915989de774fe11fTed Kremenek bool handleDecl(const Decl *D, raw_ostream &OS) { 39761cff132e48e0ccc253c34e5a2fb12718bd4e7d2eMarcin Swiderski DeclMapTy::iterator I = DeclMap.find(D); 39771cff132e48e0ccc253c34e5a2fb12718bd4e7d2eMarcin Swiderski 39781cff132e48e0ccc253c34e5a2fb12718bd4e7d2eMarcin Swiderski if (I == DeclMap.end()) 39791cff132e48e0ccc253c34e5a2fb12718bd4e7d2eMarcin Swiderski return false; 39801cff132e48e0ccc253c34e5a2fb12718bd4e7d2eMarcin Swiderski 39810a3ed3143b00f237decb1288c1ff574ae09eba4eTed Kremenek if (currentBlock >= 0 && I->second.first == (unsigned) currentBlock 398266c486f275531df6362b3511fc3af6563561801bTed Kremenek && I->second.second == currStmt) { 39831cff132e48e0ccc253c34e5a2fb12718bd4e7d2eMarcin Swiderski return false; 39841cff132e48e0ccc253c34e5a2fb12718bd4e7d2eMarcin Swiderski } 39851cff132e48e0ccc253c34e5a2fb12718bd4e7d2eMarcin Swiderski 39861cff132e48e0ccc253c34e5a2fb12718bd4e7d2eMarcin Swiderski OS << "[B" << I->second.first << "." << I->second.second << "]"; 39871cff132e48e0ccc253c34e5a2fb12718bd4e7d2eMarcin Swiderski return true; 39881cff132e48e0ccc253c34e5a2fb12718bd4e7d2eMarcin Swiderski } 398942a509f6a4f71bb805cc4abbb26722a34dffdddeTed Kremenek}; 3990e4f2142d00fa5fdb580c4e2413da91882d955381Chris Lattner} // end anonymous namespace 3991e4f2142d00fa5fdb580c4e2413da91882d955381Chris Lattner 3992e8ee26b49d68ae3ffdf9a990ff7511ef55afa04cTed Kremenek 3993e4f2142d00fa5fdb580c4e2413da91882d955381Chris Lattnernamespace { 3994ba5fb5a955c896815c439289fc51c03cf0635129Kovarththanan Rajaratnamclass CFGBlockTerminatorPrint 39956fa9b88e2c3d47d606a273df2f8d03509bcff0b9Ted Kremenek : public StmtVisitor<CFGBlockTerminatorPrint,void> { 39966d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 39979c378f705405d37f49795d5e915989de774fe11fTed Kremenek raw_ostream &OS; 399842a509f6a4f71bb805cc4abbb26722a34dffdddeTed Kremenek StmtPrinterHelper* Helper; 3999d249e1d1f1498b81314459ceda19d6ff25c278adDouglas Gregor PrintingPolicy Policy; 4000d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenekpublic: 40019c378f705405d37f49795d5e915989de774fe11fTed Kremenek CFGBlockTerminatorPrint(raw_ostream &os, StmtPrinterHelper* helper, 4002e4f2142d00fa5fdb580c4e2413da91882d955381Chris Lattner const PrintingPolicy &Policy) 4003651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines : OS(os), Helper(helper), Policy(Policy) { 4004651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines this->Policy.IncludeNewlines = false; 4005651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 40066d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 40079c378f705405d37f49795d5e915989de774fe11fTed Kremenek void VisitIfStmt(IfStmt *I) { 4008d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek OS << "if "; 4009c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines if (Stmt *C = I->getCond()) 4010c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines C->printPretty(OS, Helper, Policy); 4011d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek } 40126d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 4013d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek // Default case. 40149c378f705405d37f49795d5e915989de774fe11fTed Kremenek void VisitStmt(Stmt *Terminator) { 40156d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump Terminator->printPretty(OS, Helper, Policy); 40166d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump } 40176d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 4018fbd4b5dc7febd1d8b4fa64ab00a29d72b44bec7bTed Kremenek void VisitDeclStmt(DeclStmt *DS) { 4019fbd4b5dc7febd1d8b4fa64ab00a29d72b44bec7bTed Kremenek VarDecl *VD = cast<VarDecl>(DS->getSingleDecl()); 4020fbd4b5dc7febd1d8b4fa64ab00a29d72b44bec7bTed Kremenek OS << "static init " << VD->getName(); 4021fbd4b5dc7febd1d8b4fa64ab00a29d72b44bec7bTed Kremenek } 4022fbd4b5dc7febd1d8b4fa64ab00a29d72b44bec7bTed Kremenek 40239c378f705405d37f49795d5e915989de774fe11fTed Kremenek void VisitForStmt(ForStmt *F) { 4024d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek OS << "for (" ; 40253fa1e4b27300a4ea4cf273182d4b6427ef87f3f8Ted Kremenek if (F->getInit()) 40263fa1e4b27300a4ea4cf273182d4b6427ef87f3f8Ted Kremenek OS << "..."; 4027535bb20b6e252809bc17cc59b5d71b5e5e549e70Ted Kremenek OS << "; "; 40289c378f705405d37f49795d5e915989de774fe11fTed Kremenek if (Stmt *C = F->getCond()) 40293fa1e4b27300a4ea4cf273182d4b6427ef87f3f8Ted Kremenek C->printPretty(OS, Helper, Policy); 4030535bb20b6e252809bc17cc59b5d71b5e5e549e70Ted Kremenek OS << "; "; 40313fa1e4b27300a4ea4cf273182d4b6427ef87f3f8Ted Kremenek if (F->getInc()) 40323fa1e4b27300a4ea4cf273182d4b6427ef87f3f8Ted Kremenek OS << "..."; 4033a292585207adbf6dcf6347db3526a7ec861d8eacTed Kremenek OS << ")"; 4034d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek } 40356d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 40369c378f705405d37f49795d5e915989de774fe11fTed Kremenek void VisitWhileStmt(WhileStmt *W) { 4037d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek OS << "while " ; 40389c378f705405d37f49795d5e915989de774fe11fTed Kremenek if (Stmt *C = W->getCond()) 40393fa1e4b27300a4ea4cf273182d4b6427ef87f3f8Ted Kremenek C->printPretty(OS, Helper, Policy); 4040d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek } 40416d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 40429c378f705405d37f49795d5e915989de774fe11fTed Kremenek void VisitDoStmt(DoStmt *D) { 4043d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek OS << "do ... while "; 40449c378f705405d37f49795d5e915989de774fe11fTed Kremenek if (Stmt *C = D->getCond()) 40453fa1e4b27300a4ea4cf273182d4b6427ef87f3f8Ted Kremenek C->printPretty(OS, Helper, Policy); 40469da2fb773c473b989c78c513c5ce61641e9bbb4dTed Kremenek } 40476d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 40489c378f705405d37f49795d5e915989de774fe11fTed Kremenek void VisitSwitchStmt(SwitchStmt *Terminator) { 40499da2fb773c473b989c78c513c5ce61641e9bbb4dTed Kremenek OS << "switch "; 4050d249e1d1f1498b81314459ceda19d6ff25c278adDouglas Gregor Terminator->getCond()->printPretty(OS, Helper, Policy); 40519da2fb773c473b989c78c513c5ce61641e9bbb4dTed Kremenek } 40526d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 40539c378f705405d37f49795d5e915989de774fe11fTed Kremenek void VisitCXXTryStmt(CXXTryStmt *CS) { 40545d1d20227878cd03db8b2dd23efd4cedfe874feeMike Stump OS << "try ..."; 40555d1d20227878cd03db8b2dd23efd4cedfe874feeMike Stump } 40565d1d20227878cd03db8b2dd23efd4cedfe874feeMike Stump 405756ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall void VisitAbstractConditionalOperator(AbstractConditionalOperator* C) { 4058c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines if (Stmt *Cond = C->getCond()) 4059c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines Cond->printPretty(OS, Helper, Policy); 40606d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump OS << " ? ... : ..."; 4061805e9a8300af9489ec13cd804c070267b7c4cfecTed Kremenek } 40626d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 40639c378f705405d37f49795d5e915989de774fe11fTed Kremenek void VisitChooseExpr(ChooseExpr *C) { 4064aeddbf689eb3e3afca5117ca83c7b2e18260b0d8Ted Kremenek OS << "__builtin_choose_expr( "; 4065c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines if (Stmt *Cond = C->getCond()) 4066c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines Cond->printPretty(OS, Helper, Policy); 4067a292585207adbf6dcf6347db3526a7ec861d8eacTed Kremenek OS << " )"; 4068aeddbf689eb3e3afca5117ca83c7b2e18260b0d8Ted Kremenek } 40696d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 40709c378f705405d37f49795d5e915989de774fe11fTed Kremenek void VisitIndirectGotoStmt(IndirectGotoStmt *I) { 40711c29bba6da40bbe59fb1f81c4cd5ab5471554ffeTed Kremenek OS << "goto *"; 4072c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines if (Stmt *T = I->getTarget()) 4073c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines T->printPretty(OS, Helper, Policy); 40741c29bba6da40bbe59fb1f81c4cd5ab5471554ffeTed Kremenek } 40756d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 4076805e9a8300af9489ec13cd804c070267b7c4cfecTed Kremenek void VisitBinaryOperator(BinaryOperator* B) { 4077805e9a8300af9489ec13cd804c070267b7c4cfecTed Kremenek if (!B->isLogicalOp()) { 4078805e9a8300af9489ec13cd804c070267b7c4cfecTed Kremenek VisitExpr(B); 4079805e9a8300af9489ec13cd804c070267b7c4cfecTed Kremenek return; 4080805e9a8300af9489ec13cd804c070267b7c4cfecTed Kremenek } 40816d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 4082c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines if (B->getLHS()) 4083c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines B->getLHS()->printPretty(OS, Helper, Policy); 40846d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 4085805e9a8300af9489ec13cd804c070267b7c4cfecTed Kremenek switch (B->getOpcode()) { 40862de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall case BO_LOr: 4087a292585207adbf6dcf6347db3526a7ec861d8eacTed Kremenek OS << " || ..."; 4088805e9a8300af9489ec13cd804c070267b7c4cfecTed Kremenek return; 40892de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall case BO_LAnd: 4090a292585207adbf6dcf6347db3526a7ec861d8eacTed Kremenek OS << " && ..."; 4091805e9a8300af9489ec13cd804c070267b7c4cfecTed Kremenek return; 4092805e9a8300af9489ec13cd804c070267b7c4cfecTed Kremenek default: 4093b219cfc4d75f0a03630b7c4509ef791b7e97b2c8David Blaikie llvm_unreachable("Invalid logical operator."); 40946d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump } 4095805e9a8300af9489ec13cd804c070267b7c4cfecTed Kremenek } 40966d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 40979c378f705405d37f49795d5e915989de774fe11fTed Kremenek void VisitExpr(Expr *E) { 4098d249e1d1f1498b81314459ceda19d6ff25c278adDouglas Gregor E->printPretty(OS, Helper, Policy); 40996d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump } 4100651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 4101651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinespublic: 4102651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines void print(CFGTerminator T) { 4103651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (T.isTemporaryDtorsBranch()) 4104651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines OS << "(Temp Dtor) "; 4105651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Visit(T.getStmt()); 4106651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 4107d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek}; 4108e4f2142d00fa5fdb580c4e2413da91882d955381Chris Lattner} // end anonymous namespace 4109e4f2142d00fa5fdb580c4e2413da91882d955381Chris Lattner 411029fc11a7abc06c30146a0ba3733da1c758586784Aaron Ballmanstatic void print_elem(raw_ostream &OS, StmtPrinterHelper &Helper, 4111079bd72439448b78629a28da6b1f8abe2cdeaf4dMike Stump const CFGElement &E) { 4112b07805485c603be3d8011f72611465324c9e664bDavid Blaikie if (Optional<CFGStmt> CS = E.getAs<CFGStmt>()) { 4113b07805485c603be3d8011f72611465324c9e664bDavid Blaikie const Stmt *S = CS->getStmt(); 4114c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines assert(S != nullptr && "Expecting non-null Stmt"); 4115c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 411629fc11a7abc06c30146a0ba3733da1c758586784Aaron Ballman // special printing for statement-expressions. 411729fc11a7abc06c30146a0ba3733da1c758586784Aaron Ballman if (const StmtExpr *SE = dyn_cast<StmtExpr>(S)) { 411829fc11a7abc06c30146a0ba3733da1c758586784Aaron Ballman const CompoundStmt *Sub = SE->getSubStmt(); 411929fc11a7abc06c30146a0ba3733da1c758586784Aaron Ballman 412029fc11a7abc06c30146a0ba3733da1c758586784Aaron Ballman if (Sub->children()) { 412129fc11a7abc06c30146a0ba3733da1c758586784Aaron Ballman OS << "({ ... ; "; 412229fc11a7abc06c30146a0ba3733da1c758586784Aaron Ballman Helper.handledStmt(*SE->getSubStmt()->body_rbegin(),OS); 412329fc11a7abc06c30146a0ba3733da1c758586784Aaron Ballman OS << " })\n"; 412429fc11a7abc06c30146a0ba3733da1c758586784Aaron Ballman return; 41251cff132e48e0ccc253c34e5a2fb12718bd4e7d2eMarcin Swiderski } 412629fc11a7abc06c30146a0ba3733da1c758586784Aaron Ballman } 412729fc11a7abc06c30146a0ba3733da1c758586784Aaron Ballman // special printing for comma expressions. 412829fc11a7abc06c30146a0ba3733da1c758586784Aaron Ballman if (const BinaryOperator* B = dyn_cast<BinaryOperator>(S)) { 412929fc11a7abc06c30146a0ba3733da1c758586784Aaron Ballman if (B->getOpcode() == BO_Comma) { 413029fc11a7abc06c30146a0ba3733da1c758586784Aaron Ballman OS << "... , "; 413129fc11a7abc06c30146a0ba3733da1c758586784Aaron Ballman Helper.handledStmt(B->getRHS(),OS); 413229fc11a7abc06c30146a0ba3733da1c758586784Aaron Ballman OS << '\n'; 413329fc11a7abc06c30146a0ba3733da1c758586784Aaron Ballman return; 41341c29bba6da40bbe59fb1f81c4cd5ab5471554ffeTed Kremenek } 41351c29bba6da40bbe59fb1f81c4cd5ab5471554ffeTed Kremenek } 413629fc11a7abc06c30146a0ba3733da1c758586784Aaron Ballman S->printPretty(OS, &Helper, PrintingPolicy(Helper.getLangOpts())); 41376d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 41381cff132e48e0ccc253c34e5a2fb12718bd4e7d2eMarcin Swiderski if (isa<CXXOperatorCallExpr>(S)) { 413936f327c309b1fb6b82f1987190f0be74000b14c1Zhanyong Wan OS << " (OperatorCall)"; 4140893d414534273e153e12aef39a1ad991c6fa94c0Ted Kremenek } 4141893d414534273e153e12aef39a1ad991c6fa94c0Ted Kremenek else if (isa<CXXBindTemporaryExpr>(S)) { 414236f327c309b1fb6b82f1987190f0be74000b14c1Zhanyong Wan OS << " (BindTemporary)"; 41436d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump } 41443b7a48fbc681c6fb59e5304a210c30dbb49dabeaTed Kremenek else if (const CXXConstructExpr *CCE = dyn_cast<CXXConstructExpr>(S)) { 41453b7a48fbc681c6fb59e5304a210c30dbb49dabeaTed Kremenek OS << " (CXXConstructExpr, " << CCE->getType().getAsString() << ")"; 41463b7a48fbc681c6fb59e5304a210c30dbb49dabeaTed Kremenek } 4147893d414534273e153e12aef39a1ad991c6fa94c0Ted Kremenek else if (const CastExpr *CE = dyn_cast<CastExpr>(S)) { 4148893d414534273e153e12aef39a1ad991c6fa94c0Ted Kremenek OS << " (" << CE->getStmtClassName() << ", " 4149893d414534273e153e12aef39a1ad991c6fa94c0Ted Kremenek << CE->getCastKindName() 4150893d414534273e153e12aef39a1ad991c6fa94c0Ted Kremenek << ", " << CE->getType().getAsString() 4151893d414534273e153e12aef39a1ad991c6fa94c0Ted Kremenek << ")"; 4152893d414534273e153e12aef39a1ad991c6fa94c0Ted Kremenek } 41536d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 41541cff132e48e0ccc253c34e5a2fb12718bd4e7d2eMarcin Swiderski // Expressions need a newline. 41551cff132e48e0ccc253c34e5a2fb12718bd4e7d2eMarcin Swiderski if (isa<Expr>(S)) 41561cff132e48e0ccc253c34e5a2fb12718bd4e7d2eMarcin Swiderski OS << '\n'; 41574e0cfa8eacf76f203d6ee6ce164162ccd4275ccdTed Kremenek 4158b07805485c603be3d8011f72611465324c9e664bDavid Blaikie } else if (Optional<CFGInitializer> IE = E.getAs<CFGInitializer>()) { 4159b07805485c603be3d8011f72611465324c9e664bDavid Blaikie const CXXCtorInitializer *I = IE->getInitializer(); 41601cff132e48e0ccc253c34e5a2fb12718bd4e7d2eMarcin Swiderski if (I->isBaseInitializer()) 41611cff132e48e0ccc253c34e5a2fb12718bd4e7d2eMarcin Swiderski OS << I->getBaseClass()->getAsCXXRecordDecl()->getName(); 41623f5b4de5a05c07a2af5b0e61e919ac0f803c78c9Jordan Rose else if (I->isDelegatingInitializer()) 41633f5b4de5a05c07a2af5b0e61e919ac0f803c78c9Jordan Rose OS << I->getTypeSourceInfo()->getType()->getAsCXXRecordDecl()->getName(); 416400eb3f9c5b33e3d99aee1f8b75dd9c9678fdd66bFrancois Pichet else OS << I->getAnyMember()->getName(); 41656d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 41661cff132e48e0ccc253c34e5a2fb12718bd4e7d2eMarcin Swiderski OS << "("; 41679c378f705405d37f49795d5e915989de774fe11fTed Kremenek if (Expr *IE = I->getInit()) 416829fc11a7abc06c30146a0ba3733da1c758586784Aaron Ballman IE->printPretty(OS, &Helper, PrintingPolicy(Helper.getLangOpts())); 41691cff132e48e0ccc253c34e5a2fb12718bd4e7d2eMarcin Swiderski OS << ")"; 41701cff132e48e0ccc253c34e5a2fb12718bd4e7d2eMarcin Swiderski 41711cff132e48e0ccc253c34e5a2fb12718bd4e7d2eMarcin Swiderski if (I->isBaseInitializer()) 41721cff132e48e0ccc253c34e5a2fb12718bd4e7d2eMarcin Swiderski OS << " (Base initializer)\n"; 41733f5b4de5a05c07a2af5b0e61e919ac0f803c78c9Jordan Rose else if (I->isDelegatingInitializer()) 41743f5b4de5a05c07a2af5b0e61e919ac0f803c78c9Jordan Rose OS << " (Delegating initializer)\n"; 41751cff132e48e0ccc253c34e5a2fb12718bd4e7d2eMarcin Swiderski else OS << " (Member initializer)\n"; 41761cff132e48e0ccc253c34e5a2fb12718bd4e7d2eMarcin Swiderski 4177b07805485c603be3d8011f72611465324c9e664bDavid Blaikie } else if (Optional<CFGAutomaticObjDtor> DE = 4178b07805485c603be3d8011f72611465324c9e664bDavid Blaikie E.getAs<CFGAutomaticObjDtor>()) { 4179b07805485c603be3d8011f72611465324c9e664bDavid Blaikie const VarDecl *VD = DE->getVarDecl(); 418029fc11a7abc06c30146a0ba3733da1c758586784Aaron Ballman Helper.handleDecl(VD, OS); 41811cff132e48e0ccc253c34e5a2fb12718bd4e7d2eMarcin Swiderski 4182b1c52870b8c2feaa7cd112295368bec53af490a0Marcin Swiderski const Type* T = VD->getType().getTypePtr(); 41831cff132e48e0ccc253c34e5a2fb12718bd4e7d2eMarcin Swiderski if (const ReferenceType* RT = T->getAs<ReferenceType>()) 41841cff132e48e0ccc253c34e5a2fb12718bd4e7d2eMarcin Swiderski T = RT->getPointeeType().getTypePtr(); 418556df4a9e0461d4dfb2a740cb6b0ce531d6c82538Richard Smith T = T->getBaseElementTypeUnsafe(); 41861cff132e48e0ccc253c34e5a2fb12718bd4e7d2eMarcin Swiderski 41871cff132e48e0ccc253c34e5a2fb12718bd4e7d2eMarcin Swiderski OS << ".~" << T->getAsCXXRecordDecl()->getName().str() << "()"; 41881cff132e48e0ccc253c34e5a2fb12718bd4e7d2eMarcin Swiderski OS << " (Implicit destructor)\n"; 41897c625d8ffc20b92fff9e1690cd2484fcb6498183Marcin Swiderski 4190651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } else if (Optional<CFGNewAllocator> NE = E.getAs<CFGNewAllocator>()) { 4191651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines OS << "CFGNewAllocator("; 4192651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (const CXXNewExpr *AllocExpr = NE->getAllocatorExpr()) 4193651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines AllocExpr->getType().print(OS, PrintingPolicy(Helper.getLangOpts())); 4194651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines OS << ")\n"; 419536d558d85653315edb389677e995ec9ccdbfbf3dJordan Rose } else if (Optional<CFGDeleteDtor> DE = E.getAs<CFGDeleteDtor>()) { 419636d558d85653315edb389677e995ec9ccdbfbf3dJordan Rose const CXXRecordDecl *RD = DE->getCXXRecordDecl(); 419736d558d85653315edb389677e995ec9ccdbfbf3dJordan Rose if (!RD) 419836d558d85653315edb389677e995ec9ccdbfbf3dJordan Rose return; 419936d558d85653315edb389677e995ec9ccdbfbf3dJordan Rose CXXDeleteExpr *DelExpr = 420036d558d85653315edb389677e995ec9ccdbfbf3dJordan Rose const_cast<CXXDeleteExpr*>(DE->getDeleteExpr()); 420129fc11a7abc06c30146a0ba3733da1c758586784Aaron Ballman Helper.handledStmt(cast<Stmt>(DelExpr->getArgument()), OS); 420236d558d85653315edb389677e995ec9ccdbfbf3dJordan Rose OS << "->~" << RD->getName().str() << "()"; 420336d558d85653315edb389677e995ec9ccdbfbf3dJordan Rose OS << " (Implicit destructor)\n"; 4204b07805485c603be3d8011f72611465324c9e664bDavid Blaikie } else if (Optional<CFGBaseDtor> BE = E.getAs<CFGBaseDtor>()) { 4205b07805485c603be3d8011f72611465324c9e664bDavid Blaikie const CXXBaseSpecifier *BS = BE->getBaseSpecifier(); 42067c625d8ffc20b92fff9e1690cd2484fcb6498183Marcin Swiderski OS << "~" << BS->getType()->getAsCXXRecordDecl()->getName() << "()"; 42074e493e0dbac2aaac04c041f3d7dee9eccfb97689Zhongxing Xu OS << " (Base object destructor)\n"; 42087c625d8ffc20b92fff9e1690cd2484fcb6498183Marcin Swiderski 4209b07805485c603be3d8011f72611465324c9e664bDavid Blaikie } else if (Optional<CFGMemberDtor> ME = E.getAs<CFGMemberDtor>()) { 4210b07805485c603be3d8011f72611465324c9e664bDavid Blaikie const FieldDecl *FD = ME->getFieldDecl(); 421156df4a9e0461d4dfb2a740cb6b0ce531d6c82538Richard Smith const Type *T = FD->getType()->getBaseElementTypeUnsafe(); 42127c625d8ffc20b92fff9e1690cd2484fcb6498183Marcin Swiderski OS << "this->" << FD->getName(); 42138c5e5d6d8a316af5a9842169f541cac49717887dMarcin Swiderski OS << ".~" << T->getAsCXXRecordDecl()->getName() << "()"; 42144e493e0dbac2aaac04c041f3d7dee9eccfb97689Zhongxing Xu OS << " (Member object destructor)\n"; 42158599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski 4216b07805485c603be3d8011f72611465324c9e664bDavid Blaikie } else if (Optional<CFGTemporaryDtor> TE = E.getAs<CFGTemporaryDtor>()) { 4217b07805485c603be3d8011f72611465324c9e664bDavid Blaikie const CXXBindTemporaryExpr *BT = TE->getBindTemporaryExpr(); 421895ab9e306f4deefeabd89ea61987f4a8d67e0890Pavel Labath OS << "~"; 421929fc11a7abc06c30146a0ba3733da1c758586784Aaron Ballman BT->getType().print(OS, PrintingPolicy(Helper.getLangOpts())); 422095ab9e306f4deefeabd89ea61987f4a8d67e0890Pavel Labath OS << "() (Temporary object destructor)\n"; 42211cff132e48e0ccc253c34e5a2fb12718bd4e7d2eMarcin Swiderski } 422281bc7d07b701042371a5723b6f394cd2482ed7beZhongxing Xu} 42236d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 42249c378f705405d37f49795d5e915989de774fe11fTed Kremenekstatic void print_block(raw_ostream &OS, const CFG* cfg, 42259c378f705405d37f49795d5e915989de774fe11fTed Kremenek const CFGBlock &B, 422629fc11a7abc06c30146a0ba3733da1c758586784Aaron Ballman StmtPrinterHelper &Helper, bool print_edges, 4227682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenek bool ShowColors) { 42286d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 422929fc11a7abc06c30146a0ba3733da1c758586784Aaron Ballman Helper.setBlockID(B.getBlockID()); 42306d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 42317dba8607e59096014b7139ff20ef00870041d518Ted Kremenek // Print the header. 4232682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenek if (ShowColors) 4233682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenek OS.changeColor(raw_ostream::YELLOW, true); 4234682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenek 4235682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenek OS << "\n [B" << B.getBlockID(); 42366d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 423742a509f6a4f71bb805cc4abbb26722a34dffdddeTed Kremenek if (&B == &cfg->getEntry()) 4238682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenek OS << " (ENTRY)]\n"; 423942a509f6a4f71bb805cc4abbb26722a34dffdddeTed Kremenek else if (&B == &cfg->getExit()) 4240682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenek OS << " (EXIT)]\n"; 424142a509f6a4f71bb805cc4abbb26722a34dffdddeTed Kremenek else if (&B == cfg->getIndirectGotoBlock()) 4242682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenek OS << " (INDIRECT GOTO DISPATCH)]\n"; 4243651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines else if (B.hasNoReturnElement()) 4244651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines OS << " (NORETURN)]\n"; 424542a509f6a4f71bb805cc4abbb26722a34dffdddeTed Kremenek else 4246682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenek OS << "]\n"; 4247682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenek 4248682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenek if (ShowColors) 4249682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenek OS.resetColor(); 42506d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 42519cffe7366ea3beb33c2d58f43a8c3a04c1873e11Ted Kremenek // Print the label of this block. 42529c378f705405d37f49795d5e915989de774fe11fTed Kremenek if (Stmt *Label = const_cast<Stmt*>(B.getLabel())) { 425342a509f6a4f71bb805cc4abbb26722a34dffdddeTed Kremenek 425442a509f6a4f71bb805cc4abbb26722a34dffdddeTed Kremenek if (print_edges) 4255682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenek OS << " "; 42566d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 42579c378f705405d37f49795d5e915989de774fe11fTed Kremenek if (LabelStmt *L = dyn_cast<LabelStmt>(Label)) 42589cffe7366ea3beb33c2d58f43a8c3a04c1873e11Ted Kremenek OS << L->getName(); 42599c378f705405d37f49795d5e915989de774fe11fTed Kremenek else if (CaseStmt *C = dyn_cast<CaseStmt>(Label)) { 42609cffe7366ea3beb33c2d58f43a8c3a04c1873e11Ted Kremenek OS << "case "; 4261c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines if (C->getLHS()) 4262c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines C->getLHS()->printPretty(OS, &Helper, 4263c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines PrintingPolicy(Helper.getLangOpts())); 42649cffe7366ea3beb33c2d58f43a8c3a04c1873e11Ted Kremenek if (C->getRHS()) { 42659cffe7366ea3beb33c2d58f43a8c3a04c1873e11Ted Kremenek OS << " ... "; 426629fc11a7abc06c30146a0ba3733da1c758586784Aaron Ballman C->getRHS()->printPretty(OS, &Helper, 426729fc11a7abc06c30146a0ba3733da1c758586784Aaron Ballman PrintingPolicy(Helper.getLangOpts())); 42689cffe7366ea3beb33c2d58f43a8c3a04c1873e11Ted Kremenek } 4269079bd72439448b78629a28da6b1f8abe2cdeaf4dMike Stump } else if (isa<DefaultStmt>(Label)) 42709cffe7366ea3beb33c2d58f43a8c3a04c1873e11Ted Kremenek OS << "default"; 4271079bd72439448b78629a28da6b1f8abe2cdeaf4dMike Stump else if (CXXCatchStmt *CS = dyn_cast<CXXCatchStmt>(Label)) { 42725d1d20227878cd03db8b2dd23efd4cedfe874feeMike Stump OS << "catch ("; 4273a1f93631a84621d77aeb627691da85a8991af188Mike Stump if (CS->getExceptionDecl()) 427429fc11a7abc06c30146a0ba3733da1c758586784Aaron Ballman CS->getExceptionDecl()->print(OS, PrintingPolicy(Helper.getLangOpts()), 4275a1f93631a84621d77aeb627691da85a8991af188Mike Stump 0); 4276a1f93631a84621d77aeb627691da85a8991af188Mike Stump else 4277a1f93631a84621d77aeb627691da85a8991af188Mike Stump OS << "..."; 42785d1d20227878cd03db8b2dd23efd4cedfe874feeMike Stump OS << ")"; 42795d1d20227878cd03db8b2dd23efd4cedfe874feeMike Stump 42805d1d20227878cd03db8b2dd23efd4cedfe874feeMike Stump } else 4281b219cfc4d75f0a03630b7c4509ef791b7e97b2c8David Blaikie llvm_unreachable("Invalid label statement in CFGBlock."); 42826d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 42839cffe7366ea3beb33c2d58f43a8c3a04c1873e11Ted Kremenek OS << ":\n"; 42849cffe7366ea3beb33c2d58f43a8c3a04c1873e11Ted Kremenek } 42856d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 4286fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek // Iterate through the statements in the block and print them. 4287fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek unsigned j = 1; 42886d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 428942a509f6a4f71bb805cc4abbb26722a34dffdddeTed Kremenek for (CFGBlock::const_iterator I = B.begin(), E = B.end() ; 429042a509f6a4f71bb805cc4abbb26722a34dffdddeTed Kremenek I != E ; ++I, ++j ) { 42916d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 42929cffe7366ea3beb33c2d58f43a8c3a04c1873e11Ted Kremenek // Print the statement # in the basic block and the statement itself. 429342a509f6a4f71bb805cc4abbb26722a34dffdddeTed Kremenek if (print_edges) 4294682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenek OS << " "; 42956d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 4296a95d3750441ac8ad03e36af8e6e74039c9a3109dTed Kremenek OS << llvm::format("%3d", j) << ": "; 42976d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 429829fc11a7abc06c30146a0ba3733da1c758586784Aaron Ballman Helper.setStmtID(j); 42996d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 4300682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenek print_elem(OS, Helper, *I); 4301fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek } 43026d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 43039cffe7366ea3beb33c2d58f43a8c3a04c1873e11Ted Kremenek // Print the terminator of this block. 430442a509f6a4f71bb805cc4abbb26722a34dffdddeTed Kremenek if (B.getTerminator()) { 4305682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenek if (ShowColors) 4306682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenek OS.changeColor(raw_ostream::GREEN); 43076d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 4308682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenek OS << " T: "; 43096d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 431029fc11a7abc06c30146a0ba3733da1c758586784Aaron Ballman Helper.setBlockID(-1); 43116d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 431229fc11a7abc06c30146a0ba3733da1c758586784Aaron Ballman PrintingPolicy PP(Helper.getLangOpts()); 431329fc11a7abc06c30146a0ba3733da1c758586784Aaron Ballman CFGBlockTerminatorPrint TPrinter(OS, &Helper, PP); 4314651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines TPrinter.print(B.getTerminator()); 4315a292585207adbf6dcf6347db3526a7ec861d8eacTed Kremenek OS << '\n'; 4316682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenek 4317682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenek if (ShowColors) 4318682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenek OS.resetColor(); 4319fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek } 43206d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 43219cffe7366ea3beb33c2d58f43a8c3a04c1873e11Ted Kremenek if (print_edges) { 43229cffe7366ea3beb33c2d58f43a8c3a04c1873e11Ted Kremenek // Print the predecessors of this block. 4323682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenek if (!B.pred_empty()) { 4324682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenek const raw_ostream::Colors Color = raw_ostream::BLUE; 4325682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenek if (ShowColors) 4326682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenek OS.changeColor(Color); 4327682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenek OS << " Preds " ; 4328682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenek if (ShowColors) 4329682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenek OS.resetColor(); 4330682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenek OS << '(' << B.pred_size() << "):"; 4331682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenek unsigned i = 0; 4332682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenek 4333682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenek if (ShowColors) 4334682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenek OS.changeColor(Color); 4335682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenek 4336682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenek for (CFGBlock::const_pred_iterator I = B.pred_begin(), E = B.pred_end(); 4337682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenek I != E; ++I, ++i) { 433842a509f6a4f71bb805cc4abbb26722a34dffdddeTed Kremenek 4339dac62528c1a66db867e21cfa7cfc439d557d6f0cWill Dietz if (i % 10 == 8) 4340682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenek OS << "\n "; 43416d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 4342651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines CFGBlock *B = *I; 4343651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines bool Reachable = true; 4344651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (!B) { 4345651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Reachable = false; 4346651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines B = I->getPossiblyUnreachableBlock(); 4347651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 4348651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 4349651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines OS << " B" << B->getBlockID(); 4350651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (!Reachable) 4351651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines OS << "(Unreachable)"; 4352682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenek } 4353682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenek 4354682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenek if (ShowColors) 4355682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenek OS.resetColor(); 43566d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 4357682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenek OS << '\n'; 43589cffe7366ea3beb33c2d58f43a8c3a04c1873e11Ted Kremenek } 43596d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 43609cffe7366ea3beb33c2d58f43a8c3a04c1873e11Ted Kremenek // Print the successors of this block. 4361682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenek if (!B.succ_empty()) { 4362682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenek const raw_ostream::Colors Color = raw_ostream::MAGENTA; 4363682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenek if (ShowColors) 4364682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenek OS.changeColor(Color); 4365682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenek OS << " Succs "; 4366682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenek if (ShowColors) 4367682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenek OS.resetColor(); 4368682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenek OS << '(' << B.succ_size() << "):"; 4369682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenek unsigned i = 0; 4370682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenek 4371682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenek if (ShowColors) 4372682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenek OS.changeColor(Color); 4373682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenek 4374682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenek for (CFGBlock::const_succ_iterator I = B.succ_begin(), E = B.succ_end(); 4375682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenek I != E; ++I, ++i) { 4376682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenek 4377dac62528c1a66db867e21cfa7cfc439d557d6f0cWill Dietz if (i % 10 == 8) 4378682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenek OS << "\n "; 4379682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenek 4380651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines CFGBlock *B = *I; 4381651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 4382651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines bool Reachable = true; 4383651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (!B) { 4384651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Reachable = false; 4385651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines B = I->getPossiblyUnreachableBlock(); 4386651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 4387651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 4388651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (B) { 4389651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines OS << " B" << B->getBlockID(); 4390651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (!Reachable) 4391651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines OS << "(Unreachable)"; 4392651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 4393651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines else { 4394651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines OS << " NULL"; 4395651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 4396682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenek } 4397651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 4398682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenek if (ShowColors) 4399682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenek OS.resetColor(); 4400682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenek OS << '\n'; 4401fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek } 4402fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek } 44036d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump} 440442a509f6a4f71bb805cc4abbb26722a34dffdddeTed Kremenek 440542a509f6a4f71bb805cc4abbb26722a34dffdddeTed Kremenek 440642a509f6a4f71bb805cc4abbb26722a34dffdddeTed Kremenek/// dump - A simple pretty printer of a CFG that outputs to stderr. 4407682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenekvoid CFG::dump(const LangOptions &LO, bool ShowColors) const { 4408682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenek print(llvm::errs(), LO, ShowColors); 4409682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenek} 441042a509f6a4f71bb805cc4abbb26722a34dffdddeTed Kremenek 441142a509f6a4f71bb805cc4abbb26722a34dffdddeTed Kremenek/// print - A simple pretty printer of a CFG that outputs to an ostream. 4412682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenekvoid CFG::print(raw_ostream &OS, const LangOptions &LO, bool ShowColors) const { 4413e4f2142d00fa5fdb580c4e2413da91882d955381Chris Lattner StmtPrinterHelper Helper(this, LO); 44146d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 441542a509f6a4f71bb805cc4abbb26722a34dffdddeTed Kremenek // Print the entry block. 441629fc11a7abc06c30146a0ba3733da1c758586784Aaron Ballman print_block(OS, this, getEntry(), Helper, true, ShowColors); 44176d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 441842a509f6a4f71bb805cc4abbb26722a34dffdddeTed Kremenek // Iterate through the CFGBlocks and print them one by one. 441942a509f6a4f71bb805cc4abbb26722a34dffdddeTed Kremenek for (const_iterator I = Blocks.begin(), E = Blocks.end() ; I != E ; ++I) { 442042a509f6a4f71bb805cc4abbb26722a34dffdddeTed Kremenek // Skip the entry block, because we already printed it. 4421ee82d9bdc5025b82de8ce2a4ad4685e0a8b79da9Ted Kremenek if (&(**I) == &getEntry() || &(**I) == &getExit()) 442242a509f6a4f71bb805cc4abbb26722a34dffdddeTed Kremenek continue; 44236d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 442429fc11a7abc06c30146a0ba3733da1c758586784Aaron Ballman print_block(OS, this, **I, Helper, true, ShowColors); 442542a509f6a4f71bb805cc4abbb26722a34dffdddeTed Kremenek } 44266d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 442742a509f6a4f71bb805cc4abbb26722a34dffdddeTed Kremenek // Print the exit block. 442829fc11a7abc06c30146a0ba3733da1c758586784Aaron Ballman print_block(OS, this, getExit(), Helper, true, ShowColors); 4429682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenek OS << '\n'; 4430d0172439194b28bae62a94a0a25d58e6d21e7a14Ted Kremenek OS.flush(); 44316d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump} 443242a509f6a4f71bb805cc4abbb26722a34dffdddeTed Kremenek 443342a509f6a4f71bb805cc4abbb26722a34dffdddeTed Kremenek/// dump - A simply pretty printer of a CFGBlock that outputs to stderr. 4434682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenekvoid CFGBlock::dump(const CFG* cfg, const LangOptions &LO, 4435682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenek bool ShowColors) const { 4436682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenek print(llvm::errs(), cfg, LO, ShowColors); 4437e4f2142d00fa5fdb580c4e2413da91882d955381Chris Lattner} 443842a509f6a4f71bb805cc4abbb26722a34dffdddeTed Kremenek 4439c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hinesvoid CFGBlock::dump() const { 4440c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines dump(getParent(), LangOptions(), false); 4441c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines} 4442c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines 444342a509f6a4f71bb805cc4abbb26722a34dffdddeTed Kremenek/// print - A simple pretty printer of a CFGBlock that outputs to an ostream. 444442a509f6a4f71bb805cc4abbb26722a34dffdddeTed Kremenek/// Generally this will only be called from CFG::print. 44459c378f705405d37f49795d5e915989de774fe11fTed Kremenekvoid CFGBlock::print(raw_ostream &OS, const CFG* cfg, 4446682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenek const LangOptions &LO, bool ShowColors) const { 4447e4f2142d00fa5fdb580c4e2413da91882d955381Chris Lattner StmtPrinterHelper Helper(cfg, LO); 444829fc11a7abc06c30146a0ba3733da1c758586784Aaron Ballman print_block(OS, cfg, *this, Helper, true, ShowColors); 4449682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenek OS << '\n'; 4450026473c2175424a039f51ca8949937268721b965Ted Kremenek} 44517dba8607e59096014b7139ff20ef00870041d518Ted Kremenek 4452a292585207adbf6dcf6347db3526a7ec861d8eacTed Kremenek/// printTerminator - A simple pretty printer of the terminator of a CFGBlock. 44535f9e272e632e951b1efe824cd16acb4d96077930Chris Lattnervoid CFGBlock::printTerminator(raw_ostream &OS, 44546d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump const LangOptions &LO) const { 44556bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines CFGBlockTerminatorPrint TPrinter(OS, nullptr, PrintingPolicy(LO)); 4456651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines TPrinter.print(getTerminator()); 4457a292585207adbf6dcf6347db3526a7ec861d8eacTed Kremenek} 4458a292585207adbf6dcf6347db3526a7ec861d8eacTed Kremenek 4459651f13cea278ec967336033dd032faef0e9fc2ecStephen HinesStmt *CFGBlock::getTerminatorCondition(bool StripParens) { 44604ba72a0b28135209c435630682febe1f854ccfa6Marcin Swiderski Stmt *Terminator = this->Terminator; 4461411cdee0b490f79428c9eb977f25199eb7d21cd8Ted Kremenek if (!Terminator) 44626bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return nullptr; 44636d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 44646bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines Expr *E = nullptr; 44656d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 4466411cdee0b490f79428c9eb977f25199eb7d21cd8Ted Kremenek switch (Terminator->getStmtClass()) { 4467411cdee0b490f79428c9eb977f25199eb7d21cd8Ted Kremenek default: 4468411cdee0b490f79428c9eb977f25199eb7d21cd8Ted Kremenek break; 44696d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 447049a246f4fad959888bb0164c624c3c2b03078e91Jordan Rose case Stmt::CXXForRangeStmtClass: 447149a246f4fad959888bb0164c624c3c2b03078e91Jordan Rose E = cast<CXXForRangeStmt>(Terminator)->getCond(); 447249a246f4fad959888bb0164c624c3c2b03078e91Jordan Rose break; 447349a246f4fad959888bb0164c624c3c2b03078e91Jordan Rose 4474411cdee0b490f79428c9eb977f25199eb7d21cd8Ted Kremenek case Stmt::ForStmtClass: 4475411cdee0b490f79428c9eb977f25199eb7d21cd8Ted Kremenek E = cast<ForStmt>(Terminator)->getCond(); 4476411cdee0b490f79428c9eb977f25199eb7d21cd8Ted Kremenek break; 44776d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 4478411cdee0b490f79428c9eb977f25199eb7d21cd8Ted Kremenek case Stmt::WhileStmtClass: 4479411cdee0b490f79428c9eb977f25199eb7d21cd8Ted Kremenek E = cast<WhileStmt>(Terminator)->getCond(); 4480411cdee0b490f79428c9eb977f25199eb7d21cd8Ted Kremenek break; 44816d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 4482411cdee0b490f79428c9eb977f25199eb7d21cd8Ted Kremenek case Stmt::DoStmtClass: 4483411cdee0b490f79428c9eb977f25199eb7d21cd8Ted Kremenek E = cast<DoStmt>(Terminator)->getCond(); 4484411cdee0b490f79428c9eb977f25199eb7d21cd8Ted Kremenek break; 44856d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 4486411cdee0b490f79428c9eb977f25199eb7d21cd8Ted Kremenek case Stmt::IfStmtClass: 4487411cdee0b490f79428c9eb977f25199eb7d21cd8Ted Kremenek E = cast<IfStmt>(Terminator)->getCond(); 4488411cdee0b490f79428c9eb977f25199eb7d21cd8Ted Kremenek break; 44896d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 4490411cdee0b490f79428c9eb977f25199eb7d21cd8Ted Kremenek case Stmt::ChooseExprClass: 4491411cdee0b490f79428c9eb977f25199eb7d21cd8Ted Kremenek E = cast<ChooseExpr>(Terminator)->getCond(); 4492411cdee0b490f79428c9eb977f25199eb7d21cd8Ted Kremenek break; 44936d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 4494411cdee0b490f79428c9eb977f25199eb7d21cd8Ted Kremenek case Stmt::IndirectGotoStmtClass: 4495411cdee0b490f79428c9eb977f25199eb7d21cd8Ted Kremenek E = cast<IndirectGotoStmt>(Terminator)->getTarget(); 4496411cdee0b490f79428c9eb977f25199eb7d21cd8Ted Kremenek break; 44976d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 4498411cdee0b490f79428c9eb977f25199eb7d21cd8Ted Kremenek case Stmt::SwitchStmtClass: 4499411cdee0b490f79428c9eb977f25199eb7d21cd8Ted Kremenek E = cast<SwitchStmt>(Terminator)->getCond(); 4500411cdee0b490f79428c9eb977f25199eb7d21cd8Ted Kremenek break; 45016d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 450256ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall case Stmt::BinaryConditionalOperatorClass: 450356ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall E = cast<BinaryConditionalOperator>(Terminator)->getCond(); 450456ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall break; 450556ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall 4506411cdee0b490f79428c9eb977f25199eb7d21cd8Ted Kremenek case Stmt::ConditionalOperatorClass: 4507411cdee0b490f79428c9eb977f25199eb7d21cd8Ted Kremenek E = cast<ConditionalOperator>(Terminator)->getCond(); 4508411cdee0b490f79428c9eb977f25199eb7d21cd8Ted Kremenek break; 45096d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 4510411cdee0b490f79428c9eb977f25199eb7d21cd8Ted Kremenek case Stmt::BinaryOperatorClass: // '&&' and '||' 4511411cdee0b490f79428c9eb977f25199eb7d21cd8Ted Kremenek E = cast<BinaryOperator>(Terminator)->getLHS(); 4512390e48b15ad93f85bfd1e33b9992c198fa0db475Ted Kremenek break; 45136d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 4514390e48b15ad93f85bfd1e33b9992c198fa0db475Ted Kremenek case Stmt::ObjCForCollectionStmtClass: 45156d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump return Terminator; 4516411cdee0b490f79428c9eb977f25199eb7d21cd8Ted Kremenek } 45176d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 4518651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (!StripParens) 4519651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return E; 4520651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 45216bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return E ? E->IgnoreParens() : nullptr; 4522411cdee0b490f79428c9eb977f25199eb7d21cd8Ted Kremenek} 4523411cdee0b490f79428c9eb977f25199eb7d21cd8Ted Kremenek 45247dba8607e59096014b7139ff20ef00870041d518Ted Kremenek//===----------------------------------------------------------------------===// 45257dba8607e59096014b7139ff20ef00870041d518Ted Kremenek// CFG Graphviz Visualization 45267dba8607e59096014b7139ff20ef00870041d518Ted Kremenek//===----------------------------------------------------------------------===// 45277dba8607e59096014b7139ff20ef00870041d518Ted Kremenek 452842a509f6a4f71bb805cc4abbb26722a34dffdddeTed Kremenek 452942a509f6a4f71bb805cc4abbb26722a34dffdddeTed Kremenek#ifndef NDEBUG 45306d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stumpstatic StmtPrinterHelper* GraphHelper; 453142a509f6a4f71bb805cc4abbb26722a34dffdddeTed Kremenek#endif 453242a509f6a4f71bb805cc4abbb26722a34dffdddeTed Kremenek 4533e4f2142d00fa5fdb580c4e2413da91882d955381Chris Lattnervoid CFG::viewCFG(const LangOptions &LO) const { 453442a509f6a4f71bb805cc4abbb26722a34dffdddeTed Kremenek#ifndef NDEBUG 4535e4f2142d00fa5fdb580c4e2413da91882d955381Chris Lattner StmtPrinterHelper H(this, LO); 453642a509f6a4f71bb805cc4abbb26722a34dffdddeTed Kremenek GraphHelper = &H; 453742a509f6a4f71bb805cc4abbb26722a34dffdddeTed Kremenek llvm::ViewGraph(this,"CFG"); 45386bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines GraphHelper = nullptr; 453942a509f6a4f71bb805cc4abbb26722a34dffdddeTed Kremenek#endif 454042a509f6a4f71bb805cc4abbb26722a34dffdddeTed Kremenek} 454142a509f6a4f71bb805cc4abbb26722a34dffdddeTed Kremenek 45427dba8607e59096014b7139ff20ef00870041d518Ted Kremeneknamespace llvm { 45437dba8607e59096014b7139ff20ef00870041d518Ted Kremenektemplate<> 45447dba8607e59096014b7139ff20ef00870041d518Ted Kremenekstruct DOTGraphTraits<const CFG*> : public DefaultDOTGraphTraits { 4545006b0eb3e11162d8c06372db813ac9f71a7a16e8Tobias Grosser 4546006b0eb3e11162d8c06372db813ac9f71a7a16e8Tobias Grosser DOTGraphTraits (bool isSimple=false) : DefaultDOTGraphTraits(isSimple) {} 4547006b0eb3e11162d8c06372db813ac9f71a7a16e8Tobias Grosser 45489c378f705405d37f49795d5e915989de774fe11fTed Kremenek static std::string getNodeLabel(const CFGBlock *Node, const CFG* Graph) { 45497dba8607e59096014b7139ff20ef00870041d518Ted Kremenek 4550bd250b44d60622e7c0b60c6def6f6fe7e347addfHartmut Kaiser#ifndef NDEBUG 4551a95d3750441ac8ad03e36af8e6e74039c9a3109dTed Kremenek std::string OutSStr; 4552a95d3750441ac8ad03e36af8e6e74039c9a3109dTed Kremenek llvm::raw_string_ostream Out(OutSStr); 455329fc11a7abc06c30146a0ba3733da1c758586784Aaron Ballman print_block(Out,Graph, *Node, *GraphHelper, false, false); 4554a95d3750441ac8ad03e36af8e6e74039c9a3109dTed Kremenek std::string& OutStr = Out.str(); 45557dba8607e59096014b7139ff20ef00870041d518Ted Kremenek 45567dba8607e59096014b7139ff20ef00870041d518Ted Kremenek if (OutStr[0] == '\n') OutStr.erase(OutStr.begin()); 45577dba8607e59096014b7139ff20ef00870041d518Ted Kremenek 45587dba8607e59096014b7139ff20ef00870041d518Ted Kremenek // Process string output to make it nicer... 45597dba8607e59096014b7139ff20ef00870041d518Ted Kremenek for (unsigned i = 0; i != OutStr.length(); ++i) 45607dba8607e59096014b7139ff20ef00870041d518Ted Kremenek if (OutStr[i] == '\n') { // Left justify 45617dba8607e59096014b7139ff20ef00870041d518Ted Kremenek OutStr[i] = '\\'; 45627dba8607e59096014b7139ff20ef00870041d518Ted Kremenek OutStr.insert(OutStr.begin()+i+1, 'l'); 45637dba8607e59096014b7139ff20ef00870041d518Ted Kremenek } 45646d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 45657dba8607e59096014b7139ff20ef00870041d518Ted Kremenek return OutStr; 4566bd250b44d60622e7c0b60c6def6f6fe7e347addfHartmut Kaiser#else 4567bd250b44d60622e7c0b60c6def6f6fe7e347addfHartmut Kaiser return ""; 4568bd250b44d60622e7c0b60c6def6f6fe7e347addfHartmut Kaiser#endif 45697dba8607e59096014b7139ff20ef00870041d518Ted Kremenek } 45707dba8607e59096014b7139ff20ef00870041d518Ted Kremenek}; 45717dba8607e59096014b7139ff20ef00870041d518Ted Kremenek} // end namespace llvm 4572