]> granicus.if.org Git - clang/commitdiff
Fix a problem with objc foreach loop. It turns out that objc mode changes
authorChris Lattner <sabre@nondot.org>
Wed, 22 Apr 2009 00:54:41 +0000 (00:54 +0000)
committerChris Lattner <sabre@nondot.org>
Wed, 22 Apr 2009 00:54:41 +0000 (00:54 +0000)
for scoping to match C99 even when in C89 mode.  This patch fixes this
(eliminating a "redefinition of thisKey" error), and also prevents non-sensical
diagnostics in -pedantic mode like this:

t.m:7:8: warning: variable declaration in for loop is a C99-specific feature
  for (id thisKey in keys) ;
       ^

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@69760 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Parse/ParseStmt.cpp
test/SemaObjC/foreach-1.m

index b87ede9388dbeb5d37d2fdef98d71d889a24e309..fa712e0a9eb3fc89b594d5ea20caf881f4dafd41 100644 (file)
@@ -867,7 +867,7 @@ Parser::OwningStmtResult Parser::ParseForStatement() {
     return StmtError();
   }
 
-  bool C99orCXX = getLang().C99 || getLang().CPlusPlus;
+  bool C99orCXXorObjC = getLang().C99 || getLang().CPlusPlus || getLang().ObjC1;
 
   // C99 6.8.5p5 - In C99, the for statement is a block.  This is not
   // the case for C90.  Start the loop scope.
@@ -885,7 +885,7 @@ Parser::OwningStmtResult Parser::ParseForStatement() {
   // as those declared in the condition.
   //
   unsigned ScopeFlags;
-  if (C99orCXX)
+  if (C99orCXXorObjC)
     ScopeFlags = Scope::BreakScope | Scope::ContinueScope |
                  Scope::DeclScope  | Scope::ControlScope;
   else
@@ -906,7 +906,7 @@ Parser::OwningStmtResult Parser::ParseForStatement() {
     ConsumeToken();
   } else if (isSimpleDeclaration()) {  // for (int X = 4;
     // Parse declaration, which eats the ';'.
-    if (!C99orCXX)   // Use of C99-style for loops in C90 mode?
+    if (!C99orCXXorObjC)   // Use of C99-style for loops in C90 mode?
       Diag(Tok, diag::ext_c99_variable_decl_in_for_loop);
 
     SourceLocation DeclStart = Tok.getLocation(), DeclEnd;
@@ -976,7 +976,7 @@ Parser::OwningStmtResult Parser::ParseForStatement() {
   // for-init-statement/condition and a new scope for substatement in C++.
   //
   ParseScope InnerScope(this, Scope::DeclScope, 
-                        C99orCXX && Tok.isNot(tok::l_brace));
+                        C99orCXXorObjC && Tok.isNot(tok::l_brace));
 
   // Read the body statement.
   OwningStmtResult Body(ParseStatement());
index d3ca424a0460ab5478c61694fdc68ac01f3103f1..f136adfa363b04df400c2f217eb38142636d4678 100644 (file)
@@ -1,10 +1,18 @@
-// RUN: clang-cc -fsyntax-only -verify %s
+/* RUN: clang-cc -fsyntax-only -verify -std=c89 -pedantic %s
+ */
 
 @class NSArray;
 
-void f(NSArray *a)
-{
-    for (int i in a); // expected-error{{selector element type 'int' is not a valid object}}
-    for ((id)2 in a); // expected-error{{selector element is not a valid lvalue}}
-    for (2 in a); // expected-error{{selector element is not a valid lvalue}}
+void f(NSArray *a) {
+    id keys;
+    for (int i in a); /* expected-error{{selector element type 'int' is not a valid object}} */
+    for ((id)2 in a); /* expected-error{{selector element is not a valid lvalue}} */
+    for (2 in a); /* expected-error{{selector element is not a valid lvalue}} */
+  
+  /* This should be ok, 'thisKey' should be scoped to the loop in question,
+   * and no diagnostics even in pedantic mode should happen.
+   * rdar://6814674
+   */
+  for (id thisKey in keys);
+  for (id thisKey in keys);
 }