diff options
author | Ted Kremenek <kremenek@apple.com> | 2011-01-27 02:01:31 +0000 |
---|---|---|
committer | Ted Kremenek <kremenek@apple.com> | 2011-01-27 02:01:31 +0000 |
commit | 1ea800c4ca76d5bb41aa8a1e0a6c7628b9fff28d (patch) | |
tree | fbbbadb6dcf619f230ddd73ec6fa1d5254bdcd2d /lib/Analysis/UninitializedValuesV2.cpp | |
parent | fd1a8fd240c8067e286e3881aac2bd8b700517d3 (diff) |
Teach -Wuninitialized about ObjC fast enumeration loops.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@124347 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Analysis/UninitializedValuesV2.cpp')
-rw-r--r-- | lib/Analysis/UninitializedValuesV2.cpp | 47 |
1 files changed, 38 insertions, 9 deletions
diff --git a/lib/Analysis/UninitializedValuesV2.cpp b/lib/Analysis/UninitializedValuesV2.cpp index 3263054959..71a62f7e19 100644 --- a/lib/Analysis/UninitializedValuesV2.cpp +++ b/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<DeclRefExpr>(ex->IgnoreParenCasts())) + if (VarDecl *vd = dyn_cast<VarDecl>(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<DeclStmt>(element)) { + vd = cast<VarDecl>(ds->getSingleDecl()); + if (!isTrackedVar(vd)) + vd = 0; + } + else { + // Initialize the value of the reference variable. + const FindVarResult &res = findBlockVarDecl(cast<Expr>(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<DeclRefExpr>(ex->IgnoreParenCasts())) - if (VarDecl *vd = dyn_cast<VarDecl>(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()); |