OSDN Git Service

* g++.dg/init/new1.C, g++.dg/template/alignof1.C,
[pf3gnuchains/gcc-fork.git] / gcc / testsuite / gcc.c-torture / compile / 20010102-1.c
1 /* This testcase derives from gnu obstack.c/obstack.h and failed with
2    -O3 -funroll-all-loops, or -O1 -frename-registers -funroll-loops on
3    sparc-sun-solaris2.7.
4
5    Copyright (C) 2001  Free Software Foundation.  */
6
7 # define PTR_INT_TYPE __PTRDIFF_TYPE__
8
9 struct _obstack_chunk
10 {
11   char  *limit;
12   struct _obstack_chunk *prev;
13   char  contents[4];
14 };
15
16 struct obstack
17 {
18   long  chunk_size;
19   struct _obstack_chunk *chunk;
20   char  *object_base;
21   char  *next_free;
22   char  *chunk_limit;
23   PTR_INT_TYPE temp;
24   int   alignment_mask;
25   struct _obstack_chunk *(*chunkfun) (void *, long);
26   void (*freefun) (void *, struct _obstack_chunk *);
27   void *extra_arg;
28   unsigned use_extra_arg:1;
29   unsigned maybe_empty_object:1;
30   unsigned alloc_failed:1;
31 };
32
33 extern void _obstack_newchunk (struct obstack *, int);
34
35 struct fooalign {char x; double d;};
36 #define DEFAULT_ALIGNMENT  \
37   ((PTR_INT_TYPE) ((char *) &((struct fooalign *) 0)->d - (char *) 0))
38 union fooround {long x; double d;};
39 #define DEFAULT_ROUNDING (sizeof (union fooround))
40
41 #ifndef COPYING_UNIT
42 #define COPYING_UNIT int
43 #endif
44
45 #define CALL_CHUNKFUN(h, size) \
46   (((h) -> use_extra_arg) \
47    ? (*(h)->chunkfun) ((h)->extra_arg, (size)) \
48    : (*(struct _obstack_chunk *(*) (long)) (h)->chunkfun) ((size)))
49
50 #define CALL_FREEFUN(h, old_chunk) \
51   do { \
52     if ((h) -> use_extra_arg) \
53       (*(h)->freefun) ((h)->extra_arg, (old_chunk)); \
54     else \
55       (*(void (*) (void *)) (h)->freefun) ((old_chunk)); \
56   } while (0)
57
58 void
59 _obstack_newchunk (h, length)
60      struct obstack *h;
61      int length;
62 {
63   register struct _obstack_chunk *old_chunk = h->chunk;
64   register struct _obstack_chunk *new_chunk;
65   register long new_size;
66   register long obj_size = h->next_free - h->object_base;
67   register long i;
68   long already;
69
70   new_size = (obj_size + length) + (obj_size >> 3) + 100;
71   if (new_size < h->chunk_size)
72     new_size = h->chunk_size;
73
74   new_chunk = CALL_CHUNKFUN (h, new_size);
75   h->chunk = new_chunk;
76   new_chunk->prev = old_chunk;
77   new_chunk->limit = h->chunk_limit = (char *) new_chunk + new_size;
78
79   if (h->alignment_mask + 1 >= DEFAULT_ALIGNMENT)
80     {
81       for (i = obj_size / sizeof (COPYING_UNIT) - 1;
82            i >= 0; i--)
83         ((COPYING_UNIT *)new_chunk->contents)[i]
84           = ((COPYING_UNIT *)h->object_base)[i];
85       already = obj_size / sizeof (COPYING_UNIT) * sizeof (COPYING_UNIT);
86     }
87   else
88     already = 0;
89   for (i = already; i < obj_size; i++)
90     new_chunk->contents[i] = h->object_base[i];
91
92   if (h->object_base == old_chunk->contents && ! h->maybe_empty_object)
93     {
94       new_chunk->prev = old_chunk->prev;
95       CALL_FREEFUN (h, old_chunk);
96     }
97
98   h->object_base = new_chunk->contents;
99   h->next_free = h->object_base + obj_size;
100   h->maybe_empty_object = 0;
101 }