c-parse.in (c99_block_start, [...]): New.
authorJoseph Myers <jsm28@cam.ac.uk>
Mon, 13 Nov 2000 14:08:09 +0000 (14:08 +0000)
committerJoseph Myers <jsm28@gcc.gnu.org>
Mon, 13 Nov 2000 14:08:09 +0000 (14:08 +0000)
* c-parse.in (c99_block_start, c99_block_end,
c99_block_lineno_labeled_stmt): New.
(simple_if, do_stmt_start): Use c99_block_lineno_labeled_stmt.
(stmt): Split off selection and iteration statements into...
(select_or_iter_stmt): New.  Use c99_block_lineno_labeled_stmt.

testsuite:
* gcc.dg/c99-scope-1.c: Remove xfail.
* gcc.dg/c99-scope-2.c: New test.

From-SVN: r37427

gcc/ChangeLog
gcc/c-parse.in
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/c99-scope-1.c
gcc/testsuite/gcc.dg/c99-scope-2.c [new file with mode: 0644]

index 80a80df0e304be961083b95f68bd10aba7e46acb..6d026b153e1ba51af3bfc8946d12d3de6f88eea2 100644 (file)
@@ -1,3 +1,11 @@
+2000-11-13  Joseph S. Myers  <jsm28@cam.ac.uk>
+
+       * c-parse.in (c99_block_start, c99_block_end,
+       c99_block_lineno_labeled_stmt): New.
+       (simple_if, do_stmt_start): Use c99_block_lineno_labeled_stmt.
+       (stmt): Split off selection and iteration statements into...
+       (select_or_iter_stmt): New.  Use c99_block_lineno_labeled_stmt.
+
 2000-11-13  Joseph S. Myers  <jsm28@cam.ac.uk>
 
        * invoke.texi (-Wtrigraphs, -fdump-translation-unit, -save-temps,
index 3550befcd4cfbce6756bd9c76195a11df0d864bf..bbce2caa199c232580fa0ded300e2521f106acbf 100644 (file)
@@ -176,6 +176,7 @@ end ifc
 %type <ttype> compstmt compstmt_start compstmt_nostart compstmt_primary_start
 %type <ttype> do_stmt_start poplevel
 
+%type <ttype> c99_block_start c99_block_end
 %type <ttype> declarator
 %type <ttype> notype_declarator after_type_declarator
 %type <ttype> parm_declarator
@@ -1623,6 +1624,40 @@ end ifobjc
 poplevel:  /* empty */
                 { $$ = add_scope_stmt (/*begin_p=*/0, /*partial_p=*/0); }
 
+/* Start and end blocks created for the new scopes of C99.  */
+c99_block_start: /* empty */
+               { if (flag_isoc99)
+                   {
+                     $$ = c_begin_compound_stmt ();
+                     pushlevel (0);
+                     clear_last_expr ();
+                     add_scope_stmt (/*begin_p=*/1, /*partial_p=*/0);
+ifobjc
+                     if (objc_method_context)
+                       add_objc_decls ();
+end ifobjc
+                   }
+                 else
+                   $$ = NULL_TREE;
+               }
+       ;
+
+/* Productions using c99_block_start and c99_block_end will need to do what's
+   in compstmt: RECHAIN_STMTS ($1, COMPOUND_BODY ($1)); $$ = $2; where
+   $1 is the value of c99_block_start and $2 of c99_block_end.  */
+c99_block_end: /* empty */
+                { if (flag_isoc99)
+                   {
+                     tree scope_stmt = add_scope_stmt (/*begin_p=*/0, /*partial_p=*/0);
+                     $$ = poplevel (kept_level_p (), 0, 0); 
+                     SCOPE_STMT_BLOCK (TREE_PURPOSE (scope_stmt)) 
+                       = SCOPE_STMT_BLOCK (TREE_VALUE (scope_stmt))
+                       = $$;
+                   }
+                 else
+                   $$ = NULL_TREE; }
+       ;
+
 /* Read zero or more forward-declarations for labels
    that nested functions can jump to.  */
 maybe_label_decls:
@@ -1703,7 +1738,7 @@ compstmt: compstmt_start compstmt_nostart
 
 /* Value is number of statements counted as of the closeparen.  */
 simple_if:
-         if_prefix lineno_labeled_stmt
+         if_prefix c99_block_lineno_labeled_stmt
                 { c_finish_then (); }
 /* Make sure c_expand_end_cond is run once
    for each call to c_expand_start_cond.
@@ -1735,7 +1770,7 @@ do_stmt_start:
                     condition now.  Otherwise, we can get crashes at
                     RTL-generation time.  */
                  DO_COND ($<ttype>$) = error_mark_node; }
