Teach -Wuninitialized about ObjC fast enumeration loops.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@124347 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Ted Kremenek 2011-01-27 02:01:31 +00:00
Родитель fd1a8fd240
Коммит 1ea800c4ca
2 изменённых файлов: 65 добавлений и 9 удалений

Просмотреть файл

@ -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());

Просмотреть файл

@ -0,0 +1,27 @@
// 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;
}
}