summaryrefslogtreecommitdiff
path: root/gcc/testsuite/gcc.dg/pr45506.c
blob: e934dc93cce26375fec0e19815240e2e8934131e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
/* { dg-do compile } */
/* { dg-require-effective-target ilp32 } */
/* { dg-options "-g -O -w" } */

typedef unsigned _GCC_ATTR_ALIGN_u32t;
typedef _GCC_ATTR_ALIGN_u32t _Uint32t __attribute__((__aligned__(4)));
typedef int _Intptrt __attribute__((__mode__(__pointer__)));
typedef unsigned int _Uintptrt __attribute__((__mode__(__pointer__)));
typedef _Intptrt ptrdiff_t;
typedef _Uintptrt uintptr_t;
typedef _Uint32t Elf32_Word;
typedef struct list_head list_head_t;

struct list_head {
  list_head_t *next;
};

struct object { };

struct objlist {
  struct object *object;
};

static uintptr_t ldd(void *frame) __attribute__((__used__));
static list_head_t *_dl_all_objects_ptr;
static void fini_array(struct object *const obj) {
  if ((dynvec(obj,(unsigned)26)) != ((Elf32_Word)-1)) {
    unsigned i;
    const unsigned funcs = (dynvec(obj,(unsigned)28)) / 4;
    const Elf32_Word fa = (dynvec(obj,(unsigned)26));
    const int *const p = relative_relocp(obj);
    for (i = (funcs ? (funcs - 1) : 0U); i != 0U; i--) {
      void (*const func)(void) = (void *) p[i];
      (*func)();
    }
  }
}
static void _do_exit_fini(void) {
  const struct objlist *o;
  for (((o)) = ((void *)(((list_head_t *)(_dl_all_objects_ptr))->next));
       !((((o))) == ((void *)((list_head_t *)(_dl_all_objects_ptr))));
       ((o)) = ((void *)(((list_head_t *)((o)))->next)))
    fini_array (o->object);
}
static uintptr_t ldd (void *frame) {
  atexit(_do_exit_fini);
}