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
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
|
// This fails for VxWorks RTPs because the initialization of
// __cxa_allocate_exception's emergency buffer mutex will
// itself call malloc(), and will fail if there is no more
// memory available.
// { dg-do run { xfail { { xstormy16-*-* *-*-darwin[3-7]* } || vxworks_rtp } } }
// Copyright (C) 2000, 2002, 2003, 2010 Free Software Foundation, Inc.
// Contributed by Nathan Sidwell 6 June 2000 <nathan@codesourcery.com>
// Check we can throw a bad_alloc exception when malloc dies.
typedef __SIZE_TYPE__ size_t;
extern "C" void abort();
extern "C" void *memcpy(void *, const void *, size_t);
// Assume that STACK_SIZE defined implies a system that does not have a
// large data space either, and additionally that we're not linking against
// a shared libstdc++ (which requires quite a bit more initialization space).
#ifdef STACK_SIZE
const int arena_size = 256;
#else
#if defined(__FreeBSD__) || defined(__sun__) || defined(__hpux__) || defined(__osf__)
// FreeBSD, Solaris, HP-UX and Tru64 UNIX with threads require even more
// space at initialization time. FreeBSD 5 now requires over 131072 bytes.
const int arena_size = 262144;
#else
const int arena_size = 32768;
#endif
#endif
struct object
{
size_t size __attribute__((aligned));
};
static char arena[arena_size] __attribute__((aligned));
static size_t pos;
// So we can force a failure when needed.
static int fail;
extern "C" void *malloc (size_t size)
{
object *p = reinterpret_cast<object *>(&arena[pos]);
if (fail)
return 0;
p->size = size;
size = (size + __alignof__(object) - 1) & - __alignof__(object);
pos += size + sizeof(object);
// Verify that we didn't run out of memory before getting initialized.
if (pos > arena_size)
abort ();
return p + 1;
}
extern "C" void free (void *)
{
}
extern "C" void *realloc (void *p, size_t size)
{
void *r;
if (p)
{
object *o = reinterpret_cast<object *>(p) - 1;
size_t old_size = o->size;
if (old_size >= size)
{
r = p;
o->size = size;
}
else
{
r = malloc (size);
memcpy (r, p, old_size);
free (p);
}
}
else
r = malloc (size);
return r;
}
void fn_throw() throw(int)
{
throw 1;
}
void fn_rethrow() throw(int)
{
try{fn_throw();}
catch(int a){
throw;}
}
void fn_catchthrow() throw(int)
{
try{fn_throw();}
catch(int a){
throw a + 1;}
}
int main()
{
/* On some systems (including FreeBSD and Solaris 2.10),
__cxa_get_globals will try to call "malloc" when threads are in
use. Therefore, we throw one exception up front so that
__cxa_get_globals is all set up. Ideally, this would not be
necessary, but it is a well-known idiom, and using this technique
means that we can still validate the fact that exceptions can be
thrown when malloc fails. */
try{fn_throw();}
catch(int a){}
fail = 1;
try{fn_throw();}
catch(int a){}
try{fn_rethrow();}
catch(int a){}
try{fn_catchthrow();}
catch(int a){}
return 0;
}
|