void VisitBinaryOperator(BinaryOperator *bo);
void VisitCastExpr(CastExpr *ce);
void VisitSizeOfAlignOfExpr(SizeOfAlignOfExpr *se);
+ void BlockStmt_VisitObjCForCollectionStmt(ObjCForCollectionStmt *fs);
};
}
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;
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());
--- /dev/null
+// RUN: %clang_cc1 -fsyntax-only -Wuninitialized -fsyntax-only -fblocks %s -verify
+
+// Duplicated from uninit-variables.c.
+// Test just to ensure the analysis is working.
+int test1() {
+ int x; // expected-warning{{use of uninitialized variable 'x'}} expected-note{{add initialization to silence this warning}}
+ return x; // expected-note{{variable 'x' is possibly uninitialized when used here}}
+}
+
+// Test ObjC fast enumeration.
+void test2() {
+ id collection = 0;
+ for (id obj in collection) {
+ if (0 == obj) // no-warning
+ break;
+ }
+}
+
+void test3() {
+ id collection = 0;
+ id obj;
+ for (obj in collection) { // no-warning
+ if (0 == obj) // no-warning
+ break;
+ }
+}
+