Skip to content

Commit fb6a4b4

Browse files
committed
fixing false "error 760: 'break' statement not in loop or switch statement"
1 parent 7e00d6e commit fb6a4b4

File tree

6 files changed

+398
-376
lines changed

6 files changed

+398
-376
lines changed

src/file.c

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
1-
void f(int n)
2-
{
3-
goto target;
4-
int a[n];
5-
target:
1+
void main() {
2+
int i;
3+
switch (i) {
4+
case 0:
5+
if (1) {
6+
break;
7+
}
8+
}
69
}

src/lib.c

Lines changed: 37 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -16193,7 +16193,7 @@ struct parser_ctx
1619316193
/*
1619416194
* Points to the selection_statement we're in. Or null.
1619516195
*/
16196-
struct selection_statement* _Opt p_current_selection_statement;
16196+
struct selection_statement* _Opt p_current_switch_statement;
1619716197
const struct iteration_statement* _Opt p_current_iteration_statement;
1619816198

1619916199

@@ -28720,7 +28720,7 @@ void defer_start_visit_declaration(struct defer_visit_ctx* ctx, struct declarati
2872028720

2872128721
//#pragma once
2872228722

28723-
#define CAKE_VERSION "0.12.67"
28723+
#define CAKE_VERSION "0.12.68"
2872428724

2872528725

2872628726

@@ -31051,8 +31051,8 @@ struct declaration* _Owner _Opt declaration(struct parser_ctx* ctx,
3105131051
struct defer_visit_ctx ctx2 = { .ctx = ctx };
3105231052
defer_start_visit_declaration(&ctx2, p_declaration);
3105331053
defer_visit_ctx_destroy(&ctx2);
31054-
31055-
31054+
31055+
3105631056
if (ctx->p_report->error_count == 0 && ctx->options.flow_analysis)
3105731057
{
3105831058
/*
@@ -37545,8 +37545,8 @@ struct label* _Owner _Opt label(struct parser_ctx* ctx, struct attribute_specifi
3754537545
else if (ctx->current->type == TK_KEYWORD_CASE)
3754637546
{
3754737547

37548-
if (ctx->p_current_selection_statement == NULL ||
37549-
ctx->p_current_selection_statement->condition == NULL)
37548+
if (ctx->p_current_switch_statement == NULL ||
37549+
ctx->p_current_switch_statement->condition == NULL)
3755037550
{
3755137551
//unexpected because we are in case
3755237552
compiler_diagnostic(C_ERROR_CASE_NOT_IN_SWITCH,
@@ -37584,7 +37584,7 @@ struct label* _Owner _Opt label(struct parser_ctx* ctx, struct attribute_specifi
3758437584
*/
3758537585

3758637586
struct label* _Opt p_existing_label = case_label_list_find_range(ctx,
37587-
&ctx->p_current_selection_statement->label_list,
37587+
&ctx->p_current_switch_statement->label_list,
3758837588
&p_label->constant_expression->object,
3758937589
&p_label->constant_expression_end->object);
3759037590

@@ -37614,7 +37614,10 @@ struct label* _Owner _Opt label(struct parser_ctx* ctx, struct attribute_specifi
3761437614
}
3761537615
else
3761637616
{
37617-
struct label* _Opt p_existing_label = case_label_list_find(ctx, &ctx->p_current_selection_statement->label_list, &p_label->constant_expression->object);
37617+
struct label* _Opt p_existing_label =
37618+
case_label_list_find(ctx, &ctx->p_current_switch_statement->label_list, &p_label->constant_expression->object);
37619+
37620+
3761837621
if (p_existing_label)
3761937622
{
3762037623

@@ -37638,20 +37641,20 @@ struct label* _Owner _Opt label(struct parser_ctx* ctx, struct attribute_specifi
3763837641
if (parser_match_tk(ctx, ':') != 0)
3763937642
throw;
3764037643

37641-
case_label_list_push(&ctx->p_current_selection_statement->label_list, p_label);
37644+
case_label_list_push(&ctx->p_current_switch_statement->label_list, p_label);
3764237645

37643-
if (ctx->p_current_selection_statement &&
37644-
ctx->p_current_selection_statement->condition &&
37645-
ctx->p_current_selection_statement->condition->expression)
37646+
if (ctx->p_current_switch_statement &&
37647+
ctx->p_current_switch_statement->condition &&
37648+
ctx->p_current_switch_statement->condition->expression)
3764637649
{
37647-
if (type_is_enum(&ctx->p_current_selection_statement->condition->expression->type))
37650+
if (type_is_enum(&ctx->p_current_switch_statement->condition->expression->type))
3764837651
{
3764937652
if (type_is_enum(&p_label->constant_expression->type))
3765037653
{
3765137654
check_diferent_enuns(ctx,
3765237655
p_label->constant_expression->first_token,
3765337656
p_label->constant_expression,
37654-
ctx->p_current_selection_statement->condition->expression,
37657+
ctx->p_current_switch_statement->condition->expression,
3765537658
"mismatch in enumeration types");
3765637659
}
3765737660
else
@@ -37660,19 +37663,19 @@ struct label* _Owner _Opt label(struct parser_ctx* ctx, struct attribute_specifi
3766037663
}
3766137664
}
3766237665

37663-
if (ctx->p_current_selection_statement == NULL)
37666+
if (ctx->p_current_switch_statement == NULL)
3766437667
{
3766537668
//unexpected because we have case inside switch
3766637669
throw;
3766737670
}
3766837671

3766937672
const struct enum_specifier* _Opt p_enum_specifier = NULL;
3767037673

37671-
if (ctx->p_current_selection_statement->condition &&
37672-
ctx->p_current_selection_statement->condition->expression &&
37673-
ctx->p_current_selection_statement->condition->expression->type.enum_specifier)
37674+
if (ctx->p_current_switch_statement->condition &&
37675+
ctx->p_current_switch_statement->condition->expression &&
37676+
ctx->p_current_switch_statement->condition->expression->type.enum_specifier)
3767437677
{
37675-
p_enum_specifier = get_complete_enum_specifier(ctx->p_current_selection_statement->condition->expression->type.enum_specifier);
37678+
p_enum_specifier = get_complete_enum_specifier(ctx->p_current_switch_statement->condition->expression->type.enum_specifier);
3767637679
}
3767737680

3767837681
if (p_enum_specifier)
@@ -37700,8 +37703,8 @@ struct label* _Owner _Opt label(struct parser_ctx* ctx, struct attribute_specifi
3770037703
}
3770137704
else if (ctx->current->type == TK_KEYWORD_DEFAULT)
3770237705
{
37703-
if (ctx->p_current_selection_statement == NULL ||
37704-
ctx->p_current_selection_statement->condition == NULL)
37706+
if (ctx->p_current_switch_statement == NULL ||
37707+
ctx->p_current_switch_statement->condition == NULL)
3770537708
{
3770637709
//unexpected because we are in case
3770737710
compiler_diagnostic(C_ERROR_CASE_NOT_IN_SWITCH,
@@ -37713,7 +37716,7 @@ struct label* _Owner _Opt label(struct parser_ctx* ctx, struct attribute_specifi
3771337716
throw;
3771437717
}
3771537718

37716-
struct label* _Opt p_existing_default_label = case_label_list_find_default(ctx, &ctx->p_current_selection_statement->label_list);
37719+
struct label* _Opt p_existing_default_label = case_label_list_find_default(ctx, &ctx->p_current_switch_statement->label_list);
3771737720

3771837721
if (p_existing_default_label)
3771937722
{
@@ -37738,7 +37741,7 @@ struct label* _Owner _Opt label(struct parser_ctx* ctx, struct attribute_specifi
3773837741
if (parser_match_tk(ctx, ':') != 0)
3773937742
throw;
3774037743

37741-
case_label_list_push(&ctx->p_current_selection_statement->label_list, p_label);
37744+
case_label_list_push(&ctx->p_current_switch_statement->label_list, p_label);
3774237745
}
3774337746
// attribute_specifier_sequence_opt identifier ':'
3774437747
// attribute_specifier_sequence_opt 'case' constant_expression ':'
@@ -38783,8 +38786,12 @@ struct selection_statement* _Owner _Opt selection_statement(struct parser_ctx* c
3878338786
}
3878438787
}
3878538788

38786-
struct selection_statement* _Opt previous = ctx->p_current_selection_statement;
38787-
ctx->p_current_selection_statement = p_selection_statement;
38789+
struct selection_statement* _Opt previous = ctx->p_current_switch_statement;
38790+
38791+
if (p_selection_statement->first_token->type == TK_KEYWORD_SWITCH)
38792+
{
38793+
ctx->p_current_switch_statement = p_selection_statement;
38794+
}
3878838795

3878938796
struct secondary_block* _Owner _Opt p_secondary_block = secondary_block(ctx);
3879038797

@@ -38810,7 +38817,7 @@ struct selection_statement* _Owner _Opt selection_statement(struct parser_ctx* c
3881038817
p_selection_statement->secondary_block = p_secondary_block;
3881138818

3881238819

38813-
ctx->p_current_selection_statement = previous;
38820+
ctx->p_current_switch_statement = previous;
3881438821

3881538822

3881638823
if (is_if && ctx->current && ctx->current->type == TK_KEYWORD_ELSE)
@@ -39238,7 +39245,7 @@ struct jump_statement* _Owner _Opt jump_statement(struct parser_ctx* ctx)
3923839245
else if (ctx->current->type == TK_KEYWORD_BREAK)
3923939246
{
3924039247
const bool in_switch =
39241-
ctx->p_current_selection_statement && ctx->p_current_selection_statement->first_token->type == TK_KEYWORD_SWITCH;
39248+
ctx->p_current_switch_statement && ctx->p_current_switch_statement->first_token->type == TK_KEYWORD_SWITCH;
3924239249

3924339250
if (ctx->p_current_iteration_statement == NULL && !in_switch)
3924439251
{
@@ -39807,8 +39814,8 @@ struct compound_statement* _Owner _Opt function_body(struct parser_ctx* ctx)
3980739814
const struct defer_statement* _Opt p_current_defer_statement_opt = ctx->p_current_defer_statement_opt;
3980839815
ctx->p_current_defer_statement_opt = NULL;
3980939816

39810-
struct selection_statement* _Opt p_current_selection_statement = ctx->p_current_selection_statement;
39811-
ctx->p_current_selection_statement = NULL;
39817+
struct selection_statement* _Opt p_current_switch_statement = ctx->p_current_switch_statement;
39818+
ctx->p_current_switch_statement = NULL;
3981239819

3981339820
struct label_list label_list = { 0 };
3981439821
label_list_swap(&label_list, &ctx->label_list);
@@ -39824,7 +39831,7 @@ struct compound_statement* _Owner _Opt function_body(struct parser_ctx* ctx)
3982439831
ctx->label_id = label_id;
3982539832
ctx->p_current_try_statement_opt = p_current_try_statement_opt;
3982639833
ctx->p_current_defer_statement_opt = p_current_defer_statement_opt;
39827-
ctx->p_current_selection_statement = p_current_selection_statement;
39834+
ctx->p_current_switch_statement = p_current_switch_statement;
3982839835

3982939836
label_list_clear(&label_list);
3983039837

src/parser.c

Lines changed: 35 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -2294,8 +2294,8 @@ struct declaration* _Owner _Opt declaration(struct parser_ctx* ctx,
22942294
struct defer_visit_ctx ctx2 = { .ctx = ctx };
22952295
defer_start_visit_declaration(&ctx2, p_declaration);
22962296
defer_visit_ctx_destroy(&ctx2);
2297-
2298-
2297+
2298+
22992299
if (ctx->p_report->error_count == 0 && ctx->options.flow_analysis)
23002300
{
23012301
/*
@@ -8788,8 +8788,8 @@ struct label* _Owner _Opt label(struct parser_ctx* ctx, struct attribute_specifi
87888788
else if (ctx->current->type == TK_KEYWORD_CASE)
87898789
{
87908790

8791-
if (ctx->p_current_selection_statement == NULL ||
8792-
ctx->p_current_selection_statement->condition == NULL)
8791+
if (ctx->p_current_switch_statement == NULL ||
8792+
ctx->p_current_switch_statement->condition == NULL)
87938793
{
87948794
//unexpected because we are in case
87958795
compiler_diagnostic(C_ERROR_CASE_NOT_IN_SWITCH,
@@ -8827,7 +8827,7 @@ struct label* _Owner _Opt label(struct parser_ctx* ctx, struct attribute_specifi
88278827
*/
88288828

88298829
struct label* _Opt p_existing_label = case_label_list_find_range(ctx,
8830-
&ctx->p_current_selection_statement->label_list,
8830+
&ctx->p_current_switch_statement->label_list,
88318831
&p_label->constant_expression->object,
88328832
&p_label->constant_expression_end->object);
88338833

@@ -8857,7 +8857,10 @@ struct label* _Owner _Opt label(struct parser_ctx* ctx, struct attribute_specifi
88578857
}
88588858
else
88598859
{
8860-
struct label* _Opt p_existing_label = case_label_list_find(ctx, &ctx->p_current_selection_statement->label_list, &p_label->constant_expression->object);
8860+
struct label* _Opt p_existing_label =
8861+
case_label_list_find(ctx, &ctx->p_current_switch_statement->label_list, &p_label->constant_expression->object);
8862+
8863+
88618864
if (p_existing_label)
88628865
{
88638866

@@ -8881,20 +8884,20 @@ struct label* _Owner _Opt label(struct parser_ctx* ctx, struct attribute_specifi
88818884
if (parser_match_tk(ctx, ':') != 0)
88828885
throw;
88838886

8884-
case_label_list_push(&ctx->p_current_selection_statement->label_list, p_label);
8887+
case_label_list_push(&ctx->p_current_switch_statement->label_list, p_label);
88858888

8886-
if (ctx->p_current_selection_statement &&
8887-
ctx->p_current_selection_statement->condition &&
8888-
ctx->p_current_selection_statement->condition->expression)
8889+
if (ctx->p_current_switch_statement &&
8890+
ctx->p_current_switch_statement->condition &&
8891+
ctx->p_current_switch_statement->condition->expression)
88898892
{
8890-
if (type_is_enum(&ctx->p_current_selection_statement->condition->expression->type))
8893+
if (type_is_enum(&ctx->p_current_switch_statement->condition->expression->type))
88918894
{
88928895
if (type_is_enum(&p_label->constant_expression->type))
88938896
{
88948897
check_diferent_enuns(ctx,
88958898
p_label->constant_expression->first_token,
88968899
p_label->constant_expression,
8897-
ctx->p_current_selection_statement->condition->expression,
8900+
ctx->p_current_switch_statement->condition->expression,
88988901
"mismatch in enumeration types");
88998902
}
89008903
else
@@ -8903,19 +8906,19 @@ struct label* _Owner _Opt label(struct parser_ctx* ctx, struct attribute_specifi
89038906
}
89048907
}
89058908

8906-
if (ctx->p_current_selection_statement == NULL)
8909+
if (ctx->p_current_switch_statement == NULL)
89078910
{
89088911
//unexpected because we have case inside switch
89098912
throw;
89108913
}
89118914

89128915
const struct enum_specifier* _Opt p_enum_specifier = NULL;
89138916

8914-
if (ctx->p_current_selection_statement->condition &&
8915-
ctx->p_current_selection_statement->condition->expression &&
8916-
ctx->p_current_selection_statement->condition->expression->type.enum_specifier)
8917+
if (ctx->p_current_switch_statement->condition &&
8918+
ctx->p_current_switch_statement->condition->expression &&
8919+
ctx->p_current_switch_statement->condition->expression->type.enum_specifier)
89178920
{
8918-
p_enum_specifier = get_complete_enum_specifier(ctx->p_current_selection_statement->condition->expression->type.enum_specifier);
8921+
p_enum_specifier = get_complete_enum_specifier(ctx->p_current_switch_statement->condition->expression->type.enum_specifier);
89198922
}
89208923

89218924
if (p_enum_specifier)
@@ -8943,8 +8946,8 @@ struct label* _Owner _Opt label(struct parser_ctx* ctx, struct attribute_specifi
89438946
}
89448947
else if (ctx->current->type == TK_KEYWORD_DEFAULT)
89458948
{
8946-
if (ctx->p_current_selection_statement == NULL ||
8947-
ctx->p_current_selection_statement->condition == NULL)
8949+
if (ctx->p_current_switch_statement == NULL ||
8950+
ctx->p_current_switch_statement->condition == NULL)
89488951
{
89498952
//unexpected because we are in case
89508953
compiler_diagnostic(C_ERROR_CASE_NOT_IN_SWITCH,
@@ -8956,7 +8959,7 @@ struct label* _Owner _Opt label(struct parser_ctx* ctx, struct attribute_specifi
89568959
throw;
89578960
}
89588961

8959-
struct label* _Opt p_existing_default_label = case_label_list_find_default(ctx, &ctx->p_current_selection_statement->label_list);
8962+
struct label* _Opt p_existing_default_label = case_label_list_find_default(ctx, &ctx->p_current_switch_statement->label_list);
89608963

89618964
if (p_existing_default_label)
89628965
{
@@ -8981,7 +8984,7 @@ struct label* _Owner _Opt label(struct parser_ctx* ctx, struct attribute_specifi
89818984
if (parser_match_tk(ctx, ':') != 0)
89828985
throw;
89838986

8984-
case_label_list_push(&ctx->p_current_selection_statement->label_list, p_label);
8987+
case_label_list_push(&ctx->p_current_switch_statement->label_list, p_label);
89858988
}
89868989
// attribute_specifier_sequence_opt identifier ':'
89878990
// attribute_specifier_sequence_opt 'case' constant_expression ':'
@@ -10026,8 +10029,12 @@ struct selection_statement* _Owner _Opt selection_statement(struct parser_ctx* c
1002610029
}
1002710030
}
1002810031

10029-
struct selection_statement* _Opt previous = ctx->p_current_selection_statement;
10030-
ctx->p_current_selection_statement = p_selection_statement;
10032+
struct selection_statement* _Opt previous = ctx->p_current_switch_statement;
10033+
10034+
if (p_selection_statement->first_token->type == TK_KEYWORD_SWITCH)
10035+
{
10036+
ctx->p_current_switch_statement = p_selection_statement;
10037+
}
1003110038

1003210039
struct secondary_block* _Owner _Opt p_secondary_block = secondary_block(ctx);
1003310040

@@ -10053,7 +10060,7 @@ struct selection_statement* _Owner _Opt selection_statement(struct parser_ctx* c
1005310060
p_selection_statement->secondary_block = p_secondary_block;
1005410061

1005510062

10056-
ctx->p_current_selection_statement = previous;
10063+
ctx->p_current_switch_statement = previous;
1005710064

1005810065

1005910066
if (is_if && ctx->current && ctx->current->type == TK_KEYWORD_ELSE)
@@ -10481,7 +10488,7 @@ struct jump_statement* _Owner _Opt jump_statement(struct parser_ctx* ctx)
1048110488
else if (ctx->current->type == TK_KEYWORD_BREAK)
1048210489
{
1048310490
const bool in_switch =
10484-
ctx->p_current_selection_statement && ctx->p_current_selection_statement->first_token->type == TK_KEYWORD_SWITCH;
10491+
ctx->p_current_switch_statement && ctx->p_current_switch_statement->first_token->type == TK_KEYWORD_SWITCH;
1048510492

1048610493
if (ctx->p_current_iteration_statement == NULL && !in_switch)
1048710494
{
@@ -11050,8 +11057,8 @@ struct compound_statement* _Owner _Opt function_body(struct parser_ctx* ctx)
1105011057
const struct defer_statement* _Opt p_current_defer_statement_opt = ctx->p_current_defer_statement_opt;
1105111058
ctx->p_current_defer_statement_opt = NULL;
1105211059

11053-
struct selection_statement* _Opt p_current_selection_statement = ctx->p_current_selection_statement;
11054-
ctx->p_current_selection_statement = NULL;
11060+
struct selection_statement* _Opt p_current_switch_statement = ctx->p_current_switch_statement;
11061+
ctx->p_current_switch_statement = NULL;
1105511062

1105611063
struct label_list label_list = { 0 };
1105711064
label_list_swap(&label_list, &ctx->label_list);
@@ -11067,7 +11074,7 @@ struct compound_statement* _Owner _Opt function_body(struct parser_ctx* ctx)
1106711074
ctx->label_id = label_id;
1106811075
ctx->p_current_try_statement_opt = p_current_try_statement_opt;
1106911076
ctx->p_current_defer_statement_opt = p_current_defer_statement_opt;
11070-
ctx->p_current_selection_statement = p_current_selection_statement;
11077+
ctx->p_current_switch_statement = p_current_switch_statement;
1107111078

1107211079
label_list_clear(&label_list);
1107311080

src/parser.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ struct parser_ctx
110110
/*
111111
* Points to the selection_statement we're in. Or null.
112112
*/
113-
struct selection_statement* _Opt p_current_selection_statement;
113+
struct selection_statement* _Opt p_current_switch_statement;
114114
const struct iteration_statement* _Opt p_current_iteration_statement;
115115

116116

0 commit comments

Comments
 (0)