-         lineno_labeled_stmt WHILE
+         c99_block_lineno_labeled_stmt WHILE
                { $$ = $<ttype>2;
                  RECHAIN_STMTS ($$, DO_BODY ($$)); }
        ;
@@ -1765,6 +1800,13 @@ lineno_labeled_stmt:
                { }
        ;
 
+/* Like lineno_labeled_stmt, but a block in C99.  */
+c99_block_lineno_labeled_stmt:
+         c99_block_start lineno_labeled_stmt c99_block_end
+               { if (flag_isoc99)
+                   RECHAIN_STMTS ($1, COMPOUND_BODY ($1)); }
+       ;
+
 lineno_stmt_or_label:
          save_filename save_lineno stmt_or_label
                { $$ = $3; }
@@ -1777,17 +1819,11 @@ stmt_or_label:
                { $$ = 1; }
        ;
 
-/* Parse a single real statement, not including any labels.  */
-stmt:
-         compstmt
-               { stmt_count++; }
-       | expr ';'
-               { stmt_count++;
-                 c_expand_expr_stmt ($1); }
-       | simple_if ELSE
+select_or_iter_stmt:
+         simple_if ELSE
                { c_expand_start_else ();
                  $<itype>1 = stmt_count; }
-         lineno_labeled_stmt
+         c99_block_lineno_labeled_stmt
                 { c_finish_else ();
                  c_expand_end_cond ();
                  if (extra_warnings && stmt_count == $<itype>1)
@@ -1812,7 +1848,7 @@ stmt:
                 { $4 = truthvalue_conversion ($4);
                  $<ttype>$ 
                    = add_stmt (build_stmt (WHILE_STMT, $4, NULL_TREE)); }
-         lineno_labeled_stmt
+         c99_block_lineno_labeled_stmt
                { RECHAIN_STMTS ($<ttype>6, WHILE_BODY ($<ttype>6)); }
        | do_stmt_start
          '(' expr ')' ';'
@@ -1831,13 +1867,25 @@ stmt:
                 { FOR_COND ($<ttype>5) = $6; }
          xexpr ')'
                { FOR_EXPR ($<ttype>5) = $9; }
-         lineno_labeled_stmt
+         c99_block_lineno_labeled_stmt
                 { RECHAIN_STMTS ($<ttype>5, FOR_BODY ($<ttype>5)); }
        | SWITCH '(' expr ')'
                { stmt_count++;
                  $<ttype>$ = c_start_case ($3); }
-         lineno_labeled_stmt
+         c99_block_lineno_labeled_stmt
                 { c_finish_case (); }
+       ;
+
+/* Parse a single real statement, not including any labels.  */
+stmt:
+         compstmt
+               { stmt_count++; }
+       | expr ';'
+               { stmt_count++;
+                 c_expand_expr_stmt ($1); }
+       | c99_block_start select_or_iter_stmt c99_block_end
+               { if (flag_isoc99)
+                   RECHAIN_STMTS ($1, COMPOUND_BODY ($1)); }
        | BREAK ';'
                { stmt_count++;
                  add_stmt (build_break_stmt ()); }
index 53362e0b2a51dc41895a7d23b9091d40eb5556ce..cf20ec6adbd782db0357cb3d657d8310fa4c2af3 100644 (file)
@@ -1,3 +1,8 @@
+2000-11-13  Joseph S. Myers  <jsm28@cam.ac.uk>
+
+       * gcc.dg/c99-scope-1.c: Remove xfail.
+       * gcc.dg/c99-scope-2.c: New test.
+
 2000-11-12  Kaveh R. Ghazi  <ghazi@caip.rutgers.edu>
 
        * gcc.c-torture/execute/string-opt-3.c: Also test builtin rindex.
index 256b39c115a446752c18e0125409ea62c6ce5281..48ea3b088f70c9d87e9b9e9e8074d90605795303 100644 (file)
@@ -1,6 +1,6 @@
 /* Test for new block scopes in C99.  Inspired by C99 Rationale (N897).  */
 /* Origin: Joseph Myers <jsm28@cam.ac.uk> */
-/* { dg-do run { xfail *-*-* } } */
+/* { dg-do run } */
 /* { dg-options "-std=iso9899:1999 -pedantic-errors" } */
 
 struct foo {
diff --git a/gcc/testsuite/gcc.dg/c99-scope-2.c b/gcc/testsuite/gcc.dg/c99-scope-2.c
new file mode 100644 (file)
index 0000000..5b81f70
--- /dev/null
@@ -0,0 +1,71 @@
+/* Test for new block scopes in C99.  Test for each new scope.  */
+/* Origin: Joseph Myers <jsm28@cam.ac.uk> */
+/* { dg-do run } */
+/* { dg-options "-std=iso9899:1999 -pedantic-errors" } */
+
+extern void abort (void);
+extern void exit (int);
+
+int
+main (void)
+{
+  struct foo { int i0; };
+  int a, b, c, d;
+  a = sizeof (struct foo);
+  if (b = sizeof (struct foo { int i0; int i1; }))
+    c = sizeof (struct foo { int i0; int i1; int i2; });
+  if (!(a < b && b < c))
+    abort ();
+  if ((b = sizeof (struct foo { int i0; int i1; })), 0)
+    c = sizeof (struct foo { int i0; int i1; int i2; });
+  else
+    d = sizeof (struct foo { int i0; int i1; int i2; int i3; });
+  if (!(a < b && b < d))
+    abort ();
+  switch (b = sizeof (struct foo { int i0; int i1; }))
+    default:
+      c = sizeof (struct foo { int i0; int i1; int i2; });
+  if (!(a < b && b < c))
+    abort ();
+  do
+    c = sizeof (struct foo { int i0; int i1; int i2; });
+  while ((b = sizeof (struct foo { int i0; int i1; })), 0);
+  if (!(a < b && b < c))
+    abort ();
+  d = 1;
+  while ((b = sizeof (struct foo { int i0; int i1; })), d)
+    (c = sizeof (struct foo { int i0; int i1; int i2; })), d--;
+  if (!(a < b && b < c))
+    abort ();
+  d = 1;
+  for ((b = sizeof (struct foo { int i0; int i1; })); d; d--)
+    c = sizeof (struct foo { int i0; int i1; int i2; });
+  if (!(a < b && b < c))
+    abort ();
+  d = 1;
+  for ((b = sizeof (struct foo { int i0; int i1; })); d; d--)
+    c = sizeof (struct foo);
+  if (!(a < b && b == c))
+    abort ();
+  d = 1;
+  for (; (b = sizeof (struct foo { int i0; int i1; })), d; d--)
+    c = sizeof (struct foo { int i0; int i1; int i2; });
+  if (!(a < b && b < c))
+    abort ();
+  d = 1;
+  for (; (b = sizeof (struct foo { int i0; int i1; })), d; d--)
+    c = sizeof (struct foo);
+  if (!(a < b && b == c))
+    abort ();
+  d = 1;
+  for (; d; (b = sizeof (struct foo { int i0; int i1; })), d--)
+    c = sizeof (struct foo { int i0; int i1; int i2; });
+  if (!(a < b && b < c))
+    abort ();
+  d = 1;
+  for (; d; (b = sizeof (struct foo { int i0; int i1; })), d--)
+    c = sizeof (struct foo);
+  if (!(a < b && b == c))
+    abort ();
+  exit (0);
+}