public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc r11-9497] objc: Fix handling of break stmt inside of switch inside of ObjC foreach [PR103639]
@ 2022-01-24 9:21 Jakub Jelinek
0 siblings, 0 replies; only message in thread
From: Jakub Jelinek @ 2022-01-24 9:21 UTC (permalink / raw)
To: gcc-cvs
https://gcc.gnu.org/g:27cfe1068239cdafb727de36ec7d9ae19ff5c141
commit r11-9497-g27cfe1068239cdafb727de36ec7d9ae19ff5c141
Author: Jakub Jelinek <jakub@redhat.com>
Date: Sat Jan 1 06:29:36 2022 +0100
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.
(cherry picked from commit 222dbebefbbc07f78e51d82ba605988ef57e5fc9)
Diff:
---
gcc/c/c-typeck.c | 3 +-
gcc/testsuite/objc.dg/pr103639.m | 101 +++++++++++++++++++++++++++++++++++++++
2 files changed, 103 insertions(+), 1 deletion(-)
diff --git a/gcc/c/c-typeck.c b/gcc/c/c-typeck.c
index b5d139e5d9b..e084d2f31d4 100644
--- a/gcc/c/c-typeck.c
+++ b/gcc/c/c-typeck.c
@@ -11216,7 +11216,8 @@ c_finish_bc_stmt (location_t loc, tree label, bool is_break)
if (skip)
return NULL_TREE;
- else if (in_statement & IN_OBJC_FOREACH)
+ else if ((in_statement & IN_OBJC_FOREACH)
+ && !(is_break && (in_statement & IN_SWITCH_STMT)))
{
/* The foreach expander produces low-level code using gotos instead
of a structured loop construct. */
diff --git a/gcc/testsuite/objc.dg/pr103639.m b/gcc/testsuite/objc.dg/pr103639.m
new file mode 100644
index 00000000000..c46e0d42c17
--- /dev/null
+++ b/gcc/testsuite/objc.dg/pr103639.m
@@ -0,0 +1,101 @@
+/* PR objc/103639 */
+/* { dg-do run } */
+/* { dg-skip-if "No NeXT fast enum. pre-Darwin9" { *-*-darwin[5-8]* } { "-fnext-runtime" } { "" } } */
+/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */
+/* { dg-additional-sources "../objc-obj-c++-shared/nsconstantstring-class-impl.m" } */
+/* { dg-additional-options "-mno-constant-cfstrings" { target *-*-darwin* } } */
+/* { dg-additional-options "-Wno-objc-root-class" } */
+
+#import "../objc-obj-c++-shared/TestsuiteObject.m"
+#ifndef __NEXT_RUNTIME__
+#include <objc/NXConstStr.h>
+#else
+#include "../objc-obj-c++-shared/nsconstantstring-class.h"
+#endif
+
+extern int printf (const char *, ...);
+#include <stdlib.h>
+
+/* A mini-array implementation that can be used to test fast
+ enumeration. You create the array with some objects; you can
+ mutate the array, and you can fast-enumerate it.
+ */
+@interface MyArray : TestsuiteObject
+{
+ unsigned int length;
+ id *objects;
+ unsigned long mutated;
+}
+- (id) initWithLength: (unsigned int)l objects: (id *)o;
+- (void) mutate;
+- (unsigned long)countByEnumeratingWithState: (struct __objcFastEnumerationState *)state
+ objects:(id *)stackbuf
+ count:(unsigned long)len;
+@end
+
+@implementation MyArray : TestsuiteObject
+- (id) initWithLength: (unsigned int)l
+ objects: (id *)o
+{
+ length = l;
+ objects = o;
+ mutated = 0;
+ return self;
+}
+- (void) mutate
+{
+ mutated = 1;
+}
+- (unsigned long)countByEnumeratingWithState: (struct __objcFastEnumerationState*)state
+ objects: (id*)stackbuf
+ count: (unsigned long)len
+{
+ unsigned long i, batch_size;
+
+ /* We keep how many objects we served in the state->state counter. So the next batch
+ will contain up to length - state->state objects. */
+ batch_size = length - state->state;
+
+ /* Make obvious adjustments. */
+ if (batch_size < 0)
+ batch_size = 0;
+
+ if (batch_size > len)
+ batch_size = len;
+
+ /* Copy the objects. */
+ for (i = 0; i < batch_size; i++)
+ stackbuf[i] = objects[i];
+
+ state->state += batch_size;
+ state->itemsPtr = stackbuf;
+ state->mutationsPtr = &mutated;
+
+ return batch_size;
+}
+@end
+
+int check = 0;
+
+int
+main()
+{
+ id *objects = malloc (sizeof (id) * 2);
+ objects[0] = @"a";
+ objects[1] = @"b";
+
+ MyArray *array = [[MyArray alloc] initWithLength: 2 objects: objects];
+
+ int someVar = 0;
+ for (id object in array) {
+ switch (someVar) {
+ case 0:
+ break;
+ }
+ ++check;
+ }
+
+ if (check != 2)
+ abort ();
+ return 0;
+}
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2022-01-24 9:21 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-01-24 9:21 [gcc r11-9497] objc: Fix handling of break stmt inside of switch inside of ObjC foreach [PR103639] Jakub Jelinek
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).