/* This testcase derives from gnu obstack.c/obstack.h and failed with -O3 -funroll-all-loops, or -O1 -frename-registers -funroll-loops on sparc-sun-solaris2.7. Copyright (C) 2001 Free Software Foundation. */ # define PTR_INT_TYPE __PTRDIFF_TYPE__ struct _obstack_chunk { char *limit; struct _obstack_chunk *prev; char contents[4]; }; struct obstack { long chunk_size; struct _obstack_chunk *chunk; char *object_base; char *next_free; char *chunk_limit; PTR_INT_TYPE temp; int alignment_mask; struct _obstack_chunk *(*chunkfun) (void *, long); void (*freefun) (void *, struct _obstack_chunk *); void *extra_arg; unsigned use_extra_arg:1; unsigned maybe_empty_object:1; unsigned alloc_failed:1; }; extern void _obstack_newchunk (struct obstack *, int); struct fooalign {char x; double d;}; #define DEFAULT_ALIGNMENT \ ((PTR_INT_TYPE) ((char *) &((struct fooalign *) 0)->d - (char *) 0)) union fooround {long x; double d;}; #define DEFAULT_ROUNDING (sizeof (union fooround)) #ifndef COPYING_UNIT #define COPYING_UNIT int #endif #define CALL_CHUNKFUN(h, size) \ (((h) -> use_extra_arg) \ ? (*(h)->chunkfun) ((h)->extra_arg, (size)) \ : (*(struct _obstack_chunk *(*) (long)) (h)->chunkfun) ((size))) #define CALL_FREEFUN(h, old_chunk) \ do { \ if ((h) -> use_extra_arg) \ (*(h)->freefun) ((h)->extra_arg, (old_chunk)); \ else \ (*(void (*) (void *)) (h)->freefun) ((old_chunk)); \ } while (0) void _obstack_newchunk (h, length) struct obstack *h; int length; { register struct _obstack_chunk *old_chunk = h->chunk; register struct _obstack_chunk *new_chunk; register long new_size; register long obj_size = h->next_free - h->object_base; register long i; long already; new_size = (obj_size + length) + (obj_size >> 3) + 100; if (new_size < h->chunk_size) new_size = h->chunk_size; new_chunk = CALL_CHUNKFUN (h, new_size); h->chunk = new_chunk; new_chunk->prev = old_chunk; new_chunk->limit = h->chunk_limit = (char *) new_chunk + new_size; if (h->alignment_mask + 1 >= DEFAULT_ALIGNMENT) { for (i = obj_size / sizeof (COPYING_UNIT) - 1; i >= 0; i--) ((COPYING_UNIT *)new_chunk->contents)[i] = ((COPYING_UNIT *)h->object_base)[i]; already = obj_size / sizeof (COPYING_UNIT) * sizeof (COPYING_UNIT); } else already = 0; for (i = already; i < obj_size; i++) new_chunk->contents[i] = h->object_base[i]; if (h->object_base == old_chunk->contents && ! h->maybe_empty_object) { new_chunk->prev = old_chunk->prev; CALL_FREEFUN (h, old_chunk); } h->object_base = new_chunk->contents; h->next_free = h->object_base + obj_size; h->maybe_empty_object = 0; }