diff options
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()) { |