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