diff options
Diffstat (limited to 'lib/StaticAnalyzer/Core/ExprEngine.cpp')
-rw-r--r-- | lib/StaticAnalyzer/Core/ExprEngine.cpp | 47 |
1 files changed, 40 insertions, 7 deletions
diff --git a/lib/StaticAnalyzer/Core/ExprEngine.cpp b/lib/StaticAnalyzer/Core/ExprEngine.cpp index aed39eb0ce..21efbac699 100644 --- a/lib/StaticAnalyzer/Core/ExprEngine.cpp +++ b/lib/StaticAnalyzer/Core/ExprEngine.cpp @@ -442,7 +442,8 @@ void ExprEngine::Visit(const Stmt* S, ExplodedNode* Pred, } switch (S->getStmtClass()) { - // C++ stuff we don't support yet. + // C++ and ARC stuff we don't support yet. + case Expr::ObjCIndirectCopyRestoreExprClass: case Stmt::CXXBindTemporaryExprClass: case Stmt::CXXCatchStmtClass: case Stmt::CXXDependentScopeMemberExprClass: @@ -520,14 +521,27 @@ void ExprEngine::Visit(const Stmt* S, ExplodedNode* Pred, VisitObjCPropertyRefExpr(cast<ObjCPropertyRefExpr>(S), Pred, Dst); break; + case Stmt::ImplicitValueInitExprClass: { + const GRState *state = GetState(Pred); + QualType ty = cast<ImplicitValueInitExpr>(S)->getType(); + SVal val = svalBuilder.makeZeroVal(ty); + MakeNode(Dst, S, Pred, state->BindExpr(S, val)); + break; + } + + case Stmt::ExprWithCleanupsClass: { + Visit(cast<ExprWithCleanups>(S)->getSubExpr(), Pred, Dst); + break; + } + // Cases not handled yet; but will handle some day. case Stmt::DesignatedInitExprClass: case Stmt::ExtVectorElementExprClass: case Stmt::ImaginaryLiteralClass: - case Stmt::ImplicitValueInitExprClass: case Stmt::ObjCAtCatchStmtClass: case Stmt::ObjCAtFinallyStmtClass: case Stmt::ObjCAtTryStmtClass: + case Stmt::ObjCAutoreleasePoolStmtClass: case Stmt::ObjCEncodeExprClass: case Stmt::ObjCIsaExprClass: case Stmt::ObjCProtocolExprClass: @@ -548,7 +562,6 @@ void ExprEngine::Visit(const Stmt* S, ExplodedNode* Pred, case Stmt::IntegerLiteralClass: case Stmt::CharacterLiteralClass: case Stmt::CXXBoolLiteralExprClass: - case Stmt::ExprWithCleanupsClass: case Stmt::FloatingLiteralClass: case Stmt::SizeOfPackExprClass: case Stmt::CXXNullPtrLiteralExprClass: @@ -668,9 +681,22 @@ void ExprEngine::Visit(const Stmt* S, ExplodedNode* Pred, case Stmt::CXXDynamicCastExprClass: case Stmt::CXXReinterpretCastExprClass: case Stmt::CXXConstCastExprClass: - case Stmt::CXXFunctionalCastExprClass: { + case Stmt::CXXFunctionalCastExprClass: + case Stmt::ObjCBridgedCastExprClass: { const CastExpr* C = cast<CastExpr>(S); - VisitCast(C, C->getSubExpr(), Pred, Dst); + // Handle the previsit checks. + ExplodedNodeSet dstPrevisit; + getCheckerManager().runCheckersForPreStmt(dstPrevisit, Pred, C, *this); + + // Handle the expression itself. + ExplodedNodeSet dstExpr; + for (ExplodedNodeSet::iterator i = dstPrevisit.begin(), + e = dstPrevisit.end(); i != e ; ++i) { + VisitCast(C, C->getSubExpr(), *i, dstExpr); + } + + // Handle the postvisit checks. + getCheckerManager().runCheckersForPostStmt(Dst, dstExpr, C, *this); break; } @@ -2148,10 +2174,18 @@ void ExprEngine::VisitCast(const CastExpr *CastE, const Expr *Ex, Pred = *I; switch (CastE->getCastKind()) { + case CK_LValueToRValue: + assert(false && "LValueToRValue casts handled earlier."); + case CK_GetObjCProperty: + assert(false && "GetObjCProperty casts handled earlier."); case CK_ToVoid: Dst.Add(Pred); continue; - case CK_LValueToRValue: + // The analyzer doesn't do anything special with these casts, + // since it understands retain/release semantics already. + case CK_ObjCProduceObject: + case CK_ObjCConsumeObject: // Fall-through. + // True no-ops. case CK_NoOp: case CK_FunctionToPointerDecay: { // Copy the SVal of Ex to CastE. @@ -2161,7 +2195,6 @@ void ExprEngine::VisitCast(const CastExpr *CastE, const Expr *Ex, MakeNode(Dst, CastE, Pred, state); continue; } - case CK_GetObjCProperty: case CK_Dependent: case CK_ArrayToPointerDecay: case CK_BitCast: |