diff options
author | Douglas Gregor <dgregor@apple.com> | 2013-04-08 20:52:24 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2013-04-08 20:52:24 +0000 |
commit | 12849d0ed2e88f8c6420944538b9c9d1985df14a (patch) | |
tree | b8cb3c2b466262a6c379075c5332db794c04bbff /lib/Sema/SemaStmt.cpp | |
parent | d83cdd61341ec95c0954687ad387f1175cc2d7bd (diff) |
<rdar://problem/13540921> Fix a crasher when an Objective-C for-in loop gets a non-variable iteration declaration.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@179053 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaStmt.cpp')
-rw-r--r-- | lib/Sema/SemaStmt.cpp | 33 |
1 files changed, 25 insertions, 8 deletions
diff --git a/lib/Sema/SemaStmt.cpp b/lib/Sema/SemaStmt.cpp index dea01d5be2..b3558a548b 100644 --- a/lib/Sema/SemaStmt.cpp +++ b/lib/Sema/SemaStmt.cpp @@ -76,10 +76,23 @@ StmtResult Sema::ActOnDeclStmt(DeclGroupPtrTy dg, SourceLocation StartLoc, void Sema::ActOnForEachDeclStmt(DeclGroupPtrTy dg) { DeclGroupRef DG = dg.getAsVal<DeclGroupRef>(); + + // If we don't have a declaration, or we have an invalid declaration, + // just return. + if (DG.isNull() || !DG.isSingleDecl()) + return; + + Decl *decl = DG.getSingleDecl(); + if (!decl || decl->isInvalidDecl()) + return; - // If we have an invalid decl, just return. - if (DG.isNull() || !DG.isSingleDecl()) return; - VarDecl *var = cast<VarDecl>(DG.getSingleDecl()); + // Only variable declarations are permitted. + VarDecl *var = dyn_cast<VarDecl>(decl); + if (!var) { + Diag(decl->getLocation(), diag::err_non_variable_decl_in_for); + decl->setInvalidDecl(); + return; + } // suppress any potential 'unused variable' warning. var->setUsed(); @@ -1426,9 +1439,10 @@ Sema::ActOnForStmt(SourceLocation ForLoc, SourceLocation LParenLoc, VarDecl *VD = dyn_cast<VarDecl>(*DI); if (VD && VD->isLocalVarDecl() && !VD->hasLocalStorage()) VD = 0; - if (VD == 0) - Diag((*DI)->getLocation(), diag::err_non_variable_decl_in_for); - // FIXME: mark decl erroneous! + if (VD == 0) { + Diag((*DI)->getLocation(), diag::err_non_local_variable_decl_in_for); + (*DI)->setInvalidDecl(); + } } } } @@ -1562,14 +1576,17 @@ Sema::ActOnObjCForCollectionStmt(SourceLocation ForLoc, return StmtError(Diag((*DS->decl_begin())->getLocation(), diag::err_toomany_element_decls)); - VarDecl *D = cast<VarDecl>(DS->getSingleDecl()); + VarDecl *D = dyn_cast<VarDecl>(DS->getSingleDecl()); + if (!D || D->isInvalidDecl()) + return StmtError(); + FirstType = D->getType(); // C99 6.8.5p3: The declaration part of a 'for' statement shall only // declare identifiers for objects having storage class 'auto' or // 'register'. if (!D->hasLocalStorage()) return StmtError(Diag(D->getLocation(), - diag::err_non_variable_decl_in_for)); + diag::err_non_local_variable_decl_in_for)); // If the type contained 'auto', deduce the 'auto' to 'id'. if (FirstType->getContainedAutoType()) { |