зеркало из https://github.com/microsoft/clang-1.git
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:
Родитель
fd1a8fd240
Коммит
1ea800c4ca
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
Загрузка…
Ссылка в новой задаче