This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
PATCH: RFA Fix C/13014
- From: Eric Christopher <echristo at redhat dot com>
- To: gcc-patches at gcc dot gnu dot org, rth at redhat dot com
- Date: Sat, 15 Nov 2003 00:06:29 -0800
- Subject: PATCH: RFA Fix C/13014
This patch brings the check into the parser where it belongs. I changed
the previous errors to abort () because we shouldn't have gotten that
far if we did. It does fix the testcases, however, I'd appreciate
someone with a better knowledge of the parser giving this a good look.
OK? Did I miss something?
Bootstrapped C and C++ and regtested on x86-linux, irix machine is
having issues (subscriptions) or I'd test there too. Fixes
gcc.dg/20031111-1.c with no regressions.
-eric
--
Eric Christopher <echristo@redhat.com>
2003-11-14 Eric Christopher <echristo@redhat.com>
PR C/13014
* c-parse.in (in_iteration_stmt, in_case_stmt): New variables.
(do_stmt_start, select_or_iter_stmt, stmt): Use. Move errors
here...
* c-semantics.c (genrtl_break_stmt, genrtl_continue_stmt):
... from here. Change previous errors to abort.
Index: c-parse.in
===================================================================
RCS file: /cvs/gcc/gcc/gcc/c-parse.in,v
retrieving revision 1.188
diff -u -p -w -r1.188 c-parse.in
--- c-parse.in 24 Oct 2003 15:30:30 -0000 1.188
+++ c-parse.in 15 Nov 2003 08:05:06 -0000
@@ -256,6 +256,8 @@ do { \
seen so far. */
static int stmt_count;
static int compstmt_count;
+static int in_iteration_stmt = 0;
+static int in_case_stmt = 0;
/* Input location of the end of the body of last simple_if;
used by the stmt-rule immediately after simple_if returns. */
@@ -2202,6 +2204,7 @@ do_stmt_start:
DO
{ stmt_count++;
compstmt_count++;
+ in_iteration_stmt++;
$<ttype>$
= add_stmt (build_stmt (DO_STMT, NULL_TREE,
NULL_TREE));
@@ -2212,7 +2215,8 @@ do_stmt_start:
DO_COND ($<ttype>$) = error_mark_node; }
c99_block_lineno_labeled_stmt WHILE
{ $$ = $<ttype>2;
- RECHAIN_STMTS ($$, DO_BODY ($$)); }
+ RECHAIN_STMTS ($$, DO_BODY ($$));
+ in_iteration_stmt--; }
;
/* The forced readahead in here is because we might be at the end of a
@@ -2295,12 +2299,14 @@ select_or_iter_stmt:
{ stmt_count++;
$<ttype>$ = c_begin_while_stmt (); }
'(' expr ')'
- { $4 = c_common_truthvalue_conversion ($4);
+ { in_iteration_stmt++;
+ $4 = c_common_truthvalue_conversion ($4);
c_finish_while_stmt_cond
(c_common_truthvalue_conversion ($4), $<ttype>2);
$<ttype>$ = add_stmt ($<ttype>2); }
c99_block_lineno_labeled_stmt
- { RECHAIN_STMTS ($<ttype>6, WHILE_BODY ($<ttype>6)); }
+ { in_iteration_stmt--;
+ RECHAIN_STMTS ($<ttype>6, WHILE_BODY ($<ttype>6)); }
| do_stmt_start
'(' expr ')' ';'
{ DO_COND ($1) = c_common_truthvalue_conversion ($3); }
@@ -2318,14 +2324,18 @@ select_or_iter_stmt:
FOR_COND ($<ttype>2)
= c_common_truthvalue_conversion ($6); }
xexpr ')'
- { FOR_EXPR ($<ttype>2) = $9; }
+ { in_iteration_stmt++;
+ FOR_EXPR ($<ttype>2) = $9; }
c99_block_lineno_labeled_stmt
- { RECHAIN_STMTS ($<ttype>2, FOR_BODY ($<ttype>2)); }
+ { RECHAIN_STMTS ($<ttype>2, FOR_BODY ($<ttype>2));
+ in_iteration_stmt--;}
| SWITCH '(' expr ')'
{ stmt_count++;
- $<ttype>$ = c_start_case ($3); }
+ $<ttype>$ = c_start_case ($3);
+ in_case_stmt++; }
c99_block_lineno_labeled_stmt
- { c_finish_case (); }
+ { c_finish_case ();
+ in_case_stmt--; }
;
for_init_stmt:
@@ -2348,9 +2358,14 @@ stmt:
$$ = NULL_TREE; }
| BREAK ';'
{ stmt_count++;
+ if (!(in_iteration_stmt || in_case_stmt))
+ error ("break statement not within loop or switch");
+
$$ = add_stmt (build_break_stmt ()); }
| CONTINUE ';'
{ stmt_count++;
+ if (!in_iteration_stmt)
+ error ("continue statement not within a loop");
$$ = add_stmt (build_continue_stmt ()); }
| RETURN ';'
{ stmt_count++;
Index: c-semantics.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/c-semantics.c,v
retrieving revision 1.73
diff -u -p -w -r1.73 c-semantics.c
--- c-semantics.c 7 Oct 2003 22:10:37 -0000 1.73
+++ c-semantics.c 15 Nov 2003 08:05:06 -0000
@@ -592,7 +592,7 @@ genrtl_break_stmt (void)
{
emit_line_note (input_location);
if ( ! expand_exit_something ())
- error ("break statement not within loop or switch");
+ abort ();
}
/* Build a continue statement node and return it. */
@@ -610,7 +610,7 @@ genrtl_continue_stmt (void)
{
emit_line_note (input_location);
if (! expand_continue_loop (0))
- error ("continue statement not within a loop");
+ abort ();
}
/* Generate the RTL for T, which is a SCOPE_STMT. */