From 4058d87ad560c4c82852562e1d08474777540d3f Mon Sep 17 00:00:00 2001 From: Ted Kremenek Date: Thu, 27 Jan 2011 02:01:31 +0000 Subject: Teach -Wuninitialized about ObjC fast enumeration loops. llvm-svn: 124347 --- clang/lib/Analysis/UninitializedValuesV2.cpp | 47 ++++++++++++++++++++++------ 1 file changed, 38 insertions(+), 9 deletions(-) (limited to 'clang/lib/Analysis/UninitializedValuesV2.cpp') diff --git a/clang/lib/Analysis/UninitializedValuesV2.cpp b/clang/lib/Analysis/UninitializedValuesV2.cpp index 32630549599..71a62f7e19f 100644 --- a/clang/lib/Analysis/UninitializedValuesV2.cpp +++ b/clang/lib/Analysis/UninitializedValuesV2.cpp @@ -311,6 +311,7 @@ public: void VisitBinaryOperator(BinaryOperator *bo); void VisitCastExpr(CastExpr *ce); void VisitSizeOfAlignOfExpr(SizeOfAlignOfExpr *se); + void BlockStmt_VisitObjCForCollectionStmt(ObjCForCollectionStmt *fs); }; } @@ -319,6 +320,43 @@ void TransferFunctions::reportUninit(const DeclRefExpr *ex, if (handler) handler->handleUseOfUninitVariable(ex, vd); } +static FindVarResult findBlockVarDecl(Expr* ex) { + if (DeclRefExpr* dr = dyn_cast(ex->IgnoreParenCasts())) + if (VarDecl *vd = dyn_cast(dr->getDecl())) + if (isTrackedVar(vd)) + return FindVarResult(vd, dr); + + return FindVarResult(0, 0); +} + +void TransferFunctions::BlockStmt_VisitObjCForCollectionStmt( + ObjCForCollectionStmt *fs) { + + Visit(fs->getCollection()); + + // This represents an initialization of the 'element' value. + Stmt *element = fs->getElement(); + const VarDecl* vd = 0; + + if (DeclStmt* ds = dyn_cast(element)) { + vd = cast(ds->getSingleDecl()); + if (!isTrackedVar(vd)) + vd = 0; + } + else { + // Initialize the value of the reference variable. + const FindVarResult &res = findBlockVarDecl(cast(element)); + vd = res.getDecl(); + if (!vd) { + Visit(element); + return; + } + } + + if (vd) + vals[vd] = Initialized; +} + void TransferFunctions::VisitBlockExpr(BlockExpr *be) { if (!flagBlockUses || !handler) return; @@ -366,15 +404,6 @@ void TransferFunctions::VisitDeclRefExpr(DeclRefExpr *dr) { vals[vd] = Initialized; } -static FindVarResult findBlockVarDecl(Expr* ex) { - if (DeclRefExpr* dr = dyn_cast(ex->IgnoreParenCasts())) - if (VarDecl *vd = dyn_cast(dr->getDecl())) - if (isTrackedVar(vd)) - return FindVarResult(vd, dr); - - return FindVarResult(0, 0); -} - void TransferFunctions::VisitBinaryOperator(clang::BinaryOperator *bo) { if (bo->isAssignmentOp()) { const FindVarResult &res = findBlockVarDecl(bo->getLHS()); -- cgit v1.2.3