In preparation for fixing PR 6884, rework CFGElement to have getAs<> return pointers instead of fresh CFGElements.
- Also, consoldiate getDtorKind() and getKind() into one "kind".
- Add empty getDestructorDecl() method to CFGImplicitDtor.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@126738 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/include/clang/Analysis/CFG.h b/include/clang/Analysis/CFG.h
index b337d74..d135286 100644
--- a/include/clang/Analysis/CFG.h
+++ b/include/clang/Analysis/CFG.h
@@ -29,6 +29,7 @@
}
namespace clang {
+ class CXXDestructorDecl;
class Decl;
class Stmt;
class Expr;
@@ -47,45 +48,45 @@
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<void *, 2> Data1;
- // The int bits are used to mark the dtor kind.
llvm::PointerIntPair<void *, 2> 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<void*>(Ptr1), ((unsigned) kind) & 0x3),
+ Data2(const_cast<void*>(Ptr2), (((unsigned) kind) >> 2) & 0x3) {}
public:
CFGElement() {}
- Kind getKind() const { return static_cast<Kind>(Data1.getInt()); }
-
- Kind getDtorKind() const {
- assert(getKind() == ImplicitDtor);
- return static_cast<Kind>(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<class ElemTy> ElemTy getAs() const {
+
+ template<class ElemTy> const ElemTy *getAs() const {
if (llvm::isa<ElemTy>(this))
- return *static_cast<const ElemTy*>(this);
- return ElemTy();
+ return static_cast<const ElemTy*>(this);
+ return 0;
}
static bool classof(const CFGElement *E) { return true; }
@@ -93,13 +94,10 @@
class CFGStmt : public CFGElement {
public:
- CFGStmt() {}
- CFGStmt(Stmt *S) : CFGElement(S, 0) {}
+ CFGStmt(Stmt *S) : CFGElement(Statement, S) {}
Stmt *getStmt() const { return static_cast<Stmt *>(Data1.getPointer()); }
- operator Stmt*() const { return getStmt(); }
-
static bool classof(const CFGElement *E) {
return E->getKind() == Statement;
}
@@ -109,14 +107,12 @@
/// 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<CXXCtorInitializer*>(Data1.getPointer());
}
- operator CXXCtorInitializer*() const { return getInitializer(); }
static bool classof(const CFGElement *E) {
return E->getKind() == Initializer;
@@ -127,14 +123,17 @@
/// 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 @@
/// 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<VarDecl*>(Data1.getPointer());
}
// Get statement end of which triggered the destructor call.
- Stmt* getTriggerStmt() const {
+ const Stmt *getTriggerStmt() const {
return static_cast<Stmt*>(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 @@
/// base object in destructor.
class CFGBaseDtor : public CFGImplicitDtor {
public:
- CFGBaseDtor() {}
- CFGBaseDtor(const CXXBaseSpecifier *BS)
- : CFGImplicitDtor(BaseDtor, const_cast<CXXBaseSpecifier*>(BS), NULL) {}
+ CFGBaseDtor(const CXXBaseSpecifier *base)
+ : CFGImplicitDtor(BaseDtor, base) {}
const CXXBaseSpecifier *getBaseSpecifier() const {
return static_cast<const CXXBaseSpecifier*>(Data1.getPointer());
}
static bool classof(const CFGElement *E) {
- return E->getKind() == ImplicitDtor && E->getDtorKind() == BaseDtor;
+ return E->getKind() == BaseDtor;
}
};
@@ -183,16 +179,15 @@
/// 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<FieldDecl*>(Data1.getPointer());
+ const FieldDecl *getFieldDecl() const {
+ return static_cast<const FieldDecl*>(Data1.getPointer());
}
static bool classof(const CFGElement *E) {
- return E->getKind() == ImplicitDtor && E->getDtorKind() == MemberDtor;
+ return E->getKind() == MemberDtor;
}
};
@@ -200,16 +195,15 @@
/// 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<CXXBindTemporaryExpr *>(Data1.getPointer());
+ const CXXBindTemporaryExpr *getBindTemporaryExpr() const {
+ return static_cast<const CXXBindTemporaryExpr *>(Data1.getPointer());
}
static bool classof(const CFGElement *E) {
- return E->getKind() == ImplicitDtor && E->getDtorKind() == TemporaryDtor;
+ return E->getKind() == TemporaryDtor;
}
};
@@ -607,8 +601,8 @@
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<CFGStmt>())
- O(S);
+ if (const CFGStmt *stmt = BI->getAs<CFGStmt>())
+ O(stmt->getStmt());
}
}
diff --git a/include/clang/Analysis/FlowSensitive/DataflowSolver.h b/include/clang/Analysis/FlowSensitive/DataflowSolver.h
index d75d333..9561b96 100644
--- a/include/clang/Analysis/FlowSensitive/DataflowSolver.h
+++ b/include/clang/Analysis/FlowSensitive/DataflowSolver.h
@@ -277,8 +277,8 @@
for (StmtItr I=ItrTraits::StmtBegin(B), E=ItrTraits::StmtEnd(B); I!=E;++I) {
CFGElement El = *I;
- if (CFGStmt S = El.getAs<CFGStmt>())
- ProcessStmt(S, recordStmtValues, AnalysisDirTag());
+ if (const CFGStmt *S = El.getAs<CFGStmt>())
+ ProcessStmt(S->getStmt(), recordStmtValues, AnalysisDirTag());
}
TF.VisitTerminator(const_cast<CFGBlock*>(B));
@@ -293,8 +293,8 @@
for (StmtItr I=ItrTraits::StmtBegin(B), E=ItrTraits::StmtEnd(B); I!=E;++I) {
CFGElement El = *I;
- if (CFGStmt S = El.getAs<CFGStmt>())
- ProcessStmt(S, recordStmtValues, AnalysisDirTag());
+ if (const CFGStmt *S = El.getAs<CFGStmt>())
+ ProcessStmt(S->getStmt(), recordStmtValues, AnalysisDirTag());
}
}
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h b/include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h
index 25c6447..74cba32 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h
@@ -219,11 +219,8 @@
/// getStmt - Return the current block-level expression associated with
/// this builder.
const Stmt* getStmt() const {
- CFGStmt CS = B[Idx].getAs<CFGStmt>();
- if (CS)
- return CS.getStmt();
- else
- return 0;
+ const CFGStmt *CS = B[Idx].getAs<CFGStmt>();
+ return CS ? CS->getStmt() : 0;
}
/// getBlock - Return the CFGBlock associated with the block-level expression
diff --git a/lib/Analysis/CFG.cpp b/lib/Analysis/CFG.cpp
index d2cccc8..7ee2a9c 100644
--- a/lib/Analysis/CFG.cpp
+++ b/lib/Analysis/CFG.cpp
@@ -2704,6 +2704,10 @@
return Builder.buildCFG(D, Statement, C, BO);
}
+const CXXDestructorDecl *CFGImplicitDtor::getDestructorDecl() const {
+ return 0;
+}
+
//===----------------------------------------------------------------------===//
// CFG: Queries for BlkExprs.
//===----------------------------------------------------------------------===//
@@ -2740,8 +2744,8 @@
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<CFGStmt>())
- FindSubExprAssignments(S, SubExprAssignments);
+ if (const CFGStmt *S = BI->getAs<CFGStmt>())
+ FindSubExprAssignments(S->getStmt(), SubExprAssignments);
for (CFG::iterator I=cfg.begin(), E=cfg.end(); I != E; ++I) {
@@ -2749,10 +2753,10 @@
// block-level that are block-level expressions.
for (CFGBlock::iterator BI=(*I)->begin(), EI=(*I)->end(); BI != EI; ++BI) {
- CFGStmt CS = BI->getAs<CFGStmt>();
- if (!CS.isValid())
+ const CFGStmt *CS = BI->getAs<CFGStmt>();
+ if (!CS)
continue;
- if (Expr* Exp = dyn_cast<Expr>(CS.getStmt())) {
+ if (Expr* Exp = dyn_cast<Expr>(CS->getStmt())) {
if (BinaryOperator* B = dyn_cast<BinaryOperator>(Exp)) {
// Assignment expressions that are not nested within another
@@ -2845,8 +2849,8 @@
namespace {
class StmtPrinterHelper : public PrinterHelper {
- typedef llvm::DenseMap<Stmt*,std::pair<unsigned,unsigned> > StmtMapTy;
- typedef llvm::DenseMap<Decl*,std::pair<unsigned,unsigned> > DeclMapTy;
+ typedef llvm::DenseMap<const Stmt*,std::pair<unsigned,unsigned> > StmtMapTy;
+ typedef llvm::DenseMap<const Decl*,std::pair<unsigned,unsigned> > DeclMapTy;
StmtMapTy StmtMap;
DeclMapTy DeclMap;
signed currentBlock;
@@ -2855,42 +2859,62 @@
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<CFGStmt>()) {
+ if (const CFGStmt *SE = BI->getAs<CFGStmt>()) {
+ const Stmt *stmt= SE->getStmt();
std::pair<unsigned, unsigned> P((*I)->getBlockID(), j);
- StmtMap[SE] = P;
+ StmtMap[stmt] = P;
- if (DeclStmt* DS = dyn_cast<DeclStmt>(SE.getStmt())) {
- DeclMap[DS->getSingleDecl()] = P;
-
- } else if (IfStmt* IS = dyn_cast<IfStmt>(SE.getStmt())) {
- if (VarDecl* VD = IS->getConditionVariable())
- DeclMap[VD] = P;
-
- } else if (ForStmt* FS = dyn_cast<ForStmt>(SE.getStmt())) {
- if (VarDecl* VD = FS->getConditionVariable())
- DeclMap[VD] = P;
-
- } else if (WhileStmt* WS = dyn_cast<WhileStmt>(SE.getStmt())) {
- if (VarDecl* VD = WS->getConditionVariable())
- DeclMap[VD] = P;
-
- } else if (SwitchStmt* SS = dyn_cast<SwitchStmt>(SE.getStmt())) {
- if (VarDecl* VD = SS->getConditionVariable())
- DeclMap[VD] = P;
-
- } else if (CXXCatchStmt* CS = dyn_cast<CXXCatchStmt>(SE.getStmt())) {
- if (VarDecl* VD = CS->getExceptionDecl())
- DeclMap[VD] = P;
+ switch (stmt->getStmtClass()) {
+ case Stmt::DeclStmtClass:
+ DeclMap[cast<DeclStmt>(stmt)->getSingleDecl()] = P;
+ break;
+ case Stmt::IfStmtClass: {
+ const VarDecl *var = cast<IfStmt>(stmt)->getConditionVariable();
+ if (var)
+ DeclMap[var] = P;
+ break;
+ }
+ case Stmt::ForStmtClass: {
+ const VarDecl *var = cast<ForStmt>(stmt)->getConditionVariable();
+ if (var)
+ DeclMap[var] = P;
+ break;
+ }
+ case Stmt::WhileStmtClass: {
+ const VarDecl *var =
+ cast<WhileStmt>(stmt)->getConditionVariable();
+ if (var)
+ DeclMap[var] = P;
+ break;
+ }
+ case Stmt::SwitchStmtClass: {
+ const VarDecl *var =
+ cast<SwitchStmt>(stmt)->getConditionVariable();
+ if (var)
+ DeclMap[var] = P;
+ break;
+ }
+ case Stmt::CXXCatchStmtClass: {
+ const VarDecl *var =
+ cast<CXXCatchStmt>(stmt)->getExceptionDecl();
+ if (var)
+ DeclMap[var] = P;
+ break;
+ }
+ default:
+ break;
}
}
}
}
}
+
virtual ~StmtPrinterHelper() {}
@@ -2913,7 +2937,7 @@
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 @@
static void print_elem(llvm::raw_ostream &OS, StmtPrinterHelper* Helper,
const CFGElement &E) {
- if (CFGStmt CS = E.getAs<CFGStmt>()) {
- Stmt *S = CS;
+ if (const CFGStmt *CS = E.getAs<CFGStmt>()) {
+ Stmt *S = CS->getStmt();
if (Helper) {
@@ -3069,8 +3093,8 @@
if (isa<Expr>(S))
OS << '\n';
- } else if (CFGInitializer IE = E.getAs<CFGInitializer>()) {
- CXXCtorInitializer* I = IE;
+ } else if (const CFGInitializer *IE = E.getAs<CFGInitializer>()) {
+ const CXXCtorInitializer *I = IE->getInitializer();
if (I->isBaseInitializer())
OS << I->getBaseClass()->getAsCXXRecordDecl()->getName();
else OS << I->getAnyMember()->getName();
@@ -3084,8 +3108,8 @@
OS << " (Base initializer)\n";
else OS << " (Member initializer)\n";
- } else if (CFGAutomaticObjDtor DE = E.getAs<CFGAutomaticObjDtor>()){
- VarDecl* VD = DE.getVarDecl();
+ } else if (const CFGAutomaticObjDtor *DE = E.getAs<CFGAutomaticObjDtor>()){
+ const VarDecl* VD = DE->getVarDecl();
Helper->handleDecl(VD, OS);
const Type* T = VD->getType().getTypePtr();
@@ -3097,13 +3121,13 @@
OS << ".~" << T->getAsCXXRecordDecl()->getName().str() << "()";
OS << " (Implicit destructor)\n";
- } else if (CFGBaseDtor BE = E.getAs<CFGBaseDtor>()) {
- const CXXBaseSpecifier *BS = BE.getBaseSpecifier();
+ } else if (const CFGBaseDtor *BE = E.getAs<CFGBaseDtor>()) {
+ const CXXBaseSpecifier *BS = BE->getBaseSpecifier();
OS << "~" << BS->getType()->getAsCXXRecordDecl()->getName() << "()";
OS << " (Base object destructor)\n";
- } else if (CFGMemberDtor ME = E.getAs<CFGMemberDtor>()) {
- FieldDecl *FD = ME.getFieldDecl();
+ } else if (const CFGMemberDtor *ME = E.getAs<CFGMemberDtor>()) {
+ const FieldDecl *FD = ME->getFieldDecl();
const Type *T = FD->getType().getTypePtr();
if (const Type *ET = T->getArrayElementTypeNoTypeQual())
@@ -3113,8 +3137,8 @@
OS << ".~" << T->getAsCXXRecordDecl()->getName() << "()";
OS << " (Member object destructor)\n";
- } else if (CFGTemporaryDtor TE = E.getAs<CFGTemporaryDtor>()) {
- CXXBindTemporaryExpr *BT = TE.getBindTemporaryExpr();
+ } else if (const CFGTemporaryDtor *TE = E.getAs<CFGTemporaryDtor>()) {
+ const CXXBindTemporaryExpr *BT = TE->getBindTemporaryExpr();
OS << "~" << BT->getType()->getAsCXXRecordDecl()->getName() << "()";
OS << " (Temporary object destructor)\n";
}
diff --git a/lib/Analysis/CFGStmtMap.cpp b/lib/Analysis/CFGStmtMap.cpp
index 3a030f9..1fd5eed 100644
--- a/lib/Analysis/CFGStmtMap.cpp
+++ b/lib/Analysis/CFGStmtMap.cpp
@@ -50,11 +50,11 @@
// 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<CFGStmt>();
- if (!CS.isValid())
+ const CFGStmt *CS = CE.getAs<CFGStmt>();
+ 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/lib/Analysis/ReachableCode.cpp b/lib/Analysis/ReachableCode.cpp
index 7afa586..9659e9e 100644
--- a/lib/Analysis/ReachableCode.cpp
+++ b/lib/Analysis/ReachableCode.cpp
@@ -31,11 +31,11 @@
R1 = R2 = SourceRange();
if (sn < b.size()) {
- CFGStmt CS = b[sn].getAs<CFGStmt>();
+ const CFGStmt *CS = b[sn].getAs<CFGStmt>();
if (!CS)
return SourceLocation();
- S = CS.getStmt();
+ S = CS->getStmt();
} else if (b.getTerminator())
S = b.getTerminator();
else
@@ -49,7 +49,7 @@
const BinaryOperator *BO = cast<BinaryOperator>(S);
if (BO->getOpcode() == BO_Comma) {
if (sn+1 < b.size())
- return b[sn+1].getAs<CFGStmt>().getStmt()->getLocStart();
+ return b[sn+1].getAs<CFGStmt>()->getStmt()->getLocStart();
const CFGBlock *n = &b;
while (1) {
if (n->getTerminator())
@@ -60,7 +60,7 @@
if (n->pred_size() != 1)
return SourceLocation();
if (!n->empty())
- return n[0][0].getAs<CFGStmt>().getStmt()->getLocStart();
+ return n[0][0].getAs<CFGStmt>()->getStmt()->getLocStart();
}
}
R1 = BO->getLHS()->getSourceRange();
diff --git a/lib/Analysis/UninitializedValuesV2.cpp b/lib/Analysis/UninitializedValuesV2.cpp
index 75eccbf..0d0bc36 100644
--- a/lib/Analysis/UninitializedValuesV2.cpp
+++ b/lib/Analysis/UninitializedValuesV2.cpp
@@ -146,8 +146,8 @@
if (block->empty())
return 0;
- CFGStmt cstmt = block->front().getAs<CFGStmt>();
- BinaryOperator *b = llvm::dyn_cast_or_null<BinaryOperator>(cstmt.getStmt());
+ const CFGStmt *cstmt = block->front().getAs<CFGStmt>();
+ BinaryOperator *b = llvm::dyn_cast_or_null<BinaryOperator>(cstmt->getStmt());
if (!b || !b->isLogicalOp())
return 0;
diff --git a/lib/StaticAnalyzer/Checkers/UnreachableCodeChecker.cpp b/lib/StaticAnalyzer/Checkers/UnreachableCodeChecker.cpp
index 3d8327f..905a99e 100644
--- a/lib/StaticAnalyzer/Checkers/UnreachableCodeChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/UnreachableCodeChecker.cpp
@@ -112,8 +112,8 @@
// such as llvm_unreachable.
if (!CB->empty()) {
CFGElement First = CB->front();
- if (CFGStmt S = First.getAs<CFGStmt>()) {
- if (const CallExpr *CE = dyn_cast<CallExpr>(S.getStmt())) {
+ if (const CFGStmt *S = First.getAs<CFGStmt>()) {
+ if (const CallExpr *CE = dyn_cast<CallExpr>(S->getStmt())) {
if (CE->isBuiltinCall(Ctx) == Builtin::BI__builtin_unreachable)
continue;
}
@@ -164,8 +164,8 @@
// 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<CFGStmt>())
- return S;
+ if (const CFGStmt *S = I->getAs<CFGStmt>())
+ return S->getStmt();
}
if (const Stmt *S = CB->getTerminator())
return S;
diff --git a/lib/StaticAnalyzer/Core/BugReporter.cpp b/lib/StaticAnalyzer/Core/BugReporter.cpp
index 672982a..74cd359 100644
--- a/lib/StaticAnalyzer/Core/BugReporter.cpp
+++ b/lib/StaticAnalyzer/Core/BugReporter.cpp
@@ -1170,13 +1170,14 @@
}
if (const BlockEntrance *BE = dyn_cast<BlockEntrance>(&P)) {
- if (CFGStmt S = BE->getFirstElement().getAs<CFGStmt>()) {
- if (IsControlFlowExpr(S)) {
+ if (const CFGStmt *S = BE->getFirstElement().getAs<CFGStmt>()) {
+ 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/lib/StaticAnalyzer/Core/ExprEngine.cpp b/lib/StaticAnalyzer/Core/ExprEngine.cpp
index cb777ae..615c216 100644
--- a/lib/StaticAnalyzer/Core/ExprEngine.cpp
+++ b/lib/StaticAnalyzer/Core/ExprEngine.cpp
@@ -191,18 +191,20 @@
void ExprEngine::processCFGElement(const CFGElement E,
StmtNodeBuilder& builder) {
switch (E.getKind()) {
- case CFGElement::Statement:
- ProcessStmt(E.getAs<CFGStmt>(), builder);
- break;
- case CFGElement::Initializer:
- ProcessInitializer(E.getAs<CFGInitializer>(), builder);
- break;
- case CFGElement::ImplicitDtor:
- ProcessImplicitDtor(E.getAs<CFGImplicitDtor>(), 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<CFGStmt>()->getStmt(), builder);
+ return;
+ case CFGElement::Initializer:
+ ProcessInitializer(E.getAs<CFGInitializer>()->getInitializer(), builder);
+ return;
+ case CFGElement::AutomaticObjectDtor:
+ case CFGElement::BaseDtor:
+ case CFGElement::MemberDtor:
+ case CFGElement::TemporaryDtor:
+ ProcessImplicitDtor(*E.getAs<CFGImplicitDtor>(), builder);
+ return;
}
}
@@ -345,7 +347,7 @@
StmtNodeBuilder &builder) {
Builder = &builder;
- switch (D.getDtorKind()) {
+ switch (D.getKind()) {
case CFGElement::AutomaticObjectDtor:
ProcessAutomaticObjDtor(cast<CFGAutomaticObjDtor>(D), builder);
break;