This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: PATCH: RFA Fix C/13014


On Mon, 2003-11-17 at 22:39, Jason Merrill wrote:
> On Mon, 17 Nov 2003 18:53:54 -0800, Eric Christopher <echristo@redhat.com> wrote:
> 
> > On Sun, 2003-11-16 at 23:38, Jason Merrill wrote:
> >> Alternately, you could add your in_*_stmt flags to cfun.
> >
> > Ended up adding it to lang_decl instead like so...
> 
> Eww.  Decl flags are for permanent attributes of the function, not parser
> state.  Why not use cfun->language?

Cause it hadn't been used out of c-decl.c before? :)

Here's a patch that does.

OK?

-eric

-- 
Eric Christopher <echristo@redhat.com>

2003-11-20  Eric Christopher  <echristo@redhat.com>

	* c-decl.c (c_in_iteration_stmt, c_in_case_stmt): New.
	(start_function): Use.
	(c_push_function_context): Ditto.
	(c-pop_function_context): Ditto.
        (language_function): Move...
	* c-tree.h: ... here. Add x_in_iteration_stmt, and
	x_in_case_stmt.
	* c-parse.in (do_stmt_start, select_or_iter_stmt, stmt): Use
	c_in_iteration_stmt, c_in_case_stmt for parser state. Move
	check for valid break or continue statment here...
	* c-semantics.c (genrtl_break_stmt, genrtl_continue_stmt): From
	here. Change original errors to abort.


Index: c-decl.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/c-decl.c,v
retrieving revision 1.457
diff -u -p -w -r1.457 c-decl.c
--- c-decl.c	13 Nov 2003 02:07:52 -0000	1.457
+++ c-decl.c	20 Nov 2003 21:52:30 -0000
@@ -126,6 +126,10 @@ static GTY(()) struct stmt_tree_s c_stmt
 
 static GTY(()) tree c_scope_stmt_stack;
 
+/* State saving variables. */
+int c_in_iteration_stmt;
+int c_in_case_stmt;
+
 /* A list of external DECLs that appeared at block scope when there was
    some other global meaning for that identifier.  */
 static GTY(()) tree truly_local_externals;
@@ -5438,6 +5442,8 @@ start_function (tree declspecs, tree dec
   current_function_returns_abnormally = 0;
   warn_about_return_type = 0;
   current_extern_inline = 0;
+  c_in_iteration_stmt = 0;
+  c_in_case_stmt = 0;
 
   /* Don't expand any sizes in the return type of the function.  */
   immediate_size_expand = 0;
@@ -6251,20 +6257,6 @@ check_for_loop_decls (void)
     }
 }
 
-/* Save and restore the variables in this file and elsewhere
-   that keep track of the progress of compilation of the current function.
-   Used for nested functions.  */
-
-struct language_function GTY(())
-{
-  struct c_language_function base;
-  int returns_value;
-  int returns_null;
-  int returns_abnormally;
-  int warn_about_return_type;
-  int extern_inline;
-};
-
 /* Save and reinitialize the variables
    used during compilation of a C function.  */
 
@@ -6277,6 +6269,8 @@ c_push_function_context (struct function
 
   p->base.x_stmt_tree = c_stmt_tree;
   p->base.x_scope_stmt_stack = c_scope_stmt_stack;
+  p->x_in_iteration_stmt = c_in_iteration_stmt;
+  p->x_in_case_stmt = c_in_case_stmt;
   p->returns_value = current_function_returns_value;
   p->returns_null = current_function_returns_null;
   p->returns_abnormally = current_function_returns_abnormally;
@@ -6303,6 +6297,8 @@ c_pop_function_context (struct function 
 
   c_stmt_tree = p->base.x_stmt_tree;
   c_scope_stmt_stack = p->base.x_scope_stmt_stack;
+  c_in_iteration_stmt = p->x_in_iteration_stmt;
+  c_in_case_stmt = p->x_in_case_stmt;
   current_function_returns_value = p->returns_value;
   current_function_returns_null = p->returns_null;
   current_function_returns_abnormally = p->returns_abnormally;
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	20 Nov 2003 21:52:30 -0000
@@ -257,6 +257,9 @@ do {									\
 static int stmt_count;
 static int compstmt_count;
 
+extern int c_in_iteration_stmt;
+extern int c_in_case_stmt;
+
 /* Input location of the end of the body of last simple_if;
    used by the stmt-rule immediately after simple_if returns.  */
 static location_t if_stmt_locus;
@@ -2202,6 +2205,7 @@ do_stmt_start:
 	  DO
 		{ stmt_count++;
 		  compstmt_count++;
+		  c_in_iteration_stmt++;
 		  $<ttype>$
 		    = add_stmt (build_stmt (DO_STMT, NULL_TREE,
 					    NULL_TREE));
@@ -2212,7 +2216,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 ($$));
+		  c_in_iteration_stmt--; }
 	;
 
 /* The forced readahead in here is because we might be at the end of a
@@ -2295,12 +2300,14 @@ select_or_iter_stmt:
                 { stmt_count++;
 		  $<ttype>$ = c_begin_while_stmt (); }
 	  '(' expr ')'
-                { $4 = c_common_truthvalue_conversion ($4);
+                { c_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)); }
+                { c_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 +2325,18 @@ select_or_iter_stmt:
 		    FOR_COND ($<ttype>2)
 		      = c_common_truthvalue_conversion ($6); }
 	  xexpr ')'
-		{ FOR_EXPR ($<ttype>2) = $9; }
+                { c_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));
+		  c_in_iteration_stmt--;}
 	| SWITCH '(' expr ')'
 		{ stmt_count++;
-		  $<ttype>$ = c_start_case ($3); }
+		  $<ttype>$ = c_start_case ($3);
+		  c_in_case_stmt++; }
 	  c99_block_lineno_labeled_stmt
-                { c_finish_case (); }
+                { c_finish_case ();
+		  c_in_case_stmt--; }
 	;
 
 for_init_stmt:
@@ -2348,9 +2359,21 @@ stmt:
 		  $$ = NULL_TREE; }
 	| BREAK ';'
 	        { stmt_count++;
+		if (!(c_in_iteration_stmt || c_in_case_stmt))
+		  {
+		    error ("break statement not within loop or switch");
+		    $$ = NULL_TREE;
+		  }
+		else
 		  $$ = add_stmt (build_break_stmt ()); }
 	| CONTINUE ';'
                 { stmt_count++;
+		if (!c_in_iteration_stmt)
+		  {
+		    error ("continue statement not within a loop");
+		    $$ = NULL_TREE;
+		  }
+		else
 		  $$ = 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	20 Nov 2003 21:52:30 -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.  */
Index: c-tree.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/c-tree.h,v
retrieving revision 1.134
diff -u -p -w -r1.134 c-tree.h
--- c-tree.h	12 Nov 2003 19:52:08 -0000	1.134
+++ c-tree.h	20 Nov 2003 21:52:30 -0000
@@ -151,6 +151,22 @@ struct lang_type GTY(())
 #define KEEP_NO		0
 #define KEEP_YES	1
 #define KEEP_MAYBE	2
+
+/* Save and restore the variables in this file and elsewhere
+   that keep track of the progress of compilation of the current function.
+   Used for nested functions.  */
+
+struct language_function GTY(())
+{
+  struct c_language_function base;
+  int returns_value;
+  int returns_null;
+  int returns_abnormally;
+  int warn_about_return_type;
+  int extern_inline;
+  int x_in_iteration_stmt;
+  int x_in_case_stmt;
+};
 
 
 /* in c-parse.in */




Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]