diff --git a/gcc/c/c-typeck.c b/gcc/c/c-typeck.c
index 78a6c68aaa6acf9e442d3c0bd5f7f19512b5e3ea..71724be6abc16c99f643719a1744a632028fad4f 100644
--- a/gcc/c/c-typeck.c
+++ b/gcc/c/c-typeck.c
@@ -11257,7 +11257,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 0000000000000000000000000000000000000000..c46e0d42c178d1f119cb193d3a2c44b49e327066
--- /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;
+}