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 1597247c88d1e41514a41085f83ebf03dd5220e054aDavid Blaikie LLVM_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 2375846720f08a6b225484bfe663599c2b057a99bc8Ted Kremenekclass reverse_children { 2385846720f08a6b225484bfe663599c2b057a99bc8Ted Kremenek llvm::SmallVector<Stmt *, 12> childrenBuf; 2395846720f08a6b225484bfe663599c2b057a99bc8Ted Kremenek ArrayRef<Stmt*> children; 2405846720f08a6b225484bfe663599c2b057a99bc8Ted Kremenekpublic: 2415846720f08a6b225484bfe663599c2b057a99bc8Ted Kremenek reverse_children(Stmt *S); 2425846720f08a6b225484bfe663599c2b057a99bc8Ted Kremenek 2435846720f08a6b225484bfe663599c2b057a99bc8Ted Kremenek typedef ArrayRef<Stmt*>::reverse_iterator iterator; 2445846720f08a6b225484bfe663599c2b057a99bc8Ted Kremenek iterator begin() const { return children.rbegin(); } 2455846720f08a6b225484bfe663599c2b057a99bc8Ted Kremenek iterator end() const { return children.rend(); } 2465846720f08a6b225484bfe663599c2b057a99bc8Ted Kremenek}; 2475846720f08a6b225484bfe663599c2b057a99bc8Ted Kremenek 2485846720f08a6b225484bfe663599c2b057a99bc8Ted Kremenek 2495846720f08a6b225484bfe663599c2b057a99bc8Ted Kremenekreverse_children::reverse_children(Stmt *S) { 2505846720f08a6b225484bfe663599c2b057a99bc8Ted Kremenek if (CallExpr *CE = dyn_cast<CallExpr>(S)) { 2515846720f08a6b225484bfe663599c2b057a99bc8Ted Kremenek children = CE->getRawSubExprs(); 2525846720f08a6b225484bfe663599c2b057a99bc8Ted Kremenek return; 2535846720f08a6b225484bfe663599c2b057a99bc8Ted Kremenek } 2545846720f08a6b225484bfe663599c2b057a99bc8Ted Kremenek switch (S->getStmtClass()) { 255b1855de3d61eab7d2f2e616ed59195f83e2a6dc0Ted Kremenek // Note: Fill in this switch with more cases we want to optimize. 2565846720f08a6b225484bfe663599c2b057a99bc8Ted Kremenek case Stmt::InitListExprClass: { 2575846720f08a6b225484bfe663599c2b057a99bc8Ted Kremenek InitListExpr *IE = cast<InitListExpr>(S); 2585846720f08a6b225484bfe663599c2b057a99bc8Ted Kremenek children = llvm::makeArrayRef(reinterpret_cast<Stmt**>(IE->getInits()), 2595846720f08a6b225484bfe663599c2b057a99bc8Ted Kremenek IE->getNumInits()); 2605846720f08a6b225484bfe663599c2b057a99bc8Ted Kremenek return; 2615846720f08a6b225484bfe663599c2b057a99bc8Ted Kremenek } 2625846720f08a6b225484bfe663599c2b057a99bc8Ted Kremenek default: 2635846720f08a6b225484bfe663599c2b057a99bc8Ted Kremenek break; 2645846720f08a6b225484bfe663599c2b057a99bc8Ted Kremenek } 2655846720f08a6b225484bfe663599c2b057a99bc8Ted Kremenek 2665846720f08a6b225484bfe663599c2b057a99bc8Ted Kremenek // Default case for all other statements. 2675846720f08a6b225484bfe663599c2b057a99bc8Ted Kremenek for (Stmt::child_range I = S->children(); I; ++I) { 2685846720f08a6b225484bfe663599c2b057a99bc8Ted Kremenek childrenBuf.push_back(*I); 2695846720f08a6b225484bfe663599c2b057a99bc8Ted Kremenek } 2705846720f08a6b225484bfe663599c2b057a99bc8Ted Kremenek 2715846720f08a6b225484bfe663599c2b057a99bc8Ted Kremenek // This needs to be done *after* childrenBuf has been populated. 2725846720f08a6b225484bfe663599c2b057a99bc8Ted Kremenek children = childrenBuf; 2735846720f08a6b225484bfe663599c2b057a99bc8Ted Kremenek} 2745846720f08a6b225484bfe663599c2b057a99bc8Ted Kremenek 275a34ea072371154c9042ce86321d17fbb4df1f84dTed Kremenek/// CFGBuilder - This class implements CFG construction from an AST. 276fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek/// The builder is stateful: an instance of the builder should be used to only 277fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek/// construct a single CFG. 278fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek/// 279fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek/// Example usage: 280fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek/// 281fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek/// CFGBuilder builder; 282fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek/// CFG* cfg = builder.BuildAST(stmt1); 283fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek/// 2846d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump/// CFG construction is done via a recursive walk of an AST. We actually parse 2856d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump/// the AST in reverse order so that the successor of a basic block is 2866d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump/// constructed prior to its predecessor. This allows us to nicely capture 2876d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump/// implicit fall-throughs without extra basic blocks. 288c310e933a9b023a280f3aa02e5a0c75398555e13Ted Kremenek/// 289ba5fb5a955c896815c439289fc51c03cf0635129Kovarththanan Rajaratnamclass CFGBuilder { 290f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski typedef BlockScopePosPair JumpTarget; 291f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski typedef BlockScopePosPair JumpSource; 292f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski 293e5af3ce53ec58995b09381ba645ab2117a46647bMike Stump ASTContext *Context; 294651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines std::unique_ptr<CFG> cfg; 295ee82d9bdc5025b82de8ce2a4ad4685e0a8b79da9Ted Kremenek 2969c378f705405d37f49795d5e915989de774fe11fTed Kremenek CFGBlock *Block; 2979c378f705405d37f49795d5e915989de774fe11fTed Kremenek CFGBlock *Succ; 298f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski JumpTarget ContinueJumpTarget; 299f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski JumpTarget BreakJumpTarget; 3009c378f705405d37f49795d5e915989de774fe11fTed Kremenek CFGBlock *SwitchTerminatedBlock; 3019c378f705405d37f49795d5e915989de774fe11fTed Kremenek CFGBlock *DefaultCaseBlock; 3029c378f705405d37f49795d5e915989de774fe11fTed Kremenek CFGBlock *TryTerminatedBlock; 303e71f3d587844110d836c82250830b27b1651afdbTed Kremenek 304f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski // Current position in local scope. 305f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski LocalScope::const_iterator ScopePos; 306f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski 307f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski // LabelMap records the mapping from Label expressions to their jump targets. 308ad8dcf4a9df0e24051dc31bf9e6f3cd138a34298Chris Lattner typedef llvm::DenseMap<LabelDecl*, JumpTarget> LabelMapTy; 3090cebe3e29b22d11f2c65ef28fcfb5f0431877266Ted Kremenek LabelMapTy LabelMap; 3106d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 3116d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump // A list of blocks that end with a "goto" that must be backpatched to their 3126d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump // resolved targets upon completion of CFG construction. 313f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski typedef std::vector<JumpSource> BackpatchBlocksTy; 3140cebe3e29b22d11f2c65ef28fcfb5f0431877266Ted Kremenek BackpatchBlocksTy BackpatchBlocks; 3156d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 31619bb356317952445b03ee341c02f6147083c9eeaTed Kremenek // A list of labels whose address has been taken (for indirect gotos). 317ad8dcf4a9df0e24051dc31bf9e6f3cd138a34298Chris Lattner typedef llvm::SmallPtrSet<LabelDecl*, 5> LabelSetTy; 31819bb356317952445b03ee341c02f6147083c9eeaTed Kremenek LabelSetTy AddressTakenLabels; 3196d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 32049b4ef364ba042f7db2ba567310fb49917ad0086Zhongxing Xu bool badCFG; 321b8ad5ee345fa1fdd1fa9253f2d01f69becc88a04Ted Kremenek const CFG::BuildOptions &BuildOpts; 322e71f3d587844110d836c82250830b27b1651afdbTed Kremenek 323e71f3d587844110d836c82250830b27b1651afdbTed Kremenek // State to track for building switch statements. 324e71f3d587844110d836c82250830b27b1651afdbTed Kremenek bool switchExclusivelyCovered; 3250498247f87ea0d716e0c2931fea812280649e33dTed Kremenek Expr::EvalResult *switchCond; 3260d28d360b5559abda755e50b855ba5e59727d9cdTed Kremenek 3270d28d360b5559abda755e50b855ba5e59727d9cdTed Kremenek CFG::BuildOptions::ForcedBlkExprs::value_type *cachedEntry; 328a8d459e8a68b1270b0c35fb73e8cc090b2b69e36Ted Kremenek const Stmt *lastLookup; 32949b4ef364ba042f7db2ba567310fb49917ad0086Zhongxing Xu 3308c6d360636dee25f1ce071c3656810c6632cb89dArgyrios Kyrtzidis // Caches boolean evaluations of expressions to avoid multiple re-evaluations 3318c6d360636dee25f1ce071c3656810c6632cb89dArgyrios Kyrtzidis // during construction of branches for chained logical operators. 3326955da2cad4bce19c541ddb85a6d965d77a1a4abNAKAMURA Takumi typedef llvm::DenseMap<Expr *, TryResult> CachedBoolEvalsTy; 3336955da2cad4bce19c541ddb85a6d965d77a1a4abNAKAMURA Takumi CachedBoolEvalsTy CachedBoolEvals; 3348c6d360636dee25f1ce071c3656810c6632cb89dArgyrios Kyrtzidis 3356d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stumppublic: 336b8ad5ee345fa1fdd1fa9253f2d01f69becc88a04Ted Kremenek explicit CFGBuilder(ASTContext *astContext, 337b8ad5ee345fa1fdd1fa9253f2d01f69becc88a04Ted Kremenek const CFG::BuildOptions &buildOpts) 338b8ad5ee345fa1fdd1fa9253f2d01f69becc88a04Ted Kremenek : Context(astContext), cfg(new CFG()), // crew a new CFG 3396bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines Block(nullptr), Succ(nullptr), 3406bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines SwitchTerminatedBlock(nullptr), DefaultCaseBlock(nullptr), 3416bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines TryTerminatedBlock(nullptr), badCFG(false), BuildOpts(buildOpts), 3426bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines switchExclusivelyCovered(false), switchCond(nullptr), 3436bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines cachedEntry(nullptr), lastLookup(nullptr) {} 3446d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 345d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek // buildCFG - Used by external clients to construct the CFG. 346b8ad5ee345fa1fdd1fa9253f2d01f69becc88a04Ted Kremenek CFG* buildCFG(const Decl *D, Stmt *Statement); 3476d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 3480d28d360b5559abda755e50b855ba5e59727d9cdTed Kremenek bool alwaysAdd(const Stmt *stmt); 3490d28d360b5559abda755e50b855ba5e59727d9cdTed Kremenek 3504f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenekprivate: 3514f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek // Visitors to walk an AST and construct the CFG. 352852274d4257134906995cb252fb3dfd2d71deae8Ted Kremenek CFGBlock *VisitAddrLabelExpr(AddrLabelExpr *A, AddStmtChoice asc); 353852274d4257134906995cb252fb3dfd2d71deae8Ted Kremenek CFGBlock *VisitBinaryOperator(BinaryOperator *B, AddStmtChoice asc); 3544f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek CFGBlock *VisitBreakStmt(BreakStmt *B); 355852274d4257134906995cb252fb3dfd2d71deae8Ted Kremenek CFGBlock *VisitCallExpr(CallExpr *C, AddStmtChoice asc); 3564f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek CFGBlock *VisitCaseStmt(CaseStmt *C); 357852274d4257134906995cb252fb3dfd2d71deae8Ted Kremenek CFGBlock *VisitChooseExpr(ChooseExpr *C, AddStmtChoice asc); 3583fc8ef574cdc09c613c329ee511852d219263c15Ted Kremenek CFGBlock *VisitCompoundStmt(CompoundStmt *C); 35956ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall CFGBlock *VisitConditionalOperator(AbstractConditionalOperator *C, 36056ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall AddStmtChoice asc); 3613fc8ef574cdc09c613c329ee511852d219263c15Ted Kremenek CFGBlock *VisitContinueStmt(ContinueStmt *C); 3626960ee6c7cc8a8883126d9861beecb51a4e4a475Ted Kremenek CFGBlock *VisitCXXBindTemporaryExpr(CXXBindTemporaryExpr *E, 3636960ee6c7cc8a8883126d9861beecb51a4e4a475Ted Kremenek AddStmtChoice asc); 3646960ee6c7cc8a8883126d9861beecb51a4e4a475Ted Kremenek CFGBlock *VisitCXXCatchStmt(CXXCatchStmt *S); 3656960ee6c7cc8a8883126d9861beecb51a4e4a475Ted Kremenek CFGBlock *VisitCXXConstructExpr(CXXConstructExpr *C, AddStmtChoice asc); 366651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines CFGBlock *VisitCXXNewExpr(CXXNewExpr *DE, AddStmtChoice asc); 36736d558d85653315edb389677e995ec9ccdbfbf3dJordan Rose CFGBlock *VisitCXXDeleteExpr(CXXDeleteExpr *DE, AddStmtChoice asc); 3686960ee6c7cc8a8883126d9861beecb51a4e4a475Ted Kremenek CFGBlock *VisitCXXForRangeStmt(CXXForRangeStmt *S); 3696960ee6c7cc8a8883126d9861beecb51a4e4a475Ted Kremenek CFGBlock *VisitCXXFunctionalCastExpr(CXXFunctionalCastExpr *E, 3706960ee6c7cc8a8883126d9861beecb51a4e4a475Ted Kremenek AddStmtChoice asc); 3716960ee6c7cc8a8883126d9861beecb51a4e4a475Ted Kremenek CFGBlock *VisitCXXTemporaryObjectExpr(CXXTemporaryObjectExpr *C, 3726960ee6c7cc8a8883126d9861beecb51a4e4a475Ted Kremenek AddStmtChoice asc); 3736960ee6c7cc8a8883126d9861beecb51a4e4a475Ted Kremenek CFGBlock *VisitCXXThrowExpr(CXXThrowExpr *T); 3746960ee6c7cc8a8883126d9861beecb51a4e4a475Ted Kremenek CFGBlock *VisitCXXTryStmt(CXXTryStmt *S); 3754f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek CFGBlock *VisitDeclStmt(DeclStmt *DS); 3769c378f705405d37f49795d5e915989de774fe11fTed Kremenek CFGBlock *VisitDeclSubExpr(DeclStmt *DS); 3773fc8ef574cdc09c613c329ee511852d219263c15Ted Kremenek CFGBlock *VisitDefaultStmt(DefaultStmt *D); 3783fc8ef574cdc09c613c329ee511852d219263c15Ted Kremenek CFGBlock *VisitDoStmt(DoStmt *D); 3796960ee6c7cc8a8883126d9861beecb51a4e4a475Ted Kremenek CFGBlock *VisitExprWithCleanups(ExprWithCleanups *E, AddStmtChoice asc); 3803fc8ef574cdc09c613c329ee511852d219263c15Ted Kremenek CFGBlock *VisitForStmt(ForStmt *F); 3819c378f705405d37f49795d5e915989de774fe11fTed Kremenek CFGBlock *VisitGotoStmt(GotoStmt *G); 3824f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek CFGBlock *VisitIfStmt(IfStmt *I); 383a725ed468585b881c43654eeb56b28554a84808aZhongxing Xu CFGBlock *VisitImplicitCastExpr(ImplicitCastExpr *E, AddStmtChoice asc); 3844f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek CFGBlock *VisitIndirectGotoStmt(IndirectGotoStmt *I); 3854f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek CFGBlock *VisitLabelStmt(LabelStmt *L); 3866960ee6c7cc8a8883126d9861beecb51a4e4a475Ted Kremenek CFGBlock *VisitLambdaExpr(LambdaExpr *E, AddStmtChoice asc); 3875c3ea5c57971317c35b120ef0a2a2c79bd171008Ted Kremenek CFGBlock *VisitLogicalOperator(BinaryOperator *B); 3883f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek std::pair<CFGBlock *, CFGBlock *> VisitLogicalOperator(BinaryOperator *B, 3893f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek Stmt *Term, 3903f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek CFGBlock *TrueBlock, 3913f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek CFGBlock *FalseBlock); 392115c1b9cc758d15f38e1d2ad4cf07b1cacfb3115Ted Kremenek CFGBlock *VisitMemberExpr(MemberExpr *M, AddStmtChoice asc); 3934f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek CFGBlock *VisitObjCAtCatchStmt(ObjCAtCatchStmt *S); 3944f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek CFGBlock *VisitObjCAtSynchronizedStmt(ObjCAtSynchronizedStmt *S); 3954f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek CFGBlock *VisitObjCAtThrowStmt(ObjCAtThrowStmt *S); 3964f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek CFGBlock *VisitObjCAtTryStmt(ObjCAtTryStmt *S); 3976960ee6c7cc8a8883126d9861beecb51a4e4a475Ted Kremenek CFGBlock *VisitObjCAutoreleasePoolStmt(ObjCAutoreleasePoolStmt *S); 3984f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek CFGBlock *VisitObjCForCollectionStmt(ObjCForCollectionStmt *S); 3994b9c2d235fb9449e249d74f48ecfec601650de93John McCall CFGBlock *VisitPseudoObjectExpr(PseudoObjectExpr *E); 4006960ee6c7cc8a8883126d9861beecb51a4e4a475Ted Kremenek CFGBlock *VisitReturnStmt(ReturnStmt *R); 401852274d4257134906995cb252fb3dfd2d71deae8Ted Kremenek CFGBlock *VisitStmtExpr(StmtExpr *S, AddStmtChoice asc); 4024f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek CFGBlock *VisitSwitchStmt(SwitchStmt *S); 4036960ee6c7cc8a8883126d9861beecb51a4e4a475Ted Kremenek CFGBlock *VisitUnaryExprOrTypeTraitExpr(UnaryExprOrTypeTraitExpr *E, 4046960ee6c7cc8a8883126d9861beecb51a4e4a475Ted Kremenek AddStmtChoice asc); 40599cae5b67b9711ca260e5b364a878a1a91183632Zhanyong Wan CFGBlock *VisitUnaryOperator(UnaryOperator *U, AddStmtChoice asc); 4064f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek CFGBlock *VisitWhileStmt(WhileStmt *W); 4074f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek 408852274d4257134906995cb252fb3dfd2d71deae8Ted Kremenek CFGBlock *Visit(Stmt *S, AddStmtChoice asc = AddStmtChoice::NotAlwaysAdd); 409852274d4257134906995cb252fb3dfd2d71deae8Ted Kremenek CFGBlock *VisitStmt(Stmt *S, AddStmtChoice asc); 4109c378f705405d37f49795d5e915989de774fe11fTed Kremenek CFGBlock *VisitChildren(Stmt *S); 41155331da3211151aa67277aa095b7d301342200d4Ted Kremenek CFGBlock *VisitNoRecurse(Expr *E, AddStmtChoice asc); 412cd7bf230a77c550115e4a78ee371fc49a7563692Mike Stump 4138599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski // Visitors to walk an AST and generate destructors of temporaries in 4148599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski // full expression. 4158599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski CFGBlock *VisitForTemporaryDtors(Stmt *E, bool BindToTemporary = false); 4168599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski CFGBlock *VisitChildrenForTemporaryDtors(Stmt *E); 4178599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski CFGBlock *VisitBinaryOperatorForTemporaryDtors(BinaryOperator *E); 4188599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski CFGBlock *VisitCXXBindTemporaryExprForTemporaryDtors(CXXBindTemporaryExpr *E, 4198599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski bool BindToTemporary); 42056ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall CFGBlock * 42156ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall VisitConditionalOperatorForTemporaryDtors(AbstractConditionalOperator *E, 42256ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall bool BindToTemporary); 4238599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski 424274f4334f6dd35239e5c3d4b86198f7f5804b059Ted Kremenek // NYS == Not Yet Supported 4259c378f705405d37f49795d5e915989de774fe11fTed Kremenek CFGBlock *NYS() { 4264102af916d52310c3deedd84d6fd5e2fd3c09bfeTed Kremenek badCFG = true; 4274102af916d52310c3deedd84d6fd5e2fd3c09bfeTed Kremenek return Block; 4284102af916d52310c3deedd84d6fd5e2fd3c09bfeTed Kremenek } 4296d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 4304f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek void autoCreateBlock() { if (!Block) Block = createBlock(); } 4314f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek CFGBlock *createBlock(bool add_successor = true); 432dba3fb5413437dc613734fa4ffac892b11a37d25Chandler Carruth CFGBlock *createNoReturnBlock(); 433d438b3dbdcde4df4f61a99054104643e6aadf78bZhongxing Xu 434df119892cf291847d6aebb117512225a8e67c0d5Zhongxing Xu CFGBlock *addStmt(Stmt *S) { 435df119892cf291847d6aebb117512225a8e67c0d5Zhongxing Xu return Visit(S, AddStmtChoice::AlwaysAdd); 436852274d4257134906995cb252fb3dfd2d71deae8Ted Kremenek } 437cbb67480094b3bcb5b715acd827cbad55e2a204cSean Hunt CFGBlock *addInitializer(CXXCtorInitializer *I); 4386a16a306f6226030f8d38ae7e32082888fa937a1Zhongxing Xu void addAutomaticObjDtors(LocalScope::const_iterator B, 4399c378f705405d37f49795d5e915989de774fe11fTed Kremenek LocalScope::const_iterator E, Stmt *S); 4407c625d8ffc20b92fff9e1690cd2484fcb6498183Marcin Swiderski void addImplicitDtorsForDestructor(const CXXDestructorDecl *DD); 441239a7c42df78abc7fd5611d806d5e199fec994d1Marcin Swiderski 442239a7c42df78abc7fd5611d806d5e199fec994d1Marcin Swiderski // Local scopes creation. 443239a7c42df78abc7fd5611d806d5e199fec994d1Marcin Swiderski LocalScope* createOrReuseLocalScope(LocalScope* Scope); 444239a7c42df78abc7fd5611d806d5e199fec994d1Marcin Swiderski 4459c378f705405d37f49795d5e915989de774fe11fTed Kremenek void addLocalScopeForStmt(Stmt *S); 4466bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines LocalScope* addLocalScopeForDeclStmt(DeclStmt *DS, 4476bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines LocalScope* Scope = nullptr); 4486bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines LocalScope* addLocalScopeForVarDecl(VarDecl *VD, LocalScope* Scope = nullptr); 449239a7c42df78abc7fd5611d806d5e199fec994d1Marcin Swiderski 4509c378f705405d37f49795d5e915989de774fe11fTed Kremenek void addLocalScopeAndDtors(Stmt *S); 451ad5a894df1841698c824381b414630799adc26caTed Kremenek 452239a7c42df78abc7fd5611d806d5e199fec994d1Marcin Swiderski // Interface to CFGBlock - adding CFGElements. 453d40066b0fb883839a9100e5455e33190b9b8abacTed Kremenek void appendStmt(CFGBlock *B, const Stmt *S) { 45474fb1a493cf5d2dd0fb51a4eadf74e85e10a3457Ted Kremenek if (alwaysAdd(S) && cachedEntry) 4550d28d360b5559abda755e50b855ba5e59727d9cdTed Kremenek cachedEntry->second = B; 4560d28d360b5559abda755e50b855ba5e59727d9cdTed Kremenek 457ac73ea8c12772fd0dcec71b83c193a2837de7f8bJordy Rose // All block-level expressions should have already been IgnoreParens()ed. 458ac73ea8c12772fd0dcec71b83c193a2837de7f8bJordy Rose assert(!isa<Expr>(S) || cast<Expr>(S)->IgnoreParens() == S); 459d40066b0fb883839a9100e5455e33190b9b8abacTed Kremenek B->appendStmt(const_cast<Stmt*>(S), cfg->getBumpVectorContext()); 460ee82d9bdc5025b82de8ce2a4ad4685e0a8b79da9Ted Kremenek } 461cbb67480094b3bcb5b715acd827cbad55e2a204cSean Hunt void appendInitializer(CFGBlock *B, CXXCtorInitializer *I) { 46282bc3fd823d85ee3ef9a641c0975b6ad25f55047Marcin Swiderski B->appendInitializer(I, cfg->getBumpVectorContext()); 46382bc3fd823d85ee3ef9a641c0975b6ad25f55047Marcin Swiderski } 464651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines void appendNewAllocator(CFGBlock *B, CXXNewExpr *NE) { 465651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines B->appendNewAllocator(NE, cfg->getBumpVectorContext()); 466651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 4677c625d8ffc20b92fff9e1690cd2484fcb6498183Marcin Swiderski void appendBaseDtor(CFGBlock *B, const CXXBaseSpecifier *BS) { 4687c625d8ffc20b92fff9e1690cd2484fcb6498183Marcin Swiderski B->appendBaseDtor(BS, cfg->getBumpVectorContext()); 4697c625d8ffc20b92fff9e1690cd2484fcb6498183Marcin Swiderski } 4707c625d8ffc20b92fff9e1690cd2484fcb6498183Marcin Swiderski void appendMemberDtor(CFGBlock *B, FieldDecl *FD) { 4717c625d8ffc20b92fff9e1690cd2484fcb6498183Marcin Swiderski B->appendMemberDtor(FD, cfg->getBumpVectorContext()); 4727c625d8ffc20b92fff9e1690cd2484fcb6498183Marcin Swiderski } 4738599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski void appendTemporaryDtor(CFGBlock *B, CXXBindTemporaryExpr *E) { 4748599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski B->appendTemporaryDtor(E, cfg->getBumpVectorContext()); 4758599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski } 476c8cfc74bdcc999828bc232294d937fb191940d5bChandler Carruth void appendAutomaticObjDtor(CFGBlock *B, VarDecl *VD, Stmt *S) { 477c8cfc74bdcc999828bc232294d937fb191940d5bChandler Carruth B->appendAutomaticObjDtor(VD, S, cfg->getBumpVectorContext()); 478c8cfc74bdcc999828bc232294d937fb191940d5bChandler Carruth } 479ad5a894df1841698c824381b414630799adc26caTed Kremenek 48036d558d85653315edb389677e995ec9ccdbfbf3dJordan Rose void appendDeleteDtor(CFGBlock *B, CXXRecordDecl *RD, CXXDeleteExpr *DE) { 48136d558d85653315edb389677e995ec9ccdbfbf3dJordan Rose B->appendDeleteDtor(RD, DE, cfg->getBumpVectorContext()); 48236d558d85653315edb389677e995ec9ccdbfbf3dJordan Rose } 48336d558d85653315edb389677e995ec9ccdbfbf3dJordan Rose 4849c378f705405d37f49795d5e915989de774fe11fTed Kremenek void prependAutomaticObjDtorsWithTerminator(CFGBlock *Blk, 48553de134e7b4686eed40bc031438d8a4560a2cda4Marcin Swiderski LocalScope::const_iterator B, LocalScope::const_iterator E); 48653de134e7b4686eed40bc031438d8a4560a2cda4Marcin Swiderski 487651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines void addSuccessor(CFGBlock *B, CFGBlock *S, bool IsReachable = true) { 488651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines B->addSuccessor(CFGBlock::AdjacentBlock(S, IsReachable), 489651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines cfg->getBumpVectorContext()); 490651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 491651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 492651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines /// Add a reachable successor to a block, with the alternate variant that is 493651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines /// unreachable. 494651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines void addSuccessor(CFGBlock *B, CFGBlock *ReachableBlock, CFGBlock *AltBlock) { 495651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines B->addSuccessor(CFGBlock::AdjacentBlock(ReachableBlock, AltBlock), 496651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines cfg->getBumpVectorContext()); 497ee82d9bdc5025b82de8ce2a4ad4685e0a8b79da9Ted Kremenek } 4981eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 4996bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines /// \brief Find a relational comparison with an expression evaluating to a 5006bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines /// boolean and a constant other than 0 and 1. 5016bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines /// e.g. if ((x < y) == 10) 5026bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines TryResult checkIncorrectRelationalOperator(const BinaryOperator *B) { 5036bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines const Expr *LHSExpr = B->getLHS()->IgnoreParens(); 5046bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines const Expr *RHSExpr = B->getRHS()->IgnoreParens(); 5056bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 5066bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines const IntegerLiteral *IntLiteral = dyn_cast<IntegerLiteral>(LHSExpr); 5076bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines const Expr *BoolExpr = RHSExpr; 5086bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines bool IntFirst = true; 5096bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (!IntLiteral) { 5106bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines IntLiteral = dyn_cast<IntegerLiteral>(RHSExpr); 5116bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines BoolExpr = LHSExpr; 5126bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines IntFirst = false; 5136bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } 5146bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 5156bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (!IntLiteral || !BoolExpr->isKnownToHaveBooleanValue()) 5166bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return TryResult(); 5176bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 5186bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines llvm::APInt IntValue = IntLiteral->getValue(); 5196bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if ((IntValue == 1) || (IntValue == 0)) 5206bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return TryResult(); 5216bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 5226bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines bool IntLarger = IntLiteral->getType()->isUnsignedIntegerType() || 5236bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines !IntValue.isNegative(); 5246bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 5256bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines BinaryOperatorKind Bok = B->getOpcode(); 5266bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (Bok == BO_GT || Bok == BO_GE) { 5276bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines // Always true for 10 > bool and bool > -1 5286bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines // Always false for -1 > bool and bool > 10 5296bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return TryResult(IntFirst == IntLarger); 5306bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } else { 5316bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines // Always true for -1 < bool and bool < 10 5326bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines // Always false for 10 < bool and bool < -1 5336bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return TryResult(IntFirst != IntLarger); 5346bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } 5356bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } 5366bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 5376bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines /// Find an incorrect equality comparison. Either with an expression 5386bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines /// evaluating to a boolean and a constant other than 0 and 1. 5396bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines /// e.g. if (!x == 10) or a bitwise and/or operation that always evaluates to 5406bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines /// true/false e.q. (x & 8) == 4. 5416bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines TryResult checkIncorrectEqualityOperator(const BinaryOperator *B) { 5426bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines const Expr *LHSExpr = B->getLHS()->IgnoreParens(); 5436bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines const Expr *RHSExpr = B->getRHS()->IgnoreParens(); 5446bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 5456bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines const IntegerLiteral *IntLiteral = dyn_cast<IntegerLiteral>(LHSExpr); 5466bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines const Expr *BoolExpr = RHSExpr; 5476bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 5486bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (!IntLiteral) { 5496bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines IntLiteral = dyn_cast<IntegerLiteral>(RHSExpr); 5506bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines BoolExpr = LHSExpr; 5516bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } 5526bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 5536bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (!IntLiteral) 5546bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return TryResult(); 5556bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 5566bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines const BinaryOperator *BitOp = dyn_cast<BinaryOperator>(BoolExpr); 5576bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (BitOp && (BitOp->getOpcode() == BO_And || 5586bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines BitOp->getOpcode() == BO_Or)) { 5596bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines const Expr *LHSExpr2 = BitOp->getLHS()->IgnoreParens(); 5606bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines const Expr *RHSExpr2 = BitOp->getRHS()->IgnoreParens(); 5616bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 5626bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines const IntegerLiteral *IntLiteral2 = dyn_cast<IntegerLiteral>(LHSExpr2); 5636bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 5646bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (!IntLiteral2) 5656bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines IntLiteral2 = dyn_cast<IntegerLiteral>(RHSExpr2); 5666bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 5676bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (!IntLiteral2) 5686bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return TryResult(); 5696bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 5706bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines llvm::APInt L1 = IntLiteral->getValue(); 5716bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines llvm::APInt L2 = IntLiteral2->getValue(); 5726bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if ((BitOp->getOpcode() == BO_And && (L2 & L1) != L1) || 5736bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines (BitOp->getOpcode() == BO_Or && (L2 | L1) != L1)) { 5746bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (BuildOpts.Observer) 5756bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines BuildOpts.Observer->compareBitwiseEquality(B, 5766bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines B->getOpcode() != BO_EQ); 5776bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines TryResult(B->getOpcode() != BO_EQ); 5786bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } 5796bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } else if (BoolExpr->isKnownToHaveBooleanValue()) { 5806bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines llvm::APInt IntValue = IntLiteral->getValue(); 5816bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if ((IntValue == 1) || (IntValue == 0)) { 5826bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return TryResult(); 5836bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } 5846bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return TryResult(B->getOpcode() != BO_EQ); 5856bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } 5866bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 5876bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return TryResult(); 5886bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } 5896bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 5906bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines TryResult analyzeLogicOperatorCondition(BinaryOperatorKind Relation, 5916bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines const llvm::APSInt &Value1, 5926bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines const llvm::APSInt &Value2) { 5936bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines assert(Value1.isSigned() == Value2.isSigned()); 5946bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines switch (Relation) { 5956bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines default: 5966bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return TryResult(); 5976bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines case BO_EQ: 5986bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return TryResult(Value1 == Value2); 5996bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines case BO_NE: 6006bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return TryResult(Value1 != Value2); 6016bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines case BO_LT: 6026bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return TryResult(Value1 < Value2); 6036bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines case BO_LE: 6046bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return TryResult(Value1 <= Value2); 6056bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines case BO_GT: 6066bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return TryResult(Value1 > Value2); 6076bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines case BO_GE: 6086bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return TryResult(Value1 >= Value2); 6096bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } 6106bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } 6116bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 6126bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines /// \brief Find a pair of comparison expressions with or without parentheses 6136bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines /// with a shared variable and constants and a logical operator between them 6146bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines /// that always evaluates to either true or false. 6156bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines /// e.g. if (x != 3 || x != 4) 6166bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines TryResult checkIncorrectLogicOperator(const BinaryOperator *B) { 6176bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines assert(B->isLogicalOp()); 6186bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines const BinaryOperator *LHS = 6196bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines dyn_cast<BinaryOperator>(B->getLHS()->IgnoreParens()); 6206bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines const BinaryOperator *RHS = 6216bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines dyn_cast<BinaryOperator>(B->getRHS()->IgnoreParens()); 6226bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (!LHS || !RHS) 6236bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return TryResult(); 6246bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 6256bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (!LHS->isComparisonOp() || !RHS->isComparisonOp()) 6266bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return TryResult(); 6276bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 6286bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines BinaryOperatorKind BO1 = LHS->getOpcode(); 6296bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines const DeclRefExpr *Decl1 = 6306bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines dyn_cast<DeclRefExpr>(LHS->getLHS()->IgnoreParenImpCasts()); 6316bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines const IntegerLiteral *Literal1 = 6326bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines dyn_cast<IntegerLiteral>(LHS->getRHS()->IgnoreParens()); 6336bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (!Decl1 && !Literal1) { 6346bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (BO1 == BO_GT) 6356bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines BO1 = BO_LT; 6366bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines else if (BO1 == BO_GE) 6376bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines BO1 = BO_LE; 6386bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines else if (BO1 == BO_LT) 6396bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines BO1 = BO_GT; 6406bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines else if (BO1 == BO_LE) 6416bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines BO1 = BO_GE; 6426bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines Decl1 = dyn_cast<DeclRefExpr>(LHS->getRHS()->IgnoreParenImpCasts()); 6436bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines Literal1 = dyn_cast<IntegerLiteral>(LHS->getLHS()->IgnoreParens()); 6446bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } 6456bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 6466bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (!Decl1 || !Literal1) 6476bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return TryResult(); 6486bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 6496bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines BinaryOperatorKind BO2 = RHS->getOpcode(); 6506bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines const DeclRefExpr *Decl2 = 6516bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines dyn_cast<DeclRefExpr>(RHS->getLHS()->IgnoreParenImpCasts()); 6526bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines const IntegerLiteral *Literal2 = 6536bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines dyn_cast<IntegerLiteral>(RHS->getRHS()->IgnoreParens()); 6546bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (!Decl2 && !Literal2) { 6556bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (BO2 == BO_GT) 6566bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines BO2 = BO_LT; 6576bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines else if (BO2 == BO_GE) 6586bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines BO2 = BO_LE; 6596bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines else if (BO2 == BO_LT) 6606bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines BO2 = BO_GT; 6616bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines else if (BO2 == BO_LE) 6626bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines BO2 = BO_GE; 6636bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines Decl2 = dyn_cast<DeclRefExpr>(RHS->getRHS()->IgnoreParenImpCasts()); 6646bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines Literal2 = dyn_cast<IntegerLiteral>(RHS->getLHS()->IgnoreParens()); 6656bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } 6666bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 6676bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (!Decl2 || !Literal2) 6686bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return TryResult(); 6696bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 6706bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines // Check that it is the same variable on both sides. 6716bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (Decl1->getDecl() != Decl2->getDecl()) 6726bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return TryResult(); 6736bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 6746bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines llvm::APSInt L1, L2; 6756bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 6766bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (!Literal1->EvaluateAsInt(L1, *Context) || 6776bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines !Literal2->EvaluateAsInt(L2, *Context)) 6786bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return TryResult(); 6796bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 6806bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines // Can't compare signed with unsigned or with different bit width. 6816bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (L1.isSigned() != L2.isSigned() || L1.getBitWidth() != L2.getBitWidth()) 6826bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return TryResult(); 6836bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 6846bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines // Values that will be used to determine if result of logical 6856bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines // operator is always true/false 6866bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines const llvm::APSInt Values[] = { 6876bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines // Value less than both Value1 and Value2 6886bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines llvm::APSInt::getMinValue(L1.getBitWidth(), L1.isUnsigned()), 6896bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines // L1 6906bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines L1, 6916bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines // Value between Value1 and Value2 6926bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines ((L1 < L2) ? L1 : L2) + llvm::APSInt(llvm::APInt(L1.getBitWidth(), 1), 6936bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines L1.isUnsigned()), 6946bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines // L2 6956bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines L2, 6966bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines // Value greater than both Value1 and Value2 6976bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines llvm::APSInt::getMaxValue(L1.getBitWidth(), L1.isUnsigned()), 6986bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines }; 6996bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 7006bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines // Check whether expression is always true/false by evaluating the following 7016bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines // * variable x is less than the smallest literal. 7026bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines // * variable x is equal to the smallest literal. 7036bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines // * Variable x is between smallest and largest literal. 7046bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines // * Variable x is equal to the largest literal. 7056bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines // * Variable x is greater than largest literal. 7066bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines bool AlwaysTrue = true, AlwaysFalse = true; 7076bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines for (unsigned int ValueIndex = 0; 7086bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines ValueIndex < sizeof(Values) / sizeof(Values[0]); 7096bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines ++ValueIndex) { 7106bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines llvm::APSInt Value = Values[ValueIndex]; 7116bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines TryResult Res1, Res2; 7126bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines Res1 = analyzeLogicOperatorCondition(BO1, Value, L1); 7136bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines Res2 = analyzeLogicOperatorCondition(BO2, Value, L2); 7146bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 7156bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (!Res1.isKnown() || !Res2.isKnown()) 7166bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return TryResult(); 7176bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 7186bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (B->getOpcode() == BO_LAnd) { 7196bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines AlwaysTrue &= (Res1.isTrue() && Res2.isTrue()); 7206bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines AlwaysFalse &= !(Res1.isTrue() && Res2.isTrue()); 7216bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } else { 7226bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines AlwaysTrue &= (Res1.isTrue() || Res2.isTrue()); 7236bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines AlwaysFalse &= !(Res1.isTrue() || Res2.isTrue()); 7246bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } 7256bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } 7266bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 7276bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (AlwaysTrue || AlwaysFalse) { 7286bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (BuildOpts.Observer) 7296bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines BuildOpts.Observer->compareAlwaysTrue(B, AlwaysTrue); 7306bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return TryResult(AlwaysTrue); 7316bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } 7326bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return TryResult(); 7336bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } 7346bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 735e71f3d587844110d836c82250830b27b1651afdbTed Kremenek /// Try and evaluate an expression to an integer constant. 736e71f3d587844110d836c82250830b27b1651afdbTed Kremenek bool tryEvaluate(Expr *S, Expr::EvalResult &outResult) { 737e71f3d587844110d836c82250830b27b1651afdbTed Kremenek if (!BuildOpts.PruneTriviallyFalseEdges) 738e71f3d587844110d836c82250830b27b1651afdbTed Kremenek return false; 739e71f3d587844110d836c82250830b27b1651afdbTed Kremenek return !S->isTypeDependent() && 740f8adeefa9e9882bff402e092024dd457f8574673Ted Kremenek !S->isValueDependent() && 74151f4708c00110940ca3f337961915f2ca1668375Richard Smith S->EvaluateAsRValue(outResult, *Context); 742e71f3d587844110d836c82250830b27b1651afdbTed Kremenek } 7431eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 7440a3ed3143b00f237decb1288c1ff574ae09eba4eTed Kremenek /// tryEvaluateBool - Try and evaluate the Stmt and return 0 or 1 74500998a068e50945118f334c98af05ed44d7c22a6Mike Stump /// if we can evaluate to a known value, otherwise return -1. 7460a3ed3143b00f237decb1288c1ff574ae09eba4eTed Kremenek TryResult tryEvaluateBool(Expr *S) { 74785df96c1f04867e26ba069aa0cc6a4cd6a01292eRichard Smith if (!BuildOpts.PruneTriviallyFalseEdges || 7488c6d360636dee25f1ce071c3656810c6632cb89dArgyrios Kyrtzidis S->isTypeDependent() || S->isValueDependent()) 749e71f3d587844110d836c82250830b27b1651afdbTed Kremenek return TryResult(); 7508c6d360636dee25f1ce071c3656810c6632cb89dArgyrios Kyrtzidis 7518c6d360636dee25f1ce071c3656810c6632cb89dArgyrios Kyrtzidis if (BinaryOperator *Bop = dyn_cast<BinaryOperator>(S)) { 7528c6d360636dee25f1ce071c3656810c6632cb89dArgyrios Kyrtzidis if (Bop->isLogicalOp()) { 7538c6d360636dee25f1ce071c3656810c6632cb89dArgyrios Kyrtzidis // Check the cache first. 7546955da2cad4bce19c541ddb85a6d965d77a1a4abNAKAMURA Takumi CachedBoolEvalsTy::iterator I = CachedBoolEvals.find(S); 7556955da2cad4bce19c541ddb85a6d965d77a1a4abNAKAMURA Takumi if (I != CachedBoolEvals.end()) 7568c6d360636dee25f1ce071c3656810c6632cb89dArgyrios Kyrtzidis return I->second; // already in map; 7579260f618e72f7c70dc76312f95d679f0ed03858cNAKAMURA Takumi 7589260f618e72f7c70dc76312f95d679f0ed03858cNAKAMURA Takumi // Retrieve result at first, or the map might be updated. 7599260f618e72f7c70dc76312f95d679f0ed03858cNAKAMURA Takumi TryResult Result = evaluateAsBooleanConditionNoCache(S); 7609260f618e72f7c70dc76312f95d679f0ed03858cNAKAMURA Takumi CachedBoolEvals[S] = Result; // update or insert 7619260f618e72f7c70dc76312f95d679f0ed03858cNAKAMURA Takumi return Result; 7628c6d360636dee25f1ce071c3656810c6632cb89dArgyrios Kyrtzidis } 7633d1125b27e8006385a830f5b3748b7b44d227b4cTed Kremenek else { 7643d1125b27e8006385a830f5b3748b7b44d227b4cTed Kremenek switch (Bop->getOpcode()) { 7653d1125b27e8006385a830f5b3748b7b44d227b4cTed Kremenek default: break; 7663d1125b27e8006385a830f5b3748b7b44d227b4cTed Kremenek // For 'x & 0' and 'x * 0', we can determine that 7673d1125b27e8006385a830f5b3748b7b44d227b4cTed Kremenek // the value is always false. 7683d1125b27e8006385a830f5b3748b7b44d227b4cTed Kremenek case BO_Mul: 7693d1125b27e8006385a830f5b3748b7b44d227b4cTed Kremenek case BO_And: { 7703d1125b27e8006385a830f5b3748b7b44d227b4cTed Kremenek // If either operand is zero, we know the value 7713d1125b27e8006385a830f5b3748b7b44d227b4cTed Kremenek // must be false. 7723d1125b27e8006385a830f5b3748b7b44d227b4cTed Kremenek llvm::APSInt IntVal; 7733d1125b27e8006385a830f5b3748b7b44d227b4cTed Kremenek if (Bop->getLHS()->EvaluateAsInt(IntVal, *Context)) { 7743d1125b27e8006385a830f5b3748b7b44d227b4cTed Kremenek if (IntVal.getBoolValue() == false) { 7753d1125b27e8006385a830f5b3748b7b44d227b4cTed Kremenek return TryResult(false); 7763d1125b27e8006385a830f5b3748b7b44d227b4cTed Kremenek } 7773d1125b27e8006385a830f5b3748b7b44d227b4cTed Kremenek } 7783d1125b27e8006385a830f5b3748b7b44d227b4cTed Kremenek if (Bop->getRHS()->EvaluateAsInt(IntVal, *Context)) { 7793d1125b27e8006385a830f5b3748b7b44d227b4cTed Kremenek if (IntVal.getBoolValue() == false) { 7803d1125b27e8006385a830f5b3748b7b44d227b4cTed Kremenek return TryResult(false); 7813d1125b27e8006385a830f5b3748b7b44d227b4cTed Kremenek } 7823d1125b27e8006385a830f5b3748b7b44d227b4cTed Kremenek } 7833d1125b27e8006385a830f5b3748b7b44d227b4cTed Kremenek } 7843d1125b27e8006385a830f5b3748b7b44d227b4cTed Kremenek break; 7853d1125b27e8006385a830f5b3748b7b44d227b4cTed Kremenek } 7863d1125b27e8006385a830f5b3748b7b44d227b4cTed Kremenek } 7878c6d360636dee25f1ce071c3656810c6632cb89dArgyrios Kyrtzidis } 7888c6d360636dee25f1ce071c3656810c6632cb89dArgyrios Kyrtzidis 7898c6d360636dee25f1ce071c3656810c6632cb89dArgyrios Kyrtzidis return evaluateAsBooleanConditionNoCache(S); 7908c6d360636dee25f1ce071c3656810c6632cb89dArgyrios Kyrtzidis } 7918c6d360636dee25f1ce071c3656810c6632cb89dArgyrios Kyrtzidis 7928c6d360636dee25f1ce071c3656810c6632cb89dArgyrios Kyrtzidis /// \brief Evaluate as boolean \param E without using the cache. 7938c6d360636dee25f1ce071c3656810c6632cb89dArgyrios Kyrtzidis TryResult evaluateAsBooleanConditionNoCache(Expr *E) { 7948c6d360636dee25f1ce071c3656810c6632cb89dArgyrios Kyrtzidis if (BinaryOperator *Bop = dyn_cast<BinaryOperator>(E)) { 7958c6d360636dee25f1ce071c3656810c6632cb89dArgyrios Kyrtzidis if (Bop->isLogicalOp()) { 7968c6d360636dee25f1ce071c3656810c6632cb89dArgyrios Kyrtzidis TryResult LHS = tryEvaluateBool(Bop->getLHS()); 7978c6d360636dee25f1ce071c3656810c6632cb89dArgyrios Kyrtzidis if (LHS.isKnown()) { 7988c6d360636dee25f1ce071c3656810c6632cb89dArgyrios Kyrtzidis // We were able to evaluate the LHS, see if we can get away with not 7998c6d360636dee25f1ce071c3656810c6632cb89dArgyrios Kyrtzidis // evaluating the RHS: 0 && X -> 0, 1 || X -> 1 8008c6d360636dee25f1ce071c3656810c6632cb89dArgyrios Kyrtzidis if (LHS.isTrue() == (Bop->getOpcode() == BO_LOr)) 8018c6d360636dee25f1ce071c3656810c6632cb89dArgyrios Kyrtzidis return LHS.isTrue(); 8028c6d360636dee25f1ce071c3656810c6632cb89dArgyrios Kyrtzidis 8038c6d360636dee25f1ce071c3656810c6632cb89dArgyrios Kyrtzidis TryResult RHS = tryEvaluateBool(Bop->getRHS()); 8048c6d360636dee25f1ce071c3656810c6632cb89dArgyrios Kyrtzidis if (RHS.isKnown()) { 8058c6d360636dee25f1ce071c3656810c6632cb89dArgyrios Kyrtzidis if (Bop->getOpcode() == BO_LOr) 8068c6d360636dee25f1ce071c3656810c6632cb89dArgyrios Kyrtzidis return LHS.isTrue() || RHS.isTrue(); 8078c6d360636dee25f1ce071c3656810c6632cb89dArgyrios Kyrtzidis else 8088c6d360636dee25f1ce071c3656810c6632cb89dArgyrios Kyrtzidis return LHS.isTrue() && RHS.isTrue(); 8098c6d360636dee25f1ce071c3656810c6632cb89dArgyrios Kyrtzidis } 8108c6d360636dee25f1ce071c3656810c6632cb89dArgyrios Kyrtzidis } else { 8118c6d360636dee25f1ce071c3656810c6632cb89dArgyrios Kyrtzidis TryResult RHS = tryEvaluateBool(Bop->getRHS()); 8128c6d360636dee25f1ce071c3656810c6632cb89dArgyrios Kyrtzidis if (RHS.isKnown()) { 8138c6d360636dee25f1ce071c3656810c6632cb89dArgyrios Kyrtzidis // We can't evaluate the LHS; however, sometimes the result 8148c6d360636dee25f1ce071c3656810c6632cb89dArgyrios Kyrtzidis // is determined by the RHS: X && 0 -> 0, X || 1 -> 1. 8158c6d360636dee25f1ce071c3656810c6632cb89dArgyrios Kyrtzidis if (RHS.isTrue() == (Bop->getOpcode() == BO_LOr)) 8168c6d360636dee25f1ce071c3656810c6632cb89dArgyrios Kyrtzidis return RHS.isTrue(); 8176bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } else { 8186bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines TryResult BopRes = checkIncorrectLogicOperator(Bop); 8196bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (BopRes.isKnown()) 8206bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return BopRes.isTrue(); 8218c6d360636dee25f1ce071c3656810c6632cb89dArgyrios Kyrtzidis } 8228c6d360636dee25f1ce071c3656810c6632cb89dArgyrios Kyrtzidis } 8238c6d360636dee25f1ce071c3656810c6632cb89dArgyrios Kyrtzidis 8248c6d360636dee25f1ce071c3656810c6632cb89dArgyrios Kyrtzidis return TryResult(); 8256bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } else if (Bop->isEqualityOp()) { 8266bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines TryResult BopRes = checkIncorrectEqualityOperator(Bop); 8276bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (BopRes.isKnown()) 8286bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return BopRes.isTrue(); 8296bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } else if (Bop->isRelationalOp()) { 8306bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines TryResult BopRes = checkIncorrectRelationalOperator(Bop); 8316bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (BopRes.isKnown()) 8326bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return BopRes.isTrue(); 8338c6d360636dee25f1ce071c3656810c6632cb89dArgyrios Kyrtzidis } 8348c6d360636dee25f1ce071c3656810c6632cb89dArgyrios Kyrtzidis } 8358c6d360636dee25f1ce071c3656810c6632cb89dArgyrios Kyrtzidis 8368c6d360636dee25f1ce071c3656810c6632cb89dArgyrios Kyrtzidis bool Result; 8378c6d360636dee25f1ce071c3656810c6632cb89dArgyrios Kyrtzidis if (E->EvaluateAsBooleanCondition(Result, *Context)) 8388c6d360636dee25f1ce071c3656810c6632cb89dArgyrios Kyrtzidis return Result; 8398c6d360636dee25f1ce071c3656810c6632cb89dArgyrios Kyrtzidis 8408c6d360636dee25f1ce071c3656810c6632cb89dArgyrios Kyrtzidis return TryResult(); 84100998a068e50945118f334c98af05ed44d7c22a6Mike Stump } 842e71f3d587844110d836c82250830b27b1651afdbTed Kremenek 843d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek}; 8446d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 8450d28d360b5559abda755e50b855ba5e59727d9cdTed Kremenekinline bool AddStmtChoice::alwaysAdd(CFGBuilder &builder, 8460d28d360b5559abda755e50b855ba5e59727d9cdTed Kremenek const Stmt *stmt) const { 8470d28d360b5559abda755e50b855ba5e59727d9cdTed Kremenek return builder.alwaysAdd(stmt) || kind == AlwaysAdd; 8480d28d360b5559abda755e50b855ba5e59727d9cdTed Kremenek} 849a8d459e8a68b1270b0c35fb73e8cc090b2b69e36Ted Kremenek 8500d28d360b5559abda755e50b855ba5e59727d9cdTed Kremenekbool CFGBuilder::alwaysAdd(const Stmt *stmt) { 85174fb1a493cf5d2dd0fb51a4eadf74e85e10a3457Ted Kremenek bool shouldAdd = BuildOpts.alwaysAdd(stmt); 85274fb1a493cf5d2dd0fb51a4eadf74e85e10a3457Ted Kremenek 8530d28d360b5559abda755e50b855ba5e59727d9cdTed Kremenek if (!BuildOpts.forcedBlkExprs) 85474fb1a493cf5d2dd0fb51a4eadf74e85e10a3457Ted Kremenek return shouldAdd; 855a8d459e8a68b1270b0c35fb73e8cc090b2b69e36Ted Kremenek 856a8d459e8a68b1270b0c35fb73e8cc090b2b69e36Ted Kremenek if (lastLookup == stmt) { 857a8d459e8a68b1270b0c35fb73e8cc090b2b69e36Ted Kremenek if (cachedEntry) { 858a8d459e8a68b1270b0c35fb73e8cc090b2b69e36Ted Kremenek assert(cachedEntry->first == stmt); 859a8d459e8a68b1270b0c35fb73e8cc090b2b69e36Ted Kremenek return true; 860a8d459e8a68b1270b0c35fb73e8cc090b2b69e36Ted Kremenek } 86174fb1a493cf5d2dd0fb51a4eadf74e85e10a3457Ted Kremenek return shouldAdd; 862a8d459e8a68b1270b0c35fb73e8cc090b2b69e36Ted Kremenek } 8630d28d360b5559abda755e50b855ba5e59727d9cdTed Kremenek 864a8d459e8a68b1270b0c35fb73e8cc090b2b69e36Ted Kremenek lastLookup = stmt; 865a8d459e8a68b1270b0c35fb73e8cc090b2b69e36Ted Kremenek 866a8d459e8a68b1270b0c35fb73e8cc090b2b69e36Ted Kremenek // Perform the lookup! 8670d28d360b5559abda755e50b855ba5e59727d9cdTed Kremenek CFG::BuildOptions::ForcedBlkExprs *fb = *BuildOpts.forcedBlkExprs; 8680d28d360b5559abda755e50b855ba5e59727d9cdTed Kremenek 869a8d459e8a68b1270b0c35fb73e8cc090b2b69e36Ted Kremenek if (!fb) { 870a8d459e8a68b1270b0c35fb73e8cc090b2b69e36Ted Kremenek // No need to update 'cachedEntry', since it will always be null. 8716bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines assert(!cachedEntry); 87274fb1a493cf5d2dd0fb51a4eadf74e85e10a3457Ted Kremenek return shouldAdd; 873a8d459e8a68b1270b0c35fb73e8cc090b2b69e36Ted Kremenek } 8740d28d360b5559abda755e50b855ba5e59727d9cdTed Kremenek 8750d28d360b5559abda755e50b855ba5e59727d9cdTed Kremenek CFG::BuildOptions::ForcedBlkExprs::iterator itr = fb->find(stmt); 876a8d459e8a68b1270b0c35fb73e8cc090b2b69e36Ted Kremenek if (itr == fb->end()) { 8776bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines cachedEntry = nullptr; 87874fb1a493cf5d2dd0fb51a4eadf74e85e10a3457Ted Kremenek return shouldAdd; 879a8d459e8a68b1270b0c35fb73e8cc090b2b69e36Ted Kremenek } 880a8d459e8a68b1270b0c35fb73e8cc090b2b69e36Ted Kremenek 8810d28d360b5559abda755e50b855ba5e59727d9cdTed Kremenek cachedEntry = &*itr; 8820d28d360b5559abda755e50b855ba5e59727d9cdTed Kremenek return true; 8833179a45a0e91c1dcf3492222170cf4499531bb92Ted Kremenek} 8843179a45a0e91c1dcf3492222170cf4499531bb92Ted Kremenek 885898574e7496ba8fd76290079d3a9d06954992734Douglas Gregor// FIXME: Add support for dependent-sized array types in C++? 886898574e7496ba8fd76290079d3a9d06954992734Douglas Gregor// Does it even make sense to build a CFG for an uninstantiated template? 887f4c7371fb1d3cebcfb40abad4537bb82515704eaJohn McCallstatic const VariableArrayType *FindVA(const Type *t) { 888f4c7371fb1d3cebcfb40abad4537bb82515704eaJohn McCall while (const ArrayType *vt = dyn_cast<ArrayType>(t)) { 889f4c7371fb1d3cebcfb40abad4537bb82515704eaJohn McCall if (const VariableArrayType *vat = dyn_cast<VariableArrayType>(vt)) 890610a09e409bea151a42dd907768f1e0c4b103f1fTed Kremenek if (vat->getSizeExpr()) 891610a09e409bea151a42dd907768f1e0c4b103f1fTed Kremenek return vat; 8926d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 893610a09e409bea151a42dd907768f1e0c4b103f1fTed Kremenek t = vt->getElementType().getTypePtr(); 894610a09e409bea151a42dd907768f1e0c4b103f1fTed Kremenek } 8956d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 8966bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return nullptr; 897610a09e409bea151a42dd907768f1e0c4b103f1fTed Kremenek} 8986d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 8996d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump/// BuildCFG - Constructs a CFG from an AST (a Stmt*). The AST can represent an 9006d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump/// arbitrary statement. Examples include a single expression or a function 9016d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump/// body (compound statement). The ownership of the returned CFG is 9026d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump/// transferred to the caller. If CFG construction fails, this method returns 9036d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump/// NULL. 9049c378f705405d37f49795d5e915989de774fe11fTed KremenekCFG* CFGBuilder::buildCFG(const Decl *D, Stmt *Statement) { 9050ba497be27170c2a23c0217366f97eeecefa1ed8Ted Kremenek assert(cfg.get()); 9064f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek if (!Statement) 9076bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return nullptr; 908d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek 9096d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump // Create an empty block that will serve as the exit block for the CFG. Since 9106d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump // this is the first block added to the CFG, it will be implicitly registered 9116d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump // as the exit block. 91249af7cb8a3aca79783e7a0708b97a8f856f0da22Ted Kremenek Succ = createBlock(); 913ee82d9bdc5025b82de8ce2a4ad4685e0a8b79da9Ted Kremenek assert(Succ == &cfg->getExit()); 9146bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines Block = nullptr; // the EXIT block is empty. Create all other blocks lazily. 9156d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 9167c625d8ffc20b92fff9e1690cd2484fcb6498183Marcin Swiderski if (BuildOpts.AddImplicitDtors) 9177c625d8ffc20b92fff9e1690cd2484fcb6498183Marcin Swiderski if (const CXXDestructorDecl *DD = dyn_cast_or_null<CXXDestructorDecl>(D)) 9187c625d8ffc20b92fff9e1690cd2484fcb6498183Marcin Swiderski addImplicitDtorsForDestructor(DD); 9197c625d8ffc20b92fff9e1690cd2484fcb6498183Marcin Swiderski 920d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek // Visit the statements and create the CFG. 9211b3b7cb15cbd02b7283bbf3ce7c0e9b0da30ef9dZhongxing Xu CFGBlock *B = addStmt(Statement); 9221b3b7cb15cbd02b7283bbf3ce7c0e9b0da30ef9dZhongxing Xu 9231b3b7cb15cbd02b7283bbf3ce7c0e9b0da30ef9dZhongxing Xu if (badCFG) 9246bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return nullptr; 9251b3b7cb15cbd02b7283bbf3ce7c0e9b0da30ef9dZhongxing Xu 92682bc3fd823d85ee3ef9a641c0975b6ad25f55047Marcin Swiderski // For C++ constructor add initializers to CFG. 927b978a441c7d8bf59e7fede938e1f3b672573b443Mike Stump if (const CXXConstructorDecl *CD = dyn_cast_or_null<CXXConstructorDecl>(D)) { 92882bc3fd823d85ee3ef9a641c0975b6ad25f55047Marcin Swiderski for (CXXConstructorDecl::init_const_reverse_iterator I = CD->init_rbegin(), 92982bc3fd823d85ee3ef9a641c0975b6ad25f55047Marcin Swiderski E = CD->init_rend(); I != E; ++I) { 93082bc3fd823d85ee3ef9a641c0975b6ad25f55047Marcin Swiderski B = addInitializer(*I); 93182bc3fd823d85ee3ef9a641c0975b6ad25f55047Marcin Swiderski if (badCFG) 9326bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return nullptr; 93382bc3fd823d85ee3ef9a641c0975b6ad25f55047Marcin Swiderski } 934b978a441c7d8bf59e7fede938e1f3b672573b443Mike Stump } 9356d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 93682bc3fd823d85ee3ef9a641c0975b6ad25f55047Marcin Swiderski if (B) 93782bc3fd823d85ee3ef9a641c0975b6ad25f55047Marcin Swiderski Succ = B; 93882bc3fd823d85ee3ef9a641c0975b6ad25f55047Marcin Swiderski 9391b3b7cb15cbd02b7283bbf3ce7c0e9b0da30ef9dZhongxing Xu // Backpatch the gotos whose label -> block mappings we didn't know when we 9401b3b7cb15cbd02b7283bbf3ce7c0e9b0da30ef9dZhongxing Xu // encountered them. 9411b3b7cb15cbd02b7283bbf3ce7c0e9b0da30ef9dZhongxing Xu for (BackpatchBlocksTy::iterator I = BackpatchBlocks.begin(), 9421b3b7cb15cbd02b7283bbf3ce7c0e9b0da30ef9dZhongxing Xu E = BackpatchBlocks.end(); I != E; ++I ) { 943c3daac59e26b63c08208de2fbaceb1ff01be3492Daniel Dunbar 9449c378f705405d37f49795d5e915989de774fe11fTed Kremenek CFGBlock *B = I->block; 9458343f8e00a222ca09dde536c77313e3e6e03ad59Rafael Espindola const GotoStmt *G = cast<GotoStmt>(B->getTerminator()); 9461b3b7cb15cbd02b7283bbf3ce7c0e9b0da30ef9dZhongxing Xu LabelMapTy::iterator LI = LabelMap.find(G->getLabel()); 9476d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 9481b3b7cb15cbd02b7283bbf3ce7c0e9b0da30ef9dZhongxing Xu // If there is no target for the goto, then we are looking at an 9491b3b7cb15cbd02b7283bbf3ce7c0e9b0da30ef9dZhongxing Xu // incomplete AST. Handle this by not registering a successor. 9501b3b7cb15cbd02b7283bbf3ce7c0e9b0da30ef9dZhongxing Xu if (LI == LabelMap.end()) continue; 951d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek 952f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski JumpTarget JT = LI->second; 9539ce5270f0aadaaf03a0cf705787f42ce9eb1194cTed Kremenek prependAutomaticObjDtorsWithTerminator(B, I->scopePosition, 9549ce5270f0aadaaf03a0cf705787f42ce9eb1194cTed Kremenek JT.scopePosition); 9559ce5270f0aadaaf03a0cf705787f42ce9eb1194cTed Kremenek addSuccessor(B, JT.block); 9561b3b7cb15cbd02b7283bbf3ce7c0e9b0da30ef9dZhongxing Xu } 9576d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 9581b3b7cb15cbd02b7283bbf3ce7c0e9b0da30ef9dZhongxing Xu // Add successors to the Indirect Goto Dispatch block (if we have one). 9599c378f705405d37f49795d5e915989de774fe11fTed Kremenek if (CFGBlock *B = cfg->getIndirectGotoBlock()) 9601b3b7cb15cbd02b7283bbf3ce7c0e9b0da30ef9dZhongxing Xu for (LabelSetTy::iterator I = AddressTakenLabels.begin(), 9611b3b7cb15cbd02b7283bbf3ce7c0e9b0da30ef9dZhongxing Xu E = AddressTakenLabels.end(); I != E; ++I ) { 9621b3b7cb15cbd02b7283bbf3ce7c0e9b0da30ef9dZhongxing Xu 9631b3b7cb15cbd02b7283bbf3ce7c0e9b0da30ef9dZhongxing Xu // Lookup the target block. 9641b3b7cb15cbd02b7283bbf3ce7c0e9b0da30ef9dZhongxing Xu LabelMapTy::iterator LI = LabelMap.find(*I); 9651b3b7cb15cbd02b7283bbf3ce7c0e9b0da30ef9dZhongxing Xu 9661b3b7cb15cbd02b7283bbf3ce7c0e9b0da30ef9dZhongxing Xu // If there is no target block that contains label, then we are looking 9671b3b7cb15cbd02b7283bbf3ce7c0e9b0da30ef9dZhongxing Xu // at an incomplete AST. Handle this by not registering a successor. 9681b3b7cb15cbd02b7283bbf3ce7c0e9b0da30ef9dZhongxing Xu if (LI == LabelMap.end()) continue; 9691b3b7cb15cbd02b7283bbf3ce7c0e9b0da30ef9dZhongxing Xu 9709ce5270f0aadaaf03a0cf705787f42ce9eb1194cTed Kremenek addSuccessor(B, LI->second.block); 971c3daac59e26b63c08208de2fbaceb1ff01be3492Daniel Dunbar } 9726d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 9736d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump // Create an empty entry block that has no predecessors. 974322f58d3830da13b419646c071e3ab801518a09cTed Kremenek cfg->setEntry(createBlock()); 9756d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 976651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return cfg.release(); 977d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek} 9786d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 979d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek/// createBlock - Used to lazily create blocks that are connected 980d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek/// to the current (global) succcessor. 9819c378f705405d37f49795d5e915989de774fe11fTed KremenekCFGBlock *CFGBuilder::createBlock(bool add_successor) { 9829c378f705405d37f49795d5e915989de774fe11fTed Kremenek CFGBlock *B = cfg->createBlock(); 9834f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek if (add_successor && Succ) 9840a3ed3143b00f237decb1288c1ff574ae09eba4eTed Kremenek addSuccessor(B, Succ); 985d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek return B; 986d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek} 9876d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 988dba3fb5413437dc613734fa4ffac892b11a37d25Chandler Carruth/// createNoReturnBlock - Used to create a block is a 'noreturn' point in the 989dba3fb5413437dc613734fa4ffac892b11a37d25Chandler Carruth/// CFG. It is *not* connected to the current (global) successor, and instead 990dba3fb5413437dc613734fa4ffac892b11a37d25Chandler Carruth/// directly tied to the exit block in order to be reachable. 991dba3fb5413437dc613734fa4ffac892b11a37d25Chandler CarruthCFGBlock *CFGBuilder::createNoReturnBlock() { 992dba3fb5413437dc613734fa4ffac892b11a37d25Chandler Carruth CFGBlock *B = createBlock(false); 99383754162f698a5dafad93fb89be0953651a604d0Chandler Carruth B->setHasNoReturnElement(); 994651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines addSuccessor(B, &cfg->getExit(), Succ); 995dba3fb5413437dc613734fa4ffac892b11a37d25Chandler Carruth return B; 996dba3fb5413437dc613734fa4ffac892b11a37d25Chandler Carruth} 997dba3fb5413437dc613734fa4ffac892b11a37d25Chandler Carruth 99882bc3fd823d85ee3ef9a641c0975b6ad25f55047Marcin Swiderski/// addInitializer - Add C++ base or member initializer element to CFG. 999cbb67480094b3bcb5b715acd827cbad55e2a204cSean HuntCFGBlock *CFGBuilder::addInitializer(CXXCtorInitializer *I) { 100082bc3fd823d85ee3ef9a641c0975b6ad25f55047Marcin Swiderski if (!BuildOpts.AddInitializers) 100182bc3fd823d85ee3ef9a641c0975b6ad25f55047Marcin Swiderski return Block; 100282bc3fd823d85ee3ef9a641c0975b6ad25f55047Marcin Swiderski 10038599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski bool IsReference = false; 10048599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski bool HasTemporaries = false; 100582bc3fd823d85ee3ef9a641c0975b6ad25f55047Marcin Swiderski 10068599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski // Destructors of temporaries in initialization expression should be called 10078599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski // after initialization finishes. 10088599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski Expr *Init = I->getInit(); 10098599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski if (Init) { 101000eb3f9c5b33e3d99aee1f8b75dd9c9678fdd66bFrancois Pichet if (FieldDecl *FD = I->getAnyMember()) 10118599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski IsReference = FD->getType()->isReferenceType(); 10124765fa05b5652fcc4356371c2f481d0ea9a1b007John McCall HasTemporaries = isa<ExprWithCleanups>(Init); 101382bc3fd823d85ee3ef9a641c0975b6ad25f55047Marcin Swiderski 10145a1ffe98b04120846a15f7105905b5f363b08635Jordan Rose if (BuildOpts.AddTemporaryDtors && HasTemporaries) { 10158599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski // Generate destructors for temporaries in initialization expression. 10164765fa05b5652fcc4356371c2f481d0ea9a1b007John McCall VisitForTemporaryDtors(cast<ExprWithCleanups>(Init)->getSubExpr(), 10178599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski IsReference); 10188599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski } 101982bc3fd823d85ee3ef9a641c0975b6ad25f55047Marcin Swiderski } 10208599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski 10218599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski autoCreateBlock(); 10228599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski appendInitializer(Block, I); 10238599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski 10248599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski if (Init) { 1025892697dd2287caf7c29aaaa82909b0e90b8b63feTed Kremenek if (HasTemporaries) { 10268599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski // For expression with temporaries go directly to subexpression to omit 10278599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski // generating destructors for the second time. 1028892697dd2287caf7c29aaaa82909b0e90b8b63feTed Kremenek return Visit(cast<ExprWithCleanups>(Init)->getSubExpr()); 1029892697dd2287caf7c29aaaa82909b0e90b8b63feTed Kremenek } 1030892697dd2287caf7c29aaaa82909b0e90b8b63feTed Kremenek return Visit(Init); 10318599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski } 10328599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski 103382bc3fd823d85ee3ef9a641c0975b6ad25f55047Marcin Swiderski return Block; 103482bc3fd823d85ee3ef9a641c0975b6ad25f55047Marcin Swiderski} 103582bc3fd823d85ee3ef9a641c0975b6ad25f55047Marcin Swiderski 10362d9eb21325a0854e86de7344f54a8e6cef2a97adDouglas Gregor/// \brief Retrieve the type of the temporary object whose lifetime was 10372d9eb21325a0854e86de7344f54a8e6cef2a97adDouglas Gregor/// extended by a local reference with the given initializer. 10382d9eb21325a0854e86de7344f54a8e6cef2a97adDouglas Gregorstatic QualType getReferenceInitTemporaryType(ASTContext &Context, 10392d9eb21325a0854e86de7344f54a8e6cef2a97adDouglas Gregor const Expr *Init) { 10402d9eb21325a0854e86de7344f54a8e6cef2a97adDouglas Gregor while (true) { 10412d9eb21325a0854e86de7344f54a8e6cef2a97adDouglas Gregor // Skip parentheses. 10422d9eb21325a0854e86de7344f54a8e6cef2a97adDouglas Gregor Init = Init->IgnoreParens(); 10432d9eb21325a0854e86de7344f54a8e6cef2a97adDouglas Gregor 10442d9eb21325a0854e86de7344f54a8e6cef2a97adDouglas Gregor // Skip through cleanups. 10452d9eb21325a0854e86de7344f54a8e6cef2a97adDouglas Gregor if (const ExprWithCleanups *EWC = dyn_cast<ExprWithCleanups>(Init)) { 10462d9eb21325a0854e86de7344f54a8e6cef2a97adDouglas Gregor Init = EWC->getSubExpr(); 10472d9eb21325a0854e86de7344f54a8e6cef2a97adDouglas Gregor continue; 10482d9eb21325a0854e86de7344f54a8e6cef2a97adDouglas Gregor } 10492d9eb21325a0854e86de7344f54a8e6cef2a97adDouglas Gregor 10502d9eb21325a0854e86de7344f54a8e6cef2a97adDouglas Gregor // Skip through the temporary-materialization expression. 10512d9eb21325a0854e86de7344f54a8e6cef2a97adDouglas Gregor if (const MaterializeTemporaryExpr *MTE 10522d9eb21325a0854e86de7344f54a8e6cef2a97adDouglas Gregor = dyn_cast<MaterializeTemporaryExpr>(Init)) { 10532d9eb21325a0854e86de7344f54a8e6cef2a97adDouglas Gregor Init = MTE->GetTemporaryExpr(); 10542d9eb21325a0854e86de7344f54a8e6cef2a97adDouglas Gregor continue; 10552d9eb21325a0854e86de7344f54a8e6cef2a97adDouglas Gregor } 10562d9eb21325a0854e86de7344f54a8e6cef2a97adDouglas Gregor 10572d9eb21325a0854e86de7344f54a8e6cef2a97adDouglas Gregor // Skip derived-to-base and no-op casts. 10582d9eb21325a0854e86de7344f54a8e6cef2a97adDouglas Gregor if (const CastExpr *CE = dyn_cast<CastExpr>(Init)) { 10592d9eb21325a0854e86de7344f54a8e6cef2a97adDouglas Gregor if ((CE->getCastKind() == CK_DerivedToBase || 10602d9eb21325a0854e86de7344f54a8e6cef2a97adDouglas Gregor CE->getCastKind() == CK_UncheckedDerivedToBase || 10612d9eb21325a0854e86de7344f54a8e6cef2a97adDouglas Gregor CE->getCastKind() == CK_NoOp) && 10622d9eb21325a0854e86de7344f54a8e6cef2a97adDouglas Gregor Init->getType()->isRecordType()) { 10632d9eb21325a0854e86de7344f54a8e6cef2a97adDouglas Gregor Init = CE->getSubExpr(); 10642d9eb21325a0854e86de7344f54a8e6cef2a97adDouglas Gregor continue; 10652d9eb21325a0854e86de7344f54a8e6cef2a97adDouglas Gregor } 10662d9eb21325a0854e86de7344f54a8e6cef2a97adDouglas Gregor } 10672d9eb21325a0854e86de7344f54a8e6cef2a97adDouglas Gregor 10682d9eb21325a0854e86de7344f54a8e6cef2a97adDouglas Gregor // Skip member accesses into rvalues. 10692d9eb21325a0854e86de7344f54a8e6cef2a97adDouglas Gregor if (const MemberExpr *ME = dyn_cast<MemberExpr>(Init)) { 10702d9eb21325a0854e86de7344f54a8e6cef2a97adDouglas Gregor if (!ME->isArrow() && ME->getBase()->isRValue()) { 10712d9eb21325a0854e86de7344f54a8e6cef2a97adDouglas Gregor Init = ME->getBase(); 10722d9eb21325a0854e86de7344f54a8e6cef2a97adDouglas Gregor continue; 10732d9eb21325a0854e86de7344f54a8e6cef2a97adDouglas Gregor } 10742d9eb21325a0854e86de7344f54a8e6cef2a97adDouglas Gregor } 10752d9eb21325a0854e86de7344f54a8e6cef2a97adDouglas Gregor 10762d9eb21325a0854e86de7344f54a8e6cef2a97adDouglas Gregor break; 10772d9eb21325a0854e86de7344f54a8e6cef2a97adDouglas Gregor } 10782d9eb21325a0854e86de7344f54a8e6cef2a97adDouglas Gregor 10792d9eb21325a0854e86de7344f54a8e6cef2a97adDouglas Gregor return Init->getType(); 10802d9eb21325a0854e86de7344f54a8e6cef2a97adDouglas Gregor} 10812d9eb21325a0854e86de7344f54a8e6cef2a97adDouglas Gregor 1082239a7c42df78abc7fd5611d806d5e199fec994d1Marcin Swiderski/// addAutomaticObjDtors - Add to current block automatic objects destructors 1083239a7c42df78abc7fd5611d806d5e199fec994d1Marcin Swiderski/// for objects in range of local scope positions. Use S as trigger statement 1084239a7c42df78abc7fd5611d806d5e199fec994d1Marcin Swiderski/// for destructors. 10856a16a306f6226030f8d38ae7e32082888fa937a1Zhongxing Xuvoid CFGBuilder::addAutomaticObjDtors(LocalScope::const_iterator B, 10869c378f705405d37f49795d5e915989de774fe11fTed Kremenek LocalScope::const_iterator E, Stmt *S) { 1087239a7c42df78abc7fd5611d806d5e199fec994d1Marcin Swiderski if (!BuildOpts.AddImplicitDtors) 10886a16a306f6226030f8d38ae7e32082888fa937a1Zhongxing Xu return; 10896a16a306f6226030f8d38ae7e32082888fa937a1Zhongxing Xu 1090239a7c42df78abc7fd5611d806d5e199fec994d1Marcin Swiderski if (B == E) 10916a16a306f6226030f8d38ae7e32082888fa937a1Zhongxing Xu return; 1092239a7c42df78abc7fd5611d806d5e199fec994d1Marcin Swiderski 1093c8cfc74bdcc999828bc232294d937fb191940d5bChandler Carruth // We need to append the destructors in reverse order, but any one of them 1094c8cfc74bdcc999828bc232294d937fb191940d5bChandler Carruth // may be a no-return destructor which changes the CFG. As a result, buffer 1095c8cfc74bdcc999828bc232294d937fb191940d5bChandler Carruth // this sequence up and replay them in reverse order when appending onto the 1096c8cfc74bdcc999828bc232294d937fb191940d5bChandler Carruth // CFGBlock(s). 1097c8cfc74bdcc999828bc232294d937fb191940d5bChandler Carruth SmallVector<VarDecl*, 10> Decls; 1098c8cfc74bdcc999828bc232294d937fb191940d5bChandler Carruth Decls.reserve(B.distance(E)); 1099c8cfc74bdcc999828bc232294d937fb191940d5bChandler Carruth for (LocalScope::const_iterator I = B; I != E; ++I) 1100c8cfc74bdcc999828bc232294d937fb191940d5bChandler Carruth Decls.push_back(*I); 1101c8cfc74bdcc999828bc232294d937fb191940d5bChandler Carruth 1102c8cfc74bdcc999828bc232294d937fb191940d5bChandler Carruth for (SmallVectorImpl<VarDecl*>::reverse_iterator I = Decls.rbegin(), 1103c8cfc74bdcc999828bc232294d937fb191940d5bChandler Carruth E = Decls.rend(); 1104c8cfc74bdcc999828bc232294d937fb191940d5bChandler Carruth I != E; ++I) { 1105c8cfc74bdcc999828bc232294d937fb191940d5bChandler Carruth // If this destructor is marked as a no-return destructor, we need to 1106c8cfc74bdcc999828bc232294d937fb191940d5bChandler Carruth // create a new block for the destructor which does not have as a successor 1107c8cfc74bdcc999828bc232294d937fb191940d5bChandler Carruth // anything built thus far: control won't flow out of this block. 110888237bf587581026dcfc8386abf055cb201aa487Ted Kremenek QualType Ty = (*I)->getType(); 110988237bf587581026dcfc8386abf055cb201aa487Ted Kremenek if (Ty->isReferenceType()) { 11102d9eb21325a0854e86de7344f54a8e6cef2a97adDouglas Gregor Ty = getReferenceInitTemporaryType(*Context, (*I)->getInit()); 11112d9eb21325a0854e86de7344f54a8e6cef2a97adDouglas Gregor } 111288237bf587581026dcfc8386abf055cb201aa487Ted Kremenek Ty = Context->getBaseElementType(Ty); 111388237bf587581026dcfc8386abf055cb201aa487Ted Kremenek 1114c8cfc74bdcc999828bc232294d937fb191940d5bChandler Carruth const CXXDestructorDecl *Dtor = Ty->getAsCXXRecordDecl()->getDestructor(); 1115cd8ab51a44e80625d84126780b0d85a7732e25afRichard Smith if (Dtor->isNoReturn()) 1116dba3fb5413437dc613734fa4ffac892b11a37d25Chandler Carruth Block = createNoReturnBlock(); 1117dba3fb5413437dc613734fa4ffac892b11a37d25Chandler Carruth else 1118c8cfc74bdcc999828bc232294d937fb191940d5bChandler Carruth autoCreateBlock(); 1119c8cfc74bdcc999828bc232294d937fb191940d5bChandler Carruth 1120c8cfc74bdcc999828bc232294d937fb191940d5bChandler Carruth appendAutomaticObjDtor(Block, *I, S); 1121c8cfc74bdcc999828bc232294d937fb191940d5bChandler Carruth } 1122239a7c42df78abc7fd5611d806d5e199fec994d1Marcin Swiderski} 1123239a7c42df78abc7fd5611d806d5e199fec994d1Marcin Swiderski 11247c625d8ffc20b92fff9e1690cd2484fcb6498183Marcin Swiderski/// addImplicitDtorsForDestructor - Add implicit destructors generated for 11257c625d8ffc20b92fff9e1690cd2484fcb6498183Marcin Swiderski/// base and member objects in destructor. 11267c625d8ffc20b92fff9e1690cd2484fcb6498183Marcin Swiderskivoid CFGBuilder::addImplicitDtorsForDestructor(const CXXDestructorDecl *DD) { 11277c625d8ffc20b92fff9e1690cd2484fcb6498183Marcin Swiderski assert (BuildOpts.AddImplicitDtors 11287c625d8ffc20b92fff9e1690cd2484fcb6498183Marcin Swiderski && "Can be called only when dtors should be added"); 11297c625d8ffc20b92fff9e1690cd2484fcb6498183Marcin Swiderski const CXXRecordDecl *RD = DD->getParent(); 11307c625d8ffc20b92fff9e1690cd2484fcb6498183Marcin Swiderski 11317c625d8ffc20b92fff9e1690cd2484fcb6498183Marcin Swiderski // At the end destroy virtual base objects. 1132651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines for (const auto &VI : RD->vbases()) { 1133651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines const CXXRecordDecl *CD = VI.getType()->getAsCXXRecordDecl(); 11347c625d8ffc20b92fff9e1690cd2484fcb6498183Marcin Swiderski if (!CD->hasTrivialDestructor()) { 11357c625d8ffc20b92fff9e1690cd2484fcb6498183Marcin Swiderski autoCreateBlock(); 1136651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines appendBaseDtor(Block, &VI); 11377c625d8ffc20b92fff9e1690cd2484fcb6498183Marcin Swiderski } 11387c625d8ffc20b92fff9e1690cd2484fcb6498183Marcin Swiderski } 11397c625d8ffc20b92fff9e1690cd2484fcb6498183Marcin Swiderski 11407c625d8ffc20b92fff9e1690cd2484fcb6498183Marcin Swiderski // Before virtual bases destroy direct base objects. 1141651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines for (const auto &BI : RD->bases()) { 1142651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (!BI.isVirtual()) { 1143651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines const CXXRecordDecl *CD = BI.getType()->getAsCXXRecordDecl(); 114423661d3e348c5f44ae89b6848bbc331829bb46f2David Blaikie if (!CD->hasTrivialDestructor()) { 114523661d3e348c5f44ae89b6848bbc331829bb46f2David Blaikie autoCreateBlock(); 1146651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines appendBaseDtor(Block, &BI); 114723661d3e348c5f44ae89b6848bbc331829bb46f2David Blaikie } 114823661d3e348c5f44ae89b6848bbc331829bb46f2David Blaikie } 11497c625d8ffc20b92fff9e1690cd2484fcb6498183Marcin Swiderski } 11507c625d8ffc20b92fff9e1690cd2484fcb6498183Marcin Swiderski 11517c625d8ffc20b92fff9e1690cd2484fcb6498183Marcin Swiderski // First destroy member objects. 1152651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines for (auto *FI : RD->fields()) { 11538c5e5d6d8a316af5a9842169f541cac49717887dMarcin Swiderski // Check for constant size array. Set type to array element type. 11548c5e5d6d8a316af5a9842169f541cac49717887dMarcin Swiderski QualType QT = FI->getType(); 11558c5e5d6d8a316af5a9842169f541cac49717887dMarcin Swiderski if (const ConstantArrayType *AT = Context->getAsConstantArrayType(QT)) { 11568c5e5d6d8a316af5a9842169f541cac49717887dMarcin Swiderski if (AT->getSize() == 0) 11578c5e5d6d8a316af5a9842169f541cac49717887dMarcin Swiderski continue; 11588c5e5d6d8a316af5a9842169f541cac49717887dMarcin Swiderski QT = AT->getElementType(); 11598c5e5d6d8a316af5a9842169f541cac49717887dMarcin Swiderski } 11608c5e5d6d8a316af5a9842169f541cac49717887dMarcin Swiderski 11618c5e5d6d8a316af5a9842169f541cac49717887dMarcin Swiderski if (const CXXRecordDecl *CD = QT->getAsCXXRecordDecl()) 11627c625d8ffc20b92fff9e1690cd2484fcb6498183Marcin Swiderski if (!CD->hasTrivialDestructor()) { 11637c625d8ffc20b92fff9e1690cd2484fcb6498183Marcin Swiderski autoCreateBlock(); 1164651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines appendMemberDtor(Block, FI); 11657c625d8ffc20b92fff9e1690cd2484fcb6498183Marcin Swiderski } 11667c625d8ffc20b92fff9e1690cd2484fcb6498183Marcin Swiderski } 11677c625d8ffc20b92fff9e1690cd2484fcb6498183Marcin Swiderski} 11687c625d8ffc20b92fff9e1690cd2484fcb6498183Marcin Swiderski 1169239a7c42df78abc7fd5611d806d5e199fec994d1Marcin Swiderski/// createOrReuseLocalScope - If Scope is NULL create new LocalScope. Either 1170239a7c42df78abc7fd5611d806d5e199fec994d1Marcin Swiderski/// way return valid LocalScope object. 1171239a7c42df78abc7fd5611d806d5e199fec994d1Marcin SwiderskiLocalScope* CFGBuilder::createOrReuseLocalScope(LocalScope* Scope) { 1172239a7c42df78abc7fd5611d806d5e199fec994d1Marcin Swiderski if (!Scope) { 1173fe59b7472c06b36efb74fbb50bbdf464fa30c0d8Ted Kremenek llvm::BumpPtrAllocator &alloc = cfg->getAllocator(); 1174fe59b7472c06b36efb74fbb50bbdf464fa30c0d8Ted Kremenek Scope = alloc.Allocate<LocalScope>(); 1175fe59b7472c06b36efb74fbb50bbdf464fa30c0d8Ted Kremenek BumpVectorContext ctx(alloc); 1176fe59b7472c06b36efb74fbb50bbdf464fa30c0d8Ted Kremenek new (Scope) LocalScope(ctx, ScopePos); 1177239a7c42df78abc7fd5611d806d5e199fec994d1Marcin Swiderski } 1178239a7c42df78abc7fd5611d806d5e199fec994d1Marcin Swiderski return Scope; 1179239a7c42df78abc7fd5611d806d5e199fec994d1Marcin Swiderski} 1180239a7c42df78abc7fd5611d806d5e199fec994d1Marcin Swiderski 1181239a7c42df78abc7fd5611d806d5e199fec994d1Marcin Swiderski/// addLocalScopeForStmt - Add LocalScope to local scopes tree for statement 118202acdfaeb3f3805b65e4707e5dff096209adb367Zhongxing Xu/// that should create implicit scope (e.g. if/else substatements). 11839c378f705405d37f49795d5e915989de774fe11fTed Kremenekvoid CFGBuilder::addLocalScopeForStmt(Stmt *S) { 1184239a7c42df78abc7fd5611d806d5e199fec994d1Marcin Swiderski if (!BuildOpts.AddImplicitDtors) 118502acdfaeb3f3805b65e4707e5dff096209adb367Zhongxing Xu return; 118602acdfaeb3f3805b65e4707e5dff096209adb367Zhongxing Xu 11876bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines LocalScope *Scope = nullptr; 1188239a7c42df78abc7fd5611d806d5e199fec994d1Marcin Swiderski 1189239a7c42df78abc7fd5611d806d5e199fec994d1Marcin Swiderski // For compound statement we will be creating explicit scope. 1190ad8dcf4a9df0e24051dc31bf9e6f3cd138a34298Chris Lattner if (CompoundStmt *CS = dyn_cast<CompoundStmt>(S)) { 1191651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines for (auto *BI : CS->body()) { 1192651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Stmt *SI = BI->stripLabelLikeStatements(); 1193ad8dcf4a9df0e24051dc31bf9e6f3cd138a34298Chris Lattner if (DeclStmt *DS = dyn_cast<DeclStmt>(SI)) 1194239a7c42df78abc7fd5611d806d5e199fec994d1Marcin Swiderski Scope = addLocalScopeForDeclStmt(DS, Scope); 1195239a7c42df78abc7fd5611d806d5e199fec994d1Marcin Swiderski } 119602acdfaeb3f3805b65e4707e5dff096209adb367Zhongxing Xu return; 1197239a7c42df78abc7fd5611d806d5e199fec994d1Marcin Swiderski } 1198239a7c42df78abc7fd5611d806d5e199fec994d1Marcin Swiderski 1199239a7c42df78abc7fd5611d806d5e199fec994d1Marcin Swiderski // For any other statement scope will be implicit and as such will be 1200239a7c42df78abc7fd5611d806d5e199fec994d1Marcin Swiderski // interesting only for DeclStmt. 1201a1364be341550d71dff27dd8de0c6872ba6c707eChandler Carruth if (DeclStmt *DS = dyn_cast<DeclStmt>(S->stripLabelLikeStatements())) 1202b6edff55db4ff240d56d33594d68a711e4b1e24aZhongxing Xu addLocalScopeForDeclStmt(DS); 1203239a7c42df78abc7fd5611d806d5e199fec994d1Marcin Swiderski} 1204239a7c42df78abc7fd5611d806d5e199fec994d1Marcin Swiderski 1205239a7c42df78abc7fd5611d806d5e199fec994d1Marcin Swiderski/// addLocalScopeForDeclStmt - Add LocalScope for declaration statement. Will 1206239a7c42df78abc7fd5611d806d5e199fec994d1Marcin Swiderski/// reuse Scope if not NULL. 12079c378f705405d37f49795d5e915989de774fe11fTed KremenekLocalScope* CFGBuilder::addLocalScopeForDeclStmt(DeclStmt *DS, 1208b6edff55db4ff240d56d33594d68a711e4b1e24aZhongxing Xu LocalScope* Scope) { 1209239a7c42df78abc7fd5611d806d5e199fec994d1Marcin Swiderski if (!BuildOpts.AddImplicitDtors) 1210239a7c42df78abc7fd5611d806d5e199fec994d1Marcin Swiderski return Scope; 1211239a7c42df78abc7fd5611d806d5e199fec994d1Marcin Swiderski 1212651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines for (auto *DI : DS->decls()) 1213651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (VarDecl *VD = dyn_cast<VarDecl>(DI)) 1214239a7c42df78abc7fd5611d806d5e199fec994d1Marcin Swiderski Scope = addLocalScopeForVarDecl(VD, Scope); 1215239a7c42df78abc7fd5611d806d5e199fec994d1Marcin Swiderski return Scope; 1216239a7c42df78abc7fd5611d806d5e199fec994d1Marcin Swiderski} 1217239a7c42df78abc7fd5611d806d5e199fec994d1Marcin Swiderski 1218239a7c42df78abc7fd5611d806d5e199fec994d1Marcin Swiderski/// addLocalScopeForVarDecl - Add LocalScope for variable declaration. It will 1219239a7c42df78abc7fd5611d806d5e199fec994d1Marcin Swiderski/// create add scope for automatic objects and temporary objects bound to 1220239a7c42df78abc7fd5611d806d5e199fec994d1Marcin Swiderski/// const reference. Will reuse Scope if not NULL. 12219c378f705405d37f49795d5e915989de774fe11fTed KremenekLocalScope* CFGBuilder::addLocalScopeForVarDecl(VarDecl *VD, 1222b6edff55db4ff240d56d33594d68a711e4b1e24aZhongxing Xu LocalScope* Scope) { 1223239a7c42df78abc7fd5611d806d5e199fec994d1Marcin Swiderski if (!BuildOpts.AddImplicitDtors) 1224239a7c42df78abc7fd5611d806d5e199fec994d1Marcin Swiderski return Scope; 1225239a7c42df78abc7fd5611d806d5e199fec994d1Marcin Swiderski 1226239a7c42df78abc7fd5611d806d5e199fec994d1Marcin Swiderski // Check if variable is local. 1227239a7c42df78abc7fd5611d806d5e199fec994d1Marcin Swiderski switch (VD->getStorageClass()) { 1228239a7c42df78abc7fd5611d806d5e199fec994d1Marcin Swiderski case SC_None: 1229239a7c42df78abc7fd5611d806d5e199fec994d1Marcin Swiderski case SC_Auto: 1230239a7c42df78abc7fd5611d806d5e199fec994d1Marcin Swiderski case SC_Register: 1231239a7c42df78abc7fd5611d806d5e199fec994d1Marcin Swiderski break; 1232239a7c42df78abc7fd5611d806d5e199fec994d1Marcin Swiderski default: return Scope; 1233239a7c42df78abc7fd5611d806d5e199fec994d1Marcin Swiderski } 1234239a7c42df78abc7fd5611d806d5e199fec994d1Marcin Swiderski 1235239a7c42df78abc7fd5611d806d5e199fec994d1Marcin Swiderski // Check for const references bound to temporary. Set type to pointee. 1236239a7c42df78abc7fd5611d806d5e199fec994d1Marcin Swiderski QualType QT = VD->getType(); 12372d9eb21325a0854e86de7344f54a8e6cef2a97adDouglas Gregor if (QT.getTypePtr()->isReferenceType()) { 123849bab4c0046e8300c79e79b7ca9a479696c7e87aRichard Smith // Attempt to determine whether this declaration lifetime-extends a 123949bab4c0046e8300c79e79b7ca9a479696c7e87aRichard Smith // temporary. 124049bab4c0046e8300c79e79b7ca9a479696c7e87aRichard Smith // 124149bab4c0046e8300c79e79b7ca9a479696c7e87aRichard Smith // FIXME: This is incorrect. Non-reference declarations can lifetime-extend 124249bab4c0046e8300c79e79b7ca9a479696c7e87aRichard Smith // temporaries, and a single declaration can extend multiple temporaries. 124349bab4c0046e8300c79e79b7ca9a479696c7e87aRichard Smith // We should look at the storage duration on each nested 124449bab4c0046e8300c79e79b7ca9a479696c7e87aRichard Smith // MaterializeTemporaryExpr instead. 124549bab4c0046e8300c79e79b7ca9a479696c7e87aRichard Smith const Expr *Init = VD->getInit(); 124649bab4c0046e8300c79e79b7ca9a479696c7e87aRichard Smith if (!Init) 124749bab4c0046e8300c79e79b7ca9a479696c7e87aRichard Smith return Scope; 124849bab4c0046e8300c79e79b7ca9a479696c7e87aRichard Smith if (const ExprWithCleanups *EWC = dyn_cast<ExprWithCleanups>(Init)) 124949bab4c0046e8300c79e79b7ca9a479696c7e87aRichard Smith Init = EWC->getSubExpr(); 125049bab4c0046e8300c79e79b7ca9a479696c7e87aRichard Smith if (!isa<MaterializeTemporaryExpr>(Init)) 1251239a7c42df78abc7fd5611d806d5e199fec994d1Marcin Swiderski return Scope; 12522d9eb21325a0854e86de7344f54a8e6cef2a97adDouglas Gregor 125349bab4c0046e8300c79e79b7ca9a479696c7e87aRichard Smith // Lifetime-extending a temporary. 125449bab4c0046e8300c79e79b7ca9a479696c7e87aRichard Smith QT = getReferenceInitTemporaryType(*Context, Init); 1255239a7c42df78abc7fd5611d806d5e199fec994d1Marcin Swiderski } 1256239a7c42df78abc7fd5611d806d5e199fec994d1Marcin Swiderski 1257b1c52870b8c2feaa7cd112295368bec53af490a0Marcin Swiderski // Check for constant size array. Set type to array element type. 12582d9eb21325a0854e86de7344f54a8e6cef2a97adDouglas Gregor while (const ConstantArrayType *AT = Context->getAsConstantArrayType(QT)) { 1259b1c52870b8c2feaa7cd112295368bec53af490a0Marcin Swiderski if (AT->getSize() == 0) 1260b1c52870b8c2feaa7cd112295368bec53af490a0Marcin Swiderski return Scope; 1261b1c52870b8c2feaa7cd112295368bec53af490a0Marcin Swiderski QT = AT->getElementType(); 1262b1c52870b8c2feaa7cd112295368bec53af490a0Marcin Swiderski } 12634e493e0dbac2aaac04c041f3d7dee9eccfb97689Zhongxing Xu 1264b1c52870b8c2feaa7cd112295368bec53af490a0Marcin Swiderski // Check if type is a C++ class with non-trivial destructor. 12659c378f705405d37f49795d5e915989de774fe11fTed Kremenek if (const CXXRecordDecl *CD = QT->getAsCXXRecordDecl()) 126623661d3e348c5f44ae89b6848bbc331829bb46f2David Blaikie if (!CD->hasTrivialDestructor()) { 12674e493e0dbac2aaac04c041f3d7dee9eccfb97689Zhongxing Xu // Add the variable to scope 12684e493e0dbac2aaac04c041f3d7dee9eccfb97689Zhongxing Xu Scope = createOrReuseLocalScope(Scope); 12694e493e0dbac2aaac04c041f3d7dee9eccfb97689Zhongxing Xu Scope->addVar(VD); 12704e493e0dbac2aaac04c041f3d7dee9eccfb97689Zhongxing Xu ScopePos = Scope->begin(); 12714e493e0dbac2aaac04c041f3d7dee9eccfb97689Zhongxing Xu } 1272239a7c42df78abc7fd5611d806d5e199fec994d1Marcin Swiderski return Scope; 1273239a7c42df78abc7fd5611d806d5e199fec994d1Marcin Swiderski} 1274239a7c42df78abc7fd5611d806d5e199fec994d1Marcin Swiderski 1275239a7c42df78abc7fd5611d806d5e199fec994d1Marcin Swiderski/// addLocalScopeAndDtors - For given statement add local scope for it and 1276239a7c42df78abc7fd5611d806d5e199fec994d1Marcin Swiderski/// add destructors that will cleanup the scope. Will reuse Scope if not NULL. 12779c378f705405d37f49795d5e915989de774fe11fTed Kremenekvoid CFGBuilder::addLocalScopeAndDtors(Stmt *S) { 1278239a7c42df78abc7fd5611d806d5e199fec994d1Marcin Swiderski if (!BuildOpts.AddImplicitDtors) 1279239a7c42df78abc7fd5611d806d5e199fec994d1Marcin Swiderski return; 1280239a7c42df78abc7fd5611d806d5e199fec994d1Marcin Swiderski 1281239a7c42df78abc7fd5611d806d5e199fec994d1Marcin Swiderski LocalScope::const_iterator scopeBeginPos = ScopePos; 128202acdfaeb3f3805b65e4707e5dff096209adb367Zhongxing Xu addLocalScopeForStmt(S); 1283239a7c42df78abc7fd5611d806d5e199fec994d1Marcin Swiderski addAutomaticObjDtors(ScopePos, scopeBeginPos, S); 1284239a7c42df78abc7fd5611d806d5e199fec994d1Marcin Swiderski} 1285239a7c42df78abc7fd5611d806d5e199fec994d1Marcin Swiderski 128653de134e7b4686eed40bc031438d8a4560a2cda4Marcin Swiderski/// prependAutomaticObjDtorsWithTerminator - Prepend destructor CFGElements for 128753de134e7b4686eed40bc031438d8a4560a2cda4Marcin Swiderski/// variables with automatic storage duration to CFGBlock's elements vector. 128853de134e7b4686eed40bc031438d8a4560a2cda4Marcin Swiderski/// Elements will be prepended to physical beginning of the vector which 128953de134e7b4686eed40bc031438d8a4560a2cda4Marcin Swiderski/// happens to be logical end. Use blocks terminator as statement that specifies 129053de134e7b4686eed40bc031438d8a4560a2cda4Marcin Swiderski/// destructors call site. 1291c8cfc74bdcc999828bc232294d937fb191940d5bChandler Carruth/// FIXME: This mechanism for adding automatic destructors doesn't handle 1292c8cfc74bdcc999828bc232294d937fb191940d5bChandler Carruth/// no-return destructors properly. 12939c378f705405d37f49795d5e915989de774fe11fTed Kremenekvoid CFGBuilder::prependAutomaticObjDtorsWithTerminator(CFGBlock *Blk, 129453de134e7b4686eed40bc031438d8a4560a2cda4Marcin Swiderski LocalScope::const_iterator B, LocalScope::const_iterator E) { 1295c8cfc74bdcc999828bc232294d937fb191940d5bChandler Carruth BumpVectorContext &C = cfg->getBumpVectorContext(); 1296c8cfc74bdcc999828bc232294d937fb191940d5bChandler Carruth CFGBlock::iterator InsertPos 1297c8cfc74bdcc999828bc232294d937fb191940d5bChandler Carruth = Blk->beginAutomaticObjDtorsInsert(Blk->end(), B.distance(E), C); 1298c8cfc74bdcc999828bc232294d937fb191940d5bChandler Carruth for (LocalScope::const_iterator I = B; I != E; ++I) 1299c8cfc74bdcc999828bc232294d937fb191940d5bChandler Carruth InsertPos = Blk->insertAutomaticObjDtor(InsertPos, *I, 1300c8cfc74bdcc999828bc232294d937fb191940d5bChandler Carruth Blk->getTerminator()); 130153de134e7b4686eed40bc031438d8a4560a2cda4Marcin Swiderski} 130253de134e7b4686eed40bc031438d8a4560a2cda4Marcin Swiderski 13034f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek/// Visit - Walk the subtree of a statement and add extra 13046d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump/// blocks for ternary operators, &&, and ||. We also process "," and 13056d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump/// DeclStmts (which may contain nested control-flow). 13069c378f705405d37f49795d5e915989de774fe11fTed KremenekCFGBlock *CFGBuilder::Visit(Stmt * S, AddStmtChoice asc) { 1307f42e3371079de333c3822a060c008bf6680677c8Ted Kremenek if (!S) { 1308f42e3371079de333c3822a060c008bf6680677c8Ted Kremenek badCFG = true; 13096bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return nullptr; 1310f42e3371079de333c3822a060c008bf6680677c8Ted Kremenek } 1311ac73ea8c12772fd0dcec71b83c193a2837de7f8bJordy Rose 1312ac73ea8c12772fd0dcec71b83c193a2837de7f8bJordy Rose if (Expr *E = dyn_cast<Expr>(S)) 1313ac73ea8c12772fd0dcec71b83c193a2837de7f8bJordy Rose S = E->IgnoreParens(); 1314ac73ea8c12772fd0dcec71b83c193a2837de7f8bJordy Rose 13154f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek switch (S->getStmtClass()) { 13164f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek default: 1317852274d4257134906995cb252fb3dfd2d71deae8Ted Kremenek return VisitStmt(S, asc); 13184f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek 13194f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek case Stmt::AddrLabelExprClass: 1320852274d4257134906995cb252fb3dfd2d71deae8Ted Kremenek return VisitAddrLabelExpr(cast<AddrLabelExpr>(S), asc); 13211eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 132256ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall case Stmt::BinaryConditionalOperatorClass: 132356ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall return VisitConditionalOperator(cast<BinaryConditionalOperator>(S), asc); 132456ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall 13254f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek case Stmt::BinaryOperatorClass: 1326852274d4257134906995cb252fb3dfd2d71deae8Ted Kremenek return VisitBinaryOperator(cast<BinaryOperator>(S), asc); 13271eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 13284f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek case Stmt::BlockExprClass: 132955331da3211151aa67277aa095b7d301342200d4Ted Kremenek return VisitNoRecurse(cast<Expr>(S), asc); 13304f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek 13314f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek case Stmt::BreakStmtClass: 13324f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek return VisitBreakStmt(cast<BreakStmt>(S)); 13331eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 13344f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek case Stmt::CallExprClass: 1335a427f1d8f0848997029d1bdc0c5c137f982f775dTed Kremenek case Stmt::CXXOperatorCallExprClass: 13361de85338543dd6228eb518185e385d94d377f4cbJohn McCall case Stmt::CXXMemberCallExprClass: 13379fcce65e7e1307b5b8da9be13e4092d6bb94dc1dRichard Smith case Stmt::UserDefinedLiteralClass: 1338852274d4257134906995cb252fb3dfd2d71deae8Ted Kremenek return VisitCallExpr(cast<CallExpr>(S), asc); 13391eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 13404f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek case Stmt::CaseStmtClass: 13414f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek return VisitCaseStmt(cast<CaseStmt>(S)); 13424f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek 13434f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek case Stmt::ChooseExprClass: 1344852274d4257134906995cb252fb3dfd2d71deae8Ted Kremenek return VisitChooseExpr(cast<ChooseExpr>(S), asc); 13451eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 13464f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek case Stmt::CompoundStmtClass: 13474f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek return VisitCompoundStmt(cast<CompoundStmt>(S)); 13481eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 13494f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek case Stmt::ConditionalOperatorClass: 1350852274d4257134906995cb252fb3dfd2d71deae8Ted Kremenek return VisitConditionalOperator(cast<ConditionalOperator>(S), asc); 13511eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 13524f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek case Stmt::ContinueStmtClass: 13534f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek return VisitContinueStmt(cast<ContinueStmt>(S)); 13541eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1355021c8afbab95c71fbdd95c0b5cea36fd316281f9Ted Kremenek case Stmt::CXXCatchStmtClass: 1356021c8afbab95c71fbdd95c0b5cea36fd316281f9Ted Kremenek return VisitCXXCatchStmt(cast<CXXCatchStmt>(S)); 1357021c8afbab95c71fbdd95c0b5cea36fd316281f9Ted Kremenek 13584765fa05b5652fcc4356371c2f481d0ea9a1b007John McCall case Stmt::ExprWithCleanupsClass: 13594765fa05b5652fcc4356371c2f481d0ea9a1b007John McCall return VisitExprWithCleanups(cast<ExprWithCleanups>(S), asc); 136047e331ed28c2536bec227c5e2fa094ab3d46eed1Ted Kremenek 1361b66529d04727dc686b97ea3d937fc9785792f505Jordan Rose case Stmt::CXXDefaultArgExprClass: 1362c3bf52ced9652f555aa0767bb822ec4c64546212Richard Smith case Stmt::CXXDefaultInitExprClass: 1363b66529d04727dc686b97ea3d937fc9785792f505Jordan Rose // FIXME: The expression inside a CXXDefaultArgExpr is owned by the 1364b66529d04727dc686b97ea3d937fc9785792f505Jordan Rose // called function's declaration, not by the caller. If we simply add 1365b66529d04727dc686b97ea3d937fc9785792f505Jordan Rose // this expression to the CFG, we could end up with the same Expr 1366b66529d04727dc686b97ea3d937fc9785792f505Jordan Rose // appearing multiple times. 1367b66529d04727dc686b97ea3d937fc9785792f505Jordan Rose // PR13385 / <rdar://problem/12156507> 1368c3bf52ced9652f555aa0767bb822ec4c64546212Richard Smith // 1369c3bf52ced9652f555aa0767bb822ec4c64546212Richard Smith // It's likewise possible for multiple CXXDefaultInitExprs for the same 1370c3bf52ced9652f555aa0767bb822ec4c64546212Richard Smith // expression to be used in the same function (through aggregate 1371c3bf52ced9652f555aa0767bb822ec4c64546212Richard Smith // initialization). 1372b66529d04727dc686b97ea3d937fc9785792f505Jordan Rose return VisitStmt(S, asc); 1373b66529d04727dc686b97ea3d937fc9785792f505Jordan Rose 1374a725ed468585b881c43654eeb56b28554a84808aZhongxing Xu case Stmt::CXXBindTemporaryExprClass: 1375a725ed468585b881c43654eeb56b28554a84808aZhongxing Xu return VisitCXXBindTemporaryExpr(cast<CXXBindTemporaryExpr>(S), asc); 1376a725ed468585b881c43654eeb56b28554a84808aZhongxing Xu 137781bc7d07b701042371a5723b6f394cd2482ed7beZhongxing Xu case Stmt::CXXConstructExprClass: 137881bc7d07b701042371a5723b6f394cd2482ed7beZhongxing Xu return VisitCXXConstructExpr(cast<CXXConstructExpr>(S), asc); 137981bc7d07b701042371a5723b6f394cd2482ed7beZhongxing Xu 1380651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines case Stmt::CXXNewExprClass: 1381651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return VisitCXXNewExpr(cast<CXXNewExpr>(S), asc); 1382651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 138336d558d85653315edb389677e995ec9ccdbfbf3dJordan Rose case Stmt::CXXDeleteExprClass: 138436d558d85653315edb389677e995ec9ccdbfbf3dJordan Rose return VisitCXXDeleteExpr(cast<CXXDeleteExpr>(S), asc); 138536d558d85653315edb389677e995ec9ccdbfbf3dJordan Rose 1386a725ed468585b881c43654eeb56b28554a84808aZhongxing Xu case Stmt::CXXFunctionalCastExprClass: 1387a725ed468585b881c43654eeb56b28554a84808aZhongxing Xu return VisitCXXFunctionalCastExpr(cast<CXXFunctionalCastExpr>(S), asc); 1388a725ed468585b881c43654eeb56b28554a84808aZhongxing Xu 138981bc7d07b701042371a5723b6f394cd2482ed7beZhongxing Xu case Stmt::CXXTemporaryObjectExprClass: 139081bc7d07b701042371a5723b6f394cd2482ed7beZhongxing Xu return VisitCXXTemporaryObjectExpr(cast<CXXTemporaryObjectExpr>(S), asc); 139181bc7d07b701042371a5723b6f394cd2482ed7beZhongxing Xu 1392021c8afbab95c71fbdd95c0b5cea36fd316281f9Ted Kremenek case Stmt::CXXThrowExprClass: 1393021c8afbab95c71fbdd95c0b5cea36fd316281f9Ted Kremenek return VisitCXXThrowExpr(cast<CXXThrowExpr>(S)); 1394ad5a894df1841698c824381b414630799adc26caTed Kremenek 1395021c8afbab95c71fbdd95c0b5cea36fd316281f9Ted Kremenek case Stmt::CXXTryStmtClass: 1396021c8afbab95c71fbdd95c0b5cea36fd316281f9Ted Kremenek return VisitCXXTryStmt(cast<CXXTryStmt>(S)); 1397ad5a894df1841698c824381b414630799adc26caTed Kremenek 1398ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith case Stmt::CXXForRangeStmtClass: 1399ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith return VisitCXXForRangeStmt(cast<CXXForRangeStmt>(S)); 1400ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith 14014f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek case Stmt::DeclStmtClass: 14024f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek return VisitDeclStmt(cast<DeclStmt>(S)); 14031eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 14044f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek case Stmt::DefaultStmtClass: 14054f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek return VisitDefaultStmt(cast<DefaultStmt>(S)); 14061eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 14074f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek case Stmt::DoStmtClass: 14084f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek return VisitDoStmt(cast<DoStmt>(S)); 14091eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 14104f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek case Stmt::ForStmtClass: 14114f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek return VisitForStmt(cast<ForStmt>(S)); 14121eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 14134f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek case Stmt::GotoStmtClass: 14144f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek return VisitGotoStmt(cast<GotoStmt>(S)); 14151eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 14164f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek case Stmt::IfStmtClass: 14174f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek return VisitIfStmt(cast<IfStmt>(S)); 14181eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1419892697dd2287caf7c29aaaa82909b0e90b8b63feTed Kremenek case Stmt::ImplicitCastExprClass: 1420892697dd2287caf7c29aaaa82909b0e90b8b63feTed Kremenek return VisitImplicitCastExpr(cast<ImplicitCastExpr>(S), asc); 1421a725ed468585b881c43654eeb56b28554a84808aZhongxing Xu 14224f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek case Stmt::IndirectGotoStmtClass: 14234f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek return VisitIndirectGotoStmt(cast<IndirectGotoStmt>(S)); 14241eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 14254f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek case Stmt::LabelStmtClass: 14264f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek return VisitLabelStmt(cast<LabelStmt>(S)); 14271eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 142883748e2f41ea0ac7c954946feb5da9ccc6ab8becTed Kremenek case Stmt::LambdaExprClass: 142983748e2f41ea0ac7c954946feb5da9ccc6ab8becTed Kremenek return VisitLambdaExpr(cast<LambdaExpr>(S), asc); 143083748e2f41ea0ac7c954946feb5da9ccc6ab8becTed Kremenek 1431115c1b9cc758d15f38e1d2ad4cf07b1cacfb3115Ted Kremenek case Stmt::MemberExprClass: 1432115c1b9cc758d15f38e1d2ad4cf07b1cacfb3115Ted Kremenek return VisitMemberExpr(cast<MemberExpr>(S), asc); 1433115c1b9cc758d15f38e1d2ad4cf07b1cacfb3115Ted Kremenek 14346a9065a39ab15383082b914af28759da1652db18Ted Kremenek case Stmt::NullStmtClass: 14356a9065a39ab15383082b914af28759da1652db18Ted Kremenek return Block; 14366a9065a39ab15383082b914af28759da1652db18Ted Kremenek 14374f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek case Stmt::ObjCAtCatchStmtClass: 14381eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump return VisitObjCAtCatchStmt(cast<ObjCAtCatchStmt>(S)); 14391eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 14408e282c332f8ad51dedf86a185a4dcb78ef93fb51Ted Kremenek case Stmt::ObjCAutoreleasePoolStmtClass: 14418e282c332f8ad51dedf86a185a4dcb78ef93fb51Ted Kremenek return VisitObjCAutoreleasePoolStmt(cast<ObjCAutoreleasePoolStmt>(S)); 14428e282c332f8ad51dedf86a185a4dcb78ef93fb51Ted Kremenek 14434f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek case Stmt::ObjCAtSynchronizedStmtClass: 14444f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek return VisitObjCAtSynchronizedStmt(cast<ObjCAtSynchronizedStmt>(S)); 14451eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 14464f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek case Stmt::ObjCAtThrowStmtClass: 14474f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek return VisitObjCAtThrowStmt(cast<ObjCAtThrowStmt>(S)); 14481eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 14494f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek case Stmt::ObjCAtTryStmtClass: 14504f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek return VisitObjCAtTryStmt(cast<ObjCAtTryStmt>(S)); 14511eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 14524f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek case Stmt::ObjCForCollectionStmtClass: 14534f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek return VisitObjCForCollectionStmt(cast<ObjCForCollectionStmt>(S)); 14541eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 14556a9065a39ab15383082b914af28759da1652db18Ted Kremenek case Stmt::OpaqueValueExprClass: 14564f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek return Block; 14571eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 14584b9c2d235fb9449e249d74f48ecfec601650de93John McCall case Stmt::PseudoObjectExprClass: 14594b9c2d235fb9449e249d74f48ecfec601650de93John McCall return VisitPseudoObjectExpr(cast<PseudoObjectExpr>(S)); 14604b9c2d235fb9449e249d74f48ecfec601650de93John McCall 14614f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek case Stmt::ReturnStmtClass: 14624f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek return VisitReturnStmt(cast<ReturnStmt>(S)); 14631eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1464f4e3cfbe8abd124be6341ef5d714819b4fbd9082Peter Collingbourne case Stmt::UnaryExprOrTypeTraitExprClass: 1465f4e3cfbe8abd124be6341ef5d714819b4fbd9082Peter Collingbourne return VisitUnaryExprOrTypeTraitExpr(cast<UnaryExprOrTypeTraitExpr>(S), 1466f4e3cfbe8abd124be6341ef5d714819b4fbd9082Peter Collingbourne asc); 14671eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 14684f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek case Stmt::StmtExprClass: 1469852274d4257134906995cb252fb3dfd2d71deae8Ted Kremenek return VisitStmtExpr(cast<StmtExpr>(S), asc); 14701eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 14714f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek case Stmt::SwitchStmtClass: 14724f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek return VisitSwitchStmt(cast<SwitchStmt>(S)); 14731eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 147499cae5b67b9711ca260e5b364a878a1a91183632Zhanyong Wan case Stmt::UnaryOperatorClass: 147599cae5b67b9711ca260e5b364a878a1a91183632Zhanyong Wan return VisitUnaryOperator(cast<UnaryOperator>(S), asc); 147699cae5b67b9711ca260e5b364a878a1a91183632Zhanyong Wan 14774f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek case Stmt::WhileStmtClass: 14784f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek return VisitWhileStmt(cast<WhileStmt>(S)); 14794f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek } 14804f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek} 14811eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1482852274d4257134906995cb252fb3dfd2d71deae8Ted KremenekCFGBlock *CFGBuilder::VisitStmt(Stmt *S, AddStmtChoice asc) { 14833179a45a0e91c1dcf3492222170cf4499531bb92Ted Kremenek if (asc.alwaysAdd(*this, S)) { 14844f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek autoCreateBlock(); 1485247e9665d897a7bbbf60c1c0d3b6609c4504a961Ted Kremenek appendStmt(Block, S); 14866d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump } 14871eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 14884f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek return VisitChildren(S); 14894f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek} 14906d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 14914f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek/// VisitChildren - Visit the children of a Stmt. 14925846720f08a6b225484bfe663599c2b057a99bc8Ted KremenekCFGBlock *CFGBuilder::VisitChildren(Stmt *S) { 14935846720f08a6b225484bfe663599c2b057a99bc8Ted Kremenek CFGBlock *B = Block; 14946b12da9f89b7863e6fc995312355b94197b75657Ted Kremenek 14955846720f08a6b225484bfe663599c2b057a99bc8Ted Kremenek // Visit the children in their reverse order so that they appear in 14965846720f08a6b225484bfe663599c2b057a99bc8Ted Kremenek // left-to-right (natural) order in the CFG. 14975846720f08a6b225484bfe663599c2b057a99bc8Ted Kremenek reverse_children RChildren(S); 14985846720f08a6b225484bfe663599c2b057a99bc8Ted Kremenek for (reverse_children::iterator I = RChildren.begin(), E = RChildren.end(); 14995846720f08a6b225484bfe663599c2b057a99bc8Ted Kremenek I != E; ++I) { 15005846720f08a6b225484bfe663599c2b057a99bc8Ted Kremenek if (Stmt *Child = *I) 15015846720f08a6b225484bfe663599c2b057a99bc8Ted Kremenek if (CFGBlock *R = Visit(Child)) 15025846720f08a6b225484bfe663599c2b057a99bc8Ted Kremenek B = R; 15035846720f08a6b225484bfe663599c2b057a99bc8Ted Kremenek } 15045846720f08a6b225484bfe663599c2b057a99bc8Ted Kremenek return B; 15054f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek} 15061eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1507852274d4257134906995cb252fb3dfd2d71deae8Ted KremenekCFGBlock *CFGBuilder::VisitAddrLabelExpr(AddrLabelExpr *A, 1508852274d4257134906995cb252fb3dfd2d71deae8Ted Kremenek AddStmtChoice asc) { 15094f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek AddressTakenLabels.insert(A->getLabel()); 15106d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 15113179a45a0e91c1dcf3492222170cf4499531bb92Ted Kremenek if (asc.alwaysAdd(*this, A)) { 15124f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek autoCreateBlock(); 1513247e9665d897a7bbbf60c1c0d3b6609c4504a961Ted Kremenek appendStmt(Block, A); 15146d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump } 15156d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 15164f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek return Block; 15174f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek} 15181eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 151999cae5b67b9711ca260e5b364a878a1a91183632Zhanyong WanCFGBlock *CFGBuilder::VisitUnaryOperator(UnaryOperator *U, 1520892697dd2287caf7c29aaaa82909b0e90b8b63feTed Kremenek AddStmtChoice asc) { 15213179a45a0e91c1dcf3492222170cf4499531bb92Ted Kremenek if (asc.alwaysAdd(*this, U)) { 152299cae5b67b9711ca260e5b364a878a1a91183632Zhanyong Wan autoCreateBlock(); 1523247e9665d897a7bbbf60c1c0d3b6609c4504a961Ted Kremenek appendStmt(Block, U); 152499cae5b67b9711ca260e5b364a878a1a91183632Zhanyong Wan } 152599cae5b67b9711ca260e5b364a878a1a91183632Zhanyong Wan 1526892697dd2287caf7c29aaaa82909b0e90b8b63feTed Kremenek return Visit(U->getSubExpr(), AddStmtChoice()); 152799cae5b67b9711ca260e5b364a878a1a91183632Zhanyong Wan} 152899cae5b67b9711ca260e5b364a878a1a91183632Zhanyong Wan 15295c3ea5c57971317c35b120ef0a2a2c79bd171008Ted KremenekCFGBlock *CFGBuilder::VisitLogicalOperator(BinaryOperator *B) { 15305c3ea5c57971317c35b120ef0a2a2c79bd171008Ted Kremenek CFGBlock *ConfluenceBlock = Block ? Block : createBlock(); 15315c3ea5c57971317c35b120ef0a2a2c79bd171008Ted Kremenek appendStmt(ConfluenceBlock, B); 15321eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 15335c3ea5c57971317c35b120ef0a2a2c79bd171008Ted Kremenek if (badCFG) 15346bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return nullptr; 15351eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 15366bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return VisitLogicalOperator(B, nullptr, ConfluenceBlock, 15376bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines ConfluenceBlock).first; 15383f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek} 1539862b24f8e9b1a3b332399591e48b303f57f01d0aTed Kremenek 15403f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenekstd::pair<CFGBlock*, CFGBlock*> 15413f635c08b2d0b2d5bafb38da09589cb238407faaTed KremenekCFGBuilder::VisitLogicalOperator(BinaryOperator *B, 15423f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek Stmt *Term, 15433f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek CFGBlock *TrueBlock, 15443f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek CFGBlock *FalseBlock) { 15453f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek 15463f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek // Introspect the RHS. If it is a nested logical operation, we recursively 15473f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek // build the CFG using this function. Otherwise, resort to default 15483f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek // CFG construction behavior. 15493f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek Expr *RHS = B->getRHS()->IgnoreParens(); 15503f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek CFGBlock *RHSBlock, *ExitBlock; 15513f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek 15523f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek do { 15533f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek if (BinaryOperator *B_RHS = dyn_cast<BinaryOperator>(RHS)) 15543f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek if (B_RHS->isLogicalOp()) { 1555651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines std::tie(RHSBlock, ExitBlock) = 15563f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek VisitLogicalOperator(B_RHS, Term, TrueBlock, FalseBlock); 15573f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek break; 15583f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek } 15591eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 15603f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek // The RHS is not a nested logical operation. Don't push the terminator 15613f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek // down further, but instead visit RHS and construct the respective 15623f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek // pieces of the CFG, and link up the RHSBlock with the terminator 15633f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek // we have been provided. 15643f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek ExitBlock = RHSBlock = createBlock(false); 15653f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek 15663f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek if (!Term) { 15673f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek assert(TrueBlock == FalseBlock); 15683f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek addSuccessor(RHSBlock, TrueBlock); 15693f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek } 15703f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek else { 15713f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek RHSBlock->setTerminator(Term); 15723f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek TryResult KnownVal = tryEvaluateBool(RHS); 15736bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (!KnownVal.isKnown()) 15746bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines KnownVal = tryEvaluateBool(B); 1575651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines addSuccessor(RHSBlock, TrueBlock, !KnownVal.isFalse()); 1576651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines addSuccessor(RHSBlock, FalseBlock, !KnownVal.isTrue()); 15773f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek } 15783f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek 15793f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek Block = RHSBlock; 15803f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek RHSBlock = addStmt(RHS); 15815c3ea5c57971317c35b120ef0a2a2c79bd171008Ted Kremenek } 15823f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek while (false); 15833f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek 15843f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek if (badCFG) 15856bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return std::make_pair(nullptr, nullptr); 15868c6d360636dee25f1ce071c3656810c6632cb89dArgyrios Kyrtzidis 15875c3ea5c57971317c35b120ef0a2a2c79bd171008Ted Kremenek // Generate the blocks for evaluating the LHS. 15883f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek Expr *LHS = B->getLHS()->IgnoreParens(); 15893f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek 15903f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek if (BinaryOperator *B_LHS = dyn_cast<BinaryOperator>(LHS)) 15913f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek if (B_LHS->isLogicalOp()) { 15923f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek if (B->getOpcode() == BO_LOr) 15933f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek FalseBlock = RHSBlock; 15943f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek else 15953f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek TrueBlock = RHSBlock; 15963f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek 15973f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek // For the LHS, treat 'B' as the terminator that we want to sink 15983f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek // into the nested branch. The RHS always gets the top-most 15993f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek // terminator. 16003f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek return VisitLogicalOperator(B_LHS, B, TrueBlock, FalseBlock); 16013f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek } 16023f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek 16033f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek // Create the block evaluating the LHS. 16043f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek // This contains the '&&' or '||' as the terminator. 16053f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek CFGBlock *LHSBlock = createBlock(false); 16063f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek LHSBlock->setTerminator(B); 16073f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek 16085c3ea5c57971317c35b120ef0a2a2c79bd171008Ted Kremenek Block = LHSBlock; 16093f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek CFGBlock *EntryLHSBlock = addStmt(LHS); 16103f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek 16113f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek if (badCFG) 16126bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return std::make_pair(nullptr, nullptr); 16135c3ea5c57971317c35b120ef0a2a2c79bd171008Ted Kremenek 16145c3ea5c57971317c35b120ef0a2a2c79bd171008Ted Kremenek // See if this is a known constant. 16153f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek TryResult KnownVal = tryEvaluateBool(LHS); 16165c3ea5c57971317c35b120ef0a2a2c79bd171008Ted Kremenek 16175c3ea5c57971317c35b120ef0a2a2c79bd171008Ted Kremenek // Now link the LHSBlock with RHSBlock. 16185c3ea5c57971317c35b120ef0a2a2c79bd171008Ted Kremenek if (B->getOpcode() == BO_LOr) { 1619651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines addSuccessor(LHSBlock, TrueBlock, !KnownVal.isFalse()); 1620651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines addSuccessor(LHSBlock, RHSBlock, !KnownVal.isTrue()); 16215c3ea5c57971317c35b120ef0a2a2c79bd171008Ted Kremenek } else { 16225c3ea5c57971317c35b120ef0a2a2c79bd171008Ted Kremenek assert(B->getOpcode() == BO_LAnd); 1623651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines addSuccessor(LHSBlock, RHSBlock, !KnownVal.isFalse()); 1624651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines addSuccessor(LHSBlock, FalseBlock, !KnownVal.isTrue()); 16255c3ea5c57971317c35b120ef0a2a2c79bd171008Ted Kremenek } 162600998a068e50945118f334c98af05ed44d7c22a6Mike Stump 16273f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek return std::make_pair(EntryLHSBlock, ExitBlock); 16285c3ea5c57971317c35b120ef0a2a2c79bd171008Ted Kremenek} 16291eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 16303f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek 16315c3ea5c57971317c35b120ef0a2a2c79bd171008Ted KremenekCFGBlock *CFGBuilder::VisitBinaryOperator(BinaryOperator *B, 16325c3ea5c57971317c35b120ef0a2a2c79bd171008Ted Kremenek AddStmtChoice asc) { 16335c3ea5c57971317c35b120ef0a2a2c79bd171008Ted Kremenek // && or || 16345c3ea5c57971317c35b120ef0a2a2c79bd171008Ted Kremenek if (B->isLogicalOp()) 16355c3ea5c57971317c35b120ef0a2a2c79bd171008Ted Kremenek return VisitLogicalOperator(B); 163636f327c309b1fb6b82f1987190f0be74000b14c1Zhanyong Wan 163736f327c309b1fb6b82f1987190f0be74000b14c1Zhanyong Wan if (B->getOpcode() == BO_Comma) { // , 16386dc534ecc19a045ebcfe93eefa45da509968e888Ted Kremenek autoCreateBlock(); 1639247e9665d897a7bbbf60c1c0d3b6609c4504a961Ted Kremenek appendStmt(Block, B); 16404f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek addStmt(B->getRHS()); 16414f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek return addStmt(B->getLHS()); 16426d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump } 164336f327c309b1fb6b82f1987190f0be74000b14c1Zhanyong Wan 164436f327c309b1fb6b82f1987190f0be74000b14c1Zhanyong Wan if (B->isAssignmentOp()) { 16453179a45a0e91c1dcf3492222170cf4499531bb92Ted Kremenek if (asc.alwaysAdd(*this, B)) { 1646fc61d94fbdbcd2b423976e21f24d423fcd442486Zhongxing Xu autoCreateBlock(); 1647247e9665d897a7bbbf60c1c0d3b6609c4504a961Ted Kremenek appendStmt(Block, B); 1648fc61d94fbdbcd2b423976e21f24d423fcd442486Zhongxing Xu } 1649892697dd2287caf7c29aaaa82909b0e90b8b63feTed Kremenek Visit(B->getLHS()); 1650e1667190dff025936a21e5eb43889ac93b570468Marcin Swiderski return Visit(B->getRHS()); 1651fc61d94fbdbcd2b423976e21f24d423fcd442486Zhongxing Xu } 16521eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 16533179a45a0e91c1dcf3492222170cf4499531bb92Ted Kremenek if (asc.alwaysAdd(*this, B)) { 1654e1667190dff025936a21e5eb43889ac93b570468Marcin Swiderski autoCreateBlock(); 1655247e9665d897a7bbbf60c1c0d3b6609c4504a961Ted Kremenek appendStmt(Block, B); 1656e1667190dff025936a21e5eb43889ac93b570468Marcin Swiderski } 1657e1667190dff025936a21e5eb43889ac93b570468Marcin Swiderski 1658a1898ddd5d0e46330898930b9185b628b5cede63Zhongxing Xu CFGBlock *RBlock = Visit(B->getRHS()); 1659a1898ddd5d0e46330898930b9185b628b5cede63Zhongxing Xu CFGBlock *LBlock = Visit(B->getLHS()); 1660a1898ddd5d0e46330898930b9185b628b5cede63Zhongxing Xu // If visiting RHS causes us to finish 'Block', e.g. the RHS is a StmtExpr 1661a1898ddd5d0e46330898930b9185b628b5cede63Zhongxing Xu // containing a DoStmt, and the LHS doesn't create a new block, then we should 1662a1898ddd5d0e46330898930b9185b628b5cede63Zhongxing Xu // return RBlock. Otherwise we'll incorrectly return NULL. 1663a1898ddd5d0e46330898930b9185b628b5cede63Zhongxing Xu return (LBlock ? LBlock : RBlock); 16644f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek} 16656d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 166655331da3211151aa67277aa095b7d301342200d4Ted KremenekCFGBlock *CFGBuilder::VisitNoRecurse(Expr *E, AddStmtChoice asc) { 16673179a45a0e91c1dcf3492222170cf4499531bb92Ted Kremenek if (asc.alwaysAdd(*this, E)) { 1668721903eca33f6115296083aed17685eaa73d3e8cTed Kremenek autoCreateBlock(); 1669247e9665d897a7bbbf60c1c0d3b6609c4504a961Ted Kremenek appendStmt(Block, E); 1670721903eca33f6115296083aed17685eaa73d3e8cTed Kremenek } 1671721903eca33f6115296083aed17685eaa73d3e8cTed Kremenek return Block; 16724f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek} 1673cd7bf230a77c550115e4a78ee371fc49a7563692Mike Stump 16744f88063677a2d990a44bb0d5f8437d2498b91d7fTed KremenekCFGBlock *CFGBuilder::VisitBreakStmt(BreakStmt *B) { 16754f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek // "break" is a control-flow statement. Thus we stop processing the current 16764f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek // block. 1677d438b3dbdcde4df4f61a99054104643e6aadf78bZhongxing Xu if (badCFG) 16786bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return nullptr; 16791eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 16804f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek // Now create a new block that ends with the break statement. 16814f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek Block = createBlock(false); 16824f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek Block->setTerminator(B); 16831eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 16844f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek // If there is no target for the break, then we are looking at an incomplete 16854f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek // AST. This means that the CFG cannot be constructed. 16869ce5270f0aadaaf03a0cf705787f42ce9eb1194cTed Kremenek if (BreakJumpTarget.block) { 16879ce5270f0aadaaf03a0cf705787f42ce9eb1194cTed Kremenek addAutomaticObjDtors(ScopePos, BreakJumpTarget.scopePosition, B); 16889ce5270f0aadaaf03a0cf705787f42ce9eb1194cTed Kremenek addSuccessor(Block, BreakJumpTarget.block); 1689f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski } else 16904f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek badCFG = true; 16911eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 16921eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 16934f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek return Block; 16944f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek} 16951eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 16968026f6d82f7fa544bc0453714fe94bca62a1196eSebastian Redlstatic bool CanThrow(Expr *E, ASTContext &Ctx) { 16974c45aa1b00b91847acfb082acfaced3ffa294d1dMike Stump QualType Ty = E->getType(); 16984c45aa1b00b91847acfb082acfaced3ffa294d1dMike Stump if (Ty->isFunctionPointerType()) 16994c45aa1b00b91847acfb082acfaced3ffa294d1dMike Stump Ty = Ty->getAs<PointerType>()->getPointeeType(); 17004c45aa1b00b91847acfb082acfaced3ffa294d1dMike Stump else if (Ty->isBlockPointerType()) 17014c45aa1b00b91847acfb082acfaced3ffa294d1dMike Stump Ty = Ty->getAs<BlockPointerType>()->getPointeeType(); 1702ad5a894df1841698c824381b414630799adc26caTed Kremenek 17034c45aa1b00b91847acfb082acfaced3ffa294d1dMike Stump const FunctionType *FT = Ty->getAs<FunctionType>(); 17044c45aa1b00b91847acfb082acfaced3ffa294d1dMike Stump if (FT) { 17054c45aa1b00b91847acfb082acfaced3ffa294d1dMike Stump if (const FunctionProtoType *Proto = dyn_cast<FunctionProtoType>(FT)) 1706b9d0b76e42fd2d4cdfd135220302458d03ad09feRichard Smith if (!isUnresolvedExceptionSpec(Proto->getExceptionSpecType()) && 1707e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith Proto->isNothrow(Ctx)) 17084c45aa1b00b91847acfb082acfaced3ffa294d1dMike Stump return false; 17094c45aa1b00b91847acfb082acfaced3ffa294d1dMike Stump } 17104c45aa1b00b91847acfb082acfaced3ffa294d1dMike Stump return true; 17114c45aa1b00b91847acfb082acfaced3ffa294d1dMike Stump} 17124c45aa1b00b91847acfb082acfaced3ffa294d1dMike Stump 1713852274d4257134906995cb252fb3dfd2d71deae8Ted KremenekCFGBlock *CFGBuilder::VisitCallExpr(CallExpr *C, AddStmtChoice asc) { 17141de85338543dd6228eb518185e385d94d377f4cbJohn McCall // Compute the callee type. 17151de85338543dd6228eb518185e385d94d377f4cbJohn McCall QualType calleeType = C->getCallee()->getType(); 17161de85338543dd6228eb518185e385d94d377f4cbJohn McCall if (calleeType == Context->BoundMemberTy) { 17171de85338543dd6228eb518185e385d94d377f4cbJohn McCall QualType boundType = Expr::findBoundMemberType(C->getCallee()); 17181de85338543dd6228eb518185e385d94d377f4cbJohn McCall 17191de85338543dd6228eb518185e385d94d377f4cbJohn McCall // We should only get a null bound type if processing a dependent 17201de85338543dd6228eb518185e385d94d377f4cbJohn McCall // CFG. Recover by assuming nothing. 17211de85338543dd6228eb518185e385d94d377f4cbJohn McCall if (!boundType.isNull()) calleeType = boundType; 17222455636163fdd18581d7fdae816433f886d88213Mike Stump } 17232455636163fdd18581d7fdae816433f886d88213Mike Stump 17241de85338543dd6228eb518185e385d94d377f4cbJohn McCall // If this is a call to a no-return function, this stops the block here. 17251de85338543dd6228eb518185e385d94d377f4cbJohn McCall bool NoReturn = getFunctionExtInfo(*calleeType).getNoReturn(); 17261de85338543dd6228eb518185e385d94d377f4cbJohn McCall 17274c45aa1b00b91847acfb082acfaced3ffa294d1dMike Stump bool AddEHEdge = false; 1728079bd72439448b78629a28da6b1f8abe2cdeaf4dMike Stump 1729079bd72439448b78629a28da6b1f8abe2cdeaf4dMike Stump // Languages without exceptions are assumed to not throw. 17304e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie if (Context->getLangOpts().Exceptions) { 17316c52c7850bccb6991470668429a1e1edf01b0873Ted Kremenek if (BuildOpts.AddEHEdges) 17324c45aa1b00b91847acfb082acfaced3ffa294d1dMike Stump AddEHEdge = true; 1733079bd72439448b78629a28da6b1f8abe2cdeaf4dMike Stump } 1734079bd72439448b78629a28da6b1f8abe2cdeaf4dMike Stump 17357d0dcd2de023e2667a3f1f14daff9d087fab9bf7Jordan Rose // If this is a call to a builtin function, it might not actually evaluate 17367d0dcd2de023e2667a3f1f14daff9d087fab9bf7Jordan Rose // its arguments. Don't add them to the CFG if this is the case. 17377d0dcd2de023e2667a3f1f14daff9d087fab9bf7Jordan Rose bool OmitArguments = false; 17387d0dcd2de023e2667a3f1f14daff9d087fab9bf7Jordan Rose 1739079bd72439448b78629a28da6b1f8abe2cdeaf4dMike Stump if (FunctionDecl *FD = C->getDirectCallee()) { 1740cd8ab51a44e80625d84126780b0d85a7732e25afRichard Smith if (FD->isNoReturn()) 17412455636163fdd18581d7fdae816433f886d88213Mike Stump NoReturn = true; 1742079bd72439448b78629a28da6b1f8abe2cdeaf4dMike Stump if (FD->hasAttr<NoThrowAttr>()) 17434c45aa1b00b91847acfb082acfaced3ffa294d1dMike Stump AddEHEdge = false; 17447d0dcd2de023e2667a3f1f14daff9d087fab9bf7Jordan Rose if (FD->getBuiltinID() == Builtin::BI__builtin_object_size) 17457d0dcd2de023e2667a3f1f14daff9d087fab9bf7Jordan Rose OmitArguments = true; 1746079bd72439448b78629a28da6b1f8abe2cdeaf4dMike Stump } 17472455636163fdd18581d7fdae816433f886d88213Mike Stump 17488026f6d82f7fa544bc0453714fe94bca62a1196eSebastian Redl if (!CanThrow(C->getCallee(), *Context)) 17494c45aa1b00b91847acfb082acfaced3ffa294d1dMike Stump AddEHEdge = false; 17504c45aa1b00b91847acfb082acfaced3ffa294d1dMike Stump 17517d0dcd2de023e2667a3f1f14daff9d087fab9bf7Jordan Rose if (OmitArguments) { 17527d0dcd2de023e2667a3f1f14daff9d087fab9bf7Jordan Rose assert(!NoReturn && "noreturn calls with unevaluated args not implemented"); 17537d0dcd2de023e2667a3f1f14daff9d087fab9bf7Jordan Rose assert(!AddEHEdge && "EH calls with unevaluated args not implemented"); 17547d0dcd2de023e2667a3f1f14daff9d087fab9bf7Jordan Rose autoCreateBlock(); 17557d0dcd2de023e2667a3f1f14daff9d087fab9bf7Jordan Rose appendStmt(Block, C); 17567d0dcd2de023e2667a3f1f14daff9d087fab9bf7Jordan Rose return Visit(C->getCallee()); 17577d0dcd2de023e2667a3f1f14daff9d087fab9bf7Jordan Rose } 17587d0dcd2de023e2667a3f1f14daff9d087fab9bf7Jordan Rose 17597d0dcd2de023e2667a3f1f14daff9d087fab9bf7Jordan Rose if (!NoReturn && !AddEHEdge) { 176094a3dcf146451eb6b0192873e267c4cb0f6147e8Zhanyong Wan return VisitStmt(C, asc.withAlwaysAdd(true)); 17617d0dcd2de023e2667a3f1f14daff9d087fab9bf7Jordan Rose } 17621eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1763079bd72439448b78629a28da6b1f8abe2cdeaf4dMike Stump if (Block) { 1764079bd72439448b78629a28da6b1f8abe2cdeaf4dMike Stump Succ = Block; 1765d438b3dbdcde4df4f61a99054104643e6aadf78bZhongxing Xu if (badCFG) 17666bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return nullptr; 1767079bd72439448b78629a28da6b1f8abe2cdeaf4dMike Stump } 17681eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1769dba3fb5413437dc613734fa4ffac892b11a37d25Chandler Carruth if (NoReturn) 1770dba3fb5413437dc613734fa4ffac892b11a37d25Chandler Carruth Block = createNoReturnBlock(); 1771dba3fb5413437dc613734fa4ffac892b11a37d25Chandler Carruth else 1772dba3fb5413437dc613734fa4ffac892b11a37d25Chandler Carruth Block = createBlock(); 1773dba3fb5413437dc613734fa4ffac892b11a37d25Chandler Carruth 1774247e9665d897a7bbbf60c1c0d3b6609c4504a961Ted Kremenek appendStmt(Block, C); 17752455636163fdd18581d7fdae816433f886d88213Mike Stump 17764c45aa1b00b91847acfb082acfaced3ffa294d1dMike Stump if (AddEHEdge) { 1777079bd72439448b78629a28da6b1f8abe2cdeaf4dMike Stump // Add exceptional edges. 1778079bd72439448b78629a28da6b1f8abe2cdeaf4dMike Stump if (TryTerminatedBlock) 17790a3ed3143b00f237decb1288c1ff574ae09eba4eTed Kremenek addSuccessor(Block, TryTerminatedBlock); 1780079bd72439448b78629a28da6b1f8abe2cdeaf4dMike Stump else 17810a3ed3143b00f237decb1288c1ff574ae09eba4eTed Kremenek addSuccessor(Block, &cfg->getExit()); 1782079bd72439448b78629a28da6b1f8abe2cdeaf4dMike Stump } 17831eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 17842455636163fdd18581d7fdae816433f886d88213Mike Stump return VisitChildren(C); 1785d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek} 1786d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek 1787852274d4257134906995cb252fb3dfd2d71deae8Ted KremenekCFGBlock *CFGBuilder::VisitChooseExpr(ChooseExpr *C, 1788852274d4257134906995cb252fb3dfd2d71deae8Ted Kremenek AddStmtChoice asc) { 17899c378f705405d37f49795d5e915989de774fe11fTed Kremenek CFGBlock *ConfluenceBlock = Block ? Block : createBlock(); 1790247e9665d897a7bbbf60c1c0d3b6609c4504a961Ted Kremenek appendStmt(ConfluenceBlock, C); 1791d438b3dbdcde4df4f61a99054104643e6aadf78bZhongxing Xu if (badCFG) 17926bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return nullptr; 17931eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 179494a3dcf146451eb6b0192873e267c4cb0f6147e8Zhanyong Wan AddStmtChoice alwaysAdd = asc.withAlwaysAdd(true); 17953fc8ef574cdc09c613c329ee511852d219263c15Ted Kremenek Succ = ConfluenceBlock; 17966bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines Block = nullptr; 17979c378f705405d37f49795d5e915989de774fe11fTed Kremenek CFGBlock *LHSBlock = Visit(C->getLHS(), alwaysAdd); 1798d438b3dbdcde4df4f61a99054104643e6aadf78bZhongxing Xu if (badCFG) 17996bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return nullptr; 18001eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 18013fc8ef574cdc09c613c329ee511852d219263c15Ted Kremenek Succ = ConfluenceBlock; 18026bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines Block = nullptr; 18039c378f705405d37f49795d5e915989de774fe11fTed Kremenek CFGBlock *RHSBlock = Visit(C->getRHS(), alwaysAdd); 1804d438b3dbdcde4df4f61a99054104643e6aadf78bZhongxing Xu if (badCFG) 18056bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return nullptr; 18061eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 18073fc8ef574cdc09c613c329ee511852d219263c15Ted Kremenek Block = createBlock(false); 180800998a068e50945118f334c98af05ed44d7c22a6Mike Stump // See if this is a known constant. 18090a3ed3143b00f237decb1288c1ff574ae09eba4eTed Kremenek const TryResult& KnownVal = tryEvaluateBool(C->getCond()); 18106bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines addSuccessor(Block, KnownVal.isFalse() ? nullptr : LHSBlock); 18116bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines addSuccessor(Block, KnownVal.isTrue() ? nullptr : RHSBlock); 18123fc8ef574cdc09c613c329ee511852d219263c15Ted Kremenek Block->setTerminator(C); 18131eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump return addStmt(C->getCond()); 18143fc8ef574cdc09c613c329ee511852d219263c15Ted Kremenek} 18151eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 18161eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 18179c378f705405d37f49795d5e915989de774fe11fTed KremenekCFGBlock *CFGBuilder::VisitCompoundStmt(CompoundStmt *C) { 1818fcb72ac985c26372315fabc08d43d6f66ff906b4Marcin Swiderski addLocalScopeAndDtors(C); 18199c378f705405d37f49795d5e915989de774fe11fTed Kremenek CFGBlock *LastBlock = Block; 18204f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek 18214f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek for (CompoundStmt::reverse_body_iterator I=C->body_rbegin(), E=C->body_rend(); 18224f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek I != E; ++I ) { 1823334c19566104d3333cf662f0017088a18eddfa81Ted Kremenek // If we hit a segment of code just containing ';' (NullStmts), we can 1824334c19566104d3333cf662f0017088a18eddfa81Ted Kremenek // get a null block back. In such cases, just use the LastBlock 1825334c19566104d3333cf662f0017088a18eddfa81Ted Kremenek if (CFGBlock *newBlock = addStmt(*I)) 1826334c19566104d3333cf662f0017088a18eddfa81Ted Kremenek LastBlock = newBlock; 18271eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1828e8d6d2b9a2c5d3f0e7e0f88f54f1711bbc6c6f78Ted Kremenek if (badCFG) 18296bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return nullptr; 18301eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump } 1831079bd72439448b78629a28da6b1f8abe2cdeaf4dMike Stump 18324f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek return LastBlock; 18334f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek} 18341eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 183556ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCallCFGBlock *CFGBuilder::VisitConditionalOperator(AbstractConditionalOperator *C, 1836852274d4257134906995cb252fb3dfd2d71deae8Ted Kremenek AddStmtChoice asc) { 183756ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall const BinaryConditionalOperator *BCO = dyn_cast<BinaryConditionalOperator>(C); 18386bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines const OpaqueValueExpr *opaqueValue = (BCO ? BCO->getOpaqueValue() : nullptr); 183956ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall 1840f34bb2eaa87aa28bcc8b6ff0dfc696cd75605b11Ted Kremenek // Create the confluence block that will "merge" the results of the ternary 1841f34bb2eaa87aa28bcc8b6ff0dfc696cd75605b11Ted Kremenek // expression. 18429c378f705405d37f49795d5e915989de774fe11fTed Kremenek CFGBlock *ConfluenceBlock = Block ? Block : createBlock(); 1843247e9665d897a7bbbf60c1c0d3b6609c4504a961Ted Kremenek appendStmt(ConfluenceBlock, C); 1844d438b3dbdcde4df4f61a99054104643e6aadf78bZhongxing Xu if (badCFG) 18456bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return nullptr; 18461eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 184794a3dcf146451eb6b0192873e267c4cb0f6147e8Zhanyong Wan AddStmtChoice alwaysAdd = asc.withAlwaysAdd(true); 1848115c1b9cc758d15f38e1d2ad4cf07b1cacfb3115Ted Kremenek 1849f34bb2eaa87aa28bcc8b6ff0dfc696cd75605b11Ted Kremenek // Create a block for the LHS expression if there is an LHS expression. A 1850f34bb2eaa87aa28bcc8b6ff0dfc696cd75605b11Ted Kremenek // GCC extension allows LHS to be NULL, causing the condition to be the 1851f34bb2eaa87aa28bcc8b6ff0dfc696cd75605b11Ted Kremenek // value that is returned instead. 1852f34bb2eaa87aa28bcc8b6ff0dfc696cd75605b11Ted Kremenek // e.g: x ?: y is shorthand for: x ? x : y; 1853f34bb2eaa87aa28bcc8b6ff0dfc696cd75605b11Ted Kremenek Succ = ConfluenceBlock; 18546bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines Block = nullptr; 18556bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines CFGBlock *LHSBlock = nullptr; 185656ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall const Expr *trueExpr = C->getTrueExpr(); 185756ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall if (trueExpr != opaqueValue) { 185856ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall LHSBlock = Visit(C->getTrueExpr(), alwaysAdd); 1859d438b3dbdcde4df4f61a99054104643e6aadf78bZhongxing Xu if (badCFG) 18606bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return nullptr; 18616bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines Block = nullptr; 1862f34bb2eaa87aa28bcc8b6ff0dfc696cd75605b11Ted Kremenek } 1863f226d18f0f49394cec460699f4268e32bd0ce833Ted Kremenek else 1864f226d18f0f49394cec460699f4268e32bd0ce833Ted Kremenek LHSBlock = ConfluenceBlock; 18651eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1866f34bb2eaa87aa28bcc8b6ff0dfc696cd75605b11Ted Kremenek // Create the block for the RHS expression. 1867f34bb2eaa87aa28bcc8b6ff0dfc696cd75605b11Ted Kremenek Succ = ConfluenceBlock; 18689c378f705405d37f49795d5e915989de774fe11fTed Kremenek CFGBlock *RHSBlock = Visit(C->getFalseExpr(), alwaysAdd); 1869d438b3dbdcde4df4f61a99054104643e6aadf78bZhongxing Xu if (badCFG) 18706bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return nullptr; 18711eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 187256df4a9e0461d4dfb2a740cb6b0ce531d6c82538Richard Smith // If the condition is a logical '&&' or '||', build a more accurate CFG. 187356df4a9e0461d4dfb2a740cb6b0ce531d6c82538Richard Smith if (BinaryOperator *Cond = 187456df4a9e0461d4dfb2a740cb6b0ce531d6c82538Richard Smith dyn_cast<BinaryOperator>(C->getCond()->IgnoreParens())) 187556df4a9e0461d4dfb2a740cb6b0ce531d6c82538Richard Smith if (Cond->isLogicalOp()) 187656df4a9e0461d4dfb2a740cb6b0ce531d6c82538Richard Smith return VisitLogicalOperator(Cond, C, LHSBlock, RHSBlock).first; 187756df4a9e0461d4dfb2a740cb6b0ce531d6c82538Richard Smith 1878f34bb2eaa87aa28bcc8b6ff0dfc696cd75605b11Ted Kremenek // Create the block that will contain the condition. 1879f34bb2eaa87aa28bcc8b6ff0dfc696cd75605b11Ted Kremenek Block = createBlock(false); 18801eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 188100998a068e50945118f334c98af05ed44d7c22a6Mike Stump // See if this is a known constant. 18820a3ed3143b00f237decb1288c1ff574ae09eba4eTed Kremenek const TryResult& KnownVal = tryEvaluateBool(C->getCond()); 1883651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines addSuccessor(Block, LHSBlock, !KnownVal.isFalse()); 1884651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines addSuccessor(Block, RHSBlock, !KnownVal.isTrue()); 1885f34bb2eaa87aa28bcc8b6ff0dfc696cd75605b11Ted Kremenek Block->setTerminator(C); 188656ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall Expr *condExpr = C->getCond(); 1887d40baf6a77f6353a93f181da5d1347d3730aad37John McCall 1888f226d18f0f49394cec460699f4268e32bd0ce833Ted Kremenek if (opaqueValue) { 1889f226d18f0f49394cec460699f4268e32bd0ce833Ted Kremenek // Run the condition expression if it's not trivially expressed in 1890f226d18f0f49394cec460699f4268e32bd0ce833Ted Kremenek // terms of the opaque value (or if there is no opaque value). 1891f226d18f0f49394cec460699f4268e32bd0ce833Ted Kremenek if (condExpr != opaqueValue) 1892f226d18f0f49394cec460699f4268e32bd0ce833Ted Kremenek addStmt(condExpr); 1893d40baf6a77f6353a93f181da5d1347d3730aad37John McCall 1894f226d18f0f49394cec460699f4268e32bd0ce833Ted Kremenek // Before that, run the common subexpression if there was one. 1895f226d18f0f49394cec460699f4268e32bd0ce833Ted Kremenek // At least one of this or the above will be run. 1896f226d18f0f49394cec460699f4268e32bd0ce833Ted Kremenek return addStmt(BCO->getCommon()); 1897f226d18f0f49394cec460699f4268e32bd0ce833Ted Kremenek } 1898f226d18f0f49394cec460699f4268e32bd0ce833Ted Kremenek 1899f226d18f0f49394cec460699f4268e32bd0ce833Ted Kremenek return addStmt(condExpr); 1900f34bb2eaa87aa28bcc8b6ff0dfc696cd75605b11Ted Kremenek} 1901f34bb2eaa87aa28bcc8b6ff0dfc696cd75605b11Ted Kremenek 19024f88063677a2d990a44bb0d5f8437d2498b91d7fTed KremenekCFGBlock *CFGBuilder::VisitDeclStmt(DeclStmt *DS) { 1903bc869de349227707a07ccc783344d255cf37ec16Ted Kremenek // Check if the Decl is for an __label__. If so, elide it from the 1904bc869de349227707a07ccc783344d255cf37ec16Ted Kremenek // CFG entirely. 1905bc869de349227707a07ccc783344d255cf37ec16Ted Kremenek if (isa<LabelDecl>(*DS->decl_begin())) 1906bc869de349227707a07ccc783344d255cf37ec16Ted Kremenek return Block; 1907bc869de349227707a07ccc783344d255cf37ec16Ted Kremenek 190829c9e62f412c9db3ee238db2472390685a6303f3Ted Kremenek // This case also handles static_asserts. 19098599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski if (DS->isSingleDecl()) 19108599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski return VisitDeclSubExpr(DS); 19111eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 19126bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines CFGBlock *B = nullptr; 19131eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1914fd8b43596478b779b6777cb3a595e69d7856c378Jordan Rose // Build an individual DeclStmt for each decl. 1915fd8b43596478b779b6777cb3a595e69d7856c378Jordan Rose for (DeclStmt::reverse_decl_iterator I = DS->decl_rbegin(), 1916fd8b43596478b779b6777cb3a595e69d7856c378Jordan Rose E = DS->decl_rend(); 1917fd8b43596478b779b6777cb3a595e69d7856c378Jordan Rose I != E; ++I) { 19184f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek // Get the alignment of the new DeclStmt, padding out to >=8 bytes. 19194f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek unsigned A = llvm::AlignOf<DeclStmt>::Alignment < 8 19204f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek ? 8 : llvm::AlignOf<DeclStmt>::Alignment; 19211eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 19224f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek // Allocate the DeclStmt using the BumpPtrAllocator. It will get 19234f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek // automatically freed with the CFG. 19244f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek DeclGroupRef DG(*I); 19254f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek Decl *D = *I; 19261eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump void *Mem = cfg->getAllocator().Allocate(sizeof(DeclStmt), A); 19274f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek DeclStmt *DSNew = new (Mem) DeclStmt(DG, D->getLocation(), GetEndLoc(D)); 192849a246f4fad959888bb0164c624c3c2b03078e91Jordan Rose cfg->addSyntheticDeclStmt(DSNew, DS); 19291eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 19304f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek // Append the fake DeclStmt to block. 19318599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski B = VisitDeclSubExpr(DSNew); 19324f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek } 19331eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 19341eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump return B; 19354f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek} 19361eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 19374f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek/// VisitDeclSubExpr - Utility method to add block-level expressions for 19388599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski/// DeclStmts and initializers in them. 19399c378f705405d37f49795d5e915989de774fe11fTed KremenekCFGBlock *CFGBuilder::VisitDeclSubExpr(DeclStmt *DS) { 19408599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski assert(DS->isSingleDecl() && "Can handle single declarations only."); 19418599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski VarDecl *VD = dyn_cast<VarDecl>(DS->getSingleDecl()); 19421eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 19438599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski if (!VD) { 19442794bc0e3757992194dd587d0f6a253ec72afc9aJordan Rose // Of everything that can be declared in a DeclStmt, only VarDecls impact 19452794bc0e3757992194dd587d0f6a253ec72afc9aJordan Rose // runtime semantics. 19464f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek return Block; 19478599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski } 19481eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 19498599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski bool IsReference = false; 19508599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski bool HasTemporaries = false; 19518599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski 1952fbd4b5dc7febd1d8b4fa64ab00a29d72b44bec7bTed Kremenek // Guard static initializers under a branch. 19536bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines CFGBlock *blockAfterStaticInit = nullptr; 19545062bb22706c8f2ceec5815533ff5a88d169d098Ted Kremenek 19555062bb22706c8f2ceec5815533ff5a88d169d098Ted Kremenek if (BuildOpts.AddStaticInitBranches && VD->isStaticLocal()) { 19565062bb22706c8f2ceec5815533ff5a88d169d098Ted Kremenek // For static variables, we need to create a branch to track 19575062bb22706c8f2ceec5815533ff5a88d169d098Ted Kremenek // whether or not they are initialized. 19585062bb22706c8f2ceec5815533ff5a88d169d098Ted Kremenek if (Block) { 19595062bb22706c8f2ceec5815533ff5a88d169d098Ted Kremenek Succ = Block; 19606bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines Block = nullptr; 19615062bb22706c8f2ceec5815533ff5a88d169d098Ted Kremenek if (badCFG) 19626bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return nullptr; 19635062bb22706c8f2ceec5815533ff5a88d169d098Ted Kremenek } 19645062bb22706c8f2ceec5815533ff5a88d169d098Ted Kremenek blockAfterStaticInit = Succ; 19655062bb22706c8f2ceec5815533ff5a88d169d098Ted Kremenek } 1966fbd4b5dc7febd1d8b4fa64ab00a29d72b44bec7bTed Kremenek 19678599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski // Destructors of temporaries in initialization expression should be called 19688599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski // after initialization finishes. 19694f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek Expr *Init = VD->getInit(); 19708599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski if (Init) { 19718599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski IsReference = VD->getType()->isReferenceType(); 19724765fa05b5652fcc4356371c2f481d0ea9a1b007John McCall HasTemporaries = isa<ExprWithCleanups>(Init); 19738599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski 19745a1ffe98b04120846a15f7105905b5f363b08635Jordan Rose if (BuildOpts.AddTemporaryDtors && HasTemporaries) { 19758599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski // Generate destructors for temporaries in initialization expression. 19764765fa05b5652fcc4356371c2f481d0ea9a1b007John McCall VisitForTemporaryDtors(cast<ExprWithCleanups>(Init)->getSubExpr(), 19778599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski IsReference); 19788599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski } 19798599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski } 19808599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski 19818599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski autoCreateBlock(); 1982892697dd2287caf7c29aaaa82909b0e90b8b63feTed Kremenek appendStmt(Block, DS); 1983550f2234fc9218914c325041067052342dfce553Ted Kremenek 1984550f2234fc9218914c325041067052342dfce553Ted Kremenek // Keep track of the last non-null block, as 'Block' can be nulled out 1985550f2234fc9218914c325041067052342dfce553Ted Kremenek // if the initializer expression is something like a 'while' in a 1986550f2234fc9218914c325041067052342dfce553Ted Kremenek // statement-expression. 1987550f2234fc9218914c325041067052342dfce553Ted Kremenek CFGBlock *LastBlock = Block; 19881eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 19894f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek if (Init) { 1990550f2234fc9218914c325041067052342dfce553Ted Kremenek if (HasTemporaries) { 19918599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski // For expression with temporaries go directly to subexpression to omit 19928599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski // generating destructors for the second time. 1993550f2234fc9218914c325041067052342dfce553Ted Kremenek ExprWithCleanups *EC = cast<ExprWithCleanups>(Init); 1994550f2234fc9218914c325041067052342dfce553Ted Kremenek if (CFGBlock *newBlock = Visit(EC->getSubExpr())) 1995550f2234fc9218914c325041067052342dfce553Ted Kremenek LastBlock = newBlock; 1996550f2234fc9218914c325041067052342dfce553Ted Kremenek } 1997550f2234fc9218914c325041067052342dfce553Ted Kremenek else { 1998550f2234fc9218914c325041067052342dfce553Ted Kremenek if (CFGBlock *newBlock = Visit(Init)) 1999550f2234fc9218914c325041067052342dfce553Ted Kremenek LastBlock = newBlock; 2000550f2234fc9218914c325041067052342dfce553Ted Kremenek } 20014f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek } 20021eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 20034f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek // If the type of VD is a VLA, then we must process its size expressions. 2004f4c7371fb1d3cebcfb40abad4537bb82515704eaJohn McCall for (const VariableArrayType* VA = FindVA(VD->getType().getTypePtr()); 20056bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines VA != nullptr; VA = FindVA(VA->getElementType().getTypePtr())) { 20068f81acfa95a5d2a22fc875c1a10901eaa30b8405Ted Kremenek if (CFGBlock *newBlock = addStmt(VA->getSizeExpr())) 20078f81acfa95a5d2a22fc875c1a10901eaa30b8405Ted Kremenek LastBlock = newBlock; 20088f81acfa95a5d2a22fc875c1a10901eaa30b8405Ted Kremenek } 20091eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 2010fcb72ac985c26372315fabc08d43d6f66ff906b4Marcin Swiderski // Remove variable from local scope. 2011fcb72ac985c26372315fabc08d43d6f66ff906b4Marcin Swiderski if (ScopePos && VD == *ScopePos) 2012fcb72ac985c26372315fabc08d43d6f66ff906b4Marcin Swiderski ++ScopePos; 2013fcb72ac985c26372315fabc08d43d6f66ff906b4Marcin Swiderski 20140f5c5c60e9806d13f0907cd99d7204ffab0e08f7Ted Kremenek CFGBlock *B = LastBlock; 20155062bb22706c8f2ceec5815533ff5a88d169d098Ted Kremenek if (blockAfterStaticInit) { 2016fbd4b5dc7febd1d8b4fa64ab00a29d72b44bec7bTed Kremenek Succ = B; 20170f5c5c60e9806d13f0907cd99d7204ffab0e08f7Ted Kremenek Block = createBlock(false); 20180f5c5c60e9806d13f0907cd99d7204ffab0e08f7Ted Kremenek Block->setTerminator(DS); 20195062bb22706c8f2ceec5815533ff5a88d169d098Ted Kremenek addSuccessor(Block, blockAfterStaticInit); 20200f5c5c60e9806d13f0907cd99d7204ffab0e08f7Ted Kremenek addSuccessor(Block, B); 20210f5c5c60e9806d13f0907cd99d7204ffab0e08f7Ted Kremenek B = Block; 2022fbd4b5dc7febd1d8b4fa64ab00a29d72b44bec7bTed Kremenek } 2023fbd4b5dc7febd1d8b4fa64ab00a29d72b44bec7bTed Kremenek 2024fbd4b5dc7febd1d8b4fa64ab00a29d72b44bec7bTed Kremenek return B; 2025d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek} 2026fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek 20279c378f705405d37f49795d5e915989de774fe11fTed KremenekCFGBlock *CFGBuilder::VisitIfStmt(IfStmt *I) { 20286d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump // We may see an if statement in the middle of a basic block, or it may be the 20296d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump // first statement we are processing. In either case, we create a new basic 20306d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump // block. First, we create the blocks for the then...else statements, and 20316d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump // then we create the block containing the if statement. If we were in the 20326c2497248bc4f7fd8e5fb0a206d20abbf0e16645Ted Kremenek // middle of a block, we stop processing that block. That block is then the 20336c2497248bc4f7fd8e5fb0a206d20abbf0e16645Ted Kremenek // implicit successor for the "then" and "else" clauses. 20346d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 203504e046cbf7153fc261d730d460f081322d5c42f6Marcin Swiderski // Save local scope position because in case of condition variable ScopePos 203604e046cbf7153fc261d730d460f081322d5c42f6Marcin Swiderski // won't be restored when traversing AST. 203704e046cbf7153fc261d730d460f081322d5c42f6Marcin Swiderski SaveAndRestore<LocalScope::const_iterator> save_scope_pos(ScopePos); 203804e046cbf7153fc261d730d460f081322d5c42f6Marcin Swiderski 203904e046cbf7153fc261d730d460f081322d5c42f6Marcin Swiderski // Create local scope for possible condition variable. 204004e046cbf7153fc261d730d460f081322d5c42f6Marcin Swiderski // Store scope position. Add implicit destructor. 20419c378f705405d37f49795d5e915989de774fe11fTed Kremenek if (VarDecl *VD = I->getConditionVariable()) { 204204e046cbf7153fc261d730d460f081322d5c42f6Marcin Swiderski LocalScope::const_iterator BeginScopePos = ScopePos; 204304e046cbf7153fc261d730d460f081322d5c42f6Marcin Swiderski addLocalScopeForVarDecl(VD); 204404e046cbf7153fc261d730d460f081322d5c42f6Marcin Swiderski addAutomaticObjDtors(ScopePos, BeginScopePos, I); 204504e046cbf7153fc261d730d460f081322d5c42f6Marcin Swiderski } 204604e046cbf7153fc261d730d460f081322d5c42f6Marcin Swiderski 2047fc8f0e14ad142ed811e90fbd9a30e419e301c717Chris Lattner // The block we were processing is now finished. Make it the successor 20486d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump // block. 20496d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump if (Block) { 2050d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek Succ = Block; 2051d438b3dbdcde4df4f61a99054104643e6aadf78bZhongxing Xu if (badCFG) 20526bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return nullptr; 2053c310e933a9b023a280f3aa02e5a0c75398555e13Ted Kremenek } 20546d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 2055b6f1d782e0dc5fad138a17e6aa0ff6f9bc4788c6Ted Kremenek // Process the false branch. 20569c378f705405d37f49795d5e915989de774fe11fTed Kremenek CFGBlock *ElseBlock = Succ; 20576d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 20589c378f705405d37f49795d5e915989de774fe11fTed Kremenek if (Stmt *Else = I->getElse()) { 2059d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek SaveAndRestore<CFGBlock*> sv(Succ); 20606d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 2061d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek // NULL out Block so that the recursive call to Visit will 20626d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump // create a new basic block. 20636bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines Block = nullptr; 206404e046cbf7153fc261d730d460f081322d5c42f6Marcin Swiderski 206504e046cbf7153fc261d730d460f081322d5c42f6Marcin Swiderski // If branch is not a compound statement create implicit scope 206604e046cbf7153fc261d730d460f081322d5c42f6Marcin Swiderski // and add destructors. 206704e046cbf7153fc261d730d460f081322d5c42f6Marcin Swiderski if (!isa<CompoundStmt>(Else)) 206804e046cbf7153fc261d730d460f081322d5c42f6Marcin Swiderski addLocalScopeAndDtors(Else); 206904e046cbf7153fc261d730d460f081322d5c42f6Marcin Swiderski 20704f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek ElseBlock = addStmt(Else); 20716d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 2072b6f7b72047b3fd3f96a5040e1e4d520a9dea01cdTed Kremenek if (!ElseBlock) // Can occur when the Else body has all NullStmts. 2073b6f7b72047b3fd3f96a5040e1e4d520a9dea01cdTed Kremenek ElseBlock = sv.get(); 20744e8df2eb7072db8f66572c3db31a2a08b12a752eTed Kremenek else if (Block) { 2075d438b3dbdcde4df4f61a99054104643e6aadf78bZhongxing Xu if (badCFG) 20766bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return nullptr; 20774e8df2eb7072db8f66572c3db31a2a08b12a752eTed Kremenek } 2078c310e933a9b023a280f3aa02e5a0c75398555e13Ted Kremenek } 20796d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 2080b6f1d782e0dc5fad138a17e6aa0ff6f9bc4788c6Ted Kremenek // Process the true branch. 20819c378f705405d37f49795d5e915989de774fe11fTed Kremenek CFGBlock *ThenBlock; 2082d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek { 20839c378f705405d37f49795d5e915989de774fe11fTed Kremenek Stmt *Then = I->getThen(); 20846db0ad32fa0987ff76d4c41393991ef4b6895ea3Ted Kremenek assert(Then); 2085d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek SaveAndRestore<CFGBlock*> sv(Succ); 20866bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines Block = nullptr; 208704e046cbf7153fc261d730d460f081322d5c42f6Marcin Swiderski 208804e046cbf7153fc261d730d460f081322d5c42f6Marcin Swiderski // If branch is not a compound statement create implicit scope 208904e046cbf7153fc261d730d460f081322d5c42f6Marcin Swiderski // and add destructors. 209004e046cbf7153fc261d730d460f081322d5c42f6Marcin Swiderski if (!isa<CompoundStmt>(Then)) 209104e046cbf7153fc261d730d460f081322d5c42f6Marcin Swiderski addLocalScopeAndDtors(Then); 209204e046cbf7153fc261d730d460f081322d5c42f6Marcin Swiderski 20934f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek ThenBlock = addStmt(Then); 20946d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 2095dbdf7949a7a50f5a65055a3e95f6432ecc541056Ted Kremenek if (!ThenBlock) { 2096dbdf7949a7a50f5a65055a3e95f6432ecc541056Ted Kremenek // We can reach here if the "then" body has all NullStmts. 2097dbdf7949a7a50f5a65055a3e95f6432ecc541056Ted Kremenek // Create an empty block so we can distinguish between true and false 2098dbdf7949a7a50f5a65055a3e95f6432ecc541056Ted Kremenek // branches in path-sensitive analyses. 2099dbdf7949a7a50f5a65055a3e95f6432ecc541056Ted Kremenek ThenBlock = createBlock(false); 21000a3ed3143b00f237decb1288c1ff574ae09eba4eTed Kremenek addSuccessor(ThenBlock, sv.get()); 21016d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump } else if (Block) { 2102d438b3dbdcde4df4f61a99054104643e6aadf78bZhongxing Xu if (badCFG) 21036bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return nullptr; 21046d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump } 21050cebe3e29b22d11f2c65ef28fcfb5f0431877266Ted Kremenek } 2106d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek 21073f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek // Specially handle "if (expr1 || ...)" and "if (expr1 && ...)" by 21083f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek // having these handle the actual control-flow jump. Note that 21093f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek // if we introduce a condition variable, e.g. "if (int x = exp1 || exp2)" 21103f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek // we resort to the old control-flow behavior. This special handling 21113f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek // removes infeasible paths from the control-flow graph by having the 21123f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek // control-flow transfer of '&&' or '||' go directly into the then/else 21133f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek // blocks directly. 21143f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek if (!I->getConditionVariable()) 211556df4a9e0461d4dfb2a740cb6b0ce531d6c82538Richard Smith if (BinaryOperator *Cond = 211656df4a9e0461d4dfb2a740cb6b0ce531d6c82538Richard Smith dyn_cast<BinaryOperator>(I->getCond()->IgnoreParens())) 21173f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek if (Cond->isLogicalOp()) 21183f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek return VisitLogicalOperator(Cond, I, ThenBlock, ElseBlock).first; 21193f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek 21206d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump // Now create a new block containing the if statement. 2121d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek Block = createBlock(false); 21226d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 2123d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek // Set the terminator of the new block to the If statement. 2124d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek Block->setTerminator(I); 21256d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 212600998a068e50945118f334c98af05ed44d7c22a6Mike Stump // See if this is a known constant. 21270a3ed3143b00f237decb1288c1ff574ae09eba4eTed Kremenek const TryResult &KnownVal = tryEvaluateBool(I->getCond()); 212800998a068e50945118f334c98af05ed44d7c22a6Mike Stump 2129651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // Add the successors. If we know that specific branches are 2130651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // unreachable, inform addSuccessor() of that knowledge. 2131651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines addSuccessor(Block, ThenBlock, /* isReachable = */ !KnownVal.isFalse()); 2132651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines addSuccessor(Block, ElseBlock, /* isReachable = */ !KnownVal.isTrue()); 21336d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 21346d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump // Add the condition as the last statement in the new block. This may create 21356d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump // new blocks as the condition may contain control-flow. Any newly created 21366d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump // blocks will be pointed to be "Block". 21378f81acfa95a5d2a22fc875c1a10901eaa30b8405Ted Kremenek CFGBlock *LastBlock = addStmt(I->getCond()); 2138ad5a894df1841698c824381b414630799adc26caTed Kremenek 21396bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines // Finally, if the IfStmt contains a condition variable, add it and its 21406bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines // initializer to the CFG. 21416bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (const DeclStmt* DS = I->getConditionVariableDeclStmt()) { 21426bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines autoCreateBlock(); 21436bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines LastBlock = addStmt(const_cast<DeclStmt *>(DS)); 214461dfbecd8e6181b2ba42ffb5feede27a2bab3b8aTed Kremenek } 2145ad5a894df1841698c824381b414630799adc26caTed Kremenek 21468f81acfa95a5d2a22fc875c1a10901eaa30b8405Ted Kremenek return LastBlock; 2147d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek} 21486d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 21496d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 21509c378f705405d37f49795d5e915989de774fe11fTed KremenekCFGBlock *CFGBuilder::VisitReturnStmt(ReturnStmt *R) { 21516c2497248bc4f7fd8e5fb0a206d20abbf0e16645Ted Kremenek // If we were in the middle of a block we stop processing that block. 2152d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek // 21536d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump // NOTE: If a "return" appears in the middle of a block, this means that the 21546d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump // code afterwards is DEAD (unreachable). We still keep a basic block 21556d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump // for that code; a simple "mark-and-sweep" from the entry block will be 21566d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump // able to report such dead blocks. 2157d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek 2158d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek // Create the new block. 2159d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek Block = createBlock(false); 21606d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 2161fcb72ac985c26372315fabc08d43d6f66ff906b4Marcin Swiderski addAutomaticObjDtors(ScopePos, LocalScope::const_iterator(), R); 21621ae74842cd1be37a8d99d0865623ef16432d3b67Pavel Labath 21631ae74842cd1be37a8d99d0865623ef16432d3b67Pavel Labath // If the one of the destructors does not return, we already have the Exit 21641ae74842cd1be37a8d99d0865623ef16432d3b67Pavel Labath // block as a successor. 21651ae74842cd1be37a8d99d0865623ef16432d3b67Pavel Labath if (!Block->hasNoReturnElement()) 21661ae74842cd1be37a8d99d0865623ef16432d3b67Pavel Labath addSuccessor(Block, &cfg->getExit()); 21676d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 21686d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump // Add the return statement to the block. This may create new blocks if R 21696d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump // contains control-flow (short-circuit operations). 2170852274d4257134906995cb252fb3dfd2d71deae8Ted Kremenek return VisitStmt(R, AddStmtChoice::AlwaysAdd); 2171d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek} 21720cebe3e29b22d11f2c65ef28fcfb5f0431877266Ted Kremenek 21739c378f705405d37f49795d5e915989de774fe11fTed KremenekCFGBlock *CFGBuilder::VisitLabelStmt(LabelStmt *L) { 2174d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek // Get the block of the labeled statement. Add it to our map. 21754f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek addStmt(L->getSubStmt()); 2176ad8dcf4a9df0e24051dc31bf9e6f3cd138a34298Chris Lattner CFGBlock *LabelBlock = Block; 21776d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 21784f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek if (!LabelBlock) // This can happen when the body is empty, i.e. 21794f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek LabelBlock = createBlock(); // scopes that only contains NullStmts. 21806d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 2181ad8dcf4a9df0e24051dc31bf9e6f3cd138a34298Chris Lattner assert(LabelMap.find(L->getDecl()) == LabelMap.end() && 2182ad8dcf4a9df0e24051dc31bf9e6f3cd138a34298Chris Lattner "label already in map"); 2183ad8dcf4a9df0e24051dc31bf9e6f3cd138a34298Chris Lattner LabelMap[L->getDecl()] = JumpTarget(LabelBlock, ScopePos); 21846d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 21856d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump // Labels partition blocks, so this is the end of the basic block we were 21866d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump // processing (L is the block's label). Because this is label (and we have 21876d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump // already processed the substatement) there is no extra control-flow to worry 21886d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump // about. 21899cffe7366ea3beb33c2d58f43a8c3a04c1873e11Ted Kremenek LabelBlock->setLabel(L); 2190d438b3dbdcde4df4f61a99054104643e6aadf78bZhongxing Xu if (badCFG) 21916bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return nullptr; 21926d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 21936d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump // We set Block to NULL to allow lazy creation of a new block (if necessary); 21946bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines Block = nullptr; 21956d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 2196d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek // This block is now the implicit successor of other blocks. 2197d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek Succ = LabelBlock; 21986d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 2199d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek return LabelBlock; 2200d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek} 220131dcd3c8c4df5a656f58f50ea73afc177c101c67Ted Kremenek 220283748e2f41ea0ac7c954946feb5da9ccc6ab8becTed KremenekCFGBlock *CFGBuilder::VisitLambdaExpr(LambdaExpr *E, AddStmtChoice asc) { 220383748e2f41ea0ac7c954946feb5da9ccc6ab8becTed Kremenek CFGBlock *LastBlock = VisitNoRecurse(E, asc); 220483748e2f41ea0ac7c954946feb5da9ccc6ab8becTed Kremenek for (LambdaExpr::capture_init_iterator it = E->capture_init_begin(), 220583748e2f41ea0ac7c954946feb5da9ccc6ab8becTed Kremenek et = E->capture_init_end(); it != et; ++it) { 220683748e2f41ea0ac7c954946feb5da9ccc6ab8becTed Kremenek if (Expr *Init = *it) { 220783748e2f41ea0ac7c954946feb5da9ccc6ab8becTed Kremenek CFGBlock *Tmp = Visit(Init); 22086bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (Tmp) 220983748e2f41ea0ac7c954946feb5da9ccc6ab8becTed Kremenek LastBlock = Tmp; 221083748e2f41ea0ac7c954946feb5da9ccc6ab8becTed Kremenek } 221183748e2f41ea0ac7c954946feb5da9ccc6ab8becTed Kremenek } 221283748e2f41ea0ac7c954946feb5da9ccc6ab8becTed Kremenek return LastBlock; 221383748e2f41ea0ac7c954946feb5da9ccc6ab8becTed Kremenek} 221483748e2f41ea0ac7c954946feb5da9ccc6ab8becTed Kremenek 22159c378f705405d37f49795d5e915989de774fe11fTed KremenekCFGBlock *CFGBuilder::VisitGotoStmt(GotoStmt *G) { 22166d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump // Goto is a control-flow statement. Thus we stop processing the current 22176d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump // block and create a new one. 22184f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek 2219d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek Block = createBlock(false); 2220d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek Block->setTerminator(G); 22216d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 22226d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump // If we already know the mapping to the label block add the successor now. 2223d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek LabelMapTy::iterator I = LabelMap.find(G->getLabel()); 22246d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 2225d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek if (I == LabelMap.end()) 2226d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek // We will need to backpatch this block later. 2227f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski BackpatchBlocks.push_back(JumpSource(Block, ScopePos)); 2228f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski else { 2229f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski JumpTarget JT = I->second; 22309ce5270f0aadaaf03a0cf705787f42ce9eb1194cTed Kremenek addAutomaticObjDtors(ScopePos, JT.scopePosition, G); 22319ce5270f0aadaaf03a0cf705787f42ce9eb1194cTed Kremenek addSuccessor(Block, JT.block); 2232f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski } 2233d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek 22346d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump return Block; 2235d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek} 2236d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek 22379c378f705405d37f49795d5e915989de774fe11fTed KremenekCFGBlock *CFGBuilder::VisitForStmt(ForStmt *F) { 22386bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines CFGBlock *LoopSuccessor = nullptr; 22396d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 224047575f1f775f5f250be4f395fa694a7274a65f33Marcin Swiderski // Save local scope position because in case of condition variable ScopePos 224147575f1f775f5f250be4f395fa694a7274a65f33Marcin Swiderski // won't be restored when traversing AST. 224247575f1f775f5f250be4f395fa694a7274a65f33Marcin Swiderski SaveAndRestore<LocalScope::const_iterator> save_scope_pos(ScopePos); 224347575f1f775f5f250be4f395fa694a7274a65f33Marcin Swiderski 224447575f1f775f5f250be4f395fa694a7274a65f33Marcin Swiderski // Create local scope for init statement and possible condition variable. 224547575f1f775f5f250be4f395fa694a7274a65f33Marcin Swiderski // Add destructor for init statement and condition variable. 224647575f1f775f5f250be4f395fa694a7274a65f33Marcin Swiderski // Store scope position for continue statement. 22479c378f705405d37f49795d5e915989de774fe11fTed Kremenek if (Stmt *Init = F->getInit()) 224847575f1f775f5f250be4f395fa694a7274a65f33Marcin Swiderski addLocalScopeForStmt(Init); 2249f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski LocalScope::const_iterator LoopBeginScopePos = ScopePos; 2250f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski 22519c378f705405d37f49795d5e915989de774fe11fTed Kremenek if (VarDecl *VD = F->getConditionVariable()) 225247575f1f775f5f250be4f395fa694a7274a65f33Marcin Swiderski addLocalScopeForVarDecl(VD); 225347575f1f775f5f250be4f395fa694a7274a65f33Marcin Swiderski LocalScope::const_iterator ContinueScopePos = ScopePos; 225447575f1f775f5f250be4f395fa694a7274a65f33Marcin Swiderski 225547575f1f775f5f250be4f395fa694a7274a65f33Marcin Swiderski addAutomaticObjDtors(ScopePos, save_scope_pos.get(), F); 225647575f1f775f5f250be4f395fa694a7274a65f33Marcin Swiderski 2257fefb9f7009702befaf715e7a8debc9505c3c8634Mike Stump // "for" is a control-flow statement. Thus we stop processing the current 2258fefb9f7009702befaf715e7a8debc9505c3c8634Mike Stump // block. 2259d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek if (Block) { 2260d438b3dbdcde4df4f61a99054104643e6aadf78bZhongxing Xu if (badCFG) 22616bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return nullptr; 2262d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek LoopSuccessor = Block; 22634f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek } else 22644f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek LoopSuccessor = Succ; 22656d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 22663f64a0e3be2c9408f8256bd3aa9f0ce9e268982cTed Kremenek // Save the current value for the break targets. 22673f64a0e3be2c9408f8256bd3aa9f0ce9e268982cTed Kremenek // All breaks should go to the code following the loop. 2268f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski SaveAndRestore<JumpTarget> save_break(BreakJumpTarget); 226947575f1f775f5f250be4f395fa694a7274a65f33Marcin Swiderski BreakJumpTarget = JumpTarget(LoopSuccessor, ScopePos); 22703f64a0e3be2c9408f8256bd3aa9f0ce9e268982cTed Kremenek 22716bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines CFGBlock *BodyBlock = nullptr, *TransitionBlock = nullptr; 227200998a068e50945118f334c98af05ed44d7c22a6Mike Stump 2273d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek // Now create the loop body. 2274d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek { 22756db0ad32fa0987ff76d4c41393991ef4b6895ea3Ted Kremenek assert(F->getBody()); 22766d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 22773f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek // Save the current values for Block, Succ, continue and break targets. 22783f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek SaveAndRestore<CFGBlock*> save_Block(Block), save_Succ(Succ); 22793f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek SaveAndRestore<JumpTarget> save_continue(ContinueJumpTarget); 22806d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 22813f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek // Create an empty block to represent the transition block for looping back 22823f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek // to the head of the loop. If we have increment code, it will 22833f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek // go in this block as well. 22843f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek Block = Succ = TransitionBlock = createBlock(false); 22853f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek TransitionBlock->setLoopTarget(F); 22866d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 22879c378f705405d37f49795d5e915989de774fe11fTed Kremenek if (Stmt *I = F->getInc()) { 22886d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump // Generate increment code in its own basic block. This is the target of 22896d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump // continue statements. 22904f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek Succ = addStmt(I); 2291e933450535ab077b95e59f929a4ccb25b6f360e6Ted Kremenek } 22926d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 22933575f84e459033d6427b84b4b795b22c85c4d27dTed Kremenek // Finish up the increment (or empty) block if it hasn't been already. 22943575f84e459033d6427b84b4b795b22c85c4d27dTed Kremenek if (Block) { 22953575f84e459033d6427b84b4b795b22c85c4d27dTed Kremenek assert(Block == Succ); 2296d438b3dbdcde4df4f61a99054104643e6aadf78bZhongxing Xu if (badCFG) 22976bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return nullptr; 22986bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines Block = nullptr; 22993575f84e459033d6427b84b4b795b22c85c4d27dTed Kremenek } 23006d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 23013f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek // The starting block for the loop increment is the block that should 23023f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek // represent the 'loop target' for looping back to the start of the loop. 23033f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek ContinueJumpTarget = JumpTarget(Succ, ContinueScopePos); 23043f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek ContinueJumpTarget.block->setLoopTarget(F); 23056d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 23063f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek // Loop body should end with destructor of Condition variable (if any). 23073f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek addAutomaticObjDtors(ScopePos, LoopBeginScopePos, F); 23083575f84e459033d6427b84b4b795b22c85c4d27dTed Kremenek 230947575f1f775f5f250be4f395fa694a7274a65f33Marcin Swiderski // If body is not a compound statement create implicit scope 231047575f1f775f5f250be4f395fa694a7274a65f33Marcin Swiderski // and add destructors. 231147575f1f775f5f250be4f395fa694a7274a65f33Marcin Swiderski if (!isa<CompoundStmt>(F->getBody())) 231247575f1f775f5f250be4f395fa694a7274a65f33Marcin Swiderski addLocalScopeAndDtors(F->getBody()); 231347575f1f775f5f250be4f395fa694a7274a65f33Marcin Swiderski 23146d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump // Now populate the body block, and in the process create new blocks as we 23156d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump // walk the body of the loop. 23163f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek BodyBlock = addStmt(F->getBody()); 2317af603f742491dc4707138c0293d295171fdd51baTed Kremenek 23183f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek if (!BodyBlock) { 23193f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek // In the case of "for (...;...;...);" we can have a null BodyBlock. 23203f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek // Use the continue jump target as the proxy for the body. 23213f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek BodyBlock = ContinueJumpTarget.block; 23223f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek } 2323d438b3dbdcde4df4f61a99054104643e6aadf78bZhongxing Xu else if (badCFG) 23246bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return nullptr; 23253f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek } 23263f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek 23273f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek // Because of short-circuit evaluation, the condition of the loop can span 23283f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek // multiple basic blocks. Thus we need the "Entry" and "Exit" blocks that 23293f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek // evaluate the condition. 23306bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines CFGBlock *EntryConditionBlock = nullptr, *ExitConditionBlock = nullptr; 23313f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek 23323f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek do { 23333f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek Expr *C = F->getCond(); 23343f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek 23353f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek // Specially handle logical operators, which have a slightly 23363f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek // more optimal CFG representation. 233756df4a9e0461d4dfb2a740cb6b0ce531d6c82538Richard Smith if (BinaryOperator *Cond = 23386bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines dyn_cast_or_null<BinaryOperator>(C ? C->IgnoreParens() : nullptr)) 23393f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek if (Cond->isLogicalOp()) { 2340651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines std::tie(EntryConditionBlock, ExitConditionBlock) = 23413f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek VisitLogicalOperator(Cond, F, BodyBlock, LoopSuccessor); 23423f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek break; 23433f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek } 23446d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 23453f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek // The default case when not handling logical operators. 23463f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek EntryConditionBlock = ExitConditionBlock = createBlock(false); 23473f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek ExitConditionBlock->setTerminator(F); 23483f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek 23493f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek // See if this is a known constant. 23503f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek TryResult KnownVal(true); 23513f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek 23523f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek if (C) { 23533f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek // Now add the actual condition to the condition block. 23543f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek // Because the condition itself may contain control-flow, new blocks may 23553f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek // be created. Thus we update "Succ" after adding the condition. 23563f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek Block = ExitConditionBlock; 23573f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek EntryConditionBlock = addStmt(C); 23583f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek 23593f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek // If this block contains a condition variable, add both the condition 23603f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek // variable and initializer to the CFG. 23613f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek if (VarDecl *VD = F->getConditionVariable()) { 23623f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek if (Expr *Init = VD->getInit()) { 23633f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek autoCreateBlock(); 23643f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek appendStmt(Block, F->getConditionVariableDeclStmt()); 23653f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek EntryConditionBlock = addStmt(Init); 23663f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek assert(Block == EntryConditionBlock); 23673f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek } 23683f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek } 23693f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek 23703f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek if (Block && badCFG) 23716bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return nullptr; 23723f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek 23733f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek KnownVal = tryEvaluateBool(C); 23743f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek } 23753f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek 23763f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek // Add the loop body entry as a successor to the condition. 23776bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines addSuccessor(ExitConditionBlock, KnownVal.isFalse() ? nullptr : BodyBlock); 23783f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek // Link up the condition block with the code that follows the loop. (the 23793f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek // false branch). 23806bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines addSuccessor(ExitConditionBlock, 23816bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines KnownVal.isTrue() ? nullptr : LoopSuccessor); 23826d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 23833f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek } while (false); 23843f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek 23853f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek // Link up the loop-back block to the entry condition block. 23863f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek addSuccessor(TransitionBlock, EntryConditionBlock); 23873f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek 23883f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek // The condition block is the implicit successor for any code above the loop. 23893f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek Succ = EntryConditionBlock; 23906d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 2391d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek // If the loop contains initialization, create a new block for those 23926d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump // statements. This block can also contain statements that precede the loop. 23939c378f705405d37f49795d5e915989de774fe11fTed Kremenek if (Stmt *I = F->getInit()) { 2394d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek Block = createBlock(); 239549af7cb8a3aca79783e7a0708b97a8f856f0da22Ted Kremenek return addStmt(I); 23962bac4ea765a4a6e1f6149964663f62d4bca6743bTed Kremenek } 239736f327c309b1fb6b82f1987190f0be74000b14c1Zhanyong Wan 239836f327c309b1fb6b82f1987190f0be74000b14c1Zhanyong Wan // There is no loop initialization. We are thus basically a while loop. 239936f327c309b1fb6b82f1987190f0be74000b14c1Zhanyong Wan // NULL out Block to force lazy block construction. 24006bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines Block = nullptr; 240136f327c309b1fb6b82f1987190f0be74000b14c1Zhanyong Wan Succ = EntryConditionBlock; 240236f327c309b1fb6b82f1987190f0be74000b14c1Zhanyong Wan return EntryConditionBlock; 2403d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek} 2404d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek 2405115c1b9cc758d15f38e1d2ad4cf07b1cacfb3115Ted KremenekCFGBlock *CFGBuilder::VisitMemberExpr(MemberExpr *M, AddStmtChoice asc) { 24063179a45a0e91c1dcf3492222170cf4499531bb92Ted Kremenek if (asc.alwaysAdd(*this, M)) { 2407115c1b9cc758d15f38e1d2ad4cf07b1cacfb3115Ted Kremenek autoCreateBlock(); 2408247e9665d897a7bbbf60c1c0d3b6609c4504a961Ted Kremenek appendStmt(Block, M); 2409115c1b9cc758d15f38e1d2ad4cf07b1cacfb3115Ted Kremenek } 2410892697dd2287caf7c29aaaa82909b0e90b8b63feTed Kremenek return Visit(M->getBase()); 2411115c1b9cc758d15f38e1d2ad4cf07b1cacfb3115Ted Kremenek} 2412115c1b9cc758d15f38e1d2ad4cf07b1cacfb3115Ted Kremenek 24139c378f705405d37f49795d5e915989de774fe11fTed KremenekCFGBlock *CFGBuilder::VisitObjCForCollectionStmt(ObjCForCollectionStmt *S) { 2414514de5a21645900c92cf4f4f7313d6f66945d134Ted Kremenek // Objective-C fast enumeration 'for' statements: 2415514de5a21645900c92cf4f4f7313d6f66945d134Ted Kremenek // http://developer.apple.com/documentation/Cocoa/Conceptual/ObjectiveC 2416514de5a21645900c92cf4f4f7313d6f66945d134Ted Kremenek // 2417514de5a21645900c92cf4f4f7313d6f66945d134Ted Kremenek // for ( Type newVariable in collection_expression ) { statements } 2418514de5a21645900c92cf4f4f7313d6f66945d134Ted Kremenek // 2419514de5a21645900c92cf4f4f7313d6f66945d134Ted Kremenek // becomes: 2420514de5a21645900c92cf4f4f7313d6f66945d134Ted Kremenek // 2421514de5a21645900c92cf4f4f7313d6f66945d134Ted Kremenek // prologue: 2422514de5a21645900c92cf4f4f7313d6f66945d134Ted Kremenek // 1. collection_expression 2423514de5a21645900c92cf4f4f7313d6f66945d134Ted Kremenek // T. jump to loop_entry 2424514de5a21645900c92cf4f4f7313d6f66945d134Ted Kremenek // loop_entry: 24254cb3a855df3b3f8d551565cae9f43939a301ea89Ted Kremenek // 1. side-effects of element expression 2426514de5a21645900c92cf4f4f7313d6f66945d134Ted Kremenek // 1. ObjCForCollectionStmt [performs binding to newVariable] 2427514de5a21645900c92cf4f4f7313d6f66945d134Ted Kremenek // T. ObjCForCollectionStmt TB, FB [jumps to TB if newVariable != nil] 2428514de5a21645900c92cf4f4f7313d6f66945d134Ted Kremenek // TB: 2429514de5a21645900c92cf4f4f7313d6f66945d134Ted Kremenek // statements 2430514de5a21645900c92cf4f4f7313d6f66945d134Ted Kremenek // T. jump to loop_entry 2431514de5a21645900c92cf4f4f7313d6f66945d134Ted Kremenek // FB: 2432514de5a21645900c92cf4f4f7313d6f66945d134Ted Kremenek // what comes after 2433514de5a21645900c92cf4f4f7313d6f66945d134Ted Kremenek // 2434514de5a21645900c92cf4f4f7313d6f66945d134Ted Kremenek // and 2435514de5a21645900c92cf4f4f7313d6f66945d134Ted Kremenek // 2436514de5a21645900c92cf4f4f7313d6f66945d134Ted Kremenek // Type existingItem; 2437514de5a21645900c92cf4f4f7313d6f66945d134Ted Kremenek // for ( existingItem in expression ) { statements } 2438514de5a21645900c92cf4f4f7313d6f66945d134Ted Kremenek // 2439514de5a21645900c92cf4f4f7313d6f66945d134Ted Kremenek // becomes: 2440514de5a21645900c92cf4f4f7313d6f66945d134Ted Kremenek // 24416d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump // the same with newVariable replaced with existingItem; the binding works 24426d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump // the same except that for one ObjCForCollectionStmt::getElement() returns 24436d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump // a DeclStmt and the other returns a DeclRefExpr. 2444514de5a21645900c92cf4f4f7313d6f66945d134Ted Kremenek // 24456d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 24466bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines CFGBlock *LoopSuccessor = nullptr; 24476d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 2448514de5a21645900c92cf4f4f7313d6f66945d134Ted Kremenek if (Block) { 2449d438b3dbdcde4df4f61a99054104643e6aadf78bZhongxing Xu if (badCFG) 24506bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return nullptr; 2451514de5a21645900c92cf4f4f7313d6f66945d134Ted Kremenek LoopSuccessor = Block; 24526bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines Block = nullptr; 24534f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek } else 24544f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek LoopSuccessor = Succ; 24556d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 24564cb3a855df3b3f8d551565cae9f43939a301ea89Ted Kremenek // Build the condition blocks. 24579c378f705405d37f49795d5e915989de774fe11fTed Kremenek CFGBlock *ExitConditionBlock = createBlock(false); 24586d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 24594cb3a855df3b3f8d551565cae9f43939a301ea89Ted Kremenek // Set the terminator for the "exit" condition block. 24606d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump ExitConditionBlock->setTerminator(S); 24616d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 24626d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump // The last statement in the block should be the ObjCForCollectionStmt, which 24636d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump // performs the actual binding to 'element' and determines if there are any 24646d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump // more items in the collection. 2465892697dd2287caf7c29aaaa82909b0e90b8b63feTed Kremenek appendStmt(ExitConditionBlock, S); 24664cb3a855df3b3f8d551565cae9f43939a301ea89Ted Kremenek Block = ExitConditionBlock; 24676d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 24684cb3a855df3b3f8d551565cae9f43939a301ea89Ted Kremenek // Walk the 'element' expression to see if there are any side-effects. We 2469fc8f0e14ad142ed811e90fbd9a30e419e301c717Chris Lattner // generate new blocks as necessary. We DON'T add the statement by default to 24706d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump // the CFG unless it contains control-flow. 2471012614ecf78442368ec82ee30efb3bc047b413e6Ted Kremenek CFGBlock *EntryConditionBlock = Visit(S->getElement(), 2472012614ecf78442368ec82ee30efb3bc047b413e6Ted Kremenek AddStmtChoice::NotAlwaysAdd); 24736d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump if (Block) { 2474d438b3dbdcde4df4f61a99054104643e6aadf78bZhongxing Xu if (badCFG) 24756bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return nullptr; 24766bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines Block = nullptr; 24774e8df2eb7072db8f66572c3db31a2a08b12a752eTed Kremenek } 24786d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 24796d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump // The condition block is the implicit successor for the loop body as well as 24806d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump // any code above the loop. 24814cb3a855df3b3f8d551565cae9f43939a301ea89Ted Kremenek Succ = EntryConditionBlock; 24826d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 24834cb3a855df3b3f8d551565cae9f43939a301ea89Ted Kremenek // Now create the true branch. 24846d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump { 24854cb3a855df3b3f8d551565cae9f43939a301ea89Ted Kremenek // Save the current values for Succ, continue and break targets. 24864c98b1f67cdf385e05a86d54201b319cf1f1c042Anna Zaks SaveAndRestore<CFGBlock*> save_Block(Block), save_Succ(Succ); 2487f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski SaveAndRestore<JumpTarget> save_continue(ContinueJumpTarget), 24884c98b1f67cdf385e05a86d54201b319cf1f1c042Anna Zaks save_break(BreakJumpTarget); 24894c98b1f67cdf385e05a86d54201b319cf1f1c042Anna Zaks 24904c98b1f67cdf385e05a86d54201b319cf1f1c042Anna Zaks // Add an intermediate block between the BodyBlock and the 24914c98b1f67cdf385e05a86d54201b319cf1f1c042Anna Zaks // EntryConditionBlock to represent the "loop back" transition, for looping 24924c98b1f67cdf385e05a86d54201b319cf1f1c042Anna Zaks // back to the head of the loop. 24936bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines CFGBlock *LoopBackBlock = nullptr; 24944c98b1f67cdf385e05a86d54201b319cf1f1c042Anna Zaks Succ = LoopBackBlock = createBlock(); 24954c98b1f67cdf385e05a86d54201b319cf1f1c042Anna Zaks LoopBackBlock->setLoopTarget(S); 24964c98b1f67cdf385e05a86d54201b319cf1f1c042Anna Zaks 2497f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski BreakJumpTarget = JumpTarget(LoopSuccessor, ScopePos); 24984c98b1f67cdf385e05a86d54201b319cf1f1c042Anna Zaks ContinueJumpTarget = JumpTarget(Succ, ScopePos); 24996d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 25009c378f705405d37f49795d5e915989de774fe11fTed Kremenek CFGBlock *BodyBlock = addStmt(S->getBody()); 25016d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 25024cb3a855df3b3f8d551565cae9f43939a301ea89Ted Kremenek if (!BodyBlock) 25034c98b1f67cdf385e05a86d54201b319cf1f1c042Anna Zaks BodyBlock = ContinueJumpTarget.block; // can happen for "for (X in Y) ;" 25044e8df2eb7072db8f66572c3db31a2a08b12a752eTed Kremenek else if (Block) { 2505d438b3dbdcde4df4f61a99054104643e6aadf78bZhongxing Xu if (badCFG) 25066bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return nullptr; 25074e8df2eb7072db8f66572c3db31a2a08b12a752eTed Kremenek } 25086d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 25094cb3a855df3b3f8d551565cae9f43939a301ea89Ted Kremenek // This new body block is a successor to our "exit" condition block. 25100a3ed3143b00f237decb1288c1ff574ae09eba4eTed Kremenek addSuccessor(ExitConditionBlock, BodyBlock); 25114cb3a855df3b3f8d551565cae9f43939a301ea89Ted Kremenek } 25126d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 25134cb3a855df3b3f8d551565cae9f43939a301ea89Ted Kremenek // Link up the condition block with the code that follows the loop. 25144cb3a855df3b3f8d551565cae9f43939a301ea89Ted Kremenek // (the false branch). 25150a3ed3143b00f237decb1288c1ff574ae09eba4eTed Kremenek addSuccessor(ExitConditionBlock, LoopSuccessor); 25164cb3a855df3b3f8d551565cae9f43939a301ea89Ted Kremenek 2517514de5a21645900c92cf4f4f7313d6f66945d134Ted Kremenek // Now create a prologue block to contain the collection expression. 25184cb3a855df3b3f8d551565cae9f43939a301ea89Ted Kremenek Block = createBlock(); 2519514de5a21645900c92cf4f4f7313d6f66945d134Ted Kremenek return addStmt(S->getCollection()); 25206d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump} 25216d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 25228e282c332f8ad51dedf86a185a4dcb78ef93fb51Ted KremenekCFGBlock *CFGBuilder::VisitObjCAutoreleasePoolStmt(ObjCAutoreleasePoolStmt *S) { 25238e282c332f8ad51dedf86a185a4dcb78ef93fb51Ted Kremenek // Inline the body. 25248e282c332f8ad51dedf86a185a4dcb78ef93fb51Ted Kremenek return addStmt(S->getSubStmt()); 25258e282c332f8ad51dedf86a185a4dcb78ef93fb51Ted Kremenek // TODO: consider adding cleanups for the end of @autoreleasepool scope. 25268e282c332f8ad51dedf86a185a4dcb78ef93fb51Ted Kremenek} 25278e282c332f8ad51dedf86a185a4dcb78ef93fb51Ted Kremenek 25289c378f705405d37f49795d5e915989de774fe11fTed KremenekCFGBlock *CFGBuilder::VisitObjCAtSynchronizedStmt(ObjCAtSynchronizedStmt *S) { 2529b3b0b3624e462c2940f65b86e773bfc300005203Ted Kremenek // FIXME: Add locking 'primitives' to CFG for @synchronized. 25306d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 2531b3b0b3624e462c2940f65b86e773bfc300005203Ted Kremenek // Inline the body. 25324f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek CFGBlock *SyncBlock = addStmt(S->getSynchBody()); 25336d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 2534da5348eda7bb45d715561249dec9833d51dfda67Ted Kremenek // The sync body starts its own basic block. This makes it a little easier 2535da5348eda7bb45d715561249dec9833d51dfda67Ted Kremenek // for diagnostic clients. 2536da5348eda7bb45d715561249dec9833d51dfda67Ted Kremenek if (SyncBlock) { 2537d438b3dbdcde4df4f61a99054104643e6aadf78bZhongxing Xu if (badCFG) 25386bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return nullptr; 25396d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 25406bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines Block = nullptr; 2541fadebbafe622752c3c6565b53ce8cd42bbbbd90cTed Kremenek Succ = SyncBlock; 2542da5348eda7bb45d715561249dec9833d51dfda67Ted Kremenek } 25436d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 25444beaa9f51b2da57c64740cef2bd1c2fdb0c325d5Ted Kremenek // Add the @synchronized to the CFG. 25454beaa9f51b2da57c64740cef2bd1c2fdb0c325d5Ted Kremenek autoCreateBlock(); 2546247e9665d897a7bbbf60c1c0d3b6609c4504a961Ted Kremenek appendStmt(Block, S); 25474beaa9f51b2da57c64740cef2bd1c2fdb0c325d5Ted Kremenek 2548b3b0b3624e462c2940f65b86e773bfc300005203Ted Kremenek // Inline the sync expression. 25494f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek return addStmt(S->getSynchExpr()); 2550b3b0b3624e462c2940f65b86e773bfc300005203Ted Kremenek} 25516d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 25529c378f705405d37f49795d5e915989de774fe11fTed KremenekCFGBlock *CFGBuilder::VisitObjCAtTryStmt(ObjCAtTryStmt *S) { 25534f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek // FIXME 255490658ec72542df44eb462c69056184d2946bdbceTed Kremenek return NYS(); 2555e31c0d206b872b056dc42c3af21b11d5de4edfd9Ted Kremenek} 2556514de5a21645900c92cf4f4f7313d6f66945d134Ted Kremenek 25574b9c2d235fb9449e249d74f48ecfec601650de93John McCallCFGBlock *CFGBuilder::VisitPseudoObjectExpr(PseudoObjectExpr *E) { 25584b9c2d235fb9449e249d74f48ecfec601650de93John McCall autoCreateBlock(); 25594b9c2d235fb9449e249d74f48ecfec601650de93John McCall 25604b9c2d235fb9449e249d74f48ecfec601650de93John McCall // Add the PseudoObject as the last thing. 25614b9c2d235fb9449e249d74f48ecfec601650de93John McCall appendStmt(Block, E); 25624b9c2d235fb9449e249d74f48ecfec601650de93John McCall 25634b9c2d235fb9449e249d74f48ecfec601650de93John McCall CFGBlock *lastBlock = Block; 25644b9c2d235fb9449e249d74f48ecfec601650de93John McCall 25654b9c2d235fb9449e249d74f48ecfec601650de93John McCall // Before that, evaluate all of the semantics in order. In 25664b9c2d235fb9449e249d74f48ecfec601650de93John McCall // CFG-land, that means appending them in reverse order. 25674b9c2d235fb9449e249d74f48ecfec601650de93John McCall for (unsigned i = E->getNumSemanticExprs(); i != 0; ) { 25684b9c2d235fb9449e249d74f48ecfec601650de93John McCall Expr *Semantic = E->getSemanticExpr(--i); 25694b9c2d235fb9449e249d74f48ecfec601650de93John McCall 25704b9c2d235fb9449e249d74f48ecfec601650de93John McCall // If the semantic is an opaque value, we're being asked to bind 25714b9c2d235fb9449e249d74f48ecfec601650de93John McCall // it to its source expression. 25724b9c2d235fb9449e249d74f48ecfec601650de93John McCall if (OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(Semantic)) 25734b9c2d235fb9449e249d74f48ecfec601650de93John McCall Semantic = OVE->getSourceExpr(); 25744b9c2d235fb9449e249d74f48ecfec601650de93John McCall 25754b9c2d235fb9449e249d74f48ecfec601650de93John McCall if (CFGBlock *B = Visit(Semantic)) 25764b9c2d235fb9449e249d74f48ecfec601650de93John McCall lastBlock = B; 25774b9c2d235fb9449e249d74f48ecfec601650de93John McCall } 25784b9c2d235fb9449e249d74f48ecfec601650de93John McCall 25794b9c2d235fb9449e249d74f48ecfec601650de93John McCall return lastBlock; 25804b9c2d235fb9449e249d74f48ecfec601650de93John McCall} 25814b9c2d235fb9449e249d74f48ecfec601650de93John McCall 25829c378f705405d37f49795d5e915989de774fe11fTed KremenekCFGBlock *CFGBuilder::VisitWhileStmt(WhileStmt *W) { 25836bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines CFGBlock *LoopSuccessor = nullptr; 25846d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 258505adedcb5e199e377e35f576288caf5ceed40136Marcin Swiderski // Save local scope position because in case of condition variable ScopePos 258605adedcb5e199e377e35f576288caf5ceed40136Marcin Swiderski // won't be restored when traversing AST. 258705adedcb5e199e377e35f576288caf5ceed40136Marcin Swiderski SaveAndRestore<LocalScope::const_iterator> save_scope_pos(ScopePos); 258805adedcb5e199e377e35f576288caf5ceed40136Marcin Swiderski 258905adedcb5e199e377e35f576288caf5ceed40136Marcin Swiderski // Create local scope for possible condition variable. 259005adedcb5e199e377e35f576288caf5ceed40136Marcin Swiderski // Store scope position for continue statement. 2591f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski LocalScope::const_iterator LoopBeginScopePos = ScopePos; 25929c378f705405d37f49795d5e915989de774fe11fTed Kremenek if (VarDecl *VD = W->getConditionVariable()) { 259305adedcb5e199e377e35f576288caf5ceed40136Marcin Swiderski addLocalScopeForVarDecl(VD); 259405adedcb5e199e377e35f576288caf5ceed40136Marcin Swiderski addAutomaticObjDtors(ScopePos, LoopBeginScopePos, W); 259505adedcb5e199e377e35f576288caf5ceed40136Marcin Swiderski } 2596f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski 2597fefb9f7009702befaf715e7a8debc9505c3c8634Mike Stump // "while" is a control-flow statement. Thus we stop processing the current 2598fefb9f7009702befaf715e7a8debc9505c3c8634Mike Stump // block. 2599d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek if (Block) { 2600d438b3dbdcde4df4f61a99054104643e6aadf78bZhongxing Xu if (badCFG) 26016bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return nullptr; 2602d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek LoopSuccessor = Block; 26036bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines Block = nullptr; 26043f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek } else { 26054f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek LoopSuccessor = Succ; 260649af7cb8a3aca79783e7a0708b97a8f856f0da22Ted Kremenek } 26076d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 26086bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines CFGBlock *BodyBlock = nullptr, *TransitionBlock = nullptr; 260900998a068e50945118f334c98af05ed44d7c22a6Mike Stump 2610d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek // Process the loop body. 2611d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek { 2612f6e8541dd884029b85483a319ce7d32f3e476dccTed Kremenek assert(W->getBody()); 2613d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek 26143f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek // Save the current values for Block, Succ, continue and break targets. 2615f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski SaveAndRestore<CFGBlock*> save_Block(Block), save_Succ(Succ); 2616f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski SaveAndRestore<JumpTarget> save_continue(ContinueJumpTarget), 26173f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek save_break(BreakJumpTarget); 2618f6e8541dd884029b85483a319ce7d32f3e476dccTed Kremenek 26196d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump // Create an empty block to represent the transition block for looping back 26206d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump // to the head of the loop. 26213f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek Succ = TransitionBlock = createBlock(false); 26223f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek TransitionBlock->setLoopTarget(W); 2623f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski ContinueJumpTarget = JumpTarget(Succ, LoopBeginScopePos); 26246d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 2625d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek // All breaks should go to the code following the loop. 262605adedcb5e199e377e35f576288caf5ceed40136Marcin Swiderski BreakJumpTarget = JumpTarget(LoopSuccessor, ScopePos); 26276d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 262805adedcb5e199e377e35f576288caf5ceed40136Marcin Swiderski // Loop body should end with destructor of Condition variable (if any). 262905adedcb5e199e377e35f576288caf5ceed40136Marcin Swiderski addAutomaticObjDtors(ScopePos, LoopBeginScopePos, W); 263005adedcb5e199e377e35f576288caf5ceed40136Marcin Swiderski 263105adedcb5e199e377e35f576288caf5ceed40136Marcin Swiderski // If body is not a compound statement create implicit scope 263205adedcb5e199e377e35f576288caf5ceed40136Marcin Swiderski // and add destructors. 263305adedcb5e199e377e35f576288caf5ceed40136Marcin Swiderski if (!isa<CompoundStmt>(W->getBody())) 263405adedcb5e199e377e35f576288caf5ceed40136Marcin Swiderski addLocalScopeAndDtors(W->getBody()); 263505adedcb5e199e377e35f576288caf5ceed40136Marcin Swiderski 2636d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek // Create the body. The returned block is the entry to the loop body. 26373f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek BodyBlock = addStmt(W->getBody()); 26386d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 2639af603f742491dc4707138c0293d295171fdd51baTed Kremenek if (!BodyBlock) 26409ce5270f0aadaaf03a0cf705787f42ce9eb1194cTed Kremenek BodyBlock = ContinueJumpTarget.block; // can happen for "while(...) ;" 26413f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek else if (Block && badCFG) 26426bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return nullptr; 26433f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek } 26443f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek 26453f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek // Because of short-circuit evaluation, the condition of the loop can span 26463f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek // multiple basic blocks. Thus we need the "Entry" and "Exit" blocks that 26473f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek // evaluate the condition. 26486bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines CFGBlock *EntryConditionBlock = nullptr, *ExitConditionBlock = nullptr; 26493f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek 26503f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek do { 26513f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek Expr *C = W->getCond(); 26523f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek 26533f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek // Specially handle logical operators, which have a slightly 26543f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek // more optimal CFG representation. 265556df4a9e0461d4dfb2a740cb6b0ce531d6c82538Richard Smith if (BinaryOperator *Cond = dyn_cast<BinaryOperator>(C->IgnoreParens())) 26563f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek if (Cond->isLogicalOp()) { 2657651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines std::tie(EntryConditionBlock, ExitConditionBlock) = 2658651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines VisitLogicalOperator(Cond, W, BodyBlock, LoopSuccessor); 26593f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek break; 26603f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek } 26613f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek 26623f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek // The default case when not handling logical operators. 2663857f5681f5e2bbb482f41f461add502b556c712aTed Kremenek ExitConditionBlock = createBlock(false); 26643f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek ExitConditionBlock->setTerminator(W); 26653f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek 26663f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek // Now add the actual condition to the condition block. 26673f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek // Because the condition itself may contain control-flow, new blocks may 26683f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek // be created. Thus we update "Succ" after adding the condition. 26693f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek Block = ExitConditionBlock; 26703f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek Block = EntryConditionBlock = addStmt(C); 26713f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek 26723f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek // If this block contains a condition variable, add both the condition 26733f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek // variable and initializer to the CFG. 26743f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek if (VarDecl *VD = W->getConditionVariable()) { 26753f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek if (Expr *Init = VD->getInit()) { 26763f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek autoCreateBlock(); 26773f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek appendStmt(Block, W->getConditionVariableDeclStmt()); 26783f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek EntryConditionBlock = addStmt(Init); 26793f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek assert(Block == EntryConditionBlock); 26803f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek } 26814e8df2eb7072db8f66572c3db31a2a08b12a752eTed Kremenek } 26826d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 26833f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek if (Block && badCFG) 26846bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return nullptr; 26853f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek 26863f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek // See if this is a known constant. 26873f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek const TryResult& KnownVal = tryEvaluateBool(C); 26883f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek 2689941fde8019d47c694b8483db45d5878818fa69d1Ted Kremenek // Add the loop body entry as a successor to the condition. 26906bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines addSuccessor(ExitConditionBlock, KnownVal.isFalse() ? nullptr : BodyBlock); 26913f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek // Link up the condition block with the code that follows the loop. (the 26923f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek // false branch). 26936bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines addSuccessor(ExitConditionBlock, 26946bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines KnownVal.isTrue() ? nullptr : LoopSuccessor); 26953f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek 26963f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek } while(false); 26976d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 26983f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek // Link up the loop-back block to the entry condition block. 26993f635c08b2d0b2d5bafb38da09589cb238407faaTed Kremenek addSuccessor(TransitionBlock, EntryConditionBlock); 27006d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 27016d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump // There can be no more statements in the condition block since we loop back 27026d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump // to this block. NULL out Block to force lazy creation of another block. 27036bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines Block = nullptr; 27046d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 27054ec010a6ccf4db2ab2ef9e68942642d50f7f193cTed Kremenek // Return the condition block, which is the dominating block for the loop. 27065482713d70ecbfe608940018046aa248b3d03443Ted Kremenek Succ = EntryConditionBlock; 270749af7cb8a3aca79783e7a0708b97a8f856f0da22Ted Kremenek return EntryConditionBlock; 2708d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek} 27091eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 27101eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 27119c378f705405d37f49795d5e915989de774fe11fTed KremenekCFGBlock *CFGBuilder::VisitObjCAtCatchStmt(ObjCAtCatchStmt *S) { 27124f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek // FIXME: For now we pretend that @catch and the code it contains does not 27134f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek // exit. 27144f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek return Block; 27154f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek} 27166d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 27179c378f705405d37f49795d5e915989de774fe11fTed KremenekCFGBlock *CFGBuilder::VisitObjCAtThrowStmt(ObjCAtThrowStmt *S) { 27182fda504dccd79f91ac9a7d82acecfbab3eaa1719Ted Kremenek // FIXME: This isn't complete. We basically treat @throw like a return 27192fda504dccd79f91ac9a7d82acecfbab3eaa1719Ted Kremenek // statement. 27206d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 27216c2497248bc4f7fd8e5fb0a206d20abbf0e16645Ted Kremenek // If we were in the middle of a block we stop processing that block. 2722d438b3dbdcde4df4f61a99054104643e6aadf78bZhongxing Xu if (badCFG) 27236bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return nullptr; 27246d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 27252fda504dccd79f91ac9a7d82acecfbab3eaa1719Ted Kremenek // Create the new block. 27262fda504dccd79f91ac9a7d82acecfbab3eaa1719Ted Kremenek Block = createBlock(false); 27276d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 27282fda504dccd79f91ac9a7d82acecfbab3eaa1719Ted Kremenek // The Exit block is the only successor. 27290a3ed3143b00f237decb1288c1ff574ae09eba4eTed Kremenek addSuccessor(Block, &cfg->getExit()); 27306d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 27316d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump // Add the statement to the block. This may create new blocks if S contains 27326d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump // control-flow (short-circuit operations). 2733852274d4257134906995cb252fb3dfd2d71deae8Ted Kremenek return VisitStmt(S, AddStmtChoice::AlwaysAdd); 27342fda504dccd79f91ac9a7d82acecfbab3eaa1719Ted Kremenek} 2735989d52d469df0c202f7de82f54407066c7db2e63Ted Kremenek 27369c378f705405d37f49795d5e915989de774fe11fTed KremenekCFGBlock *CFGBuilder::VisitCXXThrowExpr(CXXThrowExpr *T) { 27376c2497248bc4f7fd8e5fb0a206d20abbf0e16645Ted Kremenek // If we were in the middle of a block we stop processing that block. 2738d438b3dbdcde4df4f61a99054104643e6aadf78bZhongxing Xu if (badCFG) 27396bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return nullptr; 27400979d80615df97c675423de631c1b884819f4712Mike Stump 27410979d80615df97c675423de631c1b884819f4712Mike Stump // Create the new block. 27420979d80615df97c675423de631c1b884819f4712Mike Stump Block = createBlock(false); 27430979d80615df97c675423de631c1b884819f4712Mike Stump 27445d1d20227878cd03db8b2dd23efd4cedfe874feeMike Stump if (TryTerminatedBlock) 27455d1d20227878cd03db8b2dd23efd4cedfe874feeMike Stump // The current try statement is the only successor. 27460a3ed3143b00f237decb1288c1ff574ae09eba4eTed Kremenek addSuccessor(Block, TryTerminatedBlock); 2747ad5a894df1841698c824381b414630799adc26caTed Kremenek else 27485d1d20227878cd03db8b2dd23efd4cedfe874feeMike Stump // otherwise the Exit block is the only successor. 27490a3ed3143b00f237decb1288c1ff574ae09eba4eTed Kremenek addSuccessor(Block, &cfg->getExit()); 27500979d80615df97c675423de631c1b884819f4712Mike Stump 27510979d80615df97c675423de631c1b884819f4712Mike Stump // Add the statement to the block. This may create new blocks if S contains 27520979d80615df97c675423de631c1b884819f4712Mike Stump // control-flow (short-circuit operations). 2753852274d4257134906995cb252fb3dfd2d71deae8Ted Kremenek return VisitStmt(T, AddStmtChoice::AlwaysAdd); 27540979d80615df97c675423de631c1b884819f4712Mike Stump} 27550979d80615df97c675423de631c1b884819f4712Mike Stump 27569c378f705405d37f49795d5e915989de774fe11fTed KremenekCFGBlock *CFGBuilder::VisitDoStmt(DoStmt *D) { 27576bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines CFGBlock *LoopSuccessor = nullptr; 27586d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 27598f9893a2beeacd5149bd2d3d4c6e130516915068Mike Stump // "do...while" is a control-flow statement. Thus we stop processing the 27608f9893a2beeacd5149bd2d3d4c6e130516915068Mike Stump // current block. 2761d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek if (Block) { 2762d438b3dbdcde4df4f61a99054104643e6aadf78bZhongxing Xu if (badCFG) 27636bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return nullptr; 2764d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek LoopSuccessor = Block; 27654f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek } else 27664f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek LoopSuccessor = Succ; 27676d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 27686d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump // Because of short-circuit evaluation, the condition of the loop can span 27696d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump // multiple basic blocks. Thus we need the "Entry" and "Exit" blocks that 27706d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump // evaluate the condition. 27719c378f705405d37f49795d5e915989de774fe11fTed Kremenek CFGBlock *ExitConditionBlock = createBlock(false); 27729c378f705405d37f49795d5e915989de774fe11fTed Kremenek CFGBlock *EntryConditionBlock = ExitConditionBlock; 27736d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 277449af7cb8a3aca79783e7a0708b97a8f856f0da22Ted Kremenek // Set the terminator for the "exit" condition block. 27756d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump ExitConditionBlock->setTerminator(D); 27766d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 27776d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump // Now add the actual condition to the condition block. Because the condition 27786d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump // itself may contain control-flow, new blocks may be created. 27799c378f705405d37f49795d5e915989de774fe11fTed Kremenek if (Stmt *C = D->getCond()) { 278049af7cb8a3aca79783e7a0708b97a8f856f0da22Ted Kremenek Block = ExitConditionBlock; 278149af7cb8a3aca79783e7a0708b97a8f856f0da22Ted Kremenek EntryConditionBlock = addStmt(C); 27824e8df2eb7072db8f66572c3db31a2a08b12a752eTed Kremenek if (Block) { 2783d438b3dbdcde4df4f61a99054104643e6aadf78bZhongxing Xu if (badCFG) 27846bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return nullptr; 27854e8df2eb7072db8f66572c3db31a2a08b12a752eTed Kremenek } 278649af7cb8a3aca79783e7a0708b97a8f856f0da22Ted Kremenek } 27876d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 27885482713d70ecbfe608940018046aa248b3d03443Ted Kremenek // The condition block is the implicit successor for the loop body. 278949af7cb8a3aca79783e7a0708b97a8f856f0da22Ted Kremenek Succ = EntryConditionBlock; 279049af7cb8a3aca79783e7a0708b97a8f856f0da22Ted Kremenek 279100998a068e50945118f334c98af05ed44d7c22a6Mike Stump // See if this is a known constant. 27920a3ed3143b00f237decb1288c1ff574ae09eba4eTed Kremenek const TryResult &KnownVal = tryEvaluateBool(D->getCond()); 279300998a068e50945118f334c98af05ed44d7c22a6Mike Stump 2794d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek // Process the loop body. 27956bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines CFGBlock *BodyBlock = nullptr; 2796d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek { 27976db0ad32fa0987ff76d4c41393991ef4b6895ea3Ted Kremenek assert(D->getBody()); 27986d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 2799d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek // Save the current values for Block, Succ, and continue and break targets 2800f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski SaveAndRestore<CFGBlock*> save_Block(Block), save_Succ(Succ); 2801f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski SaveAndRestore<JumpTarget> save_continue(ContinueJumpTarget), 2802f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski save_break(BreakJumpTarget); 28036d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 2804d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek // All continues within this loop should go to the condition block 2805f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski ContinueJumpTarget = JumpTarget(EntryConditionBlock, ScopePos); 28066d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 2807d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek // All breaks should go to the code following the loop. 2808f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski BreakJumpTarget = JumpTarget(LoopSuccessor, ScopePos); 28096d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 2810d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek // NULL out Block to force lazy instantiation of blocks for the body. 28116bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines Block = nullptr; 28126d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 281305adedcb5e199e377e35f576288caf5ceed40136Marcin Swiderski // If body is not a compound statement create implicit scope 281405adedcb5e199e377e35f576288caf5ceed40136Marcin Swiderski // and add destructors. 281505adedcb5e199e377e35f576288caf5ceed40136Marcin Swiderski if (!isa<CompoundStmt>(D->getBody())) 281605adedcb5e199e377e35f576288caf5ceed40136Marcin Swiderski addLocalScopeAndDtors(D->getBody()); 281705adedcb5e199e377e35f576288caf5ceed40136Marcin Swiderski 2818d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek // Create the body. The returned block is the entry to the loop body. 28194f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek BodyBlock = addStmt(D->getBody()); 28206d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 2821af603f742491dc4707138c0293d295171fdd51baTed Kremenek if (!BodyBlock) 2822a9d996dbeb719200c4a9d86f68166a237583025fTed Kremenek BodyBlock = EntryConditionBlock; // can happen for "do ; while(...)" 28234e8df2eb7072db8f66572c3db31a2a08b12a752eTed Kremenek else if (Block) { 2824d438b3dbdcde4df4f61a99054104643e6aadf78bZhongxing Xu if (badCFG) 28256bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return nullptr; 28264e8df2eb7072db8f66572c3db31a2a08b12a752eTed Kremenek } 28276d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 2828d173dc7825e999edab836f8215a82a96eae7c738Ted Kremenek if (!KnownVal.isFalse()) { 2829d173dc7825e999edab836f8215a82a96eae7c738Ted Kremenek // Add an intermediate block between the BodyBlock and the 2830d173dc7825e999edab836f8215a82a96eae7c738Ted Kremenek // ExitConditionBlock to represent the "loop back" transition. Create an 2831d173dc7825e999edab836f8215a82a96eae7c738Ted Kremenek // empty block to represent the transition block for looping back to the 2832d173dc7825e999edab836f8215a82a96eae7c738Ted Kremenek // head of the loop. 2833d173dc7825e999edab836f8215a82a96eae7c738Ted Kremenek // FIXME: Can we do this more efficiently without adding another block? 28346bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines Block = nullptr; 2835d173dc7825e999edab836f8215a82a96eae7c738Ted Kremenek Succ = BodyBlock; 2836d173dc7825e999edab836f8215a82a96eae7c738Ted Kremenek CFGBlock *LoopBackBlock = createBlock(); 2837d173dc7825e999edab836f8215a82a96eae7c738Ted Kremenek LoopBackBlock->setLoopTarget(D); 2838d173dc7825e999edab836f8215a82a96eae7c738Ted Kremenek 2839d173dc7825e999edab836f8215a82a96eae7c738Ted Kremenek // Add the loop body entry as a successor to the condition. 28400a3ed3143b00f237decb1288c1ff574ae09eba4eTed Kremenek addSuccessor(ExitConditionBlock, LoopBackBlock); 2841d173dc7825e999edab836f8215a82a96eae7c738Ted Kremenek } 2842d173dc7825e999edab836f8215a82a96eae7c738Ted Kremenek else 28436bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines addSuccessor(ExitConditionBlock, nullptr); 2844b5c13b0f4e438391b31dacb87641be7a1b990b57Ted Kremenek } 28456d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 2846941fde8019d47c694b8483db45d5878818fa69d1Ted Kremenek // Link up the condition block with the code that follows the loop. 2847941fde8019d47c694b8483db45d5878818fa69d1Ted Kremenek // (the false branch). 28486bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines addSuccessor(ExitConditionBlock, KnownVal.isTrue() ? nullptr : LoopSuccessor); 28496d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 28506d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump // There can be no more statements in the body block(s) since we loop back to 28516d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump // the body. NULL out Block to force lazy creation of another block. 28526bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines Block = nullptr; 28536d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 2854d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek // Return the loop body, which is the dominating block for the loop. 28555482713d70ecbfe608940018046aa248b3d03443Ted Kremenek Succ = BodyBlock; 2856d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek return BodyBlock; 2857d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek} 2858d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek 28599c378f705405d37f49795d5e915989de774fe11fTed KremenekCFGBlock *CFGBuilder::VisitContinueStmt(ContinueStmt *C) { 2860d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek // "continue" is a control-flow statement. Thus we stop processing the 2861d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek // current block. 2862d438b3dbdcde4df4f61a99054104643e6aadf78bZhongxing Xu if (badCFG) 28636bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return nullptr; 28646d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 2865d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek // Now create a new block that ends with the continue statement. 2866d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek Block = createBlock(false); 2867d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek Block->setTerminator(C); 28686d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 2869d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek // If there is no target for the continue, then we are looking at an 2870235c5ed8bee5bbcb45de1707d6988635e49b10b8Ted Kremenek // incomplete AST. This means the CFG cannot be constructed. 28719ce5270f0aadaaf03a0cf705787f42ce9eb1194cTed Kremenek if (ContinueJumpTarget.block) { 28729ce5270f0aadaaf03a0cf705787f42ce9eb1194cTed Kremenek addAutomaticObjDtors(ScopePos, ContinueJumpTarget.scopePosition, C); 28739ce5270f0aadaaf03a0cf705787f42ce9eb1194cTed Kremenek addSuccessor(Block, ContinueJumpTarget.block); 2874f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski } else 2875235c5ed8bee5bbcb45de1707d6988635e49b10b8Ted Kremenek badCFG = true; 28766d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 2877d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek return Block; 2878d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek} 28791eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 2880f4e3cfbe8abd124be6341ef5d714819b4fbd9082Peter CollingbourneCFGBlock *CFGBuilder::VisitUnaryExprOrTypeTraitExpr(UnaryExprOrTypeTraitExpr *E, 2881f4e3cfbe8abd124be6341ef5d714819b4fbd9082Peter Collingbourne AddStmtChoice asc) { 288213fc08a323b29dd97a46def1e3a15bf082476efaTed Kremenek 28833179a45a0e91c1dcf3492222170cf4499531bb92Ted Kremenek if (asc.alwaysAdd(*this, E)) { 288413fc08a323b29dd97a46def1e3a15bf082476efaTed Kremenek autoCreateBlock(); 2885892697dd2287caf7c29aaaa82909b0e90b8b63feTed Kremenek appendStmt(Block, E); 288613fc08a323b29dd97a46def1e3a15bf082476efaTed Kremenek } 28871eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 28884f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek // VLA types have expressions that must be evaluated. 288997e50714c262cc421f960303171d2c1afbc9bb4fTed Kremenek CFGBlock *lastBlock = Block; 289097e50714c262cc421f960303171d2c1afbc9bb4fTed Kremenek 28914f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek if (E->isArgumentType()) { 2892f4c7371fb1d3cebcfb40abad4537bb82515704eaJohn McCall for (const VariableArrayType *VA =FindVA(E->getArgumentType().getTypePtr()); 28936bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines VA != nullptr; VA = FindVA(VA->getElementType().getTypePtr())) 289497e50714c262cc421f960303171d2c1afbc9bb4fTed Kremenek lastBlock = addStmt(VA->getSizeExpr()); 2895f91a5b008d1a63630ae483247204c2651e512fa1Ted Kremenek } 289697e50714c262cc421f960303171d2c1afbc9bb4fTed Kremenek return lastBlock; 2897d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek} 28981eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 28994f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek/// VisitStmtExpr - Utility method to handle (nested) statement 29004f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek/// expressions (a GCC extension). 29019c378f705405d37f49795d5e915989de774fe11fTed KremenekCFGBlock *CFGBuilder::VisitStmtExpr(StmtExpr *SE, AddStmtChoice asc) { 29023179a45a0e91c1dcf3492222170cf4499531bb92Ted Kremenek if (asc.alwaysAdd(*this, SE)) { 290313fc08a323b29dd97a46def1e3a15bf082476efaTed Kremenek autoCreateBlock(); 2904892697dd2287caf7c29aaaa82909b0e90b8b63feTed Kremenek appendStmt(Block, SE); 290513fc08a323b29dd97a46def1e3a15bf082476efaTed Kremenek } 29064f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek return VisitCompoundStmt(SE->getSubStmt()); 29074f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek} 2908d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek 29099c378f705405d37f49795d5e915989de774fe11fTed KremenekCFGBlock *CFGBuilder::VisitSwitchStmt(SwitchStmt *Terminator) { 29106d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump // "switch" is a control-flow statement. Thus we stop processing the current 29116d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump // block. 29126bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines CFGBlock *SwitchSuccessor = nullptr; 29136d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 29148ae6058cecba902c0069c24bdc9c26d475559291Marcin Swiderski // Save local scope position because in case of condition variable ScopePos 29158ae6058cecba902c0069c24bdc9c26d475559291Marcin Swiderski // won't be restored when traversing AST. 29168ae6058cecba902c0069c24bdc9c26d475559291Marcin Swiderski SaveAndRestore<LocalScope::const_iterator> save_scope_pos(ScopePos); 29178ae6058cecba902c0069c24bdc9c26d475559291Marcin Swiderski 29188ae6058cecba902c0069c24bdc9c26d475559291Marcin Swiderski // Create local scope for possible condition variable. 29198ae6058cecba902c0069c24bdc9c26d475559291Marcin Swiderski // Store scope position. Add implicit destructor. 29209c378f705405d37f49795d5e915989de774fe11fTed Kremenek if (VarDecl *VD = Terminator->getConditionVariable()) { 29218ae6058cecba902c0069c24bdc9c26d475559291Marcin Swiderski LocalScope::const_iterator SwitchBeginScopePos = ScopePos; 29228ae6058cecba902c0069c24bdc9c26d475559291Marcin Swiderski addLocalScopeForVarDecl(VD); 29238ae6058cecba902c0069c24bdc9c26d475559291Marcin Swiderski addAutomaticObjDtors(ScopePos, SwitchBeginScopePos, Terminator); 29248ae6058cecba902c0069c24bdc9c26d475559291Marcin Swiderski } 29258ae6058cecba902c0069c24bdc9c26d475559291Marcin Swiderski 2926d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek if (Block) { 2927d438b3dbdcde4df4f61a99054104643e6aadf78bZhongxing Xu if (badCFG) 29286bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return nullptr; 2929d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek SwitchSuccessor = Block; 29306d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump } else SwitchSuccessor = Succ; 2931d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek 2932d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek // Save the current "switch" context. 2933d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek SaveAndRestore<CFGBlock*> save_switch(SwitchTerminatedBlock), 2934eef5a9ac59f4f8b868ef0657ccf6bec81b4fe37aTed Kremenek save_default(DefaultCaseBlock); 2935f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski SaveAndRestore<JumpTarget> save_break(BreakJumpTarget); 2936eef5a9ac59f4f8b868ef0657ccf6bec81b4fe37aTed Kremenek 29376d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump // Set the "default" case to be the block after the switch statement. If the 29386d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump // switch statement contains a "default:", this value will be overwritten with 29396d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump // the block for that code. 2940eef5a9ac59f4f8b868ef0657ccf6bec81b4fe37aTed Kremenek DefaultCaseBlock = SwitchSuccessor; 29416d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 2942d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek // Create a new block that will contain the switch statement. 2943d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek SwitchTerminatedBlock = createBlock(false); 29446d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 2945d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek // Now process the switch body. The code after the switch is the implicit 2946d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek // successor. 2947d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek Succ = SwitchSuccessor; 2948f1308c738dc1e7a36101d9e96071d0d241bc2ccbMarcin Swiderski BreakJumpTarget = JumpTarget(SwitchSuccessor, ScopePos); 29496d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 29506d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump // When visiting the body, the case statements should automatically get linked 29516d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump // up to the switch. We also don't keep a pointer to the body, since all 29526d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump // control-flow from the switch goes to case/default statements. 29536db0ad32fa0987ff76d4c41393991ef4b6895ea3Ted Kremenek assert(Terminator->getBody() && "switch must contain a non-NULL body"); 29546bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines Block = nullptr; 29558ae6058cecba902c0069c24bdc9c26d475559291Marcin Swiderski 2956e71f3d587844110d836c82250830b27b1651afdbTed Kremenek // For pruning unreachable case statements, save the current state 2957e71f3d587844110d836c82250830b27b1651afdbTed Kremenek // for tracking the condition value. 2958e71f3d587844110d836c82250830b27b1651afdbTed Kremenek SaveAndRestore<bool> save_switchExclusivelyCovered(switchExclusivelyCovered, 2959e71f3d587844110d836c82250830b27b1651afdbTed Kremenek false); 29600498247f87ea0d716e0c2931fea812280649e33dTed Kremenek 2961e71f3d587844110d836c82250830b27b1651afdbTed Kremenek // Determine if the switch condition can be explicitly evaluated. 2962e71f3d587844110d836c82250830b27b1651afdbTed Kremenek assert(Terminator->getCond() && "switch condition must be non-NULL"); 29630498247f87ea0d716e0c2931fea812280649e33dTed Kremenek Expr::EvalResult result; 2964e9cd9c0016f103fd45d41d136d5d1084aa42eb75Ted Kremenek bool b = tryEvaluate(Terminator->getCond(), result); 2965e9cd9c0016f103fd45d41d136d5d1084aa42eb75Ted Kremenek SaveAndRestore<Expr::EvalResult*> save_switchCond(switchCond, 29666bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines b ? &result : nullptr); 29670498247f87ea0d716e0c2931fea812280649e33dTed Kremenek 29688ae6058cecba902c0069c24bdc9c26d475559291Marcin Swiderski // If body is not a compound statement create implicit scope 29698ae6058cecba902c0069c24bdc9c26d475559291Marcin Swiderski // and add destructors. 29708ae6058cecba902c0069c24bdc9c26d475559291Marcin Swiderski if (!isa<CompoundStmt>(Terminator->getBody())) 29718ae6058cecba902c0069c24bdc9c26d475559291Marcin Swiderski addLocalScopeAndDtors(Terminator->getBody()); 29728ae6058cecba902c0069c24bdc9c26d475559291Marcin Swiderski 2973d438b3dbdcde4df4f61a99054104643e6aadf78bZhongxing Xu addStmt(Terminator->getBody()); 29744e8df2eb7072db8f66572c3db31a2a08b12a752eTed Kremenek if (Block) { 2975d438b3dbdcde4df4f61a99054104643e6aadf78bZhongxing Xu if (badCFG) 29766bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return nullptr; 29774e8df2eb7072db8f66572c3db31a2a08b12a752eTed Kremenek } 297849af7cb8a3aca79783e7a0708b97a8f856f0da22Ted Kremenek 29796d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump // If we have no "default:" case, the default transition is to the code 2980432c478fe0fec3946610d5dc7905daf5fbadf47bTed Kremenek // following the switch body. Moreover, take into account if all the 2981432c478fe0fec3946610d5dc7905daf5fbadf47bTed Kremenek // cases of a switch are covered (e.g., switching on an enum value). 29822a1551fa14728891bf8e325d3eb686ed404cd8b2David Majnemer // 29832a1551fa14728891bf8e325d3eb686ed404cd8b2David Majnemer // Note: We add a successor to a switch that is considered covered yet has no 29842a1551fa14728891bf8e325d3eb686ed404cd8b2David Majnemer // case statements if the enumeration has no enumerators. 29852a1551fa14728891bf8e325d3eb686ed404cd8b2David Majnemer bool SwitchAlwaysHasSuccessor = false; 29862a1551fa14728891bf8e325d3eb686ed404cd8b2David Majnemer SwitchAlwaysHasSuccessor |= switchExclusivelyCovered; 29872a1551fa14728891bf8e325d3eb686ed404cd8b2David Majnemer SwitchAlwaysHasSuccessor |= Terminator->isAllEnumCasesCovered() && 29882a1551fa14728891bf8e325d3eb686ed404cd8b2David Majnemer Terminator->getSwitchCaseList(); 2989651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines addSuccessor(SwitchTerminatedBlock, DefaultCaseBlock, 2990651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines !SwitchAlwaysHasSuccessor); 29916d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 299249af7cb8a3aca79783e7a0708b97a8f856f0da22Ted Kremenek // Add the terminator and condition in the switch block. 2993411cdee0b490f79428c9eb977f25199eb7d21cd8Ted Kremenek SwitchTerminatedBlock->setTerminator(Terminator); 2994d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek Block = SwitchTerminatedBlock; 29958f81acfa95a5d2a22fc875c1a10901eaa30b8405Ted Kremenek CFGBlock *LastBlock = addStmt(Terminator->getCond()); 2996ad5a894df1841698c824381b414630799adc26caTed Kremenek 29976b501ebaf172b28d6d7e1737db27f915175ad3c8Ted Kremenek // Finally, if the SwitchStmt contains a condition variable, add both the 29986b501ebaf172b28d6d7e1737db27f915175ad3c8Ted Kremenek // SwitchStmt and the condition variable initialization to the CFG. 29996b501ebaf172b28d6d7e1737db27f915175ad3c8Ted Kremenek if (VarDecl *VD = Terminator->getConditionVariable()) { 30006b501ebaf172b28d6d7e1737db27f915175ad3c8Ted Kremenek if (Expr *Init = VD->getInit()) { 30016b501ebaf172b28d6d7e1737db27f915175ad3c8Ted Kremenek autoCreateBlock(); 3002d40066b0fb883839a9100e5455e33190b9b8abacTed Kremenek appendStmt(Block, Terminator->getConditionVariableDeclStmt()); 30038f81acfa95a5d2a22fc875c1a10901eaa30b8405Ted Kremenek LastBlock = addStmt(Init); 30046b501ebaf172b28d6d7e1737db27f915175ad3c8Ted Kremenek } 30056b501ebaf172b28d6d7e1737db27f915175ad3c8Ted Kremenek } 3006ad5a894df1841698c824381b414630799adc26caTed Kremenek 30078f81acfa95a5d2a22fc875c1a10901eaa30b8405Ted Kremenek return LastBlock; 3008d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek} 3009e71f3d587844110d836c82250830b27b1651afdbTed Kremenek 3010e71f3d587844110d836c82250830b27b1651afdbTed Kremenekstatic bool shouldAddCase(bool &switchExclusivelyCovered, 3011e9cd9c0016f103fd45d41d136d5d1084aa42eb75Ted Kremenek const Expr::EvalResult *switchCond, 3012e71f3d587844110d836c82250830b27b1651afdbTed Kremenek const CaseStmt *CS, 3013e71f3d587844110d836c82250830b27b1651afdbTed Kremenek ASTContext &Ctx) { 3014e9cd9c0016f103fd45d41d136d5d1084aa42eb75Ted Kremenek if (!switchCond) 3015e9cd9c0016f103fd45d41d136d5d1084aa42eb75Ted Kremenek return true; 3016e9cd9c0016f103fd45d41d136d5d1084aa42eb75Ted Kremenek 3017e71f3d587844110d836c82250830b27b1651afdbTed Kremenek bool addCase = false; 30180498247f87ea0d716e0c2931fea812280649e33dTed Kremenek 3019e71f3d587844110d836c82250830b27b1651afdbTed Kremenek if (!switchExclusivelyCovered) { 3020e9cd9c0016f103fd45d41d136d5d1084aa42eb75Ted Kremenek if (switchCond->Val.isInt()) { 3021e71f3d587844110d836c82250830b27b1651afdbTed Kremenek // Evaluate the LHS of the case value. 302285df96c1f04867e26ba069aa0cc6a4cd6a01292eRichard Smith const llvm::APSInt &lhsInt = CS->getLHS()->EvaluateKnownConstInt(Ctx); 3023e9cd9c0016f103fd45d41d136d5d1084aa42eb75Ted Kremenek const llvm::APSInt &condInt = switchCond->Val.getInt(); 3024e71f3d587844110d836c82250830b27b1651afdbTed Kremenek 3025e71f3d587844110d836c82250830b27b1651afdbTed Kremenek if (condInt == lhsInt) { 3026e71f3d587844110d836c82250830b27b1651afdbTed Kremenek addCase = true; 3027e71f3d587844110d836c82250830b27b1651afdbTed Kremenek switchExclusivelyCovered = true; 3028e71f3d587844110d836c82250830b27b1651afdbTed Kremenek } 3029e71f3d587844110d836c82250830b27b1651afdbTed Kremenek else if (condInt < lhsInt) { 3030e71f3d587844110d836c82250830b27b1651afdbTed Kremenek if (const Expr *RHS = CS->getRHS()) { 3031e71f3d587844110d836c82250830b27b1651afdbTed Kremenek // Evaluate the RHS of the case value. 303285df96c1f04867e26ba069aa0cc6a4cd6a01292eRichard Smith const llvm::APSInt &V2 = RHS->EvaluateKnownConstInt(Ctx); 303385df96c1f04867e26ba069aa0cc6a4cd6a01292eRichard Smith if (V2 <= condInt) { 3034e71f3d587844110d836c82250830b27b1651afdbTed Kremenek addCase = true; 3035e71f3d587844110d836c82250830b27b1651afdbTed Kremenek switchExclusivelyCovered = true; 3036e71f3d587844110d836c82250830b27b1651afdbTed Kremenek } 3037e71f3d587844110d836c82250830b27b1651afdbTed Kremenek } 3038e71f3d587844110d836c82250830b27b1651afdbTed Kremenek } 3039e71f3d587844110d836c82250830b27b1651afdbTed Kremenek } 3040e71f3d587844110d836c82250830b27b1651afdbTed Kremenek else 3041e71f3d587844110d836c82250830b27b1651afdbTed Kremenek addCase = true; 3042e71f3d587844110d836c82250830b27b1651afdbTed Kremenek } 3043e71f3d587844110d836c82250830b27b1651afdbTed Kremenek return addCase; 3044e71f3d587844110d836c82250830b27b1651afdbTed Kremenek} 3045d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek 30469c378f705405d37f49795d5e915989de774fe11fTed KremenekCFGBlock *CFGBuilder::VisitCaseStmt(CaseStmt *CS) { 30476d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump // CaseStmts are essentially labels, so they are the first statement in a 30486d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump // block. 30496bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines CFGBlock *TopBlock = nullptr, *LastBlock = nullptr; 30500498247f87ea0d716e0c2931fea812280649e33dTed Kremenek 30510fc67e2d619088945ac71e9d2590d5158650885dTed Kremenek if (Stmt *Sub = CS->getSubStmt()) { 30520fc67e2d619088945ac71e9d2590d5158650885dTed Kremenek // For deeply nested chains of CaseStmts, instead of doing a recursion 30530fc67e2d619088945ac71e9d2590d5158650885dTed Kremenek // (which can blow out the stack), manually unroll and create blocks 30540fc67e2d619088945ac71e9d2590d5158650885dTed Kremenek // along the way. 30550fc67e2d619088945ac71e9d2590d5158650885dTed Kremenek while (isa<CaseStmt>(Sub)) { 30560a3ed3143b00f237decb1288c1ff574ae09eba4eTed Kremenek CFGBlock *currentBlock = createBlock(false); 30570a3ed3143b00f237decb1288c1ff574ae09eba4eTed Kremenek currentBlock->setLabel(CS); 30580fc67e2d619088945ac71e9d2590d5158650885dTed Kremenek 30590fc67e2d619088945ac71e9d2590d5158650885dTed Kremenek if (TopBlock) 30600a3ed3143b00f237decb1288c1ff574ae09eba4eTed Kremenek addSuccessor(LastBlock, currentBlock); 30610fc67e2d619088945ac71e9d2590d5158650885dTed Kremenek else 30620a3ed3143b00f237decb1288c1ff574ae09eba4eTed Kremenek TopBlock = currentBlock; 30630fc67e2d619088945ac71e9d2590d5158650885dTed Kremenek 3064e71f3d587844110d836c82250830b27b1651afdbTed Kremenek addSuccessor(SwitchTerminatedBlock, 3065e9cd9c0016f103fd45d41d136d5d1084aa42eb75Ted Kremenek shouldAddCase(switchExclusivelyCovered, switchCond, 3066e71f3d587844110d836c82250830b27b1651afdbTed Kremenek CS, *Context) 30676bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines ? currentBlock : nullptr); 30680fc67e2d619088945ac71e9d2590d5158650885dTed Kremenek 3069e71f3d587844110d836c82250830b27b1651afdbTed Kremenek LastBlock = currentBlock; 30700fc67e2d619088945ac71e9d2590d5158650885dTed Kremenek CS = cast<CaseStmt>(Sub); 30710fc67e2d619088945ac71e9d2590d5158650885dTed Kremenek Sub = CS->getSubStmt(); 30720fc67e2d619088945ac71e9d2590d5158650885dTed Kremenek } 307329ccaa186ac27bcb414c5acb069f6438b27dd5e7Ted Kremenek 30740fc67e2d619088945ac71e9d2590d5158650885dTed Kremenek addStmt(Sub); 30750fc67e2d619088945ac71e9d2590d5158650885dTed Kremenek } 30761eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 30779c378f705405d37f49795d5e915989de774fe11fTed Kremenek CFGBlock *CaseBlock = Block; 30784f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek if (!CaseBlock) 30794f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek CaseBlock = createBlock(); 30806d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 30816d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump // Cases statements partition blocks, so this is the top of the basic block we 30826d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump // were processing (the "case XXX:" is the label). 30834f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek CaseBlock->setLabel(CS); 30844f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek 3085d438b3dbdcde4df4f61a99054104643e6aadf78bZhongxing Xu if (badCFG) 30866bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return nullptr; 30876d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 30886d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump // Add this block to the list of successors for the block with the switch 30896d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump // statement. 30904f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek assert(SwitchTerminatedBlock); 3091651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines addSuccessor(SwitchTerminatedBlock, CaseBlock, 3092e9cd9c0016f103fd45d41d136d5d1084aa42eb75Ted Kremenek shouldAddCase(switchExclusivelyCovered, switchCond, 3093651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines CS, *Context)); 30946d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 3095d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek // We set Block to NULL to allow lazy creation of a new block (if necessary) 30966bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines Block = nullptr; 30976d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 30980fc67e2d619088945ac71e9d2590d5158650885dTed Kremenek if (TopBlock) { 30990a3ed3143b00f237decb1288c1ff574ae09eba4eTed Kremenek addSuccessor(LastBlock, CaseBlock); 31000fc67e2d619088945ac71e9d2590d5158650885dTed Kremenek Succ = TopBlock; 310136f327c309b1fb6b82f1987190f0be74000b14c1Zhanyong Wan } else { 31020fc67e2d619088945ac71e9d2590d5158650885dTed Kremenek // This block is now the implicit successor of other blocks. 31030fc67e2d619088945ac71e9d2590d5158650885dTed Kremenek Succ = CaseBlock; 31040fc67e2d619088945ac71e9d2590d5158650885dTed Kremenek } 31056d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 31060fc67e2d619088945ac71e9d2590d5158650885dTed Kremenek return Succ; 3107d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek} 31086d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 31099c378f705405d37f49795d5e915989de774fe11fTed KremenekCFGBlock *CFGBuilder::VisitDefaultStmt(DefaultStmt *Terminator) { 31104f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek if (Terminator->getSubStmt()) 31114f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek addStmt(Terminator->getSubStmt()); 31121eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 3113eef5a9ac59f4f8b868ef0657ccf6bec81b4fe37aTed Kremenek DefaultCaseBlock = Block; 31144f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek 31154f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek if (!DefaultCaseBlock) 31164f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek DefaultCaseBlock = createBlock(); 31176d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 31186d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump // Default statements partition blocks, so this is the top of the basic block 31196d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump // we were processing (the "default:" is the label). 3120411cdee0b490f79428c9eb977f25199eb7d21cd8Ted Kremenek DefaultCaseBlock->setLabel(Terminator); 31211eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 3122d438b3dbdcde4df4f61a99054104643e6aadf78bZhongxing Xu if (badCFG) 31236bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return nullptr; 3124eef5a9ac59f4f8b868ef0657ccf6bec81b4fe37aTed Kremenek 31256d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump // Unlike case statements, we don't add the default block to the successors 31266d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump // for the switch statement immediately. This is done when we finish 31276d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump // processing the switch statement. This allows for the default case 31286d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump // (including a fall-through to the code after the switch statement) to always 31296d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump // be the last successor of a switch-terminated block. 31306d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 3131eef5a9ac59f4f8b868ef0657ccf6bec81b4fe37aTed Kremenek // We set Block to NULL to allow lazy creation of a new block (if necessary) 31326bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines Block = nullptr; 31336d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 3134eef5a9ac59f4f8b868ef0657ccf6bec81b4fe37aTed Kremenek // This block is now the implicit successor of other blocks. 3135eef5a9ac59f4f8b868ef0657ccf6bec81b4fe37aTed Kremenek Succ = DefaultCaseBlock; 31366d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 31376d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump return DefaultCaseBlock; 3138295222c1f0926d84de77f076e79903523eeb5dbfTed Kremenek} 3139d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek 31405d1d20227878cd03db8b2dd23efd4cedfe874feeMike StumpCFGBlock *CFGBuilder::VisitCXXTryStmt(CXXTryStmt *Terminator) { 31415d1d20227878cd03db8b2dd23efd4cedfe874feeMike Stump // "try"/"catch" is a control-flow statement. Thus we stop processing the 31425d1d20227878cd03db8b2dd23efd4cedfe874feeMike Stump // current block. 31436bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines CFGBlock *TrySuccessor = nullptr; 31445d1d20227878cd03db8b2dd23efd4cedfe874feeMike Stump 31455d1d20227878cd03db8b2dd23efd4cedfe874feeMike Stump if (Block) { 3146d438b3dbdcde4df4f61a99054104643e6aadf78bZhongxing Xu if (badCFG) 31476bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return nullptr; 31485d1d20227878cd03db8b2dd23efd4cedfe874feeMike Stump TrySuccessor = Block; 31495d1d20227878cd03db8b2dd23efd4cedfe874feeMike Stump } else TrySuccessor = Succ; 31505d1d20227878cd03db8b2dd23efd4cedfe874feeMike Stump 3151a1f93631a84621d77aeb627691da85a8991af188Mike Stump CFGBlock *PrevTryTerminatedBlock = TryTerminatedBlock; 31525d1d20227878cd03db8b2dd23efd4cedfe874feeMike Stump 31535d1d20227878cd03db8b2dd23efd4cedfe874feeMike Stump // Create a new block that will contain the try statement. 3154f00cca5e05bb9ea51a3a21c8014ff9f3508d46e9Mike Stump CFGBlock *NewTryTerminatedBlock = createBlock(false); 31555d1d20227878cd03db8b2dd23efd4cedfe874feeMike Stump // Add the terminator in the try block. 3156f00cca5e05bb9ea51a3a21c8014ff9f3508d46e9Mike Stump NewTryTerminatedBlock->setTerminator(Terminator); 31575d1d20227878cd03db8b2dd23efd4cedfe874feeMike Stump 3158a1f93631a84621d77aeb627691da85a8991af188Mike Stump bool HasCatchAll = false; 31595d1d20227878cd03db8b2dd23efd4cedfe874feeMike Stump for (unsigned h = 0; h <Terminator->getNumHandlers(); ++h) { 31605d1d20227878cd03db8b2dd23efd4cedfe874feeMike Stump // The code after the try is the implicit successor. 31615d1d20227878cd03db8b2dd23efd4cedfe874feeMike Stump Succ = TrySuccessor; 31625d1d20227878cd03db8b2dd23efd4cedfe874feeMike Stump CXXCatchStmt *CS = Terminator->getHandler(h); 31636bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (CS->getExceptionDecl() == nullptr) { 3164a1f93631a84621d77aeb627691da85a8991af188Mike Stump HasCatchAll = true; 3165a1f93631a84621d77aeb627691da85a8991af188Mike Stump } 31666bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines Block = nullptr; 31675d1d20227878cd03db8b2dd23efd4cedfe874feeMike Stump CFGBlock *CatchBlock = VisitCXXCatchStmt(CS); 31686bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (!CatchBlock) 31696bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return nullptr; 31705d1d20227878cd03db8b2dd23efd4cedfe874feeMike Stump // Add this block to the list of successors for the block with the try 31715d1d20227878cd03db8b2dd23efd4cedfe874feeMike Stump // statement. 31720a3ed3143b00f237decb1288c1ff574ae09eba4eTed Kremenek addSuccessor(NewTryTerminatedBlock, CatchBlock); 31735d1d20227878cd03db8b2dd23efd4cedfe874feeMike Stump } 3174a1f93631a84621d77aeb627691da85a8991af188Mike Stump if (!HasCatchAll) { 3175a1f93631a84621d77aeb627691da85a8991af188Mike Stump if (PrevTryTerminatedBlock) 31760a3ed3143b00f237decb1288c1ff574ae09eba4eTed Kremenek addSuccessor(NewTryTerminatedBlock, PrevTryTerminatedBlock); 3177a1f93631a84621d77aeb627691da85a8991af188Mike Stump else 31780a3ed3143b00f237decb1288c1ff574ae09eba4eTed Kremenek addSuccessor(NewTryTerminatedBlock, &cfg->getExit()); 3179a1f93631a84621d77aeb627691da85a8991af188Mike Stump } 31805d1d20227878cd03db8b2dd23efd4cedfe874feeMike Stump 31815d1d20227878cd03db8b2dd23efd4cedfe874feeMike Stump // The code after the try is the implicit successor. 31825d1d20227878cd03db8b2dd23efd4cedfe874feeMike Stump Succ = TrySuccessor; 31835d1d20227878cd03db8b2dd23efd4cedfe874feeMike Stump 3184f00cca5e05bb9ea51a3a21c8014ff9f3508d46e9Mike Stump // Save the current "try" context. 3185f0e71aede7ccf3e311feac6a414c431f7a0fc3c8Ted Kremenek SaveAndRestore<CFGBlock*> save_try(TryTerminatedBlock, NewTryTerminatedBlock); 3186f0e71aede7ccf3e311feac6a414c431f7a0fc3c8Ted Kremenek cfg->addTryDispatchBlock(TryTerminatedBlock); 3187f00cca5e05bb9ea51a3a21c8014ff9f3508d46e9Mike Stump 31886db0ad32fa0987ff76d4c41393991ef4b6895ea3Ted Kremenek assert(Terminator->getTryBlock() && "try must contain a non-NULL body"); 31896bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines Block = nullptr; 31908f81acfa95a5d2a22fc875c1a10901eaa30b8405Ted Kremenek return addStmt(Terminator->getTryBlock()); 31915d1d20227878cd03db8b2dd23efd4cedfe874feeMike Stump} 31925d1d20227878cd03db8b2dd23efd4cedfe874feeMike Stump 31939c378f705405d37f49795d5e915989de774fe11fTed KremenekCFGBlock *CFGBuilder::VisitCXXCatchStmt(CXXCatchStmt *CS) { 31945d1d20227878cd03db8b2dd23efd4cedfe874feeMike Stump // CXXCatchStmt are treated like labels, so they are the first statement in a 31955d1d20227878cd03db8b2dd23efd4cedfe874feeMike Stump // block. 31965d1d20227878cd03db8b2dd23efd4cedfe874feeMike Stump 31970e97bcbee9d5f7735edecbccfb5031a2f065f286Marcin Swiderski // Save local scope position because in case of exception variable ScopePos 31980e97bcbee9d5f7735edecbccfb5031a2f065f286Marcin Swiderski // won't be restored when traversing AST. 31990e97bcbee9d5f7735edecbccfb5031a2f065f286Marcin Swiderski SaveAndRestore<LocalScope::const_iterator> save_scope_pos(ScopePos); 32000e97bcbee9d5f7735edecbccfb5031a2f065f286Marcin Swiderski 32010e97bcbee9d5f7735edecbccfb5031a2f065f286Marcin Swiderski // Create local scope for possible exception variable. 32020e97bcbee9d5f7735edecbccfb5031a2f065f286Marcin Swiderski // Store scope position. Add implicit destructor. 32039c378f705405d37f49795d5e915989de774fe11fTed Kremenek if (VarDecl *VD = CS->getExceptionDecl()) { 32040e97bcbee9d5f7735edecbccfb5031a2f065f286Marcin Swiderski LocalScope::const_iterator BeginScopePos = ScopePos; 32050e97bcbee9d5f7735edecbccfb5031a2f065f286Marcin Swiderski addLocalScopeForVarDecl(VD); 32060e97bcbee9d5f7735edecbccfb5031a2f065f286Marcin Swiderski addAutomaticObjDtors(ScopePos, BeginScopePos, CS); 32070e97bcbee9d5f7735edecbccfb5031a2f065f286Marcin Swiderski } 32080e97bcbee9d5f7735edecbccfb5031a2f065f286Marcin Swiderski 32095d1d20227878cd03db8b2dd23efd4cedfe874feeMike Stump if (CS->getHandlerBlock()) 32105d1d20227878cd03db8b2dd23efd4cedfe874feeMike Stump addStmt(CS->getHandlerBlock()); 32115d1d20227878cd03db8b2dd23efd4cedfe874feeMike Stump 32129c378f705405d37f49795d5e915989de774fe11fTed Kremenek CFGBlock *CatchBlock = Block; 32135d1d20227878cd03db8b2dd23efd4cedfe874feeMike Stump if (!CatchBlock) 32145d1d20227878cd03db8b2dd23efd4cedfe874feeMike Stump CatchBlock = createBlock(); 3215337e4dbc6859589b8878146a88bebf754e916702Ted Kremenek 3216337e4dbc6859589b8878146a88bebf754e916702Ted Kremenek // CXXCatchStmt is more than just a label. They have semantic meaning 3217337e4dbc6859589b8878146a88bebf754e916702Ted Kremenek // as well, as they implicitly "initialize" the catch variable. Add 3218337e4dbc6859589b8878146a88bebf754e916702Ted Kremenek // it to the CFG as a CFGElement so that the control-flow of these 3219337e4dbc6859589b8878146a88bebf754e916702Ted Kremenek // semantics gets captured. 3220337e4dbc6859589b8878146a88bebf754e916702Ted Kremenek appendStmt(CatchBlock, CS); 3221337e4dbc6859589b8878146a88bebf754e916702Ted Kremenek 3222337e4dbc6859589b8878146a88bebf754e916702Ted Kremenek // Also add the CXXCatchStmt as a label, to mirror handling of regular 3223337e4dbc6859589b8878146a88bebf754e916702Ted Kremenek // labels. 32245d1d20227878cd03db8b2dd23efd4cedfe874feeMike Stump CatchBlock->setLabel(CS); 32255d1d20227878cd03db8b2dd23efd4cedfe874feeMike Stump 3226337e4dbc6859589b8878146a88bebf754e916702Ted Kremenek // Bail out if the CFG is bad. 3227d438b3dbdcde4df4f61a99054104643e6aadf78bZhongxing Xu if (badCFG) 32286bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return nullptr; 32295d1d20227878cd03db8b2dd23efd4cedfe874feeMike Stump 32305d1d20227878cd03db8b2dd23efd4cedfe874feeMike Stump // We set Block to NULL to allow lazy creation of a new block (if necessary) 32316bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines Block = nullptr; 32325d1d20227878cd03db8b2dd23efd4cedfe874feeMike Stump 32335d1d20227878cd03db8b2dd23efd4cedfe874feeMike Stump return CatchBlock; 32345d1d20227878cd03db8b2dd23efd4cedfe874feeMike Stump} 32355d1d20227878cd03db8b2dd23efd4cedfe874feeMike Stump 32369c378f705405d37f49795d5e915989de774fe11fTed KremenekCFGBlock *CFGBuilder::VisitCXXForRangeStmt(CXXForRangeStmt *S) { 3237ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith // C++0x for-range statements are specified as [stmt.ranged]: 3238ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith // 3239ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith // { 3240ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith // auto && __range = range-init; 3241ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith // for ( auto __begin = begin-expr, 3242ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith // __end = end-expr; 3243ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith // __begin != __end; 3244ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith // ++__begin ) { 3245ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith // for-range-declaration = *__begin; 3246ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith // statement 3247ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith // } 3248ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith // } 3249ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith 3250ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith // Save local scope position before the addition of the implicit variables. 3251ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith SaveAndRestore<LocalScope::const_iterator> save_scope_pos(ScopePos); 3252ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith 3253ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith // Create local scopes and destructors for range, begin and end variables. 3254ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith if (Stmt *Range = S->getRangeStmt()) 3255ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith addLocalScopeForStmt(Range); 3256ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith if (Stmt *BeginEnd = S->getBeginEndStmt()) 3257ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith addLocalScopeForStmt(BeginEnd); 3258ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith addAutomaticObjDtors(ScopePos, save_scope_pos.get(), S); 3259ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith 3260ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith LocalScope::const_iterator ContinueScopePos = ScopePos; 3261ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith 3262ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith // "for" is a control-flow statement. Thus we stop processing the current 3263ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith // block. 32646bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines CFGBlock *LoopSuccessor = nullptr; 3265ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith if (Block) { 3266ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith if (badCFG) 32676bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return nullptr; 3268ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith LoopSuccessor = Block; 3269ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith } else 3270ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith LoopSuccessor = Succ; 3271ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith 3272ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith // Save the current value for the break targets. 3273ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith // All breaks should go to the code following the loop. 3274ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith SaveAndRestore<JumpTarget> save_break(BreakJumpTarget); 3275ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith BreakJumpTarget = JumpTarget(LoopSuccessor, ScopePos); 3276ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith 3277ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith // The block for the __begin != __end expression. 32789c378f705405d37f49795d5e915989de774fe11fTed Kremenek CFGBlock *ConditionBlock = createBlock(false); 3279ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith ConditionBlock->setTerminator(S); 3280ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith 3281ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith // Now add the actual condition to the condition block. 3282ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith if (Expr *C = S->getCond()) { 3283ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith Block = ConditionBlock; 3284ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith CFGBlock *BeginConditionBlock = addStmt(C); 3285ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith if (badCFG) 32866bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return nullptr; 3287ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith assert(BeginConditionBlock == ConditionBlock && 3288ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith "condition block in for-range was unexpectedly complex"); 3289ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith (void)BeginConditionBlock; 3290ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith } 3291ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith 3292ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith // The condition block is the implicit successor for the loop body as well as 3293ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith // any code above the loop. 3294ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith Succ = ConditionBlock; 3295ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith 3296ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith // See if this is a known constant. 3297ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith TryResult KnownVal(true); 3298ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith 3299ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith if (S->getCond()) 3300ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith KnownVal = tryEvaluateBool(S->getCond()); 3301ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith 3302ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith // Now create the loop body. 3303ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith { 3304ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith assert(S->getBody()); 3305ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith 3306ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith // Save the current values for Block, Succ, and continue targets. 3307ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith SaveAndRestore<CFGBlock*> save_Block(Block), save_Succ(Succ); 3308ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith SaveAndRestore<JumpTarget> save_continue(ContinueJumpTarget); 3309ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith 3310ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith // Generate increment code in its own basic block. This is the target of 3311ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith // continue statements. 33126bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines Block = nullptr; 3313ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith Succ = addStmt(S->getInc()); 3314ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith ContinueJumpTarget = JumpTarget(Succ, ContinueScopePos); 3315ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith 3316ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith // The starting block for the loop increment is the block that should 3317ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith // represent the 'loop target' for looping back to the start of the loop. 3318ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith ContinueJumpTarget.block->setLoopTarget(S); 3319ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith 3320ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith // Finish up the increment block and prepare to start the loop body. 3321ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith assert(Block); 3322ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith if (badCFG) 33236bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return nullptr; 33246bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines Block = nullptr; 3325ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith 3326ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith // Add implicit scope and dtors for loop variable. 3327ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith addLocalScopeAndDtors(S->getLoopVarStmt()); 3328ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith 3329ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith // Populate a new block to contain the loop body and loop variable. 33308f81acfa95a5d2a22fc875c1a10901eaa30b8405Ted Kremenek addStmt(S->getBody()); 3331ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith if (badCFG) 33326bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return nullptr; 33338f81acfa95a5d2a22fc875c1a10901eaa30b8405Ted Kremenek CFGBlock *LoopVarStmtBlock = addStmt(S->getLoopVarStmt()); 3334ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith if (badCFG) 33356bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return nullptr; 33366bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 3337ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith // This new body block is a successor to our condition block. 33386bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines addSuccessor(ConditionBlock, 33396bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines KnownVal.isFalse() ? nullptr : LoopVarStmtBlock); 3340ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith } 3341ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith 3342ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith // Link up the condition block with the code that follows the loop (the 3343ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith // false branch). 33446bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines addSuccessor(ConditionBlock, KnownVal.isTrue() ? nullptr : LoopSuccessor); 3345ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith 3346ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith // Add the initialization statements. 3347ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith Block = createBlock(); 3348b403d6d746239095a2c7bac958c924d92434e2b4Richard Smith addStmt(S->getBeginEndStmt()); 3349b403d6d746239095a2c7bac958c924d92434e2b4Richard Smith return addStmt(S->getRangeStmt()); 3350ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith} 3351ad762fcdc16b9e4705b12b09d92b8c026212b906Richard Smith 33524765fa05b5652fcc4356371c2f481d0ea9a1b007John McCallCFGBlock *CFGBuilder::VisitExprWithCleanups(ExprWithCleanups *E, 33538599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski AddStmtChoice asc) { 33545a1ffe98b04120846a15f7105905b5f363b08635Jordan Rose if (BuildOpts.AddTemporaryDtors) { 33558599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski // If adding implicit destructors visit the full expression for adding 33568599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski // destructors of temporaries. 33578599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski VisitForTemporaryDtors(E->getSubExpr()); 33588599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski 33598599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski // Full expression has to be added as CFGStmt so it will be sequenced 33608599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski // before destructors of it's temporaries. 336194a3dcf146451eb6b0192873e267c4cb0f6147e8Zhanyong Wan asc = asc.withAlwaysAdd(true); 33628599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski } 33638599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski return Visit(E->getSubExpr(), asc); 33648599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski} 33658599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski 3366a725ed468585b881c43654eeb56b28554a84808aZhongxing XuCFGBlock *CFGBuilder::VisitCXXBindTemporaryExpr(CXXBindTemporaryExpr *E, 3367a725ed468585b881c43654eeb56b28554a84808aZhongxing Xu AddStmtChoice asc) { 33683179a45a0e91c1dcf3492222170cf4499531bb92Ted Kremenek if (asc.alwaysAdd(*this, E)) { 3369a725ed468585b881c43654eeb56b28554a84808aZhongxing Xu autoCreateBlock(); 3370247e9665d897a7bbbf60c1c0d3b6609c4504a961Ted Kremenek appendStmt(Block, E); 3371a725ed468585b881c43654eeb56b28554a84808aZhongxing Xu 3372a725ed468585b881c43654eeb56b28554a84808aZhongxing Xu // We do not want to propagate the AlwaysAdd property. 337394a3dcf146451eb6b0192873e267c4cb0f6147e8Zhanyong Wan asc = asc.withAlwaysAdd(false); 3374a725ed468585b881c43654eeb56b28554a84808aZhongxing Xu } 3375a725ed468585b881c43654eeb56b28554a84808aZhongxing Xu return Visit(E->getSubExpr(), asc); 3376a725ed468585b881c43654eeb56b28554a84808aZhongxing Xu} 3377a725ed468585b881c43654eeb56b28554a84808aZhongxing Xu 337881bc7d07b701042371a5723b6f394cd2482ed7beZhongxing XuCFGBlock *CFGBuilder::VisitCXXConstructExpr(CXXConstructExpr *C, 337981bc7d07b701042371a5723b6f394cd2482ed7beZhongxing Xu AddStmtChoice asc) { 338081bc7d07b701042371a5723b6f394cd2482ed7beZhongxing Xu autoCreateBlock(); 338197a72c35a62304c3781aa280e28cb97a59afd585Zhongxing Xu appendStmt(Block, C); 338294a3dcf146451eb6b0192873e267c4cb0f6147e8Zhanyong Wan 338381bc7d07b701042371a5723b6f394cd2482ed7beZhongxing Xu return VisitChildren(C); 338481bc7d07b701042371a5723b6f394cd2482ed7beZhongxing Xu} 338581bc7d07b701042371a5723b6f394cd2482ed7beZhongxing Xu 3386651f13cea278ec967336033dd032faef0e9fc2ecStephen HinesCFGBlock *CFGBuilder::VisitCXXNewExpr(CXXNewExpr *NE, 3387651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines AddStmtChoice asc) { 3388651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 3389651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines autoCreateBlock(); 3390651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines appendStmt(Block, NE); 3391651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 3392651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (NE->getInitializer()) 3393651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Block = Visit(NE->getInitializer()); 3394651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (BuildOpts.AddCXXNewAllocator) 3395651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines appendNewAllocator(Block, NE); 3396651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (NE->isArray()) 3397651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Block = Visit(NE->getArraySize()); 3398651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines for (CXXNewExpr::arg_iterator I = NE->placement_arg_begin(), 3399651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines E = NE->placement_arg_end(); I != E; ++I) 3400651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Block = Visit(*I); 3401651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return Block; 3402651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines} 340336d558d85653315edb389677e995ec9ccdbfbf3dJordan Rose 340436d558d85653315edb389677e995ec9ccdbfbf3dJordan RoseCFGBlock *CFGBuilder::VisitCXXDeleteExpr(CXXDeleteExpr *DE, 340536d558d85653315edb389677e995ec9ccdbfbf3dJordan Rose AddStmtChoice asc) { 340636d558d85653315edb389677e995ec9ccdbfbf3dJordan Rose autoCreateBlock(); 340736d558d85653315edb389677e995ec9ccdbfbf3dJordan Rose appendStmt(Block, DE); 340836d558d85653315edb389677e995ec9ccdbfbf3dJordan Rose QualType DTy = DE->getDestroyedType(); 340936d558d85653315edb389677e995ec9ccdbfbf3dJordan Rose DTy = DTy.getNonReferenceType(); 341036d558d85653315edb389677e995ec9ccdbfbf3dJordan Rose CXXRecordDecl *RD = Context->getBaseElementType(DTy)->getAsCXXRecordDecl(); 341136d558d85653315edb389677e995ec9ccdbfbf3dJordan Rose if (RD) { 3412a7be2f4c745120d6ee5adfd19ef259919bdc3f7fMatt Beaumont-Gay if (RD->isCompleteDefinition() && !RD->hasTrivialDestructor()) 341336d558d85653315edb389677e995ec9ccdbfbf3dJordan Rose appendDeleteDtor(Block, RD, DE); 341436d558d85653315edb389677e995ec9ccdbfbf3dJordan Rose } 341536d558d85653315edb389677e995ec9ccdbfbf3dJordan Rose 341636d558d85653315edb389677e995ec9ccdbfbf3dJordan Rose return VisitChildren(DE); 341736d558d85653315edb389677e995ec9ccdbfbf3dJordan Rose} 341836d558d85653315edb389677e995ec9ccdbfbf3dJordan Rose 3419a725ed468585b881c43654eeb56b28554a84808aZhongxing XuCFGBlock *CFGBuilder::VisitCXXFunctionalCastExpr(CXXFunctionalCastExpr *E, 3420a725ed468585b881c43654eeb56b28554a84808aZhongxing Xu AddStmtChoice asc) { 34213179a45a0e91c1dcf3492222170cf4499531bb92Ted Kremenek if (asc.alwaysAdd(*this, E)) { 3422a725ed468585b881c43654eeb56b28554a84808aZhongxing Xu autoCreateBlock(); 3423247e9665d897a7bbbf60c1c0d3b6609c4504a961Ted Kremenek appendStmt(Block, E); 3424a725ed468585b881c43654eeb56b28554a84808aZhongxing Xu // We do not want to propagate the AlwaysAdd property. 342594a3dcf146451eb6b0192873e267c4cb0f6147e8Zhanyong Wan asc = asc.withAlwaysAdd(false); 3426a725ed468585b881c43654eeb56b28554a84808aZhongxing Xu } 3427a725ed468585b881c43654eeb56b28554a84808aZhongxing Xu return Visit(E->getSubExpr(), asc); 3428a725ed468585b881c43654eeb56b28554a84808aZhongxing Xu} 3429a725ed468585b881c43654eeb56b28554a84808aZhongxing Xu 343081bc7d07b701042371a5723b6f394cd2482ed7beZhongxing XuCFGBlock *CFGBuilder::VisitCXXTemporaryObjectExpr(CXXTemporaryObjectExpr *C, 343181bc7d07b701042371a5723b6f394cd2482ed7beZhongxing Xu AddStmtChoice asc) { 343281bc7d07b701042371a5723b6f394cd2482ed7beZhongxing Xu autoCreateBlock(); 3433247e9665d897a7bbbf60c1c0d3b6609c4504a961Ted Kremenek appendStmt(Block, C); 343481bc7d07b701042371a5723b6f394cd2482ed7beZhongxing Xu return VisitChildren(C); 343581bc7d07b701042371a5723b6f394cd2482ed7beZhongxing Xu} 343681bc7d07b701042371a5723b6f394cd2482ed7beZhongxing Xu 3437a725ed468585b881c43654eeb56b28554a84808aZhongxing XuCFGBlock *CFGBuilder::VisitImplicitCastExpr(ImplicitCastExpr *E, 3438a725ed468585b881c43654eeb56b28554a84808aZhongxing Xu AddStmtChoice asc) { 34393179a45a0e91c1dcf3492222170cf4499531bb92Ted Kremenek if (asc.alwaysAdd(*this, E)) { 3440a725ed468585b881c43654eeb56b28554a84808aZhongxing Xu autoCreateBlock(); 3441247e9665d897a7bbbf60c1c0d3b6609c4504a961Ted Kremenek appendStmt(Block, E); 3442a725ed468585b881c43654eeb56b28554a84808aZhongxing Xu } 3443892697dd2287caf7c29aaaa82909b0e90b8b63feTed Kremenek return Visit(E->getSubExpr(), AddStmtChoice()); 3444a725ed468585b881c43654eeb56b28554a84808aZhongxing Xu} 3445a725ed468585b881c43654eeb56b28554a84808aZhongxing Xu 34469c378f705405d37f49795d5e915989de774fe11fTed KremenekCFGBlock *CFGBuilder::VisitIndirectGotoStmt(IndirectGotoStmt *I) { 34476d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump // Lazily create the indirect-goto dispatch block if there isn't one already. 34489c378f705405d37f49795d5e915989de774fe11fTed Kremenek CFGBlock *IBlock = cfg->getIndirectGotoBlock(); 34496d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 345019bb356317952445b03ee341c02f6147083c9eeaTed Kremenek if (!IBlock) { 345119bb356317952445b03ee341c02f6147083c9eeaTed Kremenek IBlock = createBlock(false); 345219bb356317952445b03ee341c02f6147083c9eeaTed Kremenek cfg->setIndirectGotoBlock(IBlock); 345319bb356317952445b03ee341c02f6147083c9eeaTed Kremenek } 34546d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 345519bb356317952445b03ee341c02f6147083c9eeaTed Kremenek // IndirectGoto is a control-flow statement. Thus we stop processing the 345619bb356317952445b03ee341c02f6147083c9eeaTed Kremenek // current block and create a new one. 3457d438b3dbdcde4df4f61a99054104643e6aadf78bZhongxing Xu if (badCFG) 34586bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return nullptr; 34594f88063677a2d990a44bb0d5f8437d2498b91d7fTed Kremenek 346019bb356317952445b03ee341c02f6147083c9eeaTed Kremenek Block = createBlock(false); 346119bb356317952445b03ee341c02f6147083c9eeaTed Kremenek Block->setTerminator(I); 34620a3ed3143b00f237decb1288c1ff574ae09eba4eTed Kremenek addSuccessor(Block, IBlock); 346319bb356317952445b03ee341c02f6147083c9eeaTed Kremenek return addStmt(I->getTarget()); 346419bb356317952445b03ee341c02f6147083c9eeaTed Kremenek} 346519bb356317952445b03ee341c02f6147083c9eeaTed Kremenek 34668599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin SwiderskiCFGBlock *CFGBuilder::VisitForTemporaryDtors(Stmt *E, bool BindToTemporary) { 34675a1ffe98b04120846a15f7105905b5f363b08635Jordan Rose assert(BuildOpts.AddImplicitDtors && BuildOpts.AddTemporaryDtors); 34685a1ffe98b04120846a15f7105905b5f363b08635Jordan Rose 34698599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin SwiderskitryAgain: 34708599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski if (!E) { 34718599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski badCFG = true; 34726bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return nullptr; 34738599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski } 34748599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski switch (E->getStmtClass()) { 34758599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski default: 34768599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski return VisitChildrenForTemporaryDtors(E); 34778599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski 34788599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski case Stmt::BinaryOperatorClass: 34798599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski return VisitBinaryOperatorForTemporaryDtors(cast<BinaryOperator>(E)); 34808599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski 34818599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski case Stmt::CXXBindTemporaryExprClass: 34828599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski return VisitCXXBindTemporaryExprForTemporaryDtors( 34838599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski cast<CXXBindTemporaryExpr>(E), BindToTemporary); 34848599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski 348556ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall case Stmt::BinaryConditionalOperatorClass: 34868599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski case Stmt::ConditionalOperatorClass: 34878599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski return VisitConditionalOperatorForTemporaryDtors( 348856ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall cast<AbstractConditionalOperator>(E), BindToTemporary); 34898599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski 34908599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski case Stmt::ImplicitCastExprClass: 34918599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski // For implicit cast we want BindToTemporary to be passed further. 34928599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski E = cast<CastExpr>(E)->getSubExpr(); 34938599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski goto tryAgain; 34948599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski 34958599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski case Stmt::ParenExprClass: 34968599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski E = cast<ParenExpr>(E)->getSubExpr(); 34978599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski goto tryAgain; 349803e80030515c800d1ab44125b9052dfffd1bd04cDouglas Gregor 349903e80030515c800d1ab44125b9052dfffd1bd04cDouglas Gregor case Stmt::MaterializeTemporaryExprClass: 350003e80030515c800d1ab44125b9052dfffd1bd04cDouglas Gregor E = cast<MaterializeTemporaryExpr>(E)->GetTemporaryExpr(); 350103e80030515c800d1ab44125b9052dfffd1bd04cDouglas Gregor goto tryAgain; 35028599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski } 35038599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski} 35048599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski 35058599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin SwiderskiCFGBlock *CFGBuilder::VisitChildrenForTemporaryDtors(Stmt *E) { 35068599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski // When visiting children for destructors we want to visit them in reverse 35075846720f08a6b225484bfe663599c2b057a99bc8Ted Kremenek // order that they will appear in the CFG. Because the CFG is built 35085846720f08a6b225484bfe663599c2b057a99bc8Ted Kremenek // bottom-up, this means we visit them in their natural order, which 35095846720f08a6b225484bfe663599c2b057a99bc8Ted Kremenek // reverses them in the CFG. 35108599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski CFGBlock *B = Block; 35115846720f08a6b225484bfe663599c2b057a99bc8Ted Kremenek for (Stmt::child_range I = E->children(); I; ++I) { 35125846720f08a6b225484bfe663599c2b057a99bc8Ted Kremenek if (Stmt *Child = *I) 35135846720f08a6b225484bfe663599c2b057a99bc8Ted Kremenek if (CFGBlock *R = VisitForTemporaryDtors(Child)) 35145846720f08a6b225484bfe663599c2b057a99bc8Ted Kremenek B = R; 35158599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski } 35168599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski return B; 35178599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski} 35188599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski 35198599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin SwiderskiCFGBlock *CFGBuilder::VisitBinaryOperatorForTemporaryDtors(BinaryOperator *E) { 35208599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski if (E->isLogicalOp()) { 35218599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski // Destructors for temporaries in LHS expression should be called after 35228599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski // those for RHS expression. Even if this will unnecessarily create a block, 35238599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski // this block will be used at least by the full expression. 35248599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski autoCreateBlock(); 35258599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski CFGBlock *ConfluenceBlock = VisitForTemporaryDtors(E->getLHS()); 35268599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski if (badCFG) 35276bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return nullptr; 35288599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski 35298599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski Succ = ConfluenceBlock; 35306bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines Block = nullptr; 35318599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski CFGBlock *RHSBlock = VisitForTemporaryDtors(E->getRHS()); 35328599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski 35338599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski if (RHSBlock) { 35348599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski if (badCFG) 35356bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return nullptr; 35368599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski 35378599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski // If RHS expression did produce destructors we need to connect created 35388599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski // blocks to CFG in same manner as for binary operator itself. 35398599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski CFGBlock *LHSBlock = createBlock(false); 35408599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski LHSBlock->setTerminator(CFGTerminator(E, true)); 35418599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski 35428599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski // For binary operator LHS block is before RHS in list of predecessors 35438599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski // of ConfluenceBlock. 35448599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski std::reverse(ConfluenceBlock->pred_begin(), 35458599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski ConfluenceBlock->pred_end()); 35468599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski 35478599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski // See if this is a known constant. 35480a3ed3143b00f237decb1288c1ff574ae09eba4eTed Kremenek TryResult KnownVal = tryEvaluateBool(E->getLHS()); 35498599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski if (KnownVal.isKnown() && (E->getOpcode() == BO_LOr)) 35508599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski KnownVal.negate(); 35518599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski 35528599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski // Link LHSBlock with RHSBlock exactly the same way as for binary operator 35538599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski // itself. 35548599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski if (E->getOpcode() == BO_LOr) { 35556bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines addSuccessor(LHSBlock, KnownVal.isTrue() ? nullptr : ConfluenceBlock); 35566bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines addSuccessor(LHSBlock, KnownVal.isFalse() ? nullptr : RHSBlock); 35578599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski } else { 35588599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski assert (E->getOpcode() == BO_LAnd); 35596bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines addSuccessor(LHSBlock, KnownVal.isFalse() ? nullptr : RHSBlock); 35606bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines addSuccessor(LHSBlock, KnownVal.isTrue() ? nullptr : ConfluenceBlock); 35618599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski } 35628599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski 35638599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski Block = LHSBlock; 35648599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski return LHSBlock; 35658599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski } 35668599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski 35678599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski Block = ConfluenceBlock; 35688599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski return ConfluenceBlock; 35698599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski } 35708599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski 357136f327c309b1fb6b82f1987190f0be74000b14c1Zhanyong Wan if (E->isAssignmentOp()) { 35728599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski // For assignment operator (=) LHS expression is visited 35738599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski // before RHS expression. For destructors visit them in reverse order. 35748599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski CFGBlock *RHSBlock = VisitForTemporaryDtors(E->getRHS()); 35758599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski CFGBlock *LHSBlock = VisitForTemporaryDtors(E->getLHS()); 35768599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski return LHSBlock ? LHSBlock : RHSBlock; 35778599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski } 35788599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski 35798599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski // For any other binary operator RHS expression is visited before 35808599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski // LHS expression (order of children). For destructors visit them in reverse 35818599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski // order. 35828599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski CFGBlock *LHSBlock = VisitForTemporaryDtors(E->getLHS()); 35838599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski CFGBlock *RHSBlock = VisitForTemporaryDtors(E->getRHS()); 35848599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski return RHSBlock ? RHSBlock : LHSBlock; 35858599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski} 35868599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski 35878599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin SwiderskiCFGBlock *CFGBuilder::VisitCXXBindTemporaryExprForTemporaryDtors( 35888599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski CXXBindTemporaryExpr *E, bool BindToTemporary) { 35898599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski // First add destructors for temporaries in subexpression. 35908599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski CFGBlock *B = VisitForTemporaryDtors(E->getSubExpr()); 3591249c9458e2cc5b671634baefe8517d7598883a20Zhongxing Xu if (!BindToTemporary) { 35928599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski // If lifetime of temporary is not prolonged (by assigning to constant 35938599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski // reference) add destructor for it. 3594c8cfc74bdcc999828bc232294d937fb191940d5bChandler Carruth 3595c8cfc74bdcc999828bc232294d937fb191940d5bChandler Carruth // If the destructor is marked as a no-return destructor, we need to create 3596c8cfc74bdcc999828bc232294d937fb191940d5bChandler Carruth // a new block for the destructor which does not have as a successor 3597c8cfc74bdcc999828bc232294d937fb191940d5bChandler Carruth // anything built thus far. Control won't flow out of this block. 3598c8cfc74bdcc999828bc232294d937fb191940d5bChandler Carruth const CXXDestructorDecl *Dtor = E->getTemporary()->getDestructor(); 3599651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (Dtor->isNoReturn()) { 3600651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Succ = B; 3601dba3fb5413437dc613734fa4ffac892b11a37d25Chandler Carruth Block = createNoReturnBlock(); 3602651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } else { 3603c8cfc74bdcc999828bc232294d937fb191940d5bChandler Carruth autoCreateBlock(); 3604651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 3605c8cfc74bdcc999828bc232294d937fb191940d5bChandler Carruth 36068599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski appendTemporaryDtor(Block, E); 36078599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski B = Block; 36088599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski } 36098599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski return B; 36108599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski} 36118599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski 36128599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin SwiderskiCFGBlock *CFGBuilder::VisitConditionalOperatorForTemporaryDtors( 361356ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall AbstractConditionalOperator *E, bool BindToTemporary) { 36148599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski // First add destructors for condition expression. Even if this will 36158599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski // unnecessarily create a block, this block will be used at least by the full 36168599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski // expression. 36178599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski autoCreateBlock(); 36188599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski CFGBlock *ConfluenceBlock = VisitForTemporaryDtors(E->getCond()); 36198599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski if (badCFG) 36206bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return nullptr; 362156ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall if (BinaryConditionalOperator *BCO 362256ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall = dyn_cast<BinaryConditionalOperator>(E)) { 362356ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall ConfluenceBlock = VisitForTemporaryDtors(BCO->getCommon()); 36248599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski if (badCFG) 36256bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return nullptr; 36268599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski } 36278599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski 362856ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall // Try to add block with destructors for LHS expression. 36296bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines CFGBlock *LHSBlock = nullptr; 363056ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall Succ = ConfluenceBlock; 36316bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines Block = nullptr; 363256ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall LHSBlock = VisitForTemporaryDtors(E->getTrueExpr(), BindToTemporary); 363356ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall if (badCFG) 36346bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return nullptr; 363556ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall 36368599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski // Try to add block with destructors for RHS expression; 36378599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski Succ = ConfluenceBlock; 36386bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines Block = nullptr; 363956ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall CFGBlock *RHSBlock = VisitForTemporaryDtors(E->getFalseExpr(), 364056ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall BindToTemporary); 36418599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski if (badCFG) 36426bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return nullptr; 36438599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski 36448599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski if (!RHSBlock && !LHSBlock) { 36458599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski // If neither LHS nor RHS expression had temporaries to destroy don't create 36468599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski // more blocks. 36478599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski Block = ConfluenceBlock; 36488599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski return Block; 36498599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski } 36508599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski 36518599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski Block = createBlock(false); 36528599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski Block->setTerminator(CFGTerminator(E, true)); 3653651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines assert(Block->getTerminator().isTemporaryDtorsBranch()); 36548599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski 36558599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski // See if this is a known constant. 36560a3ed3143b00f237decb1288c1ff574ae09eba4eTed Kremenek const TryResult &KnownVal = tryEvaluateBool(E->getCond()); 36578599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski 36588599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski if (LHSBlock) { 3659651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines addSuccessor(Block, LHSBlock, !KnownVal.isFalse()); 36608599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski } else if (KnownVal.isFalse()) { 36616bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines addSuccessor(Block, nullptr); 36628599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski } else { 36630a3ed3143b00f237decb1288c1ff574ae09eba4eTed Kremenek addSuccessor(Block, ConfluenceBlock); 36648599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski std::reverse(ConfluenceBlock->pred_begin(), ConfluenceBlock->pred_end()); 36658599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski } 36668599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski 36678599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski if (!RHSBlock) 36688599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski RHSBlock = ConfluenceBlock; 3669651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 3670651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines addSuccessor(Block, RHSBlock, !KnownVal.isTrue()); 36718599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski 36728599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski return Block; 36738599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski} 36748599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski 3675befef2f69759d7338e2b7c5ce6c8b6f47fe6e667Ted Kremenek} // end anonymous namespace 3676026473c2175424a039f51ca8949937268721b965Ted Kremenek 36776d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump/// createBlock - Constructs and adds a new CFGBlock to the CFG. The block has 36786d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump/// no successors or predecessors. If this is the first block created in the 36796d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump/// CFG, it is automatically set to be the Entry and Exit of the CFG. 36809c378f705405d37f49795d5e915989de774fe11fTed KremenekCFGBlock *CFG::createBlock() { 3681026473c2175424a039f51ca8949937268721b965Ted Kremenek bool first_block = begin() == end(); 3682026473c2175424a039f51ca8949937268721b965Ted Kremenek 3683026473c2175424a039f51ca8949937268721b965Ted Kremenek // Create the block. 3684ee82d9bdc5025b82de8ce2a4ad4685e0a8b79da9Ted Kremenek CFGBlock *Mem = getAllocator().Allocate<CFGBlock>(); 368502f34c5003b2c5067675f89ffce0a84c28faf722Anna Zaks new (Mem) CFGBlock(NumBlockIDs++, BlkBVC, this); 3686ee82d9bdc5025b82de8ce2a4ad4685e0a8b79da9Ted Kremenek Blocks.push_back(Mem, BlkBVC); 3687026473c2175424a039f51ca8949937268721b965Ted Kremenek 3688026473c2175424a039f51ca8949937268721b965Ted Kremenek // If this is the first block, set it as the Entry and Exit. 3689ee82d9bdc5025b82de8ce2a4ad4685e0a8b79da9Ted Kremenek if (first_block) 3690ee82d9bdc5025b82de8ce2a4ad4685e0a8b79da9Ted Kremenek Entry = Exit = &back(); 3691026473c2175424a039f51ca8949937268721b965Ted Kremenek 3692026473c2175424a039f51ca8949937268721b965Ted Kremenek // Return the block. 3693ee82d9bdc5025b82de8ce2a4ad4685e0a8b79da9Ted Kremenek return &back(); 3694026473c2175424a039f51ca8949937268721b965Ted Kremenek} 3695026473c2175424a039f51ca8949937268721b965Ted Kremenek 3696026473c2175424a039f51ca8949937268721b965Ted Kremenek/// buildCFG - Constructs a CFG from an AST. Ownership of the returned 3697026473c2175424a039f51ca8949937268721b965Ted Kremenek/// CFG is returned to the caller. 36989c378f705405d37f49795d5e915989de774fe11fTed KremenekCFG* CFG::buildCFG(const Decl *D, Stmt *Statement, ASTContext *C, 3699b8ad5ee345fa1fdd1fa9253f2d01f69becc88a04Ted Kremenek const BuildOptions &BO) { 3700b8ad5ee345fa1fdd1fa9253f2d01f69becc88a04Ted Kremenek CFGBuilder Builder(C, BO); 3701b8ad5ee345fa1fdd1fa9253f2d01f69becc88a04Ted Kremenek return Builder.buildCFG(D, Statement); 3702fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek} 3703fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek 3704c5aff4497e5bfd7523e00b87560c1a5aa65136ccTed Kremenekconst CXXDestructorDecl * 3705c5aff4497e5bfd7523e00b87560c1a5aa65136ccTed KremenekCFGImplicitDtor::getDestructorDecl(ASTContext &astContext) const { 3706c9f8f5a726bbb562e4b2d4b19d66e6202dcb2657Ted Kremenek switch (getKind()) { 3707c9f8f5a726bbb562e4b2d4b19d66e6202dcb2657Ted Kremenek case CFGElement::Statement: 3708c9f8f5a726bbb562e4b2d4b19d66e6202dcb2657Ted Kremenek case CFGElement::Initializer: 3709651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines case CFGElement::NewAllocator: 3710c9f8f5a726bbb562e4b2d4b19d66e6202dcb2657Ted Kremenek llvm_unreachable("getDestructorDecl should only be used with " 3711c9f8f5a726bbb562e4b2d4b19d66e6202dcb2657Ted Kremenek "ImplicitDtors"); 3712c9f8f5a726bbb562e4b2d4b19d66e6202dcb2657Ted Kremenek case CFGElement::AutomaticObjectDtor: { 3713fdf6a279c9a75c778eba382d9a156697092982a1David Blaikie const VarDecl *var = castAs<CFGAutomaticObjDtor>().getVarDecl(); 3714c9f8f5a726bbb562e4b2d4b19d66e6202dcb2657Ted Kremenek QualType ty = var->getType(); 3715697d42db6cba7a5994d955ce31be2c097902cf0cTed Kremenek ty = ty.getNonReferenceType(); 37164cf225382a8b061dce41733c962d62b6db9721f8Ted Kremenek while (const ArrayType *arrayType = astContext.getAsArrayType(ty)) { 3717c5aff4497e5bfd7523e00b87560c1a5aa65136ccTed Kremenek ty = arrayType->getElementType(); 3718c5aff4497e5bfd7523e00b87560c1a5aa65136ccTed Kremenek } 3719c9f8f5a726bbb562e4b2d4b19d66e6202dcb2657Ted Kremenek const RecordType *recordType = ty->getAs<RecordType>(); 3720c9f8f5a726bbb562e4b2d4b19d66e6202dcb2657Ted Kremenek const CXXRecordDecl *classDecl = 3721697d42db6cba7a5994d955ce31be2c097902cf0cTed Kremenek cast<CXXRecordDecl>(recordType->getDecl()); 3722c9f8f5a726bbb562e4b2d4b19d66e6202dcb2657Ted Kremenek return classDecl->getDestructor(); 3723c9f8f5a726bbb562e4b2d4b19d66e6202dcb2657Ted Kremenek } 372436d558d85653315edb389677e995ec9ccdbfbf3dJordan Rose case CFGElement::DeleteDtor: { 372536d558d85653315edb389677e995ec9ccdbfbf3dJordan Rose const CXXDeleteExpr *DE = castAs<CFGDeleteDtor>().getDeleteExpr(); 372636d558d85653315edb389677e995ec9ccdbfbf3dJordan Rose QualType DTy = DE->getDestroyedType(); 372736d558d85653315edb389677e995ec9ccdbfbf3dJordan Rose DTy = DTy.getNonReferenceType(); 372836d558d85653315edb389677e995ec9ccdbfbf3dJordan Rose const CXXRecordDecl *classDecl = 372936d558d85653315edb389677e995ec9ccdbfbf3dJordan Rose astContext.getBaseElementType(DTy)->getAsCXXRecordDecl(); 373036d558d85653315edb389677e995ec9ccdbfbf3dJordan Rose return classDecl->getDestructor(); 373136d558d85653315edb389677e995ec9ccdbfbf3dJordan Rose } 3732c9f8f5a726bbb562e4b2d4b19d66e6202dcb2657Ted Kremenek case CFGElement::TemporaryDtor: { 3733c9f8f5a726bbb562e4b2d4b19d66e6202dcb2657Ted Kremenek const CXXBindTemporaryExpr *bindExpr = 3734fdf6a279c9a75c778eba382d9a156697092982a1David Blaikie castAs<CFGTemporaryDtor>().getBindTemporaryExpr(); 3735c9f8f5a726bbb562e4b2d4b19d66e6202dcb2657Ted Kremenek const CXXTemporary *temp = bindExpr->getTemporary(); 3736c9f8f5a726bbb562e4b2d4b19d66e6202dcb2657Ted Kremenek return temp->getDestructor(); 3737c9f8f5a726bbb562e4b2d4b19d66e6202dcb2657Ted Kremenek } 3738c9f8f5a726bbb562e4b2d4b19d66e6202dcb2657Ted Kremenek case CFGElement::BaseDtor: 3739c9f8f5a726bbb562e4b2d4b19d66e6202dcb2657Ted Kremenek case CFGElement::MemberDtor: 3740c9f8f5a726bbb562e4b2d4b19d66e6202dcb2657Ted Kremenek 3741c9f8f5a726bbb562e4b2d4b19d66e6202dcb2657Ted Kremenek // Not yet supported. 37426bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return nullptr; 3743c9f8f5a726bbb562e4b2d4b19d66e6202dcb2657Ted Kremenek } 3744697d42db6cba7a5994d955ce31be2c097902cf0cTed Kremenek llvm_unreachable("getKind() returned bogus value"); 3745c9f8f5a726bbb562e4b2d4b19d66e6202dcb2657Ted Kremenek} 3746c9f8f5a726bbb562e4b2d4b19d66e6202dcb2657Ted Kremenek 3747c5aff4497e5bfd7523e00b87560c1a5aa65136ccTed Kremenekbool CFGImplicitDtor::isNoReturn(ASTContext &astContext) const { 3748cd8ab51a44e80625d84126780b0d85a7732e25afRichard Smith if (const CXXDestructorDecl *DD = getDestructorDecl(astContext)) 3749cd8ab51a44e80625d84126780b0d85a7732e25afRichard Smith return DD->isNoReturn(); 3750c9f8f5a726bbb562e4b2d4b19d66e6202dcb2657Ted Kremenek return false; 37513c0349e87cdbd7316d06d2411d86ee1086e717a5Ted Kremenek} 37523c0349e87cdbd7316d06d2411d86ee1086e717a5Ted Kremenek 375363f5887f316fb52d243fcbb3631c039de6c4b993Ted Kremenek//===----------------------------------------------------------------------===// 3754651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CFGBlock operations. 3755ee7f84d509c6382491673883598eb9ed2d3a6a8bTed Kremenek//===----------------------------------------------------------------------===// 3756ee7f84d509c6382491673883598eb9ed2d3a6a8bTed Kremenek 3757651f13cea278ec967336033dd032faef0e9fc2ecStephen HinesCFGBlock::AdjacentBlock::AdjacentBlock(CFGBlock *B, bool IsReachable) 37586bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines : ReachableBlock(IsReachable ? B : nullptr), 37596bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines UnreachableBlock(!IsReachable ? B : nullptr, 3760651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines B && IsReachable ? AB_Normal : AB_Unreachable) {} 3761651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 3762651f13cea278ec967336033dd032faef0e9fc2ecStephen HinesCFGBlock::AdjacentBlock::AdjacentBlock(CFGBlock *B, CFGBlock *AlternateBlock) 3763651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines : ReachableBlock(B), 37646bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines UnreachableBlock(B == AlternateBlock ? nullptr : AlternateBlock, 3765651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines B == AlternateBlock ? AB_Alternate : AB_Normal) {} 3766651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 3767651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesvoid CFGBlock::addSuccessor(AdjacentBlock Succ, 3768651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines BumpVectorContext &C) { 3769651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (CFGBlock *B = Succ.getReachableBlock()) 3770651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines B->Preds.push_back(AdjacentBlock(this, Succ.isReachable()), C); 3771651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 3772651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (CFGBlock *UnreachableB = Succ.getPossiblyUnreachableBlock()) 3773651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines UnreachableB->Preds.push_back(AdjacentBlock(this, false), C); 3774651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 3775651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Succs.push_back(Succ, C); 3776651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines} 3777651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 3778ee7f84d509c6382491673883598eb9ed2d3a6a8bTed Kremenekbool CFGBlock::FilterEdge(const CFGBlock::FilterOptions &F, 3779be39a566a914df8561d7a1e9654708297f0908c1Ted Kremenek const CFGBlock *From, const CFGBlock *To) { 3780ee7f84d509c6382491673883598eb9ed2d3a6a8bTed Kremenek 3781651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (F.IgnoreNullPredecessors && !From) 3782651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return true; 3783651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 3784651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (To && From && F.IgnoreDefaultsWithCoveredEnums) { 3785ee7f84d509c6382491673883598eb9ed2d3a6a8bTed Kremenek // If the 'To' has no label or is labeled but the label isn't a 3786ee7f84d509c6382491673883598eb9ed2d3a6a8bTed Kremenek // CaseStmt then filter this edge. 3787ee7f84d509c6382491673883598eb9ed2d3a6a8bTed Kremenek if (const SwitchStmt *S = 37886e40035988965340555c942d6e7afb6c7527beb1Ted Kremenek dyn_cast_or_null<SwitchStmt>(From->getTerminator().getStmt())) { 3789ee7f84d509c6382491673883598eb9ed2d3a6a8bTed Kremenek if (S->isAllEnumCasesCovered()) { 37906e40035988965340555c942d6e7afb6c7527beb1Ted Kremenek const Stmt *L = To->getLabel(); 37916e40035988965340555c942d6e7afb6c7527beb1Ted Kremenek if (!L || !isa<CaseStmt>(L)) 37926e40035988965340555c942d6e7afb6c7527beb1Ted Kremenek return true; 3793ee7f84d509c6382491673883598eb9ed2d3a6a8bTed Kremenek } 3794ee7f84d509c6382491673883598eb9ed2d3a6a8bTed Kremenek } 3795ee7f84d509c6382491673883598eb9ed2d3a6a8bTed Kremenek } 3796ee7f84d509c6382491673883598eb9ed2d3a6a8bTed Kremenek 3797ee7f84d509c6382491673883598eb9ed2d3a6a8bTed Kremenek return false; 3798ee7f84d509c6382491673883598eb9ed2d3a6a8bTed Kremenek} 3799ee7f84d509c6382491673883598eb9ed2d3a6a8bTed Kremenek 3800ee7f84d509c6382491673883598eb9ed2d3a6a8bTed Kremenek//===----------------------------------------------------------------------===// 38017dba8607e59096014b7139ff20ef00870041d518Ted Kremenek// CFG pretty printing 38027dba8607e59096014b7139ff20ef00870041d518Ted Kremenek//===----------------------------------------------------------------------===// 38037dba8607e59096014b7139ff20ef00870041d518Ted Kremenek 380442a509f6a4f71bb805cc4abbb26722a34dffdddeTed Kremeneknamespace { 38052bac4ea765a4a6e1f6149964663f62d4bca6743bTed Kremenek 3806ba5fb5a955c896815c439289fc51c03cf0635129Kovarththanan Rajaratnamclass StmtPrinterHelper : public PrinterHelper { 38073c0349e87cdbd7316d06d2411d86ee1086e717a5Ted Kremenek typedef llvm::DenseMap<const Stmt*,std::pair<unsigned,unsigned> > StmtMapTy; 38083c0349e87cdbd7316d06d2411d86ee1086e717a5Ted Kremenek typedef llvm::DenseMap<const Decl*,std::pair<unsigned,unsigned> > DeclMapTy; 380942a509f6a4f71bb805cc4abbb26722a34dffdddeTed Kremenek StmtMapTy StmtMap; 38101cff132e48e0ccc253c34e5a2fb12718bd4e7d2eMarcin Swiderski DeclMapTy DeclMap; 38110a3ed3143b00f237decb1288c1ff574ae09eba4eTed Kremenek signed currentBlock; 381266c486f275531df6362b3511fc3af6563561801bTed Kremenek unsigned currStmt; 3813e4f2142d00fa5fdb580c4e2413da91882d955381Chris Lattner const LangOptions &LangOpts; 381442a509f6a4f71bb805cc4abbb26722a34dffdddeTed Kremenekpublic: 38151c29bba6da40bbe59fb1f81c4cd5ab5471554ffeTed Kremenek 3816e4f2142d00fa5fdb580c4e2413da91882d955381Chris Lattner StmtPrinterHelper(const CFG* cfg, const LangOptions &LO) 381766c486f275531df6362b3511fc3af6563561801bTed Kremenek : currentBlock(0), currStmt(0), LangOpts(LO) 38183c0349e87cdbd7316d06d2411d86ee1086e717a5Ted Kremenek { 381942a509f6a4f71bb805cc4abbb26722a34dffdddeTed Kremenek for (CFG::const_iterator I = cfg->begin(), E = cfg->end(); I != E; ++I ) { 382042a509f6a4f71bb805cc4abbb26722a34dffdddeTed Kremenek unsigned j = 1; 3821ee82d9bdc5025b82de8ce2a4ad4685e0a8b79da9Ted Kremenek for (CFGBlock::const_iterator BI = (*I)->begin(), BEnd = (*I)->end() ; 38221cff132e48e0ccc253c34e5a2fb12718bd4e7d2eMarcin Swiderski BI != BEnd; ++BI, ++j ) { 3823b07805485c603be3d8011f72611465324c9e664bDavid Blaikie if (Optional<CFGStmt> SE = BI->getAs<CFGStmt>()) { 3824b07805485c603be3d8011f72611465324c9e664bDavid Blaikie const Stmt *stmt= SE->getStmt(); 38251cff132e48e0ccc253c34e5a2fb12718bd4e7d2eMarcin Swiderski std::pair<unsigned, unsigned> P((*I)->getBlockID(), j); 38263c0349e87cdbd7316d06d2411d86ee1086e717a5Ted Kremenek StmtMap[stmt] = P; 38273c0349e87cdbd7316d06d2411d86ee1086e717a5Ted Kremenek 38283c0349e87cdbd7316d06d2411d86ee1086e717a5Ted Kremenek switch (stmt->getStmtClass()) { 38293c0349e87cdbd7316d06d2411d86ee1086e717a5Ted Kremenek case Stmt::DeclStmtClass: 38303c0349e87cdbd7316d06d2411d86ee1086e717a5Ted Kremenek DeclMap[cast<DeclStmt>(stmt)->getSingleDecl()] = P; 38313c0349e87cdbd7316d06d2411d86ee1086e717a5Ted Kremenek break; 38323c0349e87cdbd7316d06d2411d86ee1086e717a5Ted Kremenek case Stmt::IfStmtClass: { 38333c0349e87cdbd7316d06d2411d86ee1086e717a5Ted Kremenek const VarDecl *var = cast<IfStmt>(stmt)->getConditionVariable(); 38343c0349e87cdbd7316d06d2411d86ee1086e717a5Ted Kremenek if (var) 38353c0349e87cdbd7316d06d2411d86ee1086e717a5Ted Kremenek DeclMap[var] = P; 38363c0349e87cdbd7316d06d2411d86ee1086e717a5Ted Kremenek break; 38373c0349e87cdbd7316d06d2411d86ee1086e717a5Ted Kremenek } 38383c0349e87cdbd7316d06d2411d86ee1086e717a5Ted Kremenek case Stmt::ForStmtClass: { 38393c0349e87cdbd7316d06d2411d86ee1086e717a5Ted Kremenek const VarDecl *var = cast<ForStmt>(stmt)->getConditionVariable(); 38403c0349e87cdbd7316d06d2411d86ee1086e717a5Ted Kremenek if (var) 38413c0349e87cdbd7316d06d2411d86ee1086e717a5Ted Kremenek DeclMap[var] = P; 38423c0349e87cdbd7316d06d2411d86ee1086e717a5Ted Kremenek break; 38433c0349e87cdbd7316d06d2411d86ee1086e717a5Ted Kremenek } 38443c0349e87cdbd7316d06d2411d86ee1086e717a5Ted Kremenek case Stmt::WhileStmtClass: { 38453c0349e87cdbd7316d06d2411d86ee1086e717a5Ted Kremenek const VarDecl *var = 38463c0349e87cdbd7316d06d2411d86ee1086e717a5Ted Kremenek cast<WhileStmt>(stmt)->getConditionVariable(); 38473c0349e87cdbd7316d06d2411d86ee1086e717a5Ted Kremenek if (var) 38483c0349e87cdbd7316d06d2411d86ee1086e717a5Ted Kremenek DeclMap[var] = P; 38493c0349e87cdbd7316d06d2411d86ee1086e717a5Ted Kremenek break; 38503c0349e87cdbd7316d06d2411d86ee1086e717a5Ted Kremenek } 38513c0349e87cdbd7316d06d2411d86ee1086e717a5Ted Kremenek case Stmt::SwitchStmtClass: { 38523c0349e87cdbd7316d06d2411d86ee1086e717a5Ted Kremenek const VarDecl *var = 38533c0349e87cdbd7316d06d2411d86ee1086e717a5Ted Kremenek cast<SwitchStmt>(stmt)->getConditionVariable(); 38543c0349e87cdbd7316d06d2411d86ee1086e717a5Ted Kremenek if (var) 38553c0349e87cdbd7316d06d2411d86ee1086e717a5Ted Kremenek DeclMap[var] = P; 38563c0349e87cdbd7316d06d2411d86ee1086e717a5Ted Kremenek break; 38573c0349e87cdbd7316d06d2411d86ee1086e717a5Ted Kremenek } 38583c0349e87cdbd7316d06d2411d86ee1086e717a5Ted Kremenek case Stmt::CXXCatchStmtClass: { 38593c0349e87cdbd7316d06d2411d86ee1086e717a5Ted Kremenek const VarDecl *var = 38603c0349e87cdbd7316d06d2411d86ee1086e717a5Ted Kremenek cast<CXXCatchStmt>(stmt)->getExceptionDecl(); 38613c0349e87cdbd7316d06d2411d86ee1086e717a5Ted Kremenek if (var) 38623c0349e87cdbd7316d06d2411d86ee1086e717a5Ted Kremenek DeclMap[var] = P; 38633c0349e87cdbd7316d06d2411d86ee1086e717a5Ted Kremenek break; 38643c0349e87cdbd7316d06d2411d86ee1086e717a5Ted Kremenek } 38653c0349e87cdbd7316d06d2411d86ee1086e717a5Ted Kremenek default: 38663c0349e87cdbd7316d06d2411d86ee1086e717a5Ted Kremenek break; 38671cff132e48e0ccc253c34e5a2fb12718bd4e7d2eMarcin Swiderski } 38681cff132e48e0ccc253c34e5a2fb12718bd4e7d2eMarcin Swiderski } 386942a509f6a4f71bb805cc4abbb26722a34dffdddeTed Kremenek } 3870b36cd3e1757fb4fcd9509f35558c847b04bef35fZhongxing Xu } 3871fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek } 38723c0349e87cdbd7316d06d2411d86ee1086e717a5Ted Kremenek 38736d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 387442a509f6a4f71bb805cc4abbb26722a34dffdddeTed Kremenek virtual ~StmtPrinterHelper() {} 38756d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 3876e4f2142d00fa5fdb580c4e2413da91882d955381Chris Lattner const LangOptions &getLangOpts() const { return LangOpts; } 38770a3ed3143b00f237decb1288c1ff574ae09eba4eTed Kremenek void setBlockID(signed i) { currentBlock = i; } 387866c486f275531df6362b3511fc3af6563561801bTed Kremenek void setStmtID(unsigned i) { currStmt = i; } 38796d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 3880651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines bool handledStmt(Stmt *S, raw_ostream &OS) override { 38811cff132e48e0ccc253c34e5a2fb12718bd4e7d2eMarcin Swiderski StmtMapTy::iterator I = StmtMap.find(S); 3882fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek 388342a509f6a4f71bb805cc4abbb26722a34dffdddeTed Kremenek if (I == StmtMap.end()) 388442a509f6a4f71bb805cc4abbb26722a34dffdddeTed Kremenek return false; 38856d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 38860a3ed3143b00f237decb1288c1ff574ae09eba4eTed Kremenek if (currentBlock >= 0 && I->second.first == (unsigned) currentBlock 388766c486f275531df6362b3511fc3af6563561801bTed Kremenek && I->second.second == currStmt) { 388842a509f6a4f71bb805cc4abbb26722a34dffdddeTed Kremenek return false; 38893fa1e4b27300a4ea4cf273182d4b6427ef87f3f8Ted Kremenek } 38906d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 38913fa1e4b27300a4ea4cf273182d4b6427ef87f3f8Ted Kremenek OS << "[B" << I->second.first << "." << I->second.second << "]"; 38921c29bba6da40bbe59fb1f81c4cd5ab5471554ffeTed Kremenek return true; 389342a509f6a4f71bb805cc4abbb26722a34dffdddeTed Kremenek } 38941cff132e48e0ccc253c34e5a2fb12718bd4e7d2eMarcin Swiderski 38959c378f705405d37f49795d5e915989de774fe11fTed Kremenek bool handleDecl(const Decl *D, raw_ostream &OS) { 38961cff132e48e0ccc253c34e5a2fb12718bd4e7d2eMarcin Swiderski DeclMapTy::iterator I = DeclMap.find(D); 38971cff132e48e0ccc253c34e5a2fb12718bd4e7d2eMarcin Swiderski 38981cff132e48e0ccc253c34e5a2fb12718bd4e7d2eMarcin Swiderski if (I == DeclMap.end()) 38991cff132e48e0ccc253c34e5a2fb12718bd4e7d2eMarcin Swiderski return false; 39001cff132e48e0ccc253c34e5a2fb12718bd4e7d2eMarcin Swiderski 39010a3ed3143b00f237decb1288c1ff574ae09eba4eTed Kremenek if (currentBlock >= 0 && I->second.first == (unsigned) currentBlock 390266c486f275531df6362b3511fc3af6563561801bTed Kremenek && I->second.second == currStmt) { 39031cff132e48e0ccc253c34e5a2fb12718bd4e7d2eMarcin Swiderski return false; 39041cff132e48e0ccc253c34e5a2fb12718bd4e7d2eMarcin Swiderski } 39051cff132e48e0ccc253c34e5a2fb12718bd4e7d2eMarcin Swiderski 39061cff132e48e0ccc253c34e5a2fb12718bd4e7d2eMarcin Swiderski OS << "[B" << I->second.first << "." << I->second.second << "]"; 39071cff132e48e0ccc253c34e5a2fb12718bd4e7d2eMarcin Swiderski return true; 39081cff132e48e0ccc253c34e5a2fb12718bd4e7d2eMarcin Swiderski } 390942a509f6a4f71bb805cc4abbb26722a34dffdddeTed Kremenek}; 3910e4f2142d00fa5fdb580c4e2413da91882d955381Chris Lattner} // end anonymous namespace 3911e4f2142d00fa5fdb580c4e2413da91882d955381Chris Lattner 3912e8ee26b49d68ae3ffdf9a990ff7511ef55afa04cTed Kremenek 3913e4f2142d00fa5fdb580c4e2413da91882d955381Chris Lattnernamespace { 3914ba5fb5a955c896815c439289fc51c03cf0635129Kovarththanan Rajaratnamclass CFGBlockTerminatorPrint 39156fa9b88e2c3d47d606a273df2f8d03509bcff0b9Ted Kremenek : public StmtVisitor<CFGBlockTerminatorPrint,void> { 39166d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 39179c378f705405d37f49795d5e915989de774fe11fTed Kremenek raw_ostream &OS; 391842a509f6a4f71bb805cc4abbb26722a34dffdddeTed Kremenek StmtPrinterHelper* Helper; 3919d249e1d1f1498b81314459ceda19d6ff25c278adDouglas Gregor PrintingPolicy Policy; 3920d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenekpublic: 39219c378f705405d37f49795d5e915989de774fe11fTed Kremenek CFGBlockTerminatorPrint(raw_ostream &os, StmtPrinterHelper* helper, 3922e4f2142d00fa5fdb580c4e2413da91882d955381Chris Lattner const PrintingPolicy &Policy) 3923651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines : OS(os), Helper(helper), Policy(Policy) { 3924651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines this->Policy.IncludeNewlines = false; 3925651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 39266d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 39279c378f705405d37f49795d5e915989de774fe11fTed Kremenek void VisitIfStmt(IfStmt *I) { 3928d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek OS << "if "; 3929ef8225444452a1486bd721f3285301fe84643b00Stephen Hines if (Stmt *C = I->getCond()) 3930ef8225444452a1486bd721f3285301fe84643b00Stephen Hines C->printPretty(OS, Helper, Policy); 3931d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek } 39326d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 3933d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek // Default case. 39349c378f705405d37f49795d5e915989de774fe11fTed Kremenek void VisitStmt(Stmt *Terminator) { 39356d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump Terminator->printPretty(OS, Helper, Policy); 39366d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump } 39376d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 3938fbd4b5dc7febd1d8b4fa64ab00a29d72b44bec7bTed Kremenek void VisitDeclStmt(DeclStmt *DS) { 3939fbd4b5dc7febd1d8b4fa64ab00a29d72b44bec7bTed Kremenek VarDecl *VD = cast<VarDecl>(DS->getSingleDecl()); 3940fbd4b5dc7febd1d8b4fa64ab00a29d72b44bec7bTed Kremenek OS << "static init " << VD->getName(); 3941fbd4b5dc7febd1d8b4fa64ab00a29d72b44bec7bTed Kremenek } 3942fbd4b5dc7febd1d8b4fa64ab00a29d72b44bec7bTed Kremenek 39439c378f705405d37f49795d5e915989de774fe11fTed Kremenek void VisitForStmt(ForStmt *F) { 3944d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek OS << "for (" ; 39453fa1e4b27300a4ea4cf273182d4b6427ef87f3f8Ted Kremenek if (F->getInit()) 39463fa1e4b27300a4ea4cf273182d4b6427ef87f3f8Ted Kremenek OS << "..."; 3947535bb20b6e252809bc17cc59b5d71b5e5e549e70Ted Kremenek OS << "; "; 39489c378f705405d37f49795d5e915989de774fe11fTed Kremenek if (Stmt *C = F->getCond()) 39493fa1e4b27300a4ea4cf273182d4b6427ef87f3f8Ted Kremenek C->printPretty(OS, Helper, Policy); 3950535bb20b6e252809bc17cc59b5d71b5e5e549e70Ted Kremenek OS << "; "; 39513fa1e4b27300a4ea4cf273182d4b6427ef87f3f8Ted Kremenek if (F->getInc()) 39523fa1e4b27300a4ea4cf273182d4b6427ef87f3f8Ted Kremenek OS << "..."; 3953a292585207adbf6dcf6347db3526a7ec861d8eacTed Kremenek OS << ")"; 3954d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek } 39556d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 39569c378f705405d37f49795d5e915989de774fe11fTed Kremenek void VisitWhileStmt(WhileStmt *W) { 3957d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek OS << "while " ; 39589c378f705405d37f49795d5e915989de774fe11fTed Kremenek if (Stmt *C = W->getCond()) 39593fa1e4b27300a4ea4cf273182d4b6427ef87f3f8Ted Kremenek C->printPretty(OS, Helper, Policy); 3960d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek } 39616d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 39629c378f705405d37f49795d5e915989de774fe11fTed Kremenek void VisitDoStmt(DoStmt *D) { 3963d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek OS << "do ... while "; 39649c378f705405d37f49795d5e915989de774fe11fTed Kremenek if (Stmt *C = D->getCond()) 39653fa1e4b27300a4ea4cf273182d4b6427ef87f3f8Ted Kremenek C->printPretty(OS, Helper, Policy); 39669da2fb773c473b989c78c513c5ce61641e9bbb4dTed Kremenek } 39676d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 39689c378f705405d37f49795d5e915989de774fe11fTed Kremenek void VisitSwitchStmt(SwitchStmt *Terminator) { 39699da2fb773c473b989c78c513c5ce61641e9bbb4dTed Kremenek OS << "switch "; 3970d249e1d1f1498b81314459ceda19d6ff25c278adDouglas Gregor Terminator->getCond()->printPretty(OS, Helper, Policy); 39719da2fb773c473b989c78c513c5ce61641e9bbb4dTed Kremenek } 39726d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 39739c378f705405d37f49795d5e915989de774fe11fTed Kremenek void VisitCXXTryStmt(CXXTryStmt *CS) { 39745d1d20227878cd03db8b2dd23efd4cedfe874feeMike Stump OS << "try ..."; 39755d1d20227878cd03db8b2dd23efd4cedfe874feeMike Stump } 39765d1d20227878cd03db8b2dd23efd4cedfe874feeMike Stump 397756ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall void VisitAbstractConditionalOperator(AbstractConditionalOperator* C) { 3978ef8225444452a1486bd721f3285301fe84643b00Stephen Hines if (Stmt *Cond = C->getCond()) 3979ef8225444452a1486bd721f3285301fe84643b00Stephen Hines Cond->printPretty(OS, Helper, Policy); 39806d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump OS << " ? ... : ..."; 3981805e9a8300af9489ec13cd804c070267b7c4cfecTed Kremenek } 39826d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 39839c378f705405d37f49795d5e915989de774fe11fTed Kremenek void VisitChooseExpr(ChooseExpr *C) { 3984aeddbf689eb3e3afca5117ca83c7b2e18260b0d8Ted Kremenek OS << "__builtin_choose_expr( "; 3985ef8225444452a1486bd721f3285301fe84643b00Stephen Hines if (Stmt *Cond = C->getCond()) 3986ef8225444452a1486bd721f3285301fe84643b00Stephen Hines Cond->printPretty(OS, Helper, Policy); 3987a292585207adbf6dcf6347db3526a7ec861d8eacTed Kremenek OS << " )"; 3988aeddbf689eb3e3afca5117ca83c7b2e18260b0d8Ted Kremenek } 39896d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 39909c378f705405d37f49795d5e915989de774fe11fTed Kremenek void VisitIndirectGotoStmt(IndirectGotoStmt *I) { 39911c29bba6da40bbe59fb1f81c4cd5ab5471554ffeTed Kremenek OS << "goto *"; 3992ef8225444452a1486bd721f3285301fe84643b00Stephen Hines if (Stmt *T = I->getTarget()) 3993ef8225444452a1486bd721f3285301fe84643b00Stephen Hines T->printPretty(OS, Helper, Policy); 39941c29bba6da40bbe59fb1f81c4cd5ab5471554ffeTed Kremenek } 39956d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 3996805e9a8300af9489ec13cd804c070267b7c4cfecTed Kremenek void VisitBinaryOperator(BinaryOperator* B) { 3997805e9a8300af9489ec13cd804c070267b7c4cfecTed Kremenek if (!B->isLogicalOp()) { 3998805e9a8300af9489ec13cd804c070267b7c4cfecTed Kremenek VisitExpr(B); 3999805e9a8300af9489ec13cd804c070267b7c4cfecTed Kremenek return; 4000805e9a8300af9489ec13cd804c070267b7c4cfecTed Kremenek } 40016d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 4002ef8225444452a1486bd721f3285301fe84643b00Stephen Hines if (B->getLHS()) 4003ef8225444452a1486bd721f3285301fe84643b00Stephen Hines B->getLHS()->printPretty(OS, Helper, Policy); 40046d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 4005805e9a8300af9489ec13cd804c070267b7c4cfecTed Kremenek switch (B->getOpcode()) { 40062de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall case BO_LOr: 4007a292585207adbf6dcf6347db3526a7ec861d8eacTed Kremenek OS << " || ..."; 4008805e9a8300af9489ec13cd804c070267b7c4cfecTed Kremenek return; 40092de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall case BO_LAnd: 4010a292585207adbf6dcf6347db3526a7ec861d8eacTed Kremenek OS << " && ..."; 4011805e9a8300af9489ec13cd804c070267b7c4cfecTed Kremenek return; 4012805e9a8300af9489ec13cd804c070267b7c4cfecTed Kremenek default: 4013b219cfc4d75f0a03630b7c4509ef791b7e97b2c8David Blaikie llvm_unreachable("Invalid logical operator."); 40146d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump } 4015805e9a8300af9489ec13cd804c070267b7c4cfecTed Kremenek } 40166d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 40179c378f705405d37f49795d5e915989de774fe11fTed Kremenek void VisitExpr(Expr *E) { 4018d249e1d1f1498b81314459ceda19d6ff25c278adDouglas Gregor E->printPretty(OS, Helper, Policy); 40196d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump } 4020651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 4021651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinespublic: 4022651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines void print(CFGTerminator T) { 4023651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (T.isTemporaryDtorsBranch()) 4024651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines OS << "(Temp Dtor) "; 4025651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Visit(T.getStmt()); 4026651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 4027d4fdee35477e439759eea5f67ea03ff0c570fabaTed Kremenek}; 4028e4f2142d00fa5fdb580c4e2413da91882d955381Chris Lattner} // end anonymous namespace 4029e4f2142d00fa5fdb580c4e2413da91882d955381Chris Lattner 403029fc11a7abc06c30146a0ba3733da1c758586784Aaron Ballmanstatic void print_elem(raw_ostream &OS, StmtPrinterHelper &Helper, 4031079bd72439448b78629a28da6b1f8abe2cdeaf4dMike Stump const CFGElement &E) { 4032b07805485c603be3d8011f72611465324c9e664bDavid Blaikie if (Optional<CFGStmt> CS = E.getAs<CFGStmt>()) { 4033b07805485c603be3d8011f72611465324c9e664bDavid Blaikie const Stmt *S = CS->getStmt(); 4034ef8225444452a1486bd721f3285301fe84643b00Stephen Hines assert(S != nullptr && "Expecting non-null Stmt"); 4035ef8225444452a1486bd721f3285301fe84643b00Stephen Hines 403629fc11a7abc06c30146a0ba3733da1c758586784Aaron Ballman // special printing for statement-expressions. 403729fc11a7abc06c30146a0ba3733da1c758586784Aaron Ballman if (const StmtExpr *SE = dyn_cast<StmtExpr>(S)) { 403829fc11a7abc06c30146a0ba3733da1c758586784Aaron Ballman const CompoundStmt *Sub = SE->getSubStmt(); 403929fc11a7abc06c30146a0ba3733da1c758586784Aaron Ballman 404029fc11a7abc06c30146a0ba3733da1c758586784Aaron Ballman if (Sub->children()) { 404129fc11a7abc06c30146a0ba3733da1c758586784Aaron Ballman OS << "({ ... ; "; 404229fc11a7abc06c30146a0ba3733da1c758586784Aaron Ballman Helper.handledStmt(*SE->getSubStmt()->body_rbegin(),OS); 404329fc11a7abc06c30146a0ba3733da1c758586784Aaron Ballman OS << " })\n"; 404429fc11a7abc06c30146a0ba3733da1c758586784Aaron Ballman return; 40451cff132e48e0ccc253c34e5a2fb12718bd4e7d2eMarcin Swiderski } 404629fc11a7abc06c30146a0ba3733da1c758586784Aaron Ballman } 404729fc11a7abc06c30146a0ba3733da1c758586784Aaron Ballman // special printing for comma expressions. 404829fc11a7abc06c30146a0ba3733da1c758586784Aaron Ballman if (const BinaryOperator* B = dyn_cast<BinaryOperator>(S)) { 404929fc11a7abc06c30146a0ba3733da1c758586784Aaron Ballman if (B->getOpcode() == BO_Comma) { 405029fc11a7abc06c30146a0ba3733da1c758586784Aaron Ballman OS << "... , "; 405129fc11a7abc06c30146a0ba3733da1c758586784Aaron Ballman Helper.handledStmt(B->getRHS(),OS); 405229fc11a7abc06c30146a0ba3733da1c758586784Aaron Ballman OS << '\n'; 405329fc11a7abc06c30146a0ba3733da1c758586784Aaron Ballman return; 40541c29bba6da40bbe59fb1f81c4cd5ab5471554ffeTed Kremenek } 40551c29bba6da40bbe59fb1f81c4cd5ab5471554ffeTed Kremenek } 405629fc11a7abc06c30146a0ba3733da1c758586784Aaron Ballman S->printPretty(OS, &Helper, PrintingPolicy(Helper.getLangOpts())); 40576d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 40581cff132e48e0ccc253c34e5a2fb12718bd4e7d2eMarcin Swiderski if (isa<CXXOperatorCallExpr>(S)) { 405936f327c309b1fb6b82f1987190f0be74000b14c1Zhanyong Wan OS << " (OperatorCall)"; 4060893d414534273e153e12aef39a1ad991c6fa94c0Ted Kremenek } 4061893d414534273e153e12aef39a1ad991c6fa94c0Ted Kremenek else if (isa<CXXBindTemporaryExpr>(S)) { 406236f327c309b1fb6b82f1987190f0be74000b14c1Zhanyong Wan OS << " (BindTemporary)"; 40636d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump } 40643b7a48fbc681c6fb59e5304a210c30dbb49dabeaTed Kremenek else if (const CXXConstructExpr *CCE = dyn_cast<CXXConstructExpr>(S)) { 40653b7a48fbc681c6fb59e5304a210c30dbb49dabeaTed Kremenek OS << " (CXXConstructExpr, " << CCE->getType().getAsString() << ")"; 40663b7a48fbc681c6fb59e5304a210c30dbb49dabeaTed Kremenek } 4067893d414534273e153e12aef39a1ad991c6fa94c0Ted Kremenek else if (const CastExpr *CE = dyn_cast<CastExpr>(S)) { 4068893d414534273e153e12aef39a1ad991c6fa94c0Ted Kremenek OS << " (" << CE->getStmtClassName() << ", " 4069893d414534273e153e12aef39a1ad991c6fa94c0Ted Kremenek << CE->getCastKindName() 4070893d414534273e153e12aef39a1ad991c6fa94c0Ted Kremenek << ", " << CE->getType().getAsString() 4071893d414534273e153e12aef39a1ad991c6fa94c0Ted Kremenek << ")"; 4072893d414534273e153e12aef39a1ad991c6fa94c0Ted Kremenek } 40736d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 40741cff132e48e0ccc253c34e5a2fb12718bd4e7d2eMarcin Swiderski // Expressions need a newline. 40751cff132e48e0ccc253c34e5a2fb12718bd4e7d2eMarcin Swiderski if (isa<Expr>(S)) 40761cff132e48e0ccc253c34e5a2fb12718bd4e7d2eMarcin Swiderski OS << '\n'; 40774e0cfa8eacf76f203d6ee6ce164162ccd4275ccdTed Kremenek 4078b07805485c603be3d8011f72611465324c9e664bDavid Blaikie } else if (Optional<CFGInitializer> IE = E.getAs<CFGInitializer>()) { 4079b07805485c603be3d8011f72611465324c9e664bDavid Blaikie const CXXCtorInitializer *I = IE->getInitializer(); 40801cff132e48e0ccc253c34e5a2fb12718bd4e7d2eMarcin Swiderski if (I->isBaseInitializer()) 40811cff132e48e0ccc253c34e5a2fb12718bd4e7d2eMarcin Swiderski OS << I->getBaseClass()->getAsCXXRecordDecl()->getName(); 40823f5b4de5a05c07a2af5b0e61e919ac0f803c78c9Jordan Rose else if (I->isDelegatingInitializer()) 40833f5b4de5a05c07a2af5b0e61e919ac0f803c78c9Jordan Rose OS << I->getTypeSourceInfo()->getType()->getAsCXXRecordDecl()->getName(); 408400eb3f9c5b33e3d99aee1f8b75dd9c9678fdd66bFrancois Pichet else OS << I->getAnyMember()->getName(); 40856d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 40861cff132e48e0ccc253c34e5a2fb12718bd4e7d2eMarcin Swiderski OS << "("; 40879c378f705405d37f49795d5e915989de774fe11fTed Kremenek if (Expr *IE = I->getInit()) 408829fc11a7abc06c30146a0ba3733da1c758586784Aaron Ballman IE->printPretty(OS, &Helper, PrintingPolicy(Helper.getLangOpts())); 40891cff132e48e0ccc253c34e5a2fb12718bd4e7d2eMarcin Swiderski OS << ")"; 40901cff132e48e0ccc253c34e5a2fb12718bd4e7d2eMarcin Swiderski 40911cff132e48e0ccc253c34e5a2fb12718bd4e7d2eMarcin Swiderski if (I->isBaseInitializer()) 40921cff132e48e0ccc253c34e5a2fb12718bd4e7d2eMarcin Swiderski OS << " (Base initializer)\n"; 40933f5b4de5a05c07a2af5b0e61e919ac0f803c78c9Jordan Rose else if (I->isDelegatingInitializer()) 40943f5b4de5a05c07a2af5b0e61e919ac0f803c78c9Jordan Rose OS << " (Delegating initializer)\n"; 40951cff132e48e0ccc253c34e5a2fb12718bd4e7d2eMarcin Swiderski else OS << " (Member initializer)\n"; 40961cff132e48e0ccc253c34e5a2fb12718bd4e7d2eMarcin Swiderski 4097b07805485c603be3d8011f72611465324c9e664bDavid Blaikie } else if (Optional<CFGAutomaticObjDtor> DE = 4098b07805485c603be3d8011f72611465324c9e664bDavid Blaikie E.getAs<CFGAutomaticObjDtor>()) { 4099b07805485c603be3d8011f72611465324c9e664bDavid Blaikie const VarDecl *VD = DE->getVarDecl(); 410029fc11a7abc06c30146a0ba3733da1c758586784Aaron Ballman Helper.handleDecl(VD, OS); 41011cff132e48e0ccc253c34e5a2fb12718bd4e7d2eMarcin Swiderski 4102b1c52870b8c2feaa7cd112295368bec53af490a0Marcin Swiderski const Type* T = VD->getType().getTypePtr(); 41031cff132e48e0ccc253c34e5a2fb12718bd4e7d2eMarcin Swiderski if (const ReferenceType* RT = T->getAs<ReferenceType>()) 41041cff132e48e0ccc253c34e5a2fb12718bd4e7d2eMarcin Swiderski T = RT->getPointeeType().getTypePtr(); 410556df4a9e0461d4dfb2a740cb6b0ce531d6c82538Richard Smith T = T->getBaseElementTypeUnsafe(); 41061cff132e48e0ccc253c34e5a2fb12718bd4e7d2eMarcin Swiderski 41071cff132e48e0ccc253c34e5a2fb12718bd4e7d2eMarcin Swiderski OS << ".~" << T->getAsCXXRecordDecl()->getName().str() << "()"; 41081cff132e48e0ccc253c34e5a2fb12718bd4e7d2eMarcin Swiderski OS << " (Implicit destructor)\n"; 41097c625d8ffc20b92fff9e1690cd2484fcb6498183Marcin Swiderski 4110651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } else if (Optional<CFGNewAllocator> NE = E.getAs<CFGNewAllocator>()) { 4111651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines OS << "CFGNewAllocator("; 4112651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (const CXXNewExpr *AllocExpr = NE->getAllocatorExpr()) 4113651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines AllocExpr->getType().print(OS, PrintingPolicy(Helper.getLangOpts())); 4114651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines OS << ")\n"; 411536d558d85653315edb389677e995ec9ccdbfbf3dJordan Rose } else if (Optional<CFGDeleteDtor> DE = E.getAs<CFGDeleteDtor>()) { 411636d558d85653315edb389677e995ec9ccdbfbf3dJordan Rose const CXXRecordDecl *RD = DE->getCXXRecordDecl(); 411736d558d85653315edb389677e995ec9ccdbfbf3dJordan Rose if (!RD) 411836d558d85653315edb389677e995ec9ccdbfbf3dJordan Rose return; 411936d558d85653315edb389677e995ec9ccdbfbf3dJordan Rose CXXDeleteExpr *DelExpr = 412036d558d85653315edb389677e995ec9ccdbfbf3dJordan Rose const_cast<CXXDeleteExpr*>(DE->getDeleteExpr()); 412129fc11a7abc06c30146a0ba3733da1c758586784Aaron Ballman Helper.handledStmt(cast<Stmt>(DelExpr->getArgument()), OS); 412236d558d85653315edb389677e995ec9ccdbfbf3dJordan Rose OS << "->~" << RD->getName().str() << "()"; 412336d558d85653315edb389677e995ec9ccdbfbf3dJordan Rose OS << " (Implicit destructor)\n"; 4124b07805485c603be3d8011f72611465324c9e664bDavid Blaikie } else if (Optional<CFGBaseDtor> BE = E.getAs<CFGBaseDtor>()) { 4125b07805485c603be3d8011f72611465324c9e664bDavid Blaikie const CXXBaseSpecifier *BS = BE->getBaseSpecifier(); 41267c625d8ffc20b92fff9e1690cd2484fcb6498183Marcin Swiderski OS << "~" << BS->getType()->getAsCXXRecordDecl()->getName() << "()"; 41274e493e0dbac2aaac04c041f3d7dee9eccfb97689Zhongxing Xu OS << " (Base object destructor)\n"; 41287c625d8ffc20b92fff9e1690cd2484fcb6498183Marcin Swiderski 4129b07805485c603be3d8011f72611465324c9e664bDavid Blaikie } else if (Optional<CFGMemberDtor> ME = E.getAs<CFGMemberDtor>()) { 4130b07805485c603be3d8011f72611465324c9e664bDavid Blaikie const FieldDecl *FD = ME->getFieldDecl(); 413156df4a9e0461d4dfb2a740cb6b0ce531d6c82538Richard Smith const Type *T = FD->getType()->getBaseElementTypeUnsafe(); 41327c625d8ffc20b92fff9e1690cd2484fcb6498183Marcin Swiderski OS << "this->" << FD->getName(); 41338c5e5d6d8a316af5a9842169f541cac49717887dMarcin Swiderski OS << ".~" << T->getAsCXXRecordDecl()->getName() << "()"; 41344e493e0dbac2aaac04c041f3d7dee9eccfb97689Zhongxing Xu OS << " (Member object destructor)\n"; 41358599e7677e067fd01d3b2ee4c0875747d367fd8eMarcin Swiderski 4136b07805485c603be3d8011f72611465324c9e664bDavid Blaikie } else if (Optional<CFGTemporaryDtor> TE = E.getAs<CFGTemporaryDtor>()) { 4137b07805485c603be3d8011f72611465324c9e664bDavid Blaikie const CXXBindTemporaryExpr *BT = TE->getBindTemporaryExpr(); 413895ab9e306f4deefeabd89ea61987f4a8d67e0890Pavel Labath OS << "~"; 413929fc11a7abc06c30146a0ba3733da1c758586784Aaron Ballman BT->getType().print(OS, PrintingPolicy(Helper.getLangOpts())); 414095ab9e306f4deefeabd89ea61987f4a8d67e0890Pavel Labath OS << "() (Temporary object destructor)\n"; 41411cff132e48e0ccc253c34e5a2fb12718bd4e7d2eMarcin Swiderski } 414281bc7d07b701042371a5723b6f394cd2482ed7beZhongxing Xu} 41436d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 41449c378f705405d37f49795d5e915989de774fe11fTed Kremenekstatic void print_block(raw_ostream &OS, const CFG* cfg, 41459c378f705405d37f49795d5e915989de774fe11fTed Kremenek const CFGBlock &B, 414629fc11a7abc06c30146a0ba3733da1c758586784Aaron Ballman StmtPrinterHelper &Helper, bool print_edges, 4147682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenek bool ShowColors) { 41486d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 414929fc11a7abc06c30146a0ba3733da1c758586784Aaron Ballman Helper.setBlockID(B.getBlockID()); 41506d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 41517dba8607e59096014b7139ff20ef00870041d518Ted Kremenek // Print the header. 4152682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenek if (ShowColors) 4153682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenek OS.changeColor(raw_ostream::YELLOW, true); 4154682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenek 4155682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenek OS << "\n [B" << B.getBlockID(); 41566d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 415742a509f6a4f71bb805cc4abbb26722a34dffdddeTed Kremenek if (&B == &cfg->getEntry()) 4158682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenek OS << " (ENTRY)]\n"; 415942a509f6a4f71bb805cc4abbb26722a34dffdddeTed Kremenek else if (&B == &cfg->getExit()) 4160682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenek OS << " (EXIT)]\n"; 416142a509f6a4f71bb805cc4abbb26722a34dffdddeTed Kremenek else if (&B == cfg->getIndirectGotoBlock()) 4162682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenek OS << " (INDIRECT GOTO DISPATCH)]\n"; 4163651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines else if (B.hasNoReturnElement()) 4164651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines OS << " (NORETURN)]\n"; 416542a509f6a4f71bb805cc4abbb26722a34dffdddeTed Kremenek else 4166682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenek OS << "]\n"; 4167682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenek 4168682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenek if (ShowColors) 4169682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenek OS.resetColor(); 41706d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 41719cffe7366ea3beb33c2d58f43a8c3a04c1873e11Ted Kremenek // Print the label of this block. 41729c378f705405d37f49795d5e915989de774fe11fTed Kremenek if (Stmt *Label = const_cast<Stmt*>(B.getLabel())) { 417342a509f6a4f71bb805cc4abbb26722a34dffdddeTed Kremenek 417442a509f6a4f71bb805cc4abbb26722a34dffdddeTed Kremenek if (print_edges) 4175682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenek OS << " "; 41766d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 41779c378f705405d37f49795d5e915989de774fe11fTed Kremenek if (LabelStmt *L = dyn_cast<LabelStmt>(Label)) 41789cffe7366ea3beb33c2d58f43a8c3a04c1873e11Ted Kremenek OS << L->getName(); 41799c378f705405d37f49795d5e915989de774fe11fTed Kremenek else if (CaseStmt *C = dyn_cast<CaseStmt>(Label)) { 41809cffe7366ea3beb33c2d58f43a8c3a04c1873e11Ted Kremenek OS << "case "; 4181ef8225444452a1486bd721f3285301fe84643b00Stephen Hines if (C->getLHS()) 4182ef8225444452a1486bd721f3285301fe84643b00Stephen Hines C->getLHS()->printPretty(OS, &Helper, 4183ef8225444452a1486bd721f3285301fe84643b00Stephen Hines PrintingPolicy(Helper.getLangOpts())); 41849cffe7366ea3beb33c2d58f43a8c3a04c1873e11Ted Kremenek if (C->getRHS()) { 41859cffe7366ea3beb33c2d58f43a8c3a04c1873e11Ted Kremenek OS << " ... "; 418629fc11a7abc06c30146a0ba3733da1c758586784Aaron Ballman C->getRHS()->printPretty(OS, &Helper, 418729fc11a7abc06c30146a0ba3733da1c758586784Aaron Ballman PrintingPolicy(Helper.getLangOpts())); 41889cffe7366ea3beb33c2d58f43a8c3a04c1873e11Ted Kremenek } 4189079bd72439448b78629a28da6b1f8abe2cdeaf4dMike Stump } else if (isa<DefaultStmt>(Label)) 41909cffe7366ea3beb33c2d58f43a8c3a04c1873e11Ted Kremenek OS << "default"; 4191079bd72439448b78629a28da6b1f8abe2cdeaf4dMike Stump else if (CXXCatchStmt *CS = dyn_cast<CXXCatchStmt>(Label)) { 41925d1d20227878cd03db8b2dd23efd4cedfe874feeMike Stump OS << "catch ("; 4193a1f93631a84621d77aeb627691da85a8991af188Mike Stump if (CS->getExceptionDecl()) 419429fc11a7abc06c30146a0ba3733da1c758586784Aaron Ballman CS->getExceptionDecl()->print(OS, PrintingPolicy(Helper.getLangOpts()), 4195a1f93631a84621d77aeb627691da85a8991af188Mike Stump 0); 4196a1f93631a84621d77aeb627691da85a8991af188Mike Stump else 4197a1f93631a84621d77aeb627691da85a8991af188Mike Stump OS << "..."; 41985d1d20227878cd03db8b2dd23efd4cedfe874feeMike Stump OS << ")"; 41995d1d20227878cd03db8b2dd23efd4cedfe874feeMike Stump 42005d1d20227878cd03db8b2dd23efd4cedfe874feeMike Stump } else 4201b219cfc4d75f0a03630b7c4509ef791b7e97b2c8David Blaikie llvm_unreachable("Invalid label statement in CFGBlock."); 42026d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 42039cffe7366ea3beb33c2d58f43a8c3a04c1873e11Ted Kremenek OS << ":\n"; 42049cffe7366ea3beb33c2d58f43a8c3a04c1873e11Ted Kremenek } 42056d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 4206fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek // Iterate through the statements in the block and print them. 4207fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek unsigned j = 1; 42086d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 420942a509f6a4f71bb805cc4abbb26722a34dffdddeTed Kremenek for (CFGBlock::const_iterator I = B.begin(), E = B.end() ; 421042a509f6a4f71bb805cc4abbb26722a34dffdddeTed Kremenek I != E ; ++I, ++j ) { 42116d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 42129cffe7366ea3beb33c2d58f43a8c3a04c1873e11Ted Kremenek // Print the statement # in the basic block and the statement itself. 421342a509f6a4f71bb805cc4abbb26722a34dffdddeTed Kremenek if (print_edges) 4214682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenek OS << " "; 42156d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 4216a95d3750441ac8ad03e36af8e6e74039c9a3109dTed Kremenek OS << llvm::format("%3d", j) << ": "; 42176d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 421829fc11a7abc06c30146a0ba3733da1c758586784Aaron Ballman Helper.setStmtID(j); 42196d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 4220682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenek print_elem(OS, Helper, *I); 4221fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek } 42226d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 42239cffe7366ea3beb33c2d58f43a8c3a04c1873e11Ted Kremenek // Print the terminator of this block. 422442a509f6a4f71bb805cc4abbb26722a34dffdddeTed Kremenek if (B.getTerminator()) { 4225682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenek if (ShowColors) 4226682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenek OS.changeColor(raw_ostream::GREEN); 42276d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 4228682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenek OS << " T: "; 42296d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 423029fc11a7abc06c30146a0ba3733da1c758586784Aaron Ballman Helper.setBlockID(-1); 42316d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 423229fc11a7abc06c30146a0ba3733da1c758586784Aaron Ballman PrintingPolicy PP(Helper.getLangOpts()); 423329fc11a7abc06c30146a0ba3733da1c758586784Aaron Ballman CFGBlockTerminatorPrint TPrinter(OS, &Helper, PP); 4234651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines TPrinter.print(B.getTerminator()); 4235a292585207adbf6dcf6347db3526a7ec861d8eacTed Kremenek OS << '\n'; 4236682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenek 4237682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenek if (ShowColors) 4238682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenek OS.resetColor(); 4239fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek } 42406d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 42419cffe7366ea3beb33c2d58f43a8c3a04c1873e11Ted Kremenek if (print_edges) { 42429cffe7366ea3beb33c2d58f43a8c3a04c1873e11Ted Kremenek // Print the predecessors of this block. 4243682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenek if (!B.pred_empty()) { 4244682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenek const raw_ostream::Colors Color = raw_ostream::BLUE; 4245682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenek if (ShowColors) 4246682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenek OS.changeColor(Color); 4247682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenek OS << " Preds " ; 4248682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenek if (ShowColors) 4249682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenek OS.resetColor(); 4250682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenek OS << '(' << B.pred_size() << "):"; 4251682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenek unsigned i = 0; 4252682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenek 4253682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenek if (ShowColors) 4254682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenek OS.changeColor(Color); 4255682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenek 4256682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenek for (CFGBlock::const_pred_iterator I = B.pred_begin(), E = B.pred_end(); 4257682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenek I != E; ++I, ++i) { 425842a509f6a4f71bb805cc4abbb26722a34dffdddeTed Kremenek 4259dac62528c1a66db867e21cfa7cfc439d557d6f0cWill Dietz if (i % 10 == 8) 4260682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenek OS << "\n "; 42616d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 4262651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines CFGBlock *B = *I; 4263651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines bool Reachable = true; 4264651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (!B) { 4265651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Reachable = false; 4266651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines B = I->getPossiblyUnreachableBlock(); 4267651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 4268651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 4269651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines OS << " B" << B->getBlockID(); 4270651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (!Reachable) 4271651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines OS << "(Unreachable)"; 4272682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenek } 4273682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenek 4274682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenek if (ShowColors) 4275682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenek OS.resetColor(); 42766d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 4277682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenek OS << '\n'; 42789cffe7366ea3beb33c2d58f43a8c3a04c1873e11Ted Kremenek } 42796d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 42809cffe7366ea3beb33c2d58f43a8c3a04c1873e11Ted Kremenek // Print the successors of this block. 4281682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenek if (!B.succ_empty()) { 4282682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenek const raw_ostream::Colors Color = raw_ostream::MAGENTA; 4283682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenek if (ShowColors) 4284682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenek OS.changeColor(Color); 4285682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenek OS << " Succs "; 4286682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenek if (ShowColors) 4287682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenek OS.resetColor(); 4288682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenek OS << '(' << B.succ_size() << "):"; 4289682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenek unsigned i = 0; 4290682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenek 4291682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenek if (ShowColors) 4292682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenek OS.changeColor(Color); 4293682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenek 4294682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenek for (CFGBlock::const_succ_iterator I = B.succ_begin(), E = B.succ_end(); 4295682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenek I != E; ++I, ++i) { 4296682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenek 4297dac62528c1a66db867e21cfa7cfc439d557d6f0cWill Dietz if (i % 10 == 8) 4298682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenek OS << "\n "; 4299682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenek 4300651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines CFGBlock *B = *I; 4301651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 4302651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines bool Reachable = true; 4303651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (!B) { 4304651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Reachable = false; 4305651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines B = I->getPossiblyUnreachableBlock(); 4306651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 4307651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 4308651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (B) { 4309651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines OS << " B" << B->getBlockID(); 4310651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (!Reachable) 4311651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines OS << "(Unreachable)"; 4312651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 4313651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines else { 4314651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines OS << " NULL"; 4315651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 4316682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenek } 4317651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 4318682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenek if (ShowColors) 4319682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenek OS.resetColor(); 4320682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenek OS << '\n'; 4321fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek } 4322fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek } 43236d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump} 432442a509f6a4f71bb805cc4abbb26722a34dffdddeTed Kremenek 432542a509f6a4f71bb805cc4abbb26722a34dffdddeTed Kremenek 432642a509f6a4f71bb805cc4abbb26722a34dffdddeTed Kremenek/// dump - A simple pretty printer of a CFG that outputs to stderr. 4327682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenekvoid CFG::dump(const LangOptions &LO, bool ShowColors) const { 4328682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenek print(llvm::errs(), LO, ShowColors); 4329682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenek} 433042a509f6a4f71bb805cc4abbb26722a34dffdddeTed Kremenek 433142a509f6a4f71bb805cc4abbb26722a34dffdddeTed Kremenek/// print - A simple pretty printer of a CFG that outputs to an ostream. 4332682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenekvoid CFG::print(raw_ostream &OS, const LangOptions &LO, bool ShowColors) const { 4333e4f2142d00fa5fdb580c4e2413da91882d955381Chris Lattner StmtPrinterHelper Helper(this, LO); 43346d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 433542a509f6a4f71bb805cc4abbb26722a34dffdddeTed Kremenek // Print the entry block. 433629fc11a7abc06c30146a0ba3733da1c758586784Aaron Ballman print_block(OS, this, getEntry(), Helper, true, ShowColors); 43376d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 433842a509f6a4f71bb805cc4abbb26722a34dffdddeTed Kremenek // Iterate through the CFGBlocks and print them one by one. 433942a509f6a4f71bb805cc4abbb26722a34dffdddeTed Kremenek for (const_iterator I = Blocks.begin(), E = Blocks.end() ; I != E ; ++I) { 434042a509f6a4f71bb805cc4abbb26722a34dffdddeTed Kremenek // Skip the entry block, because we already printed it. 4341ee82d9bdc5025b82de8ce2a4ad4685e0a8b79da9Ted Kremenek if (&(**I) == &getEntry() || &(**I) == &getExit()) 434242a509f6a4f71bb805cc4abbb26722a34dffdddeTed Kremenek continue; 43436d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 434429fc11a7abc06c30146a0ba3733da1c758586784Aaron Ballman print_block(OS, this, **I, Helper, true, ShowColors); 434542a509f6a4f71bb805cc4abbb26722a34dffdddeTed Kremenek } 43466d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 434742a509f6a4f71bb805cc4abbb26722a34dffdddeTed Kremenek // Print the exit block. 434829fc11a7abc06c30146a0ba3733da1c758586784Aaron Ballman print_block(OS, this, getExit(), Helper, true, ShowColors); 4349682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenek OS << '\n'; 4350d0172439194b28bae62a94a0a25d58e6d21e7a14Ted Kremenek OS.flush(); 43516d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump} 435242a509f6a4f71bb805cc4abbb26722a34dffdddeTed Kremenek 435342a509f6a4f71bb805cc4abbb26722a34dffdddeTed Kremenek/// dump - A simply pretty printer of a CFGBlock that outputs to stderr. 4354682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenekvoid CFGBlock::dump(const CFG* cfg, const LangOptions &LO, 4355682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenek bool ShowColors) const { 4356682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenek print(llvm::errs(), cfg, LO, ShowColors); 4357e4f2142d00fa5fdb580c4e2413da91882d955381Chris Lattner} 435842a509f6a4f71bb805cc4abbb26722a34dffdddeTed Kremenek 4359ef8225444452a1486bd721f3285301fe84643b00Stephen Hinesvoid CFGBlock::dump() const { 4360ef8225444452a1486bd721f3285301fe84643b00Stephen Hines dump(getParent(), LangOptions(), false); 4361ef8225444452a1486bd721f3285301fe84643b00Stephen Hines} 4362ef8225444452a1486bd721f3285301fe84643b00Stephen Hines 436342a509f6a4f71bb805cc4abbb26722a34dffdddeTed Kremenek/// print - A simple pretty printer of a CFGBlock that outputs to an ostream. 436442a509f6a4f71bb805cc4abbb26722a34dffdddeTed Kremenek/// Generally this will only be called from CFG::print. 43659c378f705405d37f49795d5e915989de774fe11fTed Kremenekvoid CFGBlock::print(raw_ostream &OS, const CFG* cfg, 4366682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenek const LangOptions &LO, bool ShowColors) const { 4367e4f2142d00fa5fdb580c4e2413da91882d955381Chris Lattner StmtPrinterHelper Helper(cfg, LO); 436829fc11a7abc06c30146a0ba3733da1c758586784Aaron Ballman print_block(OS, cfg, *this, Helper, true, ShowColors); 4369682060c5d95f6e4f79536013781ab0870cdd3850Ted Kremenek OS << '\n'; 4370026473c2175424a039f51ca8949937268721b965Ted Kremenek} 43717dba8607e59096014b7139ff20ef00870041d518Ted Kremenek 4372a292585207adbf6dcf6347db3526a7ec861d8eacTed Kremenek/// printTerminator - A simple pretty printer of the terminator of a CFGBlock. 43735f9e272e632e951b1efe824cd16acb4d96077930Chris Lattnervoid CFGBlock::printTerminator(raw_ostream &OS, 43746d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump const LangOptions &LO) const { 43756bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines CFGBlockTerminatorPrint TPrinter(OS, nullptr, PrintingPolicy(LO)); 4376651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines TPrinter.print(getTerminator()); 4377a292585207adbf6dcf6347db3526a7ec861d8eacTed Kremenek} 4378a292585207adbf6dcf6347db3526a7ec861d8eacTed Kremenek 4379651f13cea278ec967336033dd032faef0e9fc2ecStephen HinesStmt *CFGBlock::getTerminatorCondition(bool StripParens) { 43804ba72a0b28135209c435630682febe1f854ccfa6Marcin Swiderski Stmt *Terminator = this->Terminator; 4381411cdee0b490f79428c9eb977f25199eb7d21cd8Ted Kremenek if (!Terminator) 43826bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return nullptr; 43836d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 43846bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines Expr *E = nullptr; 43856d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 4386411cdee0b490f79428c9eb977f25199eb7d21cd8Ted Kremenek switch (Terminator->getStmtClass()) { 4387411cdee0b490f79428c9eb977f25199eb7d21cd8Ted Kremenek default: 4388411cdee0b490f79428c9eb977f25199eb7d21cd8Ted Kremenek break; 43896d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 439049a246f4fad959888bb0164c624c3c2b03078e91Jordan Rose case Stmt::CXXForRangeStmtClass: 439149a246f4fad959888bb0164c624c3c2b03078e91Jordan Rose E = cast<CXXForRangeStmt>(Terminator)->getCond(); 439249a246f4fad959888bb0164c624c3c2b03078e91Jordan Rose break; 439349a246f4fad959888bb0164c624c3c2b03078e91Jordan Rose 4394411cdee0b490f79428c9eb977f25199eb7d21cd8Ted Kremenek case Stmt::ForStmtClass: 4395411cdee0b490f79428c9eb977f25199eb7d21cd8Ted Kremenek E = cast<ForStmt>(Terminator)->getCond(); 4396411cdee0b490f79428c9eb977f25199eb7d21cd8Ted Kremenek break; 43976d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 4398411cdee0b490f79428c9eb977f25199eb7d21cd8Ted Kremenek case Stmt::WhileStmtClass: 4399411cdee0b490f79428c9eb977f25199eb7d21cd8Ted Kremenek E = cast<WhileStmt>(Terminator)->getCond(); 4400411cdee0b490f79428c9eb977f25199eb7d21cd8Ted Kremenek break; 44016d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 4402411cdee0b490f79428c9eb977f25199eb7d21cd8Ted Kremenek case Stmt::DoStmtClass: 4403411cdee0b490f79428c9eb977f25199eb7d21cd8Ted Kremenek E = cast<DoStmt>(Terminator)->getCond(); 4404411cdee0b490f79428c9eb977f25199eb7d21cd8Ted Kremenek break; 44056d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 4406411cdee0b490f79428c9eb977f25199eb7d21cd8Ted Kremenek case Stmt::IfStmtClass: 4407411cdee0b490f79428c9eb977f25199eb7d21cd8Ted Kremenek E = cast<IfStmt>(Terminator)->getCond(); 4408411cdee0b490f79428c9eb977f25199eb7d21cd8Ted Kremenek break; 44096d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 4410411cdee0b490f79428c9eb977f25199eb7d21cd8Ted Kremenek case Stmt::ChooseExprClass: 4411411cdee0b490f79428c9eb977f25199eb7d21cd8Ted Kremenek E = cast<ChooseExpr>(Terminator)->getCond(); 4412411cdee0b490f79428c9eb977f25199eb7d21cd8Ted Kremenek break; 44136d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 4414411cdee0b490f79428c9eb977f25199eb7d21cd8Ted Kremenek case Stmt::IndirectGotoStmtClass: 4415411cdee0b490f79428c9eb977f25199eb7d21cd8Ted Kremenek E = cast<IndirectGotoStmt>(Terminator)->getTarget(); 4416411cdee0b490f79428c9eb977f25199eb7d21cd8Ted Kremenek break; 44176d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 4418411cdee0b490f79428c9eb977f25199eb7d21cd8Ted Kremenek case Stmt::SwitchStmtClass: 4419411cdee0b490f79428c9eb977f25199eb7d21cd8Ted Kremenek E = cast<SwitchStmt>(Terminator)->getCond(); 4420411cdee0b490f79428c9eb977f25199eb7d21cd8Ted Kremenek break; 44216d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 442256ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall case Stmt::BinaryConditionalOperatorClass: 442356ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall E = cast<BinaryConditionalOperator>(Terminator)->getCond(); 442456ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall break; 442556ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall 4426411cdee0b490f79428c9eb977f25199eb7d21cd8Ted Kremenek case Stmt::ConditionalOperatorClass: 4427411cdee0b490f79428c9eb977f25199eb7d21cd8Ted Kremenek E = cast<ConditionalOperator>(Terminator)->getCond(); 4428411cdee0b490f79428c9eb977f25199eb7d21cd8Ted Kremenek break; 44296d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 4430411cdee0b490f79428c9eb977f25199eb7d21cd8Ted Kremenek case Stmt::BinaryOperatorClass: // '&&' and '||' 4431411cdee0b490f79428c9eb977f25199eb7d21cd8Ted Kremenek E = cast<BinaryOperator>(Terminator)->getLHS(); 4432390e48b15ad93f85bfd1e33b9992c198fa0db475Ted Kremenek break; 44336d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 4434390e48b15ad93f85bfd1e33b9992c198fa0db475Ted Kremenek case Stmt::ObjCForCollectionStmtClass: 44356d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump return Terminator; 4436411cdee0b490f79428c9eb977f25199eb7d21cd8Ted Kremenek } 44376d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 4438651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (!StripParens) 4439651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return E; 4440651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 44416bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return E ? E->IgnoreParens() : nullptr; 4442411cdee0b490f79428c9eb977f25199eb7d21cd8Ted Kremenek} 4443411cdee0b490f79428c9eb977f25199eb7d21cd8Ted Kremenek 44447dba8607e59096014b7139ff20ef00870041d518Ted Kremenek//===----------------------------------------------------------------------===// 44457dba8607e59096014b7139ff20ef00870041d518Ted Kremenek// CFG Graphviz Visualization 44467dba8607e59096014b7139ff20ef00870041d518Ted Kremenek//===----------------------------------------------------------------------===// 44477dba8607e59096014b7139ff20ef00870041d518Ted Kremenek 444842a509f6a4f71bb805cc4abbb26722a34dffdddeTed Kremenek 444942a509f6a4f71bb805cc4abbb26722a34dffdddeTed Kremenek#ifndef NDEBUG 44506d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stumpstatic StmtPrinterHelper* GraphHelper; 445142a509f6a4f71bb805cc4abbb26722a34dffdddeTed Kremenek#endif 445242a509f6a4f71bb805cc4abbb26722a34dffdddeTed Kremenek 4453e4f2142d00fa5fdb580c4e2413da91882d955381Chris Lattnervoid CFG::viewCFG(const LangOptions &LO) const { 445442a509f6a4f71bb805cc4abbb26722a34dffdddeTed Kremenek#ifndef NDEBUG 4455e4f2142d00fa5fdb580c4e2413da91882d955381Chris Lattner StmtPrinterHelper H(this, LO); 445642a509f6a4f71bb805cc4abbb26722a34dffdddeTed Kremenek GraphHelper = &H; 445742a509f6a4f71bb805cc4abbb26722a34dffdddeTed Kremenek llvm::ViewGraph(this,"CFG"); 44586bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines GraphHelper = nullptr; 445942a509f6a4f71bb805cc4abbb26722a34dffdddeTed Kremenek#endif 446042a509f6a4f71bb805cc4abbb26722a34dffdddeTed Kremenek} 446142a509f6a4f71bb805cc4abbb26722a34dffdddeTed Kremenek 44627dba8607e59096014b7139ff20ef00870041d518Ted Kremeneknamespace llvm { 44637dba8607e59096014b7139ff20ef00870041d518Ted Kremenektemplate<> 44647dba8607e59096014b7139ff20ef00870041d518Ted Kremenekstruct DOTGraphTraits<const CFG*> : public DefaultDOTGraphTraits { 4465006b0eb3e11162d8c06372db813ac9f71a7a16e8Tobias Grosser 4466006b0eb3e11162d8c06372db813ac9f71a7a16e8Tobias Grosser DOTGraphTraits (bool isSimple=false) : DefaultDOTGraphTraits(isSimple) {} 4467006b0eb3e11162d8c06372db813ac9f71a7a16e8Tobias Grosser 44689c378f705405d37f49795d5e915989de774fe11fTed Kremenek static std::string getNodeLabel(const CFGBlock *Node, const CFG* Graph) { 44697dba8607e59096014b7139ff20ef00870041d518Ted Kremenek 4470bd250b44d60622e7c0b60c6def6f6fe7e347addfHartmut Kaiser#ifndef NDEBUG 4471a95d3750441ac8ad03e36af8e6e74039c9a3109dTed Kremenek std::string OutSStr; 4472a95d3750441ac8ad03e36af8e6e74039c9a3109dTed Kremenek llvm::raw_string_ostream Out(OutSStr); 447329fc11a7abc06c30146a0ba3733da1c758586784Aaron Ballman print_block(Out,Graph, *Node, *GraphHelper, false, false); 4474a95d3750441ac8ad03e36af8e6e74039c9a3109dTed Kremenek std::string& OutStr = Out.str(); 44757dba8607e59096014b7139ff20ef00870041d518Ted Kremenek 44767dba8607e59096014b7139ff20ef00870041d518Ted Kremenek if (OutStr[0] == '\n') OutStr.erase(OutStr.begin()); 44777dba8607e59096014b7139ff20ef00870041d518Ted Kremenek 44787dba8607e59096014b7139ff20ef00870041d518Ted Kremenek // Process string output to make it nicer... 44797dba8607e59096014b7139ff20ef00870041d518Ted Kremenek for (unsigned i = 0; i != OutStr.length(); ++i) 44807dba8607e59096014b7139ff20ef00870041d518Ted Kremenek if (OutStr[i] == '\n') { // Left justify 44817dba8607e59096014b7139ff20ef00870041d518Ted Kremenek OutStr[i] = '\\'; 44827dba8607e59096014b7139ff20ef00870041d518Ted Kremenek OutStr.insert(OutStr.begin()+i+1, 'l'); 44837dba8607e59096014b7139ff20ef00870041d518Ted Kremenek } 44846d9828c82c9321f042ab416fd2ffaa3034347d45Mike Stump 44857dba8607e59096014b7139ff20ef00870041d518Ted Kremenek return OutStr; 4486bd250b44d60622e7c0b60c6def6f6fe7e347addfHartmut Kaiser#else 4487bd250b44d60622e7c0b60c6def6f6fe7e347addfHartmut Kaiser return ""; 4488bd250b44d60622e7c0b60c6def6f6fe7e347addfHartmut Kaiser#endif 44897dba8607e59096014b7139ff20ef00870041d518Ted Kremenek } 44907dba8607e59096014b7139ff20ef00870041d518Ted Kremenek}; 44917dba8607e59096014b7139ff20ef00870041d518Ted Kremenek} // end namespace llvm 4492