d: Fix gdc -O2 -mavx generates misaligned vmovdqa instruction [PR114171]
[official-gcc.git] / gcc / testsuite / objc.dg / foreach-2.m
blobccce557482fb99532cf1328c94758780d4ceccbc
1 /* Test basic Objective-C foreach syntax.  This tests iterations, with
2    the basic syntax 'for (object in array) statements'
3 */
4 /* { dg-do run } */
5 /* { dg-skip-if "No NeXT fast enum. pre-Darwin9" { *-*-darwin[5-8]* } { "-fnext-runtime" } { "" } } */
6 /* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */
7 /* { dg-options "-mno-constant-cfstrings" { target *-*-darwin* } } */
8 /* { dg-additional-sources "../objc-obj-c++-shared/nsconstantstring-class-impl.m" } */
9 /* { dg-additional-options "-Wno-objc-root-class" } */
11 #include "../objc-obj-c++-shared/TestsuiteObject.m"
12 #ifndef __NEXT_RUNTIME__
13 #include <objc/NXConstStr.h>
14 #else
15 #include "../objc-obj-c++-shared/nsconstantstring-class.h"
16 #endif
18 extern int printf (const char *, ...);
19 #include <stdlib.h>
22 struct __objcFastEnumerationState
24   unsigned long state;
25   id            *itemsPtr;
26   unsigned long *mutationsPtr;
27   unsigned long extra[5];
31  /* A mini-array implementation that can be used to test fast
32     enumeration.  You create the array with some objects; you can
33     mutate the array, and you can fast-enumerate it.
34  */
35 @interface MyArray : TestsuiteObject
37   unsigned int length;
38   id *objects;
39   unsigned long mutated;
41 - (id) initWithLength: (unsigned int)l  objects: (id *)o;
42 - (void) mutate;
43 - (unsigned long)countByEnumeratingWithState: (struct __objcFastEnumerationState *)state
44                                      objects:(id *)stackbuf 
45                                        count:(unsigned long)len;
46 @end
48 @implementation MyArray : TestsuiteObject
49 - (id) initWithLength: (unsigned int)l
50               objects: (id *)o
52   length = l;
53   objects = o;
54   mutated = 0;
55   return self;
57 - (void) mutate
59   mutated = 1;
61 - (unsigned long)countByEnumeratingWithState: (struct __objcFastEnumerationState*)state 
62                                      objects: (id*)stackbuf
63                                        count: (unsigned long)len
65   unsigned long i, batch_size;
67   /* We keep how many objects we served in the state->state counter.  So the next batch
68      will contain up to length - state->state objects.  */
69   batch_size = length - state->state;
71   /* Make obvious adjustments.  */
72   if (batch_size < 0)
73     batch_size = 0;
75   if (batch_size > len)
76     batch_size = len;
78   /* Copy the objects.  */
79   for (i = 0; i < batch_size; i++)
80     stackbuf[i] = objects[i];
82   state->state += batch_size;
83   state->itemsPtr = stackbuf;
84   state->mutationsPtr = &mutated;
86   return batch_size;
88 @end
90 int main (void)
92   MyArray *array;
93   TestsuiteObject *object;
94   int test_variable, counter, i;
95   id *objects;
97   array = [[MyArray alloc] initWithLength: 0
98                            objects: NULL];
100   /* Test that an empty array does nothing.  */
101   for (object in array)
102     abort ();
104   if (object != nil)
105     abort ();
107   /* Test iterating over 1 object.  */
108   objects = malloc (sizeof (id) * 1);
109   objects[0] = @"One Object";
111   array = [[MyArray alloc] initWithLength: 1
112                            objects: objects];
113   
114   for (object in array)
115     printf ("%p\n", object);
116   
117   /* Test iterating over 20 objects.  */
118   objects = malloc (sizeof (id) * 20);
119   for (i = 0; i < 20; i++)
120     objects[i] = @"object";
121   
122   array = [[MyArray alloc] initWithLength: 20
123                            objects: objects];
124   
125   for (object in array)
126     printf ("%p\n", object);
128   /* Test iterating over 200 objects.  */
129   objects = malloc (sizeof (id) * 200);
130   for (i = 0; i < 200; i++)
131     objects[i] = @"object";
132   
133   array = [[MyArray alloc] initWithLength: 200
134                            objects: objects];
135   
136   counter = 0;
137   for (object in array)
138     {
139       if (object != nil)
140         counter++;
141     }
143   if (counter != 200)
144     abort ();
146   printf ("Counter was %d (should be 200)\n", counter);
148   /* Test iterating again over the same array.  */
149   counter = 0;
150   for (object in array)
151     {
152       if (object != nil)
153         counter++;
154     }
156   if (counter != 200)
157     abort ();
159   printf ("Counter was %d (should be 200)\n", counter);
161   /* Test nested iterations.  */
162   objects = malloc (sizeof (id) * 20);
163   for (i = 0; i < 20; i++)
164     objects[i] = @"object";
165   
166   array = [[MyArray alloc] initWithLength: 20
167                            objects: objects];
168   counter = 0;
169   for (object in array)
170     {
171       id another_object;
172       for (another_object in array)
173         if (another_object != nil)
174           counter++;
175     }
177   printf ("Counter was %d (should be 400)\n", counter);
179   if (counter != 400)
180     abort ();
182   /* Test 'continue'.  */
183   objects = malloc (sizeof (id) * 20);
184   for (i = 0; i < 20; i++)
185     objects[i] = @"object";
186   
187   array = [[MyArray alloc] initWithLength: 20
188                            objects: objects];
189   counter = 0;
190   for (object in array)
191     {
192       if (counter == 15)
193         continue;
195       counter++;
196     }
198   printf ("Counter was %d (should be 15)\n", counter);
200   if (counter != 15)
201     abort ();
203   /* Test 'break'.  */
204   objects = malloc (sizeof (id) * 20);
205   for (i = 0; i < 20; i++)
206     objects[i] = @"object";
207   
208   array = [[MyArray alloc] initWithLength: 20
209                            objects: objects];
210   counter = 0;
211   for (object in array)
212     {
213       counter++;
215       if (counter == 15)
216         break;
217     }
219   printf ("Counter was %d (should be 15)\n", counter);
221   if (counter != 15)
222     abort ();
224   /* Test 'break' and 'continue' in nested iterations.  */
225   objects = malloc (sizeof (id) * 20);
226   for (i = 0; i < 20; i++)
227     objects[i] = @"object";
228   
229   array = [[MyArray alloc] initWithLength: 20
230                            objects: objects];
231   counter = 0;
232   for (object in array)
233     {
234       int local_counter = 0;
235       id another_object;
237       /* Each internal loop should increase counter by 24.  */
238       for (another_object in array)
239         {
240           local_counter++;
241           
242           if (local_counter == 10)
243             {
244               counter = counter + 20;
245               break;
246             }
248           if (local_counter >= 5)
249             continue;
251           counter++;
252         }
254       /* Exit after 4 iterations.  */
255       if (counter == 96)
256         break;
257     }
259   printf ("Counter was %d (should be 96)\n", counter);
261   if (counter != 96)
262     abort ();
264   /* Test that if we 'break', the object is set to the last one, while
265      if we run out of objects, it is set to 'nil'.  */
266   for (object in array)
267     ;
269   if (object != nil)
270     abort ();
272   for (object in array)
273     break;
275   if (object == nil)
276     abort ();
278   /* Test that C for loops still work.  */
279   test_variable = 0;
281   for (counter = 0; counter < 4; counter++)
282     test_variable++;
284   if (test_variable != 4)
285     abort ();
287   return 0;