r175796 - Replace CFGElement llvm::cast support to be well-defined.

Douglas Gregor dgregor at apple.com
Fri Feb 22 09:53:03 PST 2013


On Feb 21, 2013, at 10:53 PM, David Blaikie <dblaikie at gmail.com> wrote:

> [+Doug & Jordan who I discussed some of this with on IRC]
> 
> 
> On Thu, Feb 21, 2013 at 10:26 PM, Ted Kremenek <kremenek at apple.com> wrote:
> Hi David,
> 
> I've been mulling over this change, and while I think it is a great step in the right direction, one I thing that I'm a bit mixed about is code like this:
> 
>             if (CFGStmt CS = ElemIt->getAs<CFGStmt>()) {
> 
> The reason I don't like this is because one could easily just write:
> 
>   CFGStmt CS = ElemIt->getAs<CFGStmt>()
> 
> To play devil's advocate, the same is true of the llvm::cast usage, we write:
> 
> T* x = cast<T>(y);
> 
> All the time & have to know that cast never returns null (not even in the cast where you pass null (for that you need cast_or_null)) & thus go off and dereference 'x' unconditionally immediately after.
>  
> The problem is that, visually, there is no indication that this objct could be "invalid".  When we were dealing with pointer values, by common practice everyone knows that a pointer value is not valid if it is NULL.  When we use these objects directly we lose that intuition, and I fear people could easily do the "wrong thing" accidentally.
> 
> I agree with you.
> 
> Some context  here is that I started with TypeLoc & had exactly the same problem - I started with the "Optional<T> getAs()" version for TypeLoc & eventually discovered that TypeLoc itself was boolean testable for 'validity'. So I asked Doug on IRC if I should use TypeLoc's sense of validity or add the Optional on top of it still. To be honest, perhaps I didn't articulate the concern as well as you have here & so perhaps it wasn't apparent to him - but in any case, his preference was for the "T getAs()" form and to rely on TypeLoc's existing invalidity.
> 
> When it came to ProgramPoint and SVal there was no existing 'invalid' state that mapped well to this situation - I asked Jordan on IRC to see if I was reading these hierarchies correctly & he agreed (SVal has invalid/undef/unknown states but none match quite well enough to use in the API in this way) so I used Optional. But when I came across CFGEement I found a usable invalid state that looked much like TypeLoc, so, after chatting with Jordan again, used that - it seemed consistent with Doug's preference for the TypeLoc API as well.
>  
> While it may be more boilerplate, what do you think about getAs<> returning an Optional<CFGStmt> object instead?  We could template specialize Optional<CFGStmt> to not use more storage, etc., and basically do what you have here, except with something that really *looks* like it has a valid or invalid value respectively.  This would also match with the other changes you made to ProgramPoint.
> 
> What do you think?
> 
> Personally I'd prefer to do it the way you're suggesting.
> 
> My only concern is that there's already a sense of invalidity for CFGElement and TypeLocs that's publicly usable, so now the APIs would be returning Optional<T> where T is (without any type safety helping in this case) guaranteed to be "not invalid".

That's my main concern. If you have a type that has an invalid state, you have to be aware when objects of that type has invalid state. If we then wrap an Optional<> around it, now you have two axes of invalid state to worry about… which is actively confusing. So, for types that already have an invalid state, I'd rather not have getAs<> return an Optional<> because we'd end up with the two axes of invalidity. For types that *don't* have an invalid state, returning Optional<> from getAs<> would be a great solution.

And if we can eliminate the invalid states for some types, switching over to Optional<> for the places where do getAs<> and similar operations, I think that would improve the clarity of the code base.

> So here's a hypothetical step further: along with specializing Optional to use zero-cost "optionality" (I suppose that would negate the concern I have above - essentially Optional<T> would be another representation for "invalid T"), make it so that no code deals with raw invalid Ts (the only place where invalid Ts could be constructed would be in Optional, via friending). That way we get zero cost type safe invalid states.

Making Optional<T> have zero space cost when possible would be a great optimization. I'd consider that orthogonal to the design discussion, because I don't think we're motivated either way by the current cost of Optional.

	- Doug

> 
> Thanks for taking the time to review/consider this,
> 
> - David
>  
> 
> Ted
> 
> On Feb 21, 2013, at 12:58 PM, David Blaikie <dblaikie at gmail.com> wrote:
> 
> > Author: dblaikie
> > Date: Thu Feb 21 14:58:29 2013
> > New Revision: 175796
> >
> > URL: http://llvm.org/viewvc/llvm-project?rev=175796&view=rev
> > Log:
> > Replace CFGElement llvm::cast support to be well-defined.
> >
> > See r175462 for another example/more details.
> >
> > Modified:
> >    cfe/trunk/include/clang/Analysis/CFG.h
> >    cfe/trunk/lib/Analysis/CFG.cpp
> >    cfe/trunk/lib/Analysis/CFGStmtMap.cpp
> >    cfe/trunk/lib/Analysis/LiveVariables.cpp
> >    cfe/trunk/lib/Analysis/ReachableCode.cpp
> >    cfe/trunk/lib/Analysis/ThreadSafety.cpp
> >    cfe/trunk/lib/Analysis/UninitializedValues.cpp
> >    cfe/trunk/lib/Sema/AnalysisBasedWarnings.cpp
> >    cfe/trunk/lib/StaticAnalyzer/Checkers/AnalyzerStatsChecker.cpp
> >    cfe/trunk/lib/StaticAnalyzer/Checkers/MallocOverflowSecurityChecker.cpp
> >    cfe/trunk/lib/StaticAnalyzer/Checkers/UnreachableCodeChecker.cpp
> >    cfe/trunk/lib/StaticAnalyzer/Core/BugReporter.cpp
> >    cfe/trunk/lib/StaticAnalyzer/Core/CallEvent.cpp
> >    cfe/trunk/lib/StaticAnalyzer/Core/CoreEngine.cpp
> >    cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp
> >    cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineC.cpp
> >    cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
> >    cfe/trunk/lib/StaticAnalyzer/Core/PathDiagnostic.cpp
> >
> > Modified: cfe/trunk/include/clang/Analysis/CFG.h
> > URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Analysis/CFG.h?rev=175796&r1=175795&r2=175796&view=diff
> > ==============================================================================
> > --- cfe/trunk/include/clang/Analysis/CFG.h (original)
> > +++ cfe/trunk/include/clang/Analysis/CFG.h Thu Feb 21 14:58:29 2013
> > @@ -20,6 +20,7 @@
> > #include "clang/Basic/SourceLocation.h"
> > #include "llvm/ADT/DenseMap.h"
> > #include "llvm/ADT/GraphTraits.h"
> > +#include "llvm/ADT/Optional.h"
> > #include "llvm/ADT/OwningPtr.h"
> > #include "llvm/ADT/PointerIntPair.h"
> > #include "llvm/Support/Allocator.h"
> > @@ -72,6 +73,29 @@ protected:
> > public:
> >   CFGElement() {}
> >
> > +  /// \brief Convert to the specified CFGElement type, asserting that this
> > +  /// CFGElement is of the desired type.
> > +  template<typename T>
> > +  T castAs() const {
> > +    assert(T::isKind(*this));
> > +    T t;
> > +    CFGElement& e = t;
> > +    e = *this;
> > +    return t;
> > +  }
> > +
> > +  /// \brief Convert to the specified CFGElement type, returning an invalid
> > +  /// CFGElement if this CFGElement is not of the desired type.
> > +  template<typename T>
> > +  T getAs() const {
> > +    if (!T::isKind(*this))
> > +      return T();
> > +    T t;
> > +    CFGElement& e = t;
> > +    e = *this;
> > +    return t;
> > +  }
> > +
> >   Kind getKind() const {
> >     unsigned x = Data2.getInt();
> >     x <<= 2;
> > @@ -82,14 +106,6 @@ public:
> >   bool isValid() const { return getKind() != Invalid; }
> >
> >   operator bool() const { return isValid(); }
> > -
> > -  template<class ElemTy> const ElemTy *getAs() const LLVM_LVALUE_FUNCTION {
> > -    return dyn_cast<ElemTy>(this);
> > -  }
> > -
> > -#if LLVM_HAS_RVALUE_REFERENCE_THIS
> > -  template<class ElemTy> void getAs() && LLVM_DELETED_FUNCTION;
> > -#endif
> > };
> >
> > class CFGStmt : public CFGElement {
> > @@ -100,8 +116,11 @@ public:
> >     return static_cast<const Stmt *>(Data1.getPointer());
> >   }
> >
> > -  static bool classof(const CFGElement *E) {
> > -    return E->getKind() == Statement;
> > +private:
> > +  friend class CFGElement;
> > +  CFGStmt() {}
> > +  static bool isKind(const CFGElement &E) {
> > +    return E.getKind() == Statement;
> >   }
> > };
> >
> > @@ -116,8 +135,11 @@ public:
> >     return static_cast<CXXCtorInitializer*>(Data1.getPointer());
> >   }
> >
> > -  static bool classof(const CFGElement *E) {
> > -    return E->getKind() == Initializer;
> > +private:
> > +  friend class CFGElement;
> > +  CFGInitializer() {}
> > +  static bool isKind(const CFGElement &E) {
> > +    return E.getKind() == Initializer;
> >   }
> > };
> >
> > @@ -125,6 +147,7 @@ public:
> > /// by compiler on various occasions.
> > class CFGImplicitDtor : public CFGElement {
> > protected:
> > +  CFGImplicitDtor() {}
> >   CFGImplicitDtor(Kind kind, const void *data1, const void *data2 = 0)
> >     : CFGElement(kind, data1, data2) {
> >     assert(kind >= DTOR_BEGIN && kind <= DTOR_END);
> > @@ -134,8 +157,10 @@ public:
> >   const CXXDestructorDecl *getDestructorDecl(ASTContext &astContext) const;
> >   bool isNoReturn(ASTContext &astContext) const;
> >
> > -  static bool classof(const CFGElement *E) {
> > -    Kind kind = E->getKind();
> > +private:
> > +  friend class CFGElement;
> > +  static bool isKind(const CFGElement &E) {
> > +    Kind kind = E.getKind();
> >     return kind >= DTOR_BEGIN && kind <= DTOR_END;
> >   }
> > };
> > @@ -157,8 +182,11 @@ public:
> >     return static_cast<Stmt*>(Data2.getPointer());
> >   }
> >
> > -  static bool classof(const CFGElement *elem) {
> > -    return elem->getKind() == AutomaticObjectDtor;
> > +private:
> > +  friend class CFGElement;
> > +  CFGAutomaticObjDtor() {}
> > +  static bool isKind(const CFGElement &elem) {
> > +    return elem.getKind() == AutomaticObjectDtor;
> >   }
> > };
> >
> > @@ -173,8 +201,11 @@ public:
> >     return static_cast<const CXXBaseSpecifier*>(Data1.getPointer());
> >   }
> >
> > -  static bool classof(const CFGElement *E) {
> > -    return E->getKind() == BaseDtor;
> > +private:
> > +  friend class CFGElement;
> > +  CFGBaseDtor() {}
> > +  static bool isKind(const CFGElement &E) {
> > +    return E.getKind() == BaseDtor;
> >   }
> > };
> >
> > @@ -189,8 +220,11 @@ public:
> >     return static_cast<const FieldDecl*>(Data1.getPointer());
> >   }
> >
> > -  static bool classof(const CFGElement *E) {
> > -    return E->getKind() == MemberDtor;
> > +private:
> > +  friend class CFGElement;
> > +  CFGMemberDtor() {}
> > +  static bool isKind(const CFGElement &E) {
> > +    return E.getKind() == MemberDtor;
> >   }
> > };
> >
> > @@ -205,8 +239,11 @@ public:
> >     return static_cast<const CXXBindTemporaryExpr *>(Data1.getPointer());
> >   }
> >
> > -  static bool classof(const CFGElement *E) {
> > -    return E->getKind() == TemporaryDtor;
> > +private:
> > +  friend class CFGElement;
> > +  CFGTemporaryDtor() {}
> > +  static bool isKind(const CFGElement &E) {
> > +    return E.getKind() == TemporaryDtor;
> >   }
> > };
> >
> > @@ -720,8 +757,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 (const CFGStmt *stmt = BI->getAs<CFGStmt>())
> > -          O(const_cast<Stmt*>(stmt->getStmt()));
> > +        if (CFGStmt stmt = BI->getAs<CFGStmt>())
> > +          O(const_cast<Stmt*>(stmt.getStmt()));
> >       }
> >   }
> >
> >
> > Modified: cfe/trunk/lib/Analysis/CFG.cpp
> > URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/CFG.cpp?rev=175796&r1=175795&r2=175796&view=diff
> > ==============================================================================
> > --- cfe/trunk/lib/Analysis/CFG.cpp (original)
> > +++ cfe/trunk/lib/Analysis/CFG.cpp Thu Feb 21 14:58:29 2013
> > @@ -3338,7 +3338,7 @@ CFGImplicitDtor::getDestructorDecl(ASTCo
> >       llvm_unreachable("getDestructorDecl should only be used with "
> >                        "ImplicitDtors");
> >     case CFGElement::AutomaticObjectDtor: {
> > -      const VarDecl *var = cast<CFGAutomaticObjDtor>(this)->getVarDecl();
> > +      const VarDecl *var = castAs<CFGAutomaticObjDtor>().getVarDecl();
> >       QualType ty = var->getType();
> >       ty = ty.getNonReferenceType();
> >       while (const ArrayType *arrayType = astContext.getAsArrayType(ty)) {
> > @@ -3351,7 +3351,7 @@ CFGImplicitDtor::getDestructorDecl(ASTCo
> >     }
> >     case CFGElement::TemporaryDtor: {
> >       const CXXBindTemporaryExpr *bindExpr =
> > -        cast<CFGTemporaryDtor>(this)->getBindTemporaryExpr();
> > +        castAs<CFGTemporaryDtor>().getBindTemporaryExpr();
> >       const CXXTemporary *temp = bindExpr->getTemporary();
> >       return temp->getDestructor();
> >     }
> > @@ -3406,8 +3406,8 @@ static BlkExprMapTy* PopulateBlkExprMap(
> >
> >   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 (const CFGStmt *S = BI->getAs<CFGStmt>())
> > -        FindSubExprAssignments(S->getStmt(), SubExprAssignments);
> > +      if (CFGStmt S = BI->getAs<CFGStmt>())
> > +        FindSubExprAssignments(S.getStmt(), SubExprAssignments);
> >
> >   for (CFG::iterator I=cfg.begin(), E=cfg.end(); I != E; ++I) {
> >
> > @@ -3415,10 +3415,10 @@ static BlkExprMapTy* PopulateBlkExprMap(
> >     // block-level that are block-level expressions.
> >
> >     for (CFGBlock::iterator BI=(*I)->begin(), EI=(*I)->end(); BI != EI; ++BI) {
> > -      const CFGStmt *CS = BI->getAs<CFGStmt>();
> > +      CFGStmt CS = BI->getAs<CFGStmt>();
> >       if (!CS)
> >         continue;
> > -      if (const Expr *Exp = dyn_cast<Expr>(CS->getStmt())) {
> > +      if (const Expr *Exp = dyn_cast<Expr>(CS.getStmt())) {
> >         assert((Exp->IgnoreParens() == Exp) && "No parens on block-level exps");
> >
> >         if (const BinaryOperator* B = dyn_cast<BinaryOperator>(Exp)) {
> > @@ -3531,8 +3531,8 @@ public:
> >       unsigned j = 1;
> >       for (CFGBlock::const_iterator BI = (*I)->begin(), BEnd = (*I)->end() ;
> >            BI != BEnd; ++BI, ++j ) {
> > -        if (const CFGStmt *SE = BI->getAs<CFGStmt>()) {
> > -          const Stmt *stmt= SE->getStmt();
> > +        if (CFGStmt SE = BI->getAs<CFGStmt>()) {
> > +          const Stmt *stmt= SE.getStmt();
> >           std::pair<unsigned, unsigned> P((*I)->getBlockID(), j);
> >           StmtMap[stmt] = P;
> >
> > @@ -3721,8 +3721,8 @@ public:
> >
> > static void print_elem(raw_ostream &OS, StmtPrinterHelper* Helper,
> >                        const CFGElement &E) {
> > -  if (const CFGStmt *CS = E.getAs<CFGStmt>()) {
> > -    const Stmt *S = CS->getStmt();
> > +  if (CFGStmt CS = E.getAs<CFGStmt>()) {
> > +    const Stmt *S = CS.getStmt();
> >
> >     if (Helper) {
> >
> > @@ -3769,8 +3769,8 @@ static void print_elem(raw_ostream &OS,
> >     if (isa<Expr>(S))
> >       OS << '\n';
> >
> > -  } else if (const CFGInitializer *IE = E.getAs<CFGInitializer>()) {
> > -    const CXXCtorInitializer *I = IE->getInitializer();
> > +  } else if (CFGInitializer IE = E.getAs<CFGInitializer>()) {
> > +    const CXXCtorInitializer *I = IE.getInitializer();
> >     if (I->isBaseInitializer())
> >       OS << I->getBaseClass()->getAsCXXRecordDecl()->getName();
> >     else OS << I->getAnyMember()->getName();
> > @@ -3784,8 +3784,8 @@ static void print_elem(raw_ostream &OS,
> >       OS << " (Base initializer)\n";
> >     else OS << " (Member initializer)\n";
> >
> > -  } else if (const CFGAutomaticObjDtor *DE = E.getAs<CFGAutomaticObjDtor>()){
> > -    const VarDecl *VD = DE->getVarDecl();
> > +  } else if (CFGAutomaticObjDtor DE = E.getAs<CFGAutomaticObjDtor>()){
> > +    const VarDecl *VD = DE.getVarDecl();
> >     Helper->handleDecl(VD, OS);
> >
> >     const Type* T = VD->getType().getTypePtr();
> > @@ -3796,20 +3796,20 @@ static void print_elem(raw_ostream &OS,
> >     OS << ".~" << T->getAsCXXRecordDecl()->getName().str() << "()";
> >     OS << " (Implicit destructor)\n";
> >
> > -  } else if (const CFGBaseDtor *BE = E.getAs<CFGBaseDtor>()) {
> > -    const CXXBaseSpecifier *BS = BE->getBaseSpecifier();
> > +  } else if (CFGBaseDtor BE = E.getAs<CFGBaseDtor>()) {
> > +    const CXXBaseSpecifier *BS = BE.getBaseSpecifier();
> >     OS << "~" << BS->getType()->getAsCXXRecordDecl()->getName() << "()";
> >     OS << " (Base object destructor)\n";
> >
> > -  } else if (const CFGMemberDtor *ME = E.getAs<CFGMemberDtor>()) {
> > -    const FieldDecl *FD = ME->getFieldDecl();
> > +  } else if (CFGMemberDtor ME = E.getAs<CFGMemberDtor>()) {
> > +    const FieldDecl *FD = ME.getFieldDecl();
> >     const Type *T = FD->getType()->getBaseElementTypeUnsafe();
> >     OS << "this->" << FD->getName();
> >     OS << ".~" << T->getAsCXXRecordDecl()->getName() << "()";
> >     OS << " (Member object destructor)\n";
> >
> > -  } else if (const CFGTemporaryDtor *TE = E.getAs<CFGTemporaryDtor>()) {
> > -    const CXXBindTemporaryExpr *BT = TE->getBindTemporaryExpr();
> > +  } else if (CFGTemporaryDtor TE = E.getAs<CFGTemporaryDtor>()) {
> > +    const CXXBindTemporaryExpr *BT = TE.getBindTemporaryExpr();
> >     OS << "~" << BT->getType()->getAsCXXRecordDecl()->getName() << "()";
> >     OS << " (Temporary object destructor)\n";
> >   }
> >
> > Modified: cfe/trunk/lib/Analysis/CFGStmtMap.cpp
> > URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/CFGStmtMap.cpp?rev=175796&r1=175795&r2=175796&view=diff
> > ==============================================================================
> > --- cfe/trunk/lib/Analysis/CFGStmtMap.cpp (original)
> > +++ cfe/trunk/lib/Analysis/CFGStmtMap.cpp Thu Feb 21 14:58:29 2013
> > @@ -50,11 +50,11 @@ static void Accumulate(SMap &SM, CFGBloc
> >   // First walk the block-level expressions.
> >   for (CFGBlock::iterator I = B->begin(), E = B->end(); I != E; ++I) {
> >     const CFGElement &CE = *I;
> > -    const CFGStmt *CS = CE.getAs<CFGStmt>();
> > +    CFGStmt CS = CE.getAs<CFGStmt>();
> >     if (!CS)
> >       continue;
> >
> > -    CFGBlock *&Entry = SM[CS->getStmt()];
> > +    CFGBlock *&Entry = SM[CS.getStmt()];
> >     // If 'Entry' is already initialized (e.g., a terminator was already),
> >     // skip.
> >     if (Entry)
> >
> > Modified: cfe/trunk/lib/Analysis/LiveVariables.cpp
> > URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/LiveVariables.cpp?rev=175796&r1=175795&r2=175796&view=diff
> > ==============================================================================
> > --- cfe/trunk/lib/Analysis/LiveVariables.cpp (original)
> > +++ cfe/trunk/lib/Analysis/LiveVariables.cpp Thu Feb 21 14:58:29 2013
> > @@ -474,15 +474,15 @@ LiveVariablesImpl::runOnBlock(const CFGB
> >        ei = block->rend(); it != ei; ++it) {
> >     const CFGElement &elem = *it;
> >
> > -    if (const CFGAutomaticObjDtor *Dtor = dyn_cast<CFGAutomaticObjDtor>(&elem)){
> > -      val.liveDecls = DSetFact.add(val.liveDecls, Dtor->getVarDecl());
> > +    if (CFGAutomaticObjDtor Dtor = elem.getAs<CFGAutomaticObjDtor>()){
> > +      val.liveDecls = DSetFact.add(val.liveDecls, Dtor.getVarDecl());
> >       continue;
> >     }
> >
> > -    if (!isa<CFGStmt>(elem))
> > +    if (!elem.getAs<CFGStmt>())
> >       continue;
> >
> > -    const Stmt *S = cast<CFGStmt>(elem).getStmt();
> > +    const Stmt *S = elem.castAs<CFGStmt>().getStmt();
> >     TF.Visit(const_cast<Stmt*>(S));
> >     stmtsToLiveness[S] = val;
> >   }
> > @@ -534,8 +534,8 @@ LiveVariables::computeLiveness(AnalysisD
> >     if (killAtAssign)
> >       for (CFGBlock::const_iterator bi = block->begin(), be = block->end();
> >            bi != be; ++bi) {
> > -        if (const CFGStmt *cs = bi->getAs<CFGStmt>()) {
> > -          if (const BinaryOperator *BO = dyn_cast<BinaryOperator>(cs->getStmt())) {
> > +        if (CFGStmt cs = bi->getAs<CFGStmt>()) {
> > +          if (const BinaryOperator *BO = dyn_cast<BinaryOperator>(cs.getStmt())) {
> >             if (BO->getOpcode() == BO_Assign) {
> >               if (const DeclRefExpr *DR =
> >                     dyn_cast<DeclRefExpr>(BO->getLHS()->IgnoreParens())) {
> >
> > Modified: cfe/trunk/lib/Analysis/ReachableCode.cpp
> > URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/ReachableCode.cpp?rev=175796&r1=175795&r2=175796&view=diff
> > ==============================================================================
> > --- cfe/trunk/lib/Analysis/ReachableCode.cpp (original)
> > +++ cfe/trunk/lib/Analysis/ReachableCode.cpp Thu Feb 21 14:58:29 2013
> > @@ -95,8 +95,8 @@ static bool isValidDeadStmt(const Stmt *
> >
> > const Stmt *DeadCodeScan::findDeadCode(const clang::CFGBlock *Block) {
> >   for (CFGBlock::const_iterator I = Block->begin(), E = Block->end(); I!=E; ++I)
> > -    if (const CFGStmt *CS = I->getAs<CFGStmt>()) {
> > -      const Stmt *S = CS->getStmt();
> > +    if (CFGStmt CS = I->getAs<CFGStmt>()) {
> > +      const Stmt *S = CS.getStmt();
> >       if (isValidDeadStmt(S))
> >         return S;
> >     }
> >
> > Modified: cfe/trunk/lib/Analysis/ThreadSafety.cpp
> > URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/ThreadSafety.cpp?rev=175796&r1=175795&r2=175796&view=diff
> > ==============================================================================
> > --- cfe/trunk/lib/Analysis/ThreadSafety.cpp (original)
> > +++ cfe/trunk/lib/Analysis/ThreadSafety.cpp Thu Feb 21 14:58:29 2013
> > @@ -1350,8 +1350,8 @@ void LocalVariableMap::traverseCFG(CFG *
> >          BE = CurrBlock->end(); BI != BE; ++BI) {
> >       switch (BI->getKind()) {
> >         case CFGElement::Statement: {
> > -          const CFGStmt *CS = cast<CFGStmt>(&*BI);
> > -          VMapBuilder.Visit(const_cast<Stmt*>(CS->getStmt()));
> > +          CFGStmt CS = BI->castAs<CFGStmt>();
> > +          VMapBuilder.Visit(const_cast<Stmt*>(CS.getStmt()));
> >           break;
> >         }
> >         default:
> > @@ -1397,8 +1397,8 @@ static void findBlockLocations(CFG *CFGr
> >       for (CFGBlock::const_reverse_iterator BI = CurrBlock->rbegin(),
> >            BE = CurrBlock->rend(); BI != BE; ++BI) {
> >         // FIXME: Handle other CFGElement kinds.
> > -        if (const CFGStmt *CS = dyn_cast<CFGStmt>(&*BI)) {
> > -          CurrBlockInfo->ExitLoc = CS->getStmt()->getLocStart();
> > +        if (CFGStmt CS = BI->getAs<CFGStmt>()) {
> > +          CurrBlockInfo->ExitLoc = CS.getStmt()->getLocStart();
> >           break;
> >         }
> >       }
> > @@ -1410,8 +1410,8 @@ static void findBlockLocations(CFG *CFGr
> >       for (CFGBlock::const_iterator BI = CurrBlock->begin(),
> >            BE = CurrBlock->end(); BI != BE; ++BI) {
> >         // FIXME: Handle other CFGElement kinds.
> > -        if (const CFGStmt *CS = dyn_cast<CFGStmt>(&*BI)) {
> > -          CurrBlockInfo->EntryLoc = CS->getStmt()->getLocStart();
> > +        if (CFGStmt CS = BI->getAs<CFGStmt>()) {
> > +          CurrBlockInfo->EntryLoc = CS.getStmt()->getLocStart();
> >           break;
> >         }
> >       }
> > @@ -2234,8 +2234,8 @@ inline bool neverReturns(const CFGBlock*
> >     return false;
> >
> >   CFGElement Last = B->back();
> > -  if (CFGStmt* S = dyn_cast<CFGStmt>(&Last)) {
> > -    if (isa<CXXThrowExpr>(S->getStmt()))
> > +  if (CFGStmt S = Last.getAs<CFGStmt>()) {
> > +    if (isa<CXXThrowExpr>(S.getStmt()))
> >       return true;
> >   }
> >   return false;
> > @@ -2444,22 +2444,22 @@ void ThreadSafetyAnalyzer::runAnalysis(A
> >          BE = CurrBlock->end(); BI != BE; ++BI) {
> >       switch (BI->getKind()) {
> >         case CFGElement::Statement: {
> > -          const CFGStmt *CS = cast<CFGStmt>(&*BI);
> > -          LocksetBuilder.Visit(const_cast<Stmt*>(CS->getStmt()));
> > +          CFGStmt CS = BI->castAs<CFGStmt>();
> > +          LocksetBuilder.Visit(const_cast<Stmt*>(CS.getStmt()));
> >           break;
> >         }
> >         // Ignore BaseDtor, MemberDtor, and TemporaryDtor for now.
> >         case CFGElement::AutomaticObjectDtor: {
> > -          const CFGAutomaticObjDtor *AD = cast<CFGAutomaticObjDtor>(&*BI);
> > -          CXXDestructorDecl *DD = const_cast<CXXDestructorDecl*>(
> > -            AD->getDestructorDecl(AC.getASTContext()));
> > +          CFGAutomaticObjDtor AD = BI->castAs<CFGAutomaticObjDtor>();
> > +          CXXDestructorDecl *DD = const_cast<CXXDestructorDecl *>(
> > +              AD.getDestructorDecl(AC.getASTContext()));
> >           if (!DD->hasAttrs())
> >             break;
> >
> >           // Create a dummy expression,
> > -          VarDecl *VD = const_cast<VarDecl*>(AD->getVarDecl());
> > +          VarDecl *VD = const_cast<VarDecl*>(AD.getVarDecl());
> >           DeclRefExpr DRE(VD, false, VD->getType(), VK_LValue,
> > -                          AD->getTriggerStmt()->getLocEnd());
> > +                          AD.getTriggerStmt()->getLocEnd());
> >           LocksetBuilder.handleCall(&DRE, DD);
> >           break;
> >         }
> >
> > Modified: cfe/trunk/lib/Analysis/UninitializedValues.cpp
> > URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/UninitializedValues.cpp?rev=175796&r1=175795&r2=175796&view=diff
> > ==============================================================================
> > --- cfe/trunk/lib/Analysis/UninitializedValues.cpp (original)
> > +++ cfe/trunk/lib/Analysis/UninitializedValues.cpp Thu Feb 21 14:58:29 2013
> > @@ -746,8 +746,8 @@ static bool runOnBlock(const CFGBlock *b
> >   TransferFunctions tf(vals, cfg, block, ac, classification, handler);
> >   for (CFGBlock::const_iterator I = block->begin(), E = block->end();
> >        I != E; ++I) {
> > -    if (const CFGStmt *cs = dyn_cast<CFGStmt>(&*I)) {
> > -      tf.Visit(const_cast<Stmt*>(cs->getStmt()));
> > +    if (CFGStmt cs = I->getAs<CFGStmt>()) {
> > +      tf.Visit(const_cast<Stmt*>(cs.getStmt()));
> >     }
> >   }
> >   return vals.updateValueVectorWithScratch(block);
> >
> > Modified: cfe/trunk/lib/Sema/AnalysisBasedWarnings.cpp
> > URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/AnalysisBasedWarnings.cpp?rev=175796&r1=175795&r2=175796&view=diff
> > ==============================================================================
> > --- cfe/trunk/lib/Sema/AnalysisBasedWarnings.cpp (original)
> > +++ cfe/trunk/lib/Sema/AnalysisBasedWarnings.cpp Thu Feb 21 14:58:29 2013
> > @@ -158,7 +158,7 @@ static ControlFlowKind CheckFallThrough(
> >     CFGBlock::const_reverse_iterator ri = B.rbegin(), re = B.rend();
> >
> >     for ( ; ri != re ; ++ri)
> > -      if (isa<CFGStmt>(*ri))
> > +      if (ri->getAs<CFGStmt>())
> >         break;
> >
> >     // No more CFGElements in the block?
> > @@ -172,7 +172,7 @@ static ControlFlowKind CheckFallThrough(
> >       continue;
> >     }
> >
> > -    CFGStmt CS = cast<CFGStmt>(*ri);
> > +    CFGStmt CS = ri->castAs<CFGStmt>();
> >     const Stmt *S = CS.getStmt();
> >     if (isa<ReturnStmt>(S)) {
> >       HasLiveReturn = true;
> > @@ -762,8 +762,8 @@ namespace {
> >           for (CFGBlock::const_reverse_iterator ElemIt = P->rbegin(),
> >                                                 ElemEnd = P->rend();
> >                ElemIt != ElemEnd; ++ElemIt) {
> > -            if (const CFGStmt *CS = ElemIt->getAs<CFGStmt>()) {
> > -              if (const AttributedStmt *AS = asFallThroughAttr(CS->getStmt())) {
> > +            if (CFGStmt CS = ElemIt->getAs<CFGStmt>()) {
> > +              if (const AttributedStmt *AS = asFallThroughAttr(CS.getStmt())) {
> >                 S.Diag(AS->getLocStart(),
> >                        diag::warn_fallthrough_attr_unreachable);
> >                 markFallthroughVisited(AS);
> > @@ -833,8 +833,8 @@ namespace {
> >       for (CFGBlock::const_reverse_iterator ElemIt = B.rbegin(),
> >                                             ElemEnd = B.rend();
> >                                             ElemIt != ElemEnd; ++ElemIt) {
> > -        if (const CFGStmt *CS = ElemIt->getAs<CFGStmt>())
> > -          return CS->getStmt();
> > +        if (CFGStmt CS = ElemIt->getAs<CFGStmt>())
> > +          return CS.getStmt();
> >       }
> >       // Workaround to detect a statement thrown out by CFGBuilder:
> >       //   case X: {} case Y:
> >
> > Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/AnalyzerStatsChecker.cpp
> > URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/AnalyzerStatsChecker.cpp?rev=175796&r1=175795&r2=175796&view=diff
> > ==============================================================================
> > --- cfe/trunk/lib/StaticAnalyzer/Checkers/AnalyzerStatsChecker.cpp (original)
> > +++ cfe/trunk/lib/StaticAnalyzer/Checkers/AnalyzerStatsChecker.cpp Thu Feb 21 14:58:29 2013
> > @@ -123,13 +123,13 @@ void AnalyzerStatsChecker::checkEndAnaly
> >     const BlockEdge &BE =  I->first;
> >     const CFGBlock *Exit = BE.getDst();
> >     const CFGElement &CE = Exit->front();
> > -    if (const CFGStmt *CS = dyn_cast<CFGStmt>(&CE)) {
> > +    if (CFGStmt CS = CE.getAs<CFGStmt>()) {
> >       SmallString<128> bufI;
> >       llvm::raw_svector_ostream outputI(bufI);
> >       outputI << "(" << NameOfRootFunction << ")" <<
> >                  ": The analyzer generated a sink at this point";
> >       B.EmitBasicReport(D, "Sink Point", "Internal Statistics", outputI.str(),
> > -                        PathDiagnosticLocation::createBegin(CS->getStmt(),
> > +                        PathDiagnosticLocation::createBegin(CS.getStmt(),
> >                                                             SM, LC));
> >     }
> >   }
> >
> > Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/MallocOverflowSecurityChecker.cpp
> > URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/MallocOverflowSecurityChecker.cpp?rev=175796&r1=175795&r2=175796&view=diff
> > ==============================================================================
> > --- cfe/trunk/lib/StaticAnalyzer/Checkers/MallocOverflowSecurityChecker.cpp (original)
> > +++ cfe/trunk/lib/StaticAnalyzer/Checkers/MallocOverflowSecurityChecker.cpp Thu Feb 21 14:58:29 2013
> > @@ -236,8 +236,8 @@ void MallocOverflowSecurityChecker::chec
> >     CFGBlock *block = *it;
> >     for (CFGBlock::iterator bi = block->begin(), be = block->end();
> >          bi != be; ++bi) {
> > -      if (const CFGStmt *CS = bi->getAs<CFGStmt>()) {
> > -        if (const CallExpr *TheCall = dyn_cast<CallExpr>(CS->getStmt())) {
> > +      if (CFGStmt CS = bi->getAs<CFGStmt>()) {
> > +        if (const CallExpr *TheCall = dyn_cast<CallExpr>(CS.getStmt())) {
> >           // Get the callee.
> >           const FunctionDecl *FD = TheCall->getDirectCallee();
> >
> >
> > Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/UnreachableCodeChecker.cpp
> > URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/UnreachableCodeChecker.cpp?rev=175796&r1=175795&r2=175796&view=diff
> > ==============================================================================
> > --- cfe/trunk/lib/StaticAnalyzer/Checkers/UnreachableCodeChecker.cpp (original)
> > +++ cfe/trunk/lib/StaticAnalyzer/Checkers/UnreachableCodeChecker.cpp Thu Feb 21 14:58:29 2013
> > @@ -131,8 +131,8 @@ void UnreachableCodeChecker::checkEndAna
> >       bool foundUnreachable = false;
> >       for (CFGBlock::const_iterator ci = CB->begin(), ce = CB->end();
> >            ci != ce; ++ci) {
> > -        if (const CFGStmt *S = (*ci).getAs<CFGStmt>())
> > -          if (const CallExpr *CE = dyn_cast<CallExpr>(S->getStmt())) {
> > +        if (CFGStmt S = (*ci).getAs<CFGStmt>())
> > +          if (const CallExpr *CE = dyn_cast<CallExpr>(S.getStmt())) {
> >             if (CE->isBuiltinCall() == Builtin::BI__builtin_unreachable) {
> >               foundUnreachable = true;
> >               break;
> > @@ -189,8 +189,8 @@ void UnreachableCodeChecker::FindUnreach
> > // 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 (const CFGStmt *S = I->getAs<CFGStmt>())
> > -      return S->getStmt();
> > +    if (CFGStmt S = I->getAs<CFGStmt>())
> > +      return S.getStmt();
> >   }
> >   if (const Stmt *S = CB->getTerminator())
> >     return S;
> >
> > Modified: cfe/trunk/lib/StaticAnalyzer/Core/BugReporter.cpp
> > URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/BugReporter.cpp?rev=175796&r1=175795&r2=175796&view=diff
> > ==============================================================================
> > --- cfe/trunk/lib/StaticAnalyzer/Core/BugReporter.cpp (original)
> > +++ cfe/trunk/lib/StaticAnalyzer/Core/BugReporter.cpp Thu Feb 21 14:58:29 2013
> > @@ -1482,8 +1482,8 @@ static bool GenerateExtensivePathDiagnos
> >
> >       if (const BlockEntrance *BE = dyn_cast<BlockEntrance>(&P)) {
> >         CFGElement First = BE->getFirstElement();
> > -        if (const CFGStmt *S = First.getAs<CFGStmt>()) {
> > -          const Stmt *stmt = S->getStmt();
> > +        if (CFGStmt S = First.getAs<CFGStmt>()) {
> > +          const Stmt *stmt = S.getStmt();
> >           if (IsControlFlowExpr(stmt)) {
> >             // Add the proper context for '&&', '||', and '?'.
> >             EB.addContext(stmt);
> >
> > Modified: cfe/trunk/lib/StaticAnalyzer/Core/CallEvent.cpp
> > URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/CallEvent.cpp?rev=175796&r1=175795&r2=175796&view=diff
> > ==============================================================================
> > --- cfe/trunk/lib/StaticAnalyzer/Core/CallEvent.cpp (original)
> > +++ cfe/trunk/lib/StaticAnalyzer/Core/CallEvent.cpp Thu Feb 21 14:58:29 2013
> > @@ -961,8 +961,9 @@ CallEventManager::getCaller(const StackF
> >   // destructors, though this could change in the future.
> >   const CFGBlock *B = CalleeCtx->getCallSiteBlock();
> >   CFGElement E = (*B)[CalleeCtx->getIndex()];
> > -  assert(isa<CFGImplicitDtor>(E) && "All other CFG elements should have exprs");
> > -  assert(!isa<CFGTemporaryDtor>(E) && "We don't handle temporaries yet");
> > +  assert(E.getAs<CFGImplicitDtor>() &&
> > +         "All other CFG elements should have exprs");
> > +  assert(!E.getAs<CFGTemporaryDtor>() && "We don't handle temporaries yet");
> >
> >   SValBuilder &SVB = State->getStateManager().getSValBuilder();
> >   const CXXDestructorDecl *Dtor = cast<CXXDestructorDecl>(CalleeCtx->getDecl());
> > @@ -970,11 +971,11 @@ CallEventManager::getCaller(const StackF
> >   SVal ThisVal = State->getSVal(ThisPtr);
> >
> >   const Stmt *Trigger;
> > -  if (const CFGAutomaticObjDtor *AutoDtor = dyn_cast<CFGAutomaticObjDtor>(&E))
> > -    Trigger = AutoDtor->getTriggerStmt();
> > +  if (CFGAutomaticObjDtor AutoDtor = E.getAs<CFGAutomaticObjDtor>())
> > +    Trigger = AutoDtor.getTriggerStmt();
> >   else
> >     Trigger = Dtor->getBody();
> >
> >   return getCXXDestructorCall(Dtor, Trigger, ThisVal.getAsRegion(),
> > -                              isa<CFGBaseDtor>(E), State, CallerCtx);
> > +                              E.getAs<CFGBaseDtor>(), State, CallerCtx);
> > }
> >
> > Modified: cfe/trunk/lib/StaticAnalyzer/Core/CoreEngine.cpp
> > URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/CoreEngine.cpp?rev=175796&r1=175795&r2=175796&view=diff
> > ==============================================================================
> > --- cfe/trunk/lib/StaticAnalyzer/Core/CoreEngine.cpp (original)
> > +++ cfe/trunk/lib/StaticAnalyzer/Core/CoreEngine.cpp Thu Feb 21 14:58:29 2013
> > @@ -515,7 +515,7 @@ void CoreEngine::enqueueStmtNode(Explode
> >   }
> >
> >   // At this point, we know we're processing a normal statement.
> > -  CFGStmt CS = cast<CFGStmt>((*Block)[Idx]);
> > +  CFGStmt CS = (*Block)[Idx].castAs<CFGStmt>();
> >   PostStmt Loc(CS.getStmt(), N->getLocationContext());
> >
> >   if (Loc == N->getLocation()) {
> >
> > Modified: cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp
> > URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp?rev=175796&r1=175795&r2=175796&view=diff
> > ==============================================================================
> > --- cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp (original)
> > +++ cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp Thu Feb 21 14:58:29 2013
> > @@ -225,16 +225,16 @@ void ExprEngine::processCFGElement(const
> >     case CFGElement::Invalid:
> >       llvm_unreachable("Unexpected CFGElement kind.");
> >     case CFGElement::Statement:
> > -      ProcessStmt(const_cast<Stmt*>(E.getAs<CFGStmt>()->getStmt()), Pred);
> > +      ProcessStmt(const_cast<Stmt*>(E.castAs<CFGStmt>().getStmt()), Pred);
> >       return;
> >     case CFGElement::Initializer:
> > -      ProcessInitializer(E.getAs<CFGInitializer>()->getInitializer(), Pred);
> > +      ProcessInitializer(E.castAs<CFGInitializer>().getInitializer(), Pred);
> >       return;
> >     case CFGElement::AutomaticObjectDtor:
> >     case CFGElement::BaseDtor:
> >     case CFGElement::MemberDtor:
> >     case CFGElement::TemporaryDtor:
> > -      ProcessImplicitDtor(*E.getAs<CFGImplicitDtor>(), Pred);
> > +      ProcessImplicitDtor(E.castAs<CFGImplicitDtor>(), Pred);
> >       return;
> >   }
> >   currBldrCtx = 0;
> > @@ -440,16 +440,16 @@ void ExprEngine::ProcessImplicitDtor(con
> >   ExplodedNodeSet Dst;
> >   switch (D.getKind()) {
> >   case CFGElement::AutomaticObjectDtor:
> > -    ProcessAutomaticObjDtor(cast<CFGAutomaticObjDtor>(D), Pred, Dst);
> > +    ProcessAutomaticObjDtor(D.castAs<CFGAutomaticObjDtor>(), Pred, Dst);
> >     break;
> >   case CFGElement::BaseDtor:
> > -    ProcessBaseDtor(cast<CFGBaseDtor>(D), Pred, Dst);
> > +    ProcessBaseDtor(D.castAs<CFGBaseDtor>(), Pred, Dst);
> >     break;
> >   case CFGElement::MemberDtor:
> > -    ProcessMemberDtor(cast<CFGMemberDtor>(D), Pred, Dst);
> > +    ProcessMemberDtor(D.castAs<CFGMemberDtor>(), Pred, Dst);
> >     break;
> >   case CFGElement::TemporaryDtor:
> > -    ProcessTemporaryDtor(cast<CFGTemporaryDtor>(D), Pred, Dst);
> > +    ProcessTemporaryDtor(D.castAs<CFGTemporaryDtor>(), Pred, Dst);
> >     break;
> >   default:
> >     llvm_unreachable("Unexpected dtor kind.");
> > @@ -1200,10 +1200,10 @@ static const Stmt *ResolveCondition(cons
> >   CFGBlock::const_reverse_iterator I = B->rbegin(), E = B->rend();
> >   for (; I != E; ++I) {
> >     CFGElement Elem = *I;
> > -    CFGStmt *CS = dyn_cast<CFGStmt>(&Elem);
> > +    CFGStmt CS = Elem.getAs<CFGStmt>();
> >     if (!CS)
> >       continue;
> > -    if (CS->getStmt() != Condition)
> > +    if (CS.getStmt() != Condition)
> >       break;
> >     return Condition;
> >   }
> >
> > Modified: cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineC.cpp
> > URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineC.cpp?rev=175796&r1=175795&r2=175796&view=diff
> > ==============================================================================
> > --- cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineC.cpp (original)
> > +++ cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineC.cpp Thu Feb 21 14:58:29 2013
> > @@ -554,7 +554,7 @@ void ExprEngine::VisitLogicalExpr(const
> >     // in SrcBlock is the value of the enclosing expression.
> >     // However, we still need to constrain that value to be 0 or 1.
> >     assert(!SrcBlock->empty());
> > -    CFGStmt Elem = cast<CFGStmt>(*SrcBlock->rbegin());
> > +    CFGStmt Elem = SrcBlock->rbegin()->castAs<CFGStmt>();
> >     const Expr *RHS = cast<Expr>(Elem.getStmt());
> >     SVal RHSVal = N->getState()->getSVal(RHS, Pred->getLocationContext());
> >
> > @@ -659,8 +659,8 @@ void ExprEngine::VisitGuardedExpr(const
> >   for (CFGBlock::const_reverse_iterator I = SrcBlock->rbegin(),
> >                                         E = SrcBlock->rend(); I != E; ++I) {
> >     CFGElement CE = *I;
> > -    if (CFGStmt *CS = dyn_cast<CFGStmt>(&CE)) {
> > -      const Expr *ValEx = cast<Expr>(CS->getStmt());
> > +    if (CFGStmt CS = CE.getAs<CFGStmt>()) {
> > +      const Expr *ValEx = cast<Expr>(CS.getStmt());
> >       hasValue = true;
> >       V = state->getSVal(ValEx, LCtx);
> >       break;
> >
> > Modified: cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
> > URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp?rev=175796&r1=175795&r2=175796&view=diff
> > ==============================================================================
> > --- cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp (original)
> > +++ cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp Thu Feb 21 14:58:29 2013
> > @@ -96,8 +96,8 @@ void ExprEngine::VisitCXXConstructExpr(c
> >       CFGElement Next = (*B)[currStmtIdx+1];
> >
> >       // Is this a constructor for a local variable?
> > -      if (const CFGStmt *StmtElem = dyn_cast<CFGStmt>(&Next)) {
> > -        if (const DeclStmt *DS = dyn_cast<DeclStmt>(StmtElem->getStmt())) {
> > +      if (CFGStmt StmtElem = Next.getAs<CFGStmt>()) {
> > +        if (const DeclStmt *DS = dyn_cast<DeclStmt>(StmtElem.getStmt())) {
> >           if (const VarDecl *Var = dyn_cast<VarDecl>(DS->getSingleDecl())) {
> >             if (Var->getInit()->IgnoreImplicit() == CE) {
> >               QualType Ty = Var->getType();
> > @@ -119,8 +119,8 @@ void ExprEngine::VisitCXXConstructExpr(c
> >       }
> >
> >       // Is this a constructor for a member?
> > -      if (const CFGInitializer *InitElem = dyn_cast<CFGInitializer>(&Next)) {
> > -        const CXXCtorInitializer *Init = InitElem->getInitializer();
> > +      if (CFGInitializer InitElem = Next.getAs<CFGInitializer>()) {
> > +        const CXXCtorInitializer *Init = InitElem.getInitializer();
> >         assert(Init->isAnyMemberInitializer());
> >
> >         const CXXMethodDecl *CurCtor = cast<CXXMethodDecl>(LCtx->getDecl());
> >
> > Modified: cfe/trunk/lib/StaticAnalyzer/Core/PathDiagnostic.cpp
> > URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/PathDiagnostic.cpp?rev=175796&r1=175795&r2=175796&view=diff
> > ==============================================================================
> > --- cfe/trunk/lib/StaticAnalyzer/Core/PathDiagnostic.cpp (original)
> > +++ cfe/trunk/lib/StaticAnalyzer/Core/PathDiagnostic.cpp Thu Feb 21 14:58:29 2013
> > @@ -479,15 +479,15 @@ getLocationForCaller(const StackFrameCon
> >   case CFGElement::Invalid:
> >     llvm_unreachable("Invalid CFGElement");
> >   case CFGElement::Statement:
> > -    return PathDiagnosticLocation(cast<CFGStmt>(Source).getStmt(),
> > +    return PathDiagnosticLocation(Source.castAs<CFGStmt>().getStmt(),
> >                                   SM, CallerCtx);
> >   case CFGElement::Initializer: {
> > -    const CFGInitializer &Init = cast<CFGInitializer>(Source);
> > +    const CFGInitializer &Init = Source.castAs<CFGInitializer>();
> >     return PathDiagnosticLocation(Init.getInitializer()->getInit(),
> >                                   SM, CallerCtx);
> >   }
> >   case CFGElement::AutomaticObjectDtor: {
> > -    const CFGAutomaticObjDtor &Dtor = cast<CFGAutomaticObjDtor>(Source);
> > +    const CFGAutomaticObjDtor &Dtor = Source.castAs<CFGAutomaticObjDtor>();
> >     return PathDiagnosticLocation::createEnd(Dtor.getTriggerStmt(),
> >                                              SM, CallerCtx);
> >   }
> >
> >
> > _______________________________________________
> > cfe-commits mailing list
> > cfe-commits at cs.uiuc.edu
> > http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
> 
> 

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20130222/f710b3d5/attachment.html>


More information about the cfe-commits mailing list