diff --git a/clang/include/clang/Analysis/CFG.h b/clang/include/clang/Analysis/CFG.h index b337d74495c9..d135286d30f8 100644 --- a/clang/include/clang/Analysis/CFG.h +++ b/clang/include/clang/Analysis/CFG.h @@ -29,6 +29,7 @@ namespace llvm { } namespace clang { + class CXXDestructorDecl; class Decl; class Stmt; class Expr; @@ -47,45 +48,45 @@ class CFGElement { public: enum Kind { // main kind + Invalid, Statement, Initializer, - ImplicitDtor, // dtor kind AutomaticObjectDtor, BaseDtor, MemberDtor, TemporaryDtor, - DTOR_BEGIN = AutomaticObjectDtor + DTOR_BEGIN = AutomaticObjectDtor, + DTOR_END = TemporaryDtor }; protected: - // The int bits are used to mark the main kind. + // The int bits are used to mark the kind. llvm::PointerIntPair Data1; - // The int bits are used to mark the dtor kind. llvm::PointerIntPair Data2; - CFGElement(void *Ptr, unsigned Int) : Data1(Ptr, Int) {} - CFGElement(void *Ptr1, unsigned Int1, void *Ptr2, unsigned Int2) - : Data1(Ptr1, Int1), Data2(Ptr2, Int2) {} + CFGElement(Kind kind, const void *Ptr1, const void *Ptr2 = 0) + : Data1(const_cast(Ptr1), ((unsigned) kind) & 0x3), + Data2(const_cast(Ptr2), (((unsigned) kind) >> 2) & 0x3) {} public: CFGElement() {} - Kind getKind() const { return static_cast(Data1.getInt()); } - - Kind getDtorKind() const { - assert(getKind() == ImplicitDtor); - return static_cast(Data2.getInt() + DTOR_BEGIN); + Kind getKind() const { + unsigned x = Data2.getInt(); + x <<= 2; + x |= Data1.getInt(); + return (Kind) x; } - - bool isValid() const { return Data1.getPointer(); } + + bool isValid() const { return getKind() != Invalid; } operator bool() const { return isValid(); } - - template ElemTy getAs() const { + + template const ElemTy *getAs() const { if (llvm::isa(this)) - return *static_cast(this); - return ElemTy(); + return static_cast(this); + return 0; } static bool classof(const CFGElement *E) { return true; } @@ -93,13 +94,10 @@ public: class CFGStmt : public CFGElement { public: - CFGStmt() {} - CFGStmt(Stmt *S) : CFGElement(S, 0) {} + CFGStmt(Stmt *S) : CFGElement(Statement, S) {} Stmt *getStmt() const { return static_cast(Data1.getPointer()); } - operator Stmt*() const { return getStmt(); } - static bool classof(const CFGElement *E) { return E->getKind() == Statement; } @@ -109,14 +107,12 @@ public: /// constructor's initialization list. class CFGInitializer : public CFGElement { public: - CFGInitializer() {} - CFGInitializer(CXXCtorInitializer* I) - : CFGElement(I, Initializer) {} + CFGInitializer(CXXCtorInitializer *initializer) + : CFGElement(Initializer, initializer) {} CXXCtorInitializer* getInitializer() const { return static_cast(Data1.getPointer()); } - operator CXXCtorInitializer*() const { return getInitializer(); } static bool classof(const CFGElement *E) { return E->getKind() == Initializer; @@ -127,14 +123,17 @@ public: /// by compiler on various occasions. class CFGImplicitDtor : public CFGElement { protected: - CFGImplicitDtor(unsigned K, void* P, void* S) - : CFGElement(P, ImplicitDtor, S, K - DTOR_BEGIN) {} + CFGImplicitDtor(Kind kind, const void *data1, const void *data2 = 0) + : CFGElement(kind, data1, data2) { + assert(kind >= DTOR_BEGIN && kind <= DTOR_END); + } public: - CFGImplicitDtor() {} + const CXXDestructorDecl *getDestructorDecl() const; static bool classof(const CFGElement *E) { - return E->getKind() == ImplicitDtor; + Kind kind = E->getKind(); + return kind >= DTOR_BEGIN && kind <= DTOR_END; } }; @@ -143,22 +142,20 @@ public: /// of leaving its local scope. class CFGAutomaticObjDtor: public CFGImplicitDtor { public: - CFGAutomaticObjDtor() {} - CFGAutomaticObjDtor(VarDecl* VD, Stmt* S) - : CFGImplicitDtor(AutomaticObjectDtor, VD, S) {} + CFGAutomaticObjDtor(const VarDecl *var, const Stmt *stmt) + : CFGImplicitDtor(AutomaticObjectDtor, var, stmt) {} - VarDecl* getVarDecl() const { + const VarDecl *getVarDecl() const { return static_cast(Data1.getPointer()); } // Get statement end of which triggered the destructor call. - Stmt* getTriggerStmt() const { + const Stmt *getTriggerStmt() const { return static_cast(Data2.getPointer()); } - static bool classof(const CFGElement *E) { - return E->getKind() == ImplicitDtor && - E->getDtorKind() == AutomaticObjectDtor; + static bool classof(const CFGElement *elem) { + return elem->getKind() == AutomaticObjectDtor; } }; @@ -166,16 +163,15 @@ public: /// base object in destructor. class CFGBaseDtor : public CFGImplicitDtor { public: - CFGBaseDtor() {} - CFGBaseDtor(const CXXBaseSpecifier *BS) - : CFGImplicitDtor(BaseDtor, const_cast(BS), NULL) {} + CFGBaseDtor(const CXXBaseSpecifier *base) + : CFGImplicitDtor(BaseDtor, base) {} const CXXBaseSpecifier *getBaseSpecifier() const { return static_cast(Data1.getPointer()); } static bool classof(const CFGElement *E) { - return E->getKind() == ImplicitDtor && E->getDtorKind() == BaseDtor; + return E->getKind() == BaseDtor; } }; @@ -183,16 +179,15 @@ public: /// member object in destructor. class CFGMemberDtor : public CFGImplicitDtor { public: - CFGMemberDtor() {} - CFGMemberDtor(FieldDecl *FD) - : CFGImplicitDtor(MemberDtor, FD, NULL) {} + CFGMemberDtor(const FieldDecl *field) + : CFGImplicitDtor(MemberDtor, field, 0) {} - FieldDecl *getFieldDecl() const { - return static_cast(Data1.getPointer()); + const FieldDecl *getFieldDecl() const { + return static_cast(Data1.getPointer()); } static bool classof(const CFGElement *E) { - return E->getKind() == ImplicitDtor && E->getDtorKind() == MemberDtor; + return E->getKind() == MemberDtor; } }; @@ -200,16 +195,15 @@ public: /// at the end of full expression for temporary object. class CFGTemporaryDtor : public CFGImplicitDtor { public: - CFGTemporaryDtor() {} - CFGTemporaryDtor(CXXBindTemporaryExpr *E) - : CFGImplicitDtor(TemporaryDtor, E, NULL) {} + CFGTemporaryDtor(CXXBindTemporaryExpr *expr) + : CFGImplicitDtor(TemporaryDtor, expr, 0) {} - CXXBindTemporaryExpr *getBindTemporaryExpr() const { - return static_cast(Data1.getPointer()); + const CXXBindTemporaryExpr *getBindTemporaryExpr() const { + return static_cast(Data1.getPointer()); } static bool classof(const CFGElement *E) { - return E->getKind() == ImplicitDtor && E->getDtorKind() == TemporaryDtor; + return E->getKind() == TemporaryDtor; } }; @@ -607,8 +601,8 @@ public: for (const_iterator I=begin(), E=end(); I != E; ++I) for (CFGBlock::const_iterator BI=(*I)->begin(), BE=(*I)->end(); BI != BE; ++BI) { - if (CFGStmt S = BI->getAs()) - O(S); + if (const CFGStmt *stmt = BI->getAs()) + O(stmt->getStmt()); } } diff --git a/clang/include/clang/Analysis/FlowSensitive/DataflowSolver.h b/clang/include/clang/Analysis/FlowSensitive/DataflowSolver.h index d75d333db6b6..9561b964b5f8 100644 --- a/clang/include/clang/Analysis/FlowSensitive/DataflowSolver.h +++ b/clang/include/clang/Analysis/FlowSensitive/DataflowSolver.h @@ -277,8 +277,8 @@ private: for (StmtItr I=ItrTraits::StmtBegin(B), E=ItrTraits::StmtEnd(B); I!=E;++I) { CFGElement El = *I; - if (CFGStmt S = El.getAs()) - ProcessStmt(S, recordStmtValues, AnalysisDirTag()); + if (const CFGStmt *S = El.getAs()) + ProcessStmt(S->getStmt(), recordStmtValues, AnalysisDirTag()); } TF.VisitTerminator(const_cast(B)); @@ -293,8 +293,8 @@ private: for (StmtItr I=ItrTraits::StmtBegin(B), E=ItrTraits::StmtEnd(B); I!=E;++I) { CFGElement El = *I; - if (CFGStmt S = El.getAs()) - ProcessStmt(S, recordStmtValues, AnalysisDirTag()); + if (const CFGStmt *S = El.getAs()) + ProcessStmt(S->getStmt(), recordStmtValues, AnalysisDirTag()); } } diff --git a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h index 25c644734232..74cba32cd390 100644 --- a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h +++ b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h @@ -219,11 +219,8 @@ public: /// getStmt - Return the current block-level expression associated with /// this builder. const Stmt* getStmt() const { - CFGStmt CS = B[Idx].getAs(); - if (CS) - return CS.getStmt(); - else - return 0; + const CFGStmt *CS = B[Idx].getAs(); + return CS ? CS->getStmt() : 0; } /// getBlock - Return the CFGBlock associated with the block-level expression diff --git a/clang/lib/Analysis/CFG.cpp b/clang/lib/Analysis/CFG.cpp index d2cccc8d2b92..7ee2a9ccce55 100644 --- a/clang/lib/Analysis/CFG.cpp +++ b/clang/lib/Analysis/CFG.cpp @@ -2704,6 +2704,10 @@ CFG* CFG::buildCFG(const Decl *D, Stmt* Statement, ASTContext *C, return Builder.buildCFG(D, Statement, C, BO); } +const CXXDestructorDecl *CFGImplicitDtor::getDestructorDecl() const { + return 0; +} + //===----------------------------------------------------------------------===// // CFG: Queries for BlkExprs. //===----------------------------------------------------------------------===// @@ -2740,8 +2744,8 @@ static BlkExprMapTy* PopulateBlkExprMap(CFG& cfg) { for (CFG::iterator I=cfg.begin(), E=cfg.end(); I != E; ++I) for (CFGBlock::iterator BI=(*I)->begin(), EI=(*I)->end(); BI != EI; ++BI) - if (CFGStmt S = BI->getAs()) - FindSubExprAssignments(S, SubExprAssignments); + if (const CFGStmt *S = BI->getAs()) + FindSubExprAssignments(S->getStmt(), SubExprAssignments); for (CFG::iterator I=cfg.begin(), E=cfg.end(); I != E; ++I) { @@ -2749,10 +2753,10 @@ static BlkExprMapTy* PopulateBlkExprMap(CFG& cfg) { // block-level that are block-level expressions. for (CFGBlock::iterator BI=(*I)->begin(), EI=(*I)->end(); BI != EI; ++BI) { - CFGStmt CS = BI->getAs(); - if (!CS.isValid()) + const CFGStmt *CS = BI->getAs(); + if (!CS) continue; - if (Expr* Exp = dyn_cast(CS.getStmt())) { + if (Expr* Exp = dyn_cast(CS->getStmt())) { if (BinaryOperator* B = dyn_cast(Exp)) { // Assignment expressions that are not nested within another @@ -2845,8 +2849,8 @@ CFG::~CFG() { namespace { class StmtPrinterHelper : public PrinterHelper { - typedef llvm::DenseMap > StmtMapTy; - typedef llvm::DenseMap > DeclMapTy; + typedef llvm::DenseMap > StmtMapTy; + typedef llvm::DenseMap > DeclMapTy; StmtMapTy StmtMap; DeclMapTy DeclMap; signed currentBlock; @@ -2855,42 +2859,62 @@ class StmtPrinterHelper : public PrinterHelper { public: StmtPrinterHelper(const CFG* cfg, const LangOptions &LO) - : currentBlock(0), currentStmt(0), LangOpts(LO) { + : currentBlock(0), currentStmt(0), LangOpts(LO) + { for (CFG::const_iterator I = cfg->begin(), E = cfg->end(); I != E; ++I ) { unsigned j = 1; for (CFGBlock::const_iterator BI = (*I)->begin(), BEnd = (*I)->end() ; BI != BEnd; ++BI, ++j ) { - if (CFGStmt SE = BI->getAs()) { + if (const CFGStmt *SE = BI->getAs()) { + const Stmt *stmt= SE->getStmt(); std::pair P((*I)->getBlockID(), j); - StmtMap[SE] = P; + StmtMap[stmt] = P; - if (DeclStmt* DS = dyn_cast(SE.getStmt())) { - DeclMap[DS->getSingleDecl()] = P; - - } else if (IfStmt* IS = dyn_cast(SE.getStmt())) { - if (VarDecl* VD = IS->getConditionVariable()) - DeclMap[VD] = P; - - } else if (ForStmt* FS = dyn_cast(SE.getStmt())) { - if (VarDecl* VD = FS->getConditionVariable()) - DeclMap[VD] = P; - - } else if (WhileStmt* WS = dyn_cast(SE.getStmt())) { - if (VarDecl* VD = WS->getConditionVariable()) - DeclMap[VD] = P; - - } else if (SwitchStmt* SS = dyn_cast(SE.getStmt())) { - if (VarDecl* VD = SS->getConditionVariable()) - DeclMap[VD] = P; - - } else if (CXXCatchStmt* CS = dyn_cast(SE.getStmt())) { - if (VarDecl* VD = CS->getExceptionDecl()) - DeclMap[VD] = P; + switch (stmt->getStmtClass()) { + case Stmt::DeclStmtClass: + DeclMap[cast(stmt)->getSingleDecl()] = P; + break; + case Stmt::IfStmtClass: { + const VarDecl *var = cast(stmt)->getConditionVariable(); + if (var) + DeclMap[var] = P; + break; + } + case Stmt::ForStmtClass: { + const VarDecl *var = cast(stmt)->getConditionVariable(); + if (var) + DeclMap[var] = P; + break; + } + case Stmt::WhileStmtClass: { + const VarDecl *var = + cast(stmt)->getConditionVariable(); + if (var) + DeclMap[var] = P; + break; + } + case Stmt::SwitchStmtClass: { + const VarDecl *var = + cast(stmt)->getConditionVariable(); + if (var) + DeclMap[var] = P; + break; + } + case Stmt::CXXCatchStmtClass: { + const VarDecl *var = + cast(stmt)->getExceptionDecl(); + if (var) + DeclMap[var] = P; + break; + } + default: + break; } } } } } + virtual ~StmtPrinterHelper() {} @@ -2913,7 +2937,7 @@ public: return true; } - bool handleDecl(Decl* D, llvm::raw_ostream& OS) { + bool handleDecl(const Decl* D, llvm::raw_ostream& OS) { DeclMapTy::iterator I = DeclMap.find(D); if (I == DeclMap.end()) @@ -3031,8 +3055,8 @@ public: static void print_elem(llvm::raw_ostream &OS, StmtPrinterHelper* Helper, const CFGElement &E) { - if (CFGStmt CS = E.getAs()) { - Stmt *S = CS; + if (const CFGStmt *CS = E.getAs()) { + Stmt *S = CS->getStmt(); if (Helper) { @@ -3069,8 +3093,8 @@ static void print_elem(llvm::raw_ostream &OS, StmtPrinterHelper* Helper, if (isa(S)) OS << '\n'; - } else if (CFGInitializer IE = E.getAs()) { - CXXCtorInitializer* I = IE; + } else if (const CFGInitializer *IE = E.getAs()) { + const CXXCtorInitializer *I = IE->getInitializer(); if (I->isBaseInitializer()) OS << I->getBaseClass()->getAsCXXRecordDecl()->getName(); else OS << I->getAnyMember()->getName(); @@ -3084,8 +3108,8 @@ static void print_elem(llvm::raw_ostream &OS, StmtPrinterHelper* Helper, OS << " (Base initializer)\n"; else OS << " (Member initializer)\n"; - } else if (CFGAutomaticObjDtor DE = E.getAs()){ - VarDecl* VD = DE.getVarDecl(); + } else if (const CFGAutomaticObjDtor *DE = E.getAs()){ + const VarDecl* VD = DE->getVarDecl(); Helper->handleDecl(VD, OS); const Type* T = VD->getType().getTypePtr(); @@ -3097,13 +3121,13 @@ static void print_elem(llvm::raw_ostream &OS, StmtPrinterHelper* Helper, OS << ".~" << T->getAsCXXRecordDecl()->getName().str() << "()"; OS << " (Implicit destructor)\n"; - } else if (CFGBaseDtor BE = E.getAs()) { - const CXXBaseSpecifier *BS = BE.getBaseSpecifier(); + } else if (const CFGBaseDtor *BE = E.getAs()) { + const CXXBaseSpecifier *BS = BE->getBaseSpecifier(); OS << "~" << BS->getType()->getAsCXXRecordDecl()->getName() << "()"; OS << " (Base object destructor)\n"; - } else if (CFGMemberDtor ME = E.getAs()) { - FieldDecl *FD = ME.getFieldDecl(); + } else if (const CFGMemberDtor *ME = E.getAs()) { + const FieldDecl *FD = ME->getFieldDecl(); const Type *T = FD->getType().getTypePtr(); if (const Type *ET = T->getArrayElementTypeNoTypeQual()) @@ -3113,8 +3137,8 @@ static void print_elem(llvm::raw_ostream &OS, StmtPrinterHelper* Helper, OS << ".~" << T->getAsCXXRecordDecl()->getName() << "()"; OS << " (Member object destructor)\n"; - } else if (CFGTemporaryDtor TE = E.getAs()) { - CXXBindTemporaryExpr *BT = TE.getBindTemporaryExpr(); + } else if (const CFGTemporaryDtor *TE = E.getAs()) { + const CXXBindTemporaryExpr *BT = TE->getBindTemporaryExpr(); OS << "~" << BT->getType()->getAsCXXRecordDecl()->getName() << "()"; OS << " (Temporary object destructor)\n"; } diff --git a/clang/lib/Analysis/CFGStmtMap.cpp b/clang/lib/Analysis/CFGStmtMap.cpp index 3a030f9bdd1e..1fd5eedfeb86 100644 --- a/clang/lib/Analysis/CFGStmtMap.cpp +++ b/clang/lib/Analysis/CFGStmtMap.cpp @@ -50,11 +50,11 @@ static void Accumulate(SMap &SM, CFGBlock *B) { // First walk the block-level expressions. for (CFGBlock::iterator I = B->begin(), E = B->end(); I != E; ++I) { const CFGElement &CE = *I; - CFGStmt CS = CE.getAs(); - if (!CS.isValid()) + const CFGStmt *CS = CE.getAs(); + if (!CS) continue; - CFGBlock *&Entry = SM[CS]; + CFGBlock *&Entry = SM[CS->getStmt()]; // If 'Entry' is already initialized (e.g., a terminator was already), // skip. if (Entry) diff --git a/clang/lib/Analysis/ReachableCode.cpp b/clang/lib/Analysis/ReachableCode.cpp index 7afa586479b3..9659e9ec3ed6 100644 --- a/clang/lib/Analysis/ReachableCode.cpp +++ b/clang/lib/Analysis/ReachableCode.cpp @@ -31,11 +31,11 @@ static SourceLocation GetUnreachableLoc(const CFGBlock &b, SourceRange &R1, R1 = R2 = SourceRange(); if (sn < b.size()) { - CFGStmt CS = b[sn].getAs(); + const CFGStmt *CS = b[sn].getAs(); if (!CS) return SourceLocation(); - S = CS.getStmt(); + S = CS->getStmt(); } else if (b.getTerminator()) S = b.getTerminator(); else @@ -49,7 +49,7 @@ static SourceLocation GetUnreachableLoc(const CFGBlock &b, SourceRange &R1, const BinaryOperator *BO = cast(S); if (BO->getOpcode() == BO_Comma) { if (sn+1 < b.size()) - return b[sn+1].getAs().getStmt()->getLocStart(); + return b[sn+1].getAs()->getStmt()->getLocStart(); const CFGBlock *n = &b; while (1) { if (n->getTerminator()) @@ -60,7 +60,7 @@ static SourceLocation GetUnreachableLoc(const CFGBlock &b, SourceRange &R1, if (n->pred_size() != 1) return SourceLocation(); if (!n->empty()) - return n[0][0].getAs().getStmt()->getLocStart(); + return n[0][0].getAs()->getStmt()->getLocStart(); } } R1 = BO->getLHS()->getSourceRange(); diff --git a/clang/lib/Analysis/UninitializedValuesV2.cpp b/clang/lib/Analysis/UninitializedValuesV2.cpp index 75eccbf7a3c8..0d0bc36db364 100644 --- a/clang/lib/Analysis/UninitializedValuesV2.cpp +++ b/clang/lib/Analysis/UninitializedValuesV2.cpp @@ -146,8 +146,8 @@ static BinaryOperator *getLogicalOperatorInChain(const CFGBlock *block) { if (block->empty()) return 0; - CFGStmt cstmt = block->front().getAs(); - BinaryOperator *b = llvm::dyn_cast_or_null(cstmt.getStmt()); + const CFGStmt *cstmt = block->front().getAs(); + BinaryOperator *b = llvm::dyn_cast_or_null(cstmt->getStmt()); if (!b || !b->isLogicalOp()) return 0; diff --git a/clang/lib/StaticAnalyzer/Checkers/UnreachableCodeChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/UnreachableCodeChecker.cpp index 3d8327fed129..905a99e161ee 100644 --- a/clang/lib/StaticAnalyzer/Checkers/UnreachableCodeChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/UnreachableCodeChecker.cpp @@ -112,8 +112,8 @@ void UnreachableCodeChecker::checkEndAnalysis(ExplodedGraph &G, // such as llvm_unreachable. if (!CB->empty()) { CFGElement First = CB->front(); - if (CFGStmt S = First.getAs()) { - if (const CallExpr *CE = dyn_cast(S.getStmt())) { + if (const CFGStmt *S = First.getAs()) { + if (const CallExpr *CE = dyn_cast(S->getStmt())) { if (CE->isBuiltinCall(Ctx) == Builtin::BI__builtin_unreachable) continue; } @@ -164,8 +164,8 @@ void UnreachableCodeChecker::FindUnreachableEntryPoints(const CFGBlock *CB, // Find the Stmt* in a CFGBlock for reporting a warning const Stmt *UnreachableCodeChecker::getUnreachableStmt(const CFGBlock *CB) { for (CFGBlock::const_iterator I = CB->begin(), E = CB->end(); I != E; ++I) { - if (CFGStmt S = I->getAs()) - return S; + if (const CFGStmt *S = I->getAs()) + return S->getStmt(); } if (const Stmt *S = CB->getTerminator()) return S; diff --git a/clang/lib/StaticAnalyzer/Core/BugReporter.cpp b/clang/lib/StaticAnalyzer/Core/BugReporter.cpp index 672982a3c025..74cd35937db9 100644 --- a/clang/lib/StaticAnalyzer/Core/BugReporter.cpp +++ b/clang/lib/StaticAnalyzer/Core/BugReporter.cpp @@ -1170,13 +1170,14 @@ static void GenerateExtensivePathDiagnostic(PathDiagnostic& PD, } if (const BlockEntrance *BE = dyn_cast(&P)) { - if (CFGStmt S = BE->getFirstElement().getAs()) { - if (IsControlFlowExpr(S)) { + if (const CFGStmt *S = BE->getFirstElement().getAs()) { + const Stmt *stmt = S->getStmt(); + if (IsControlFlowExpr(stmt)) { // Add the proper context for '&&', '||', and '?'. - EB.addContext(S); + EB.addContext(stmt); } else - EB.addExtendedContext(PDB.getEnclosingStmtLocation(S).asStmt()); + EB.addExtendedContext(PDB.getEnclosingStmtLocation(stmt).asStmt()); } break; diff --git a/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp b/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp index cb777aec6d6a..615c216b0191 100644 --- a/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp +++ b/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp @@ -191,18 +191,20 @@ void ExprEngine::processEndWorklist(bool hasWorkRemaining) { void ExprEngine::processCFGElement(const CFGElement E, StmtNodeBuilder& builder) { switch (E.getKind()) { - case CFGElement::Statement: - ProcessStmt(E.getAs(), builder); - break; - case CFGElement::Initializer: - ProcessInitializer(E.getAs(), builder); - break; - case CFGElement::ImplicitDtor: - ProcessImplicitDtor(E.getAs(), builder); - break; - default: - // Suppress compiler warning. - llvm_unreachable("Unexpected CFGElement kind."); + case CFGElement::Invalid: + llvm_unreachable("Unexpected CFGElement kind."); + case CFGElement::Statement: + ProcessStmt(E.getAs()->getStmt(), builder); + return; + case CFGElement::Initializer: + ProcessInitializer(E.getAs()->getInitializer(), builder); + return; + case CFGElement::AutomaticObjectDtor: + case CFGElement::BaseDtor: + case CFGElement::MemberDtor: + case CFGElement::TemporaryDtor: + ProcessImplicitDtor(*E.getAs(), builder); + return; } } @@ -345,7 +347,7 @@ void ExprEngine::ProcessImplicitDtor(const CFGImplicitDtor D, StmtNodeBuilder &builder) { Builder = &builder; - switch (D.getDtorKind()) { + switch (D.getKind()) { case CFGElement::AutomaticObjectDtor: ProcessAutomaticObjDtor(cast(D), builder); break;