<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
diff --git a/lib/Sema/SemaStmt.cpp b/lib/Sema/SemaStmt.cpp
index dea01d5..b3558a5 100644
--- a/lib/Sema/SemaStmt.cpp
+++ b/lib/Sema/SemaStmt.cpp
@@ -76,10 +76,23 @@
 
 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;
 
-  // If we have an invalid decl, just return.
-  if (DG.isNull() || !DG.isSingleDecl()) return;
-  VarDecl *var = cast<VarDecl>(DG.getSingleDecl());
+  Decl *decl = DG.getSingleDecl();
+  if (!decl || decl->isInvalidDecl())
+    return;
+
+  // 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 @@
         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 @@
         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()) {