]> granicus.if.org Git - clang/commitdiff
now that all the infrastructure is in place, enforce C99 6.8.5p3.
authorChris Lattner <sabre@nondot.org>
Tue, 28 Aug 2007 05:03:08 +0000 (05:03 +0000)
committerChris Lattner <sabre@nondot.org>
Tue, 28 Aug 2007 05:03:08 +0000 (05:03 +0000)
Note the FIXME: we need some way to mark a decl erroneous :)

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

Sema/SemaStmt.cpp
include/clang/Basic/DiagnosticKinds.def
test/Sema/for.c [new file with mode: 0644]

index 5b4be815c0e4d6c3a1fa9ed6e1e5edbbbee244fa..6247215f0ed4884dc4348125f3bb7694ebe20e8e 100644 (file)
@@ -453,10 +453,17 @@ Sema::ParseForStmt(SourceLocation ForLoc, SourceLocation LParenLoc,
   Expr *Third  = static_cast<Expr*>(third);
   Stmt *Body  = static_cast<Stmt*>(body);
   
-  if (First) {
-    // C99 6.8.5p3: FIXME. Need to hack Parser::ParseForStatement() and
-    // declaration support to create a DeclStmt node. Once this is done, 
-    // we can test for DeclStmt vs. Expr (already a sub-class of Stmt).
+  if (DeclStmt *DS = dyn_cast_or_null<DeclStmt>(First)) {
+    // C99 6.8.5p3: The declaration part of a 'for' statement shall only declare
+    // identifiers for objects having storage class 'auto' or 'register'.
+    for (Decl *D = DS->getDecl(); D; D = D->getNextDeclarator()) {
+      BlockVarDecl *BVD = dyn_cast<BlockVarDecl>(D);
+      if (BVD && !BVD->hasLocalStorage())
+        BVD = 0;
+      if (BVD == 0)
+        Diag(D->getLocation(), diag::err_non_variable_decl_in_for);
+      // FIXME: mark decl erroneous!
+    }
   }
   if (Second) {
     DefaultFunctionArrayConversion(Second);
index 1ca8cf0b3a9bd3b195087a9a85261057ee4facb1..d77fb77fa8b570730b53dd5e5bda75328e48a39f 100644 (file)
@@ -367,6 +367,8 @@ DIAG(err_expected_semi_after_expr, ERROR,
      "expected ';' after expression")
 DIAG(err_expected_semi_for, ERROR,
      "expected ';' in 'for' statement specifier")
+DIAG(err_non_variable_decl_in_for, ERROR,
+     "declaration of non-local variable in 'for' loop")
 DIAG(err_expected_colon_after, ERROR,
      "expected ':' after %0")
 DIAG(err_label_end_of_compound_statement, ERROR,
diff --git a/test/Sema/for.c b/test/Sema/for.c
new file mode 100644 (file)
index 0000000..9004d9f
--- /dev/null
@@ -0,0 +1,7 @@
+// RUN: clang -parse-ast-check %s
+
+// Check C99 6.8.5p3
+void b1 (void) { for (void (*f) (void);;); }
+void b2 (void) { for (void f (void);;); }   // expected-error {{declaration of non-local variable}}
+void b3 (void) { for (static int f;;); }    // expected-error {{declaration of non-local variable}}
+void b4 (void) { for (typedef int f;;); }   // expected-error {{declaration of non-local variable}}