objc: Fix handling of break stmt inside of switch inside of ObjC foreach [PR103639]
authorJakub Jelinek <jakub@redhat.com>
Sat, 1 Jan 2022 05:29:36 +0000 (06:29 +0100)
committerJakub Jelinek <jakub@redhat.com>
Sat, 1 Jan 2022 05:29:36 +0000 (06:29 +0100)
commit222dbebefbbc07f78e51d82ba605988ef57e5fc9
tree159f0a56261525b5a56294d61294caa2529feba3
parentf17d2677bc2cbbc9021c81584000a2db1699d14e
objc: Fix handling of break stmt inside of switch inside of ObjC foreach [PR103639]

The r11-3302-g3696a50beeb73f changes broke the following ObjC testcase.
in_statement is either 0 (not in a looping statement), various IN_* flags
for various kinds of looping statements (or OpenMP structured blocks) or
those flags ored with IN_SWITCH_STMT when a switch appears inside of those
contexts.  This is because break binds to switch in that last case, but
continue binds to the looping construct in that case.
The c_finish_bc_stmt function performs diagnostics on incorrect
break/continue uses and then checks if in_statement & IN_OBJC_FOREACH
and in that case jumps to the label provided by the caller, otherwise
emits a BREAK_STMT or CONTINUE_STMT.  This is incorrect if we have
ObjC foreach with switch nested in it and break inside of that,
in_statement in that case is IN_OBJC_FOREACH | IN_SWITCH_STMT and
is_break is true.  We want to handle it like other breaks inside of
switch, i.e. emit a BREAK_STMT.

The following patch fixes that.

2022-01-01  Jakub Jelinek  <jakub@redhat.com>

PR objc/103639
* c-typeck.c (c_finish_bc_stmt): For break inside of switch inside of
ObjC foreach, emit normal BREAK_STMT rather than goto to label.

2022-01-01  Iain Sandoe  <iain@sandoe.co.uk>

PR objc/103639
* objc.dg/pr103639.m: New test.
gcc/c/c-typeck.c
gcc/testsuite/objc.dg/pr103639.m [new file with mode: 0644]