diff options
author | Eric Christopher <echristo@gcc.gnu.org> | 2003-11-24 20:12:06 +0000 |
---|---|---|
committer | Eric Christopher <echristo@gcc.gnu.org> | 2003-11-24 20:12:06 +0000 |
commit | e13e48e70711cf7328c91eedf04ad4771dc9a002 (patch) | |
tree | 4b0dd5bf92fd53863d57bb29f006b3c57aff1bf0 /gcc/c-parse.in | |
parent | 8273c02d611966557eff0bedb92f841e854738b1 (diff) | |
download | gcc-e13e48e70711cf7328c91eedf04ad4771dc9a002.zip gcc-e13e48e70711cf7328c91eedf04ad4771dc9a002.tar.gz gcc-e13e48e70711cf7328c91eedf04ad4771dc9a002.tar.bz2 |
re PR c/13014 (if shortcut misses required diagnostics)
2003-11-24 Eric Christopher <echristo@redhat.com>
PR C/13014
* 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.
From-SVN: r73887
Diffstat (limited to 'gcc/c-parse.in')
-rw-r--r-- | gcc/c-parse.in | 63 |
1 files changed, 43 insertions, 20 deletions
diff --git a/gcc/c-parse.in b/gcc/c-parse.in index 22bab99..d58b1ef 100644 --- a/gcc/c-parse.in +++ b/gcc/c-parse.in @@ -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; @@ -2053,12 +2056,12 @@ pushlevel: /* empty */ ; poplevel: /* empty */ - { + { @@ifobjc if (c_dialect_objc ()) objc_clear_super_receiver (); @@end_ifobjc - $$ = add_scope_stmt (/*begin_p=*/0, /*partial_p=*/0); + $$ = add_scope_stmt (/*begin_p=*/0, /*partial_p=*/0); } ; @@ -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++; @@ -2397,18 +2420,18 @@ stmt: { $$ = NULL_TREE; } @@ifobjc | AT_THROW expr ';' - { stmt_count++; - $$ = objc_build_throw_stmt ($2); + { stmt_count++; + $$ = objc_build_throw_stmt ($2); } | AT_THROW ';' - { stmt_count++; - $$ = objc_build_throw_stmt (NULL_TREE); + { stmt_count++; + $$ = objc_build_throw_stmt (NULL_TREE); } - | objc_try_catch_stmt + | objc_try_catch_stmt { objc_build_finally_prologue (); } objc_finally_block { $$ = objc_build_try_catch_finally_stmt ($1, $3); } - | AT_SYNCHRONIZED '(' expr ')' + | AT_SYNCHRONIZED '(' expr ')' { objc_build_synchronized_prologue ($3); } compstmt { $$ = objc_build_synchronized_epilogue (); } @@ -2425,18 +2448,18 @@ objc_try_catch_stmt: objc_try_stmt: - AT_TRY + AT_TRY { objc_build_try_prologue (); } - compstmt + compstmt ; - + objc_catch_list: objc_catch_list objc_catch_block | objc_catch_block ; objc_catch_block: - AT_CATCH '(' parm ')' + AT_CATCH '(' parm ')' { objc_build_catch_stmt ($3); } compstmt { stmt_count++; } @@ -3689,7 +3712,7 @@ _yylex (void) case CPP_STRING: case CPP_WSTRING: return STRING; - + case CPP_OBJC_STRING: return OBJC_STRING; |