@@ -1479,6 +1479,9 @@ struct oacc_routine_data {
1479
1479
location_t loc;
1480
1480
};
1481
1481
1482
+ /* Used for parsing objc foreach statements. */
1483
+ static tree objc_foreach_break_label, objc_foreach_continue_label;
1484
+
1482
1485
static bool c_parser_nth_token_starts_std_attributes (c_parser *,
1483
1486
unsigned int);
1484
1487
static tree c_parser_std_attribute_specifier_sequence (c_parser *);
@@ -6221,11 +6224,11 @@ c_parser_statement_after_labels (c_parser *parser, bool *if_p,
6221
6224
goto expect_semicolon;
6222
6225
case RID_CONTINUE:
6223
6226
c_parser_consume_token (parser);
6224
- stmt = c_finish_bc_stmt (loc, &c_cont_label , false);
6227
+ stmt = c_finish_bc_stmt (loc, objc_foreach_continue_label , false);
6225
6228
goto expect_semicolon;
6226
6229
case RID_BREAK:
6227
6230
c_parser_consume_token (parser);
6228
- stmt = c_finish_bc_stmt (loc, &c_break_label , true);
6231
+ stmt = c_finish_bc_stmt (loc, objc_foreach_break_label , true);
6229
6232
goto expect_semicolon;
6230
6233
case RID_RETURN:
6231
6234
c_parser_consume_token (parser);
@@ -6627,7 +6630,8 @@ static void
6627
6630
c_parser_switch_statement (c_parser *parser, bool *if_p)
6628
6631
{
6629
6632
struct c_expr ce;
6630
- tree block, expr, body, save_break;
6633
+ tree block, expr, body;
6634
+ unsigned char save_in_statement;
6631
6635
location_t switch_loc = c_parser_peek_token (parser)->location;
6632
6636
location_t switch_cond_loc;
6633
6637
gcc_assert (c_parser_next_token_is_keyword (parser, RID_SWITCH));
@@ -6653,26 +6657,18 @@ c_parser_switch_statement (c_parser *parser, bool *if_p)
6653
6657
expr = error_mark_node;
6654
6658
ce.original_type = error_mark_node;
6655
6659
}
6656
- c_start_case (switch_loc, switch_cond_loc, expr, explicit_cast_p);
6657
- save_break = c_break_label ;
6658
- c_break_label = NULL_TREE ;
6660
+ c_start_switch (switch_loc, switch_cond_loc, expr, explicit_cast_p);
6661
+ save_in_statement = in_statement ;
6662
+ in_statement |= IN_SWITCH_STMT ;
6659
6663
location_t loc_after_labels;
6660
6664
bool open_brace_p = c_parser_peek_token (parser)->type == CPP_OPEN_BRACE;
6661
6665
body = c_parser_c99_block_statement (parser, if_p, &loc_after_labels);
6662
6666
location_t next_loc = c_parser_peek_token (parser)->location;
6663
6667
if (!open_brace_p && c_parser_peek_token (parser)->type != CPP_SEMICOLON)
6664
6668
warn_for_multistatement_macros (loc_after_labels, next_loc, switch_loc,
6665
6669
RID_SWITCH);
6666
- if (c_break_label)
6667
- {
6668
- location_t here = c_parser_peek_token (parser)->location;
6669
- tree t = build1 (LABEL_EXPR, void_type_node, c_break_label);
6670
- SET_EXPR_LOCATION (t, here);
6671
- SWITCH_BREAK_LABEL_P (c_break_label) = 1;
6672
- append_to_statement_list_force (t, &body);
6673
- }
6674
- c_finish_case (body, ce.original_type);
6675
- c_break_label = save_break;
6670
+ c_finish_switch (body, ce.original_type);
6671
+ in_statement = save_in_statement;
6676
6672
add_stmt (c_end_compound_stmt (switch_loc, block, flag_isoc99));
6677
6673
c_parser_maybe_reclassify_token (parser);
6678
6674
}
@@ -6690,7 +6686,8 @@ static void
6690
6686
c_parser_while_statement (c_parser *parser, bool ivdep, unsigned short unroll,
6691
6687
bool *if_p)
6692
6688
{
6693
- tree block, cond, body, save_break, save_cont;
6689
+ tree block, cond, body;
6690
+ unsigned char save_in_statement;
6694
6691
location_t loc;
6695
6692
gcc_assert (c_parser_next_token_is_keyword (parser, RID_WHILE));
6696
6693
token_indent_info while_tinfo
@@ -6709,19 +6706,16 @@ c_parser_while_statement (c_parser *parser, bool ivdep, unsigned short unroll,
6709
6706
build_int_cst (integer_type_node,
6710
6707
annot_expr_unroll_kind),
6711
6708
build_int_cst (integer_type_node, unroll));
6712
- save_break = c_break_label;
6713
- c_break_label = NULL_TREE;
6714
- save_cont = c_cont_label;
6715
- c_cont_label = NULL_TREE;
6709
+ save_in_statement = in_statement;
6710
+ in_statement = IN_ITERATION_STMT;
6716
6711
6717
6712
token_indent_info body_tinfo
6718
6713
= get_token_indent_info (c_parser_peek_token (parser));
6719
6714
6720
6715
location_t loc_after_labels;
6721
6716
bool open_brace = c_parser_next_token_is (parser, CPP_OPEN_BRACE);
6722
6717
body = c_parser_c99_block_statement (parser, if_p, &loc_after_labels);
6723
- c_finish_loop (loc, loc, cond, UNKNOWN_LOCATION, NULL, body,
6724
- c_break_label, c_cont_label, true);
6718
+ add_stmt (build_stmt (loc, WHILE_STMT, cond, body));
6725
6719
add_stmt (c_end_compound_stmt (loc, block, flag_isoc99));
6726
6720
c_parser_maybe_reclassify_token (parser);
6727
6721
@@ -6733,8 +6727,7 @@ c_parser_while_statement (c_parser *parser, bool ivdep, unsigned short unroll,
6733
6727
warn_for_multistatement_macros (loc_after_labels, next_tinfo.location,
6734
6728
while_tinfo.location, RID_WHILE);
6735
6729
6736
- c_break_label = save_break;
6737
- c_cont_label = save_cont;
6730
+ in_statement = save_in_statement;
6738
6731
}
6739
6732
6740
6733
/* Parse a do statement (C90 6.6.5, C99 6.8.5, C11 6.8.5).
@@ -6746,7 +6739,8 @@ c_parser_while_statement (c_parser *parser, bool ivdep, unsigned short unroll,
6746
6739
static void
6747
6740
c_parser_do_statement (c_parser *parser, bool ivdep, unsigned short unroll)
6748
6741
{
6749
- tree block, cond, body, save_break, save_cont, new_break, new_cont;
6742
+ tree block, cond, body;
6743
+ unsigned char save_in_statement;
6750
6744
location_t loc;
6751
6745
gcc_assert (c_parser_next_token_is_keyword (parser, RID_DO));
6752
6746
c_parser_consume_token (parser);
@@ -6756,17 +6750,11 @@ c_parser_do_statement (c_parser *parser, bool ivdep, unsigned short unroll)
6756
6750
"suggest braces around empty body in %<do%> statement");
6757
6751
block = c_begin_compound_stmt (flag_isoc99);
6758
6752
loc = c_parser_peek_token (parser)->location;
6759
- save_break = c_break_label;
6760
- c_break_label = NULL_TREE;
6761
- save_cont = c_cont_label;
6762
- c_cont_label = NULL_TREE;
6753
+ save_in_statement = in_statement;
6754
+ in_statement = IN_ITERATION_STMT;
6763
6755
body = c_parser_c99_block_statement (parser, NULL);
6764
6756
c_parser_require_keyword (parser, RID_WHILE, "expected %<while%>");
6765
- new_break = c_break_label;
6766
- c_break_label = save_break;
6767
- new_cont = c_cont_label;
6768
- c_cont_label = save_cont;
6769
- location_t cond_loc = c_parser_peek_token (parser)->location;
6757
+ in_statement = save_in_statement;
6770
6758
cond = c_parser_paren_condition (parser);
6771
6759
if (ivdep && cond != error_mark_node)
6772
6760
cond = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond,
@@ -6780,8 +6768,8 @@ c_parser_do_statement (c_parser *parser, bool ivdep, unsigned short unroll)
6780
6768
build_int_cst (integer_type_node, unroll));
6781
6769
if (!c_parser_require (parser, CPP_SEMICOLON, "expected %<;%>"))
6782
6770
c_parser_skip_to_end_of_block_or_statement (parser);
6783
- c_finish_loop (loc, cond_loc, cond, UNKNOWN_LOCATION, NULL, body,
6784
- new_break, new_cont, false );
6771
+
6772
+ add_stmt (build_stmt (loc, DO_STMT, cond, body) );
6785
6773
add_stmt (c_end_compound_stmt (loc, block, flag_isoc99));
6786
6774
}
6787
6775
@@ -6848,15 +6836,15 @@ static void
6848
6836
c_parser_for_statement (c_parser *parser, bool ivdep, unsigned short unroll,
6849
6837
bool *if_p)
6850
6838
{
6851
- tree block, cond, incr, save_break, save_cont, body;
6839
+ tree block, cond, incr, body;
6840
+ unsigned char save_in_statement;
6841
+ tree save_objc_foreach_break_label, save_objc_foreach_continue_label;
6852
6842
/* The following are only used when parsing an ObjC foreach statement. */
6853
6843
tree object_expression;
6854
6844
/* Silence the bogus uninitialized warning. */
6855
6845
tree collection_expression = NULL;
6856
6846
location_t loc = c_parser_peek_token (parser)->location;
6857
6847
location_t for_loc = loc;
6858
- location_t cond_loc = UNKNOWN_LOCATION;
6859
- location_t incr_loc = UNKNOWN_LOCATION;
6860
6848
bool is_foreach_statement = false;
6861
6849
gcc_assert (c_parser_next_token_is_keyword (parser, RID_FOR));
6862
6850
token_indent_info for_tinfo
@@ -6966,7 +6954,6 @@ c_parser_for_statement (c_parser *parser, bool ivdep, unsigned short unroll,
6966
6954
gcc_assert (!parser->objc_could_be_foreach_context);
6967
6955
if (!is_foreach_statement)
6968
6956
{
6969
- cond_loc = c_parser_peek_token (parser)->location;
6970
6957
if (c_parser_next_token_is (parser, CPP_SEMICOLON))
6971
6958
{
6972
6959
if (ivdep)
@@ -7007,7 +6994,7 @@ c_parser_for_statement (c_parser *parser, bool ivdep, unsigned short unroll,
7007
6994
/* Parse the increment expression (the third expression in a
7008
6995
for-statement). In the case of a foreach-statement, this is
7009
6996
the expression that follows the 'in'. */
7010
- loc = incr_loc = c_parser_peek_token (parser)->location;
6997
+ loc = c_parser_peek_token (parser)->location;
7011
6998
if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
7012
6999
{
7013
7000
if (is_foreach_statement)
@@ -7033,10 +7020,17 @@ c_parser_for_statement (c_parser *parser, bool ivdep, unsigned short unroll,
7033
7020
}
7034
7021
parens.skip_until_found_close (parser);
7035
7022
}
7036
- save_break = c_break_label;
7037
- c_break_label = NULL_TREE;
7038
- save_cont = c_cont_label;
7039
- c_cont_label = NULL_TREE;
7023
+ save_in_statement = in_statement;
7024
+ if (is_foreach_statement)
7025
+ {
7026
+ in_statement = IN_OBJC_FOREACH;
7027
+ save_objc_foreach_break_label = objc_foreach_break_label;
7028
+ save_objc_foreach_continue_label = objc_foreach_continue_label;
7029
+ objc_foreach_break_label = create_artificial_label (loc);
7030
+ objc_foreach_continue_label = create_artificial_label (loc);
7031
+ }
7032
+ else
7033
+ in_statement = IN_ITERATION_STMT;
7040
7034
7041
7035
token_indent_info body_tinfo
7042
7036
= get_token_indent_info (c_parser_peek_token (parser));
@@ -7047,11 +7041,12 @@ c_parser_for_statement (c_parser *parser, bool ivdep, unsigned short unroll,
7047
7041
7048
7042
if (is_foreach_statement)
7049
7043
objc_finish_foreach_loop (for_loc, object_expression,
7050
- collection_expression, body, c_break_label,
7051
- c_cont_label);
7044
+ collection_expression, body,
7045
+ objc_foreach_break_label,
7046
+ objc_foreach_continue_label);
7052
7047
else
7053
- c_finish_loop ( for_loc, cond_loc, cond, incr_loc , incr, body ,
7054
- c_break_label, c_cont_label, true );
7048
+ add_stmt (build_stmt ( for_loc, FOR_STMT, NULL_TREE, cond , incr,
7049
+ body, NULL_TREE) );
7055
7050
add_stmt (c_end_compound_stmt (for_loc, block,
7056
7051
flag_isoc99 || c_dialect_objc ()));
7057
7052
c_parser_maybe_reclassify_token (parser);
@@ -7064,8 +7059,12 @@ c_parser_for_statement (c_parser *parser, bool ivdep, unsigned short unroll,
7064
7059
warn_for_multistatement_macros (loc_after_labels, next_tinfo.location,
7065
7060
for_tinfo.location, RID_FOR);
7066
7061
7067
- c_break_label = save_break;
7068
- c_cont_label = save_cont;
7062
+ in_statement = save_in_statement;
7063
+ if (is_foreach_statement)
7064
+ {
7065
+ objc_foreach_break_label = save_objc_foreach_break_label;
7066
+ objc_foreach_continue_label = save_objc_foreach_continue_label;
7067
+ }
7069
7068
}
7070
7069
7071
7070
/* Parse an asm statement, a GNU extension. This is a full-blown asm
@@ -18038,7 +18037,8 @@ static tree
18038
18037
c_parser_omp_for_loop (location_t loc, c_parser *parser, enum tree_code code,
18039
18038
tree clauses, tree *cclauses, bool *if_p)
18040
18039
{
18041
- tree decl, cond, incr, save_break, save_cont, body, init, stmt, cl;
18040
+ tree decl, cond, incr, body, init, stmt, cl;
18041
+ unsigned char save_in_statement;
18042
18042
tree declv, condv, incrv, initv, ret = NULL_TREE;
18043
18043
tree pre_body = NULL_TREE, this_pre_body;
18044
18044
tree ordered_cl = NULL_TREE;
@@ -18106,6 +18106,11 @@ c_parser_omp_for_loop (location_t loc, c_parser *parser, enum tree_code code,
18106
18106
for_loc = c_parser_peek_token (parser)->location;
18107
18107
c_parser_consume_token (parser);
18108
18108
18109
+ /* Forbid break/continue in the loop initializer, condition, and
18110
+ increment expressions. */
18111
+ save_in_statement = in_statement;
18112
+ in_statement = IN_OMP_BLOCK;
18113
+
18109
18114
for (i = 0; i < count; i++)
18110
18115
{
18111
18116
int bracecount = 0;
@@ -18279,10 +18284,7 @@ c_parser_omp_for_loop (location_t loc, c_parser *parser, enum tree_code code,
18279
18284
if (nbraces)
18280
18285
if_p = NULL;
18281
18286
18282
- save_break = c_break_label;
18283
- c_break_label = size_one_node;
18284
- save_cont = c_cont_label;
18285
- c_cont_label = NULL_TREE;
18287
+ in_statement = IN_OMP_FOR;
18286
18288
body = push_stmt_list ();
18287
18289
18288
18290
if (inscan)
@@ -18296,16 +18298,9 @@ c_parser_omp_for_loop (location_t loc, c_parser *parser, enum tree_code code,
18296
18298
}
18297
18299
else
18298
18300
add_stmt (c_parser_c99_block_statement (parser, if_p));
18299
- if (c_cont_label)
18300
- {
18301
- tree t = build1 (LABEL_EXPR, void_type_node, c_cont_label);
18302
- SET_EXPR_LOCATION (t, loc);
18303
- add_stmt (t);
18304
- }
18305
18301
18306
18302
body = pop_stmt_list (body);
18307
- c_break_label = save_break;
18308
- c_cont_label = save_cont;
18303
+ in_statement = save_in_statement;
18309
18304
18310
18305
while (nbraces)
18311
18306
{
0 commit comments