Daily bump.
[official-gcc.git] / gcc / testsuite / g++.old-deja / g++.eh / badalloc1.C
blob7fd35308dc6414dc2338b0544d70bf284b67b69c
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, 2010, 2012, 2014 Free Software Foundation, Inc.
7 // Contributed by Nathan Sidwell 6 June 2000 <nathan@codesourcery.com>
9 // Check we can throw a bad_alloc exception when malloc dies.
11 typedef __SIZE_TYPE__ size_t;
12 extern "C" void abort();
13 extern "C" void *memcpy(void *, const void *, size_t);
15 // libstdc++ requires a large initialization time allocation for the
16 // emergency EH allocation pool.  Add that to the arena size.
18 #if defined(__FreeBSD__) || defined(__sun__) || defined(__hpux__)
19 // FreeBSD, Solaris and HP-UX require even more space at initialization time.
20 // FreeBSD 5 now requires over 131072 bytes.
21 const int arena_size = 262144 + 72 * 1024;
22 #else
23 // Because pointers make up the bulk of our exception-initialization
24 // allocations, we scale by the pointer size from the original
25 // 32-bit-systems-based estimate.
26 const int arena_size = 32768 * ((sizeof (void *) + 3)/4) + 72 * 1024;
27 #endif
29 struct object
31   size_t size __attribute__((aligned));
34 static char arena[arena_size] __attribute__((aligned));
35 static size_t pos;
37 // So we can force a failure when needed.
38 static int fail;
40 extern "C" void *malloc (size_t size)
42   object *p = reinterpret_cast<object *>(&arena[pos]);
44   if (fail)
45     return 0;
47   p->size = size;
48   size = (size + __alignof__(object) - 1) & - __alignof__(object);
49   pos += size + sizeof(object);
51   // Verify that we didn't run out of memory before getting initialized.
52   if (pos > arena_size)
53     abort ();
55   return p + 1;
58 extern "C" void free (void *)
62 extern "C" void *realloc (void *p, size_t size)
64   void *r;
66   if (p)
67     {
68       object *o = reinterpret_cast<object *>(p) - 1;
69       size_t old_size = o->size;
71       if (old_size >= size)
72         {
73           r = p;
74           o->size = size;
75         }
76       else
77         {
78           r = malloc (size);
79           memcpy (r, p, old_size);
80           free (p);
81         }
82     }
83   else
84     r = malloc (size);
86   return r;
89 void fn_throw()
90 #if __cplusplus <= 201402L
91 throw(int)                      // { dg-warning "deprecated" "" { target { c++11 && { ! c++17 } } } }
92 #endif
94   throw 1;
97 void fn_rethrow()
98 #if __cplusplus <= 201402L
99 throw(int)                      // { dg-warning "deprecated" "" { target { c++11 && { ! c++17 } } } }
100 #endif
102   try{fn_throw();}
103   catch(int a){
104     throw;}
107 void fn_catchthrow()
108 #if __cplusplus <= 201402L
109 throw(int)                      // { dg-warning "deprecated" "" { target { c++11 && { ! c++17 } } } }
110 #endif
112   try{fn_throw();}
113   catch(int a){
114     throw a + 1;}
117 int main()
119   /* On some systems (including FreeBSD and Solaris 2.10),
120      __cxa_get_globals will try to call "malloc" when threads are in
121      use.  Therefore, we throw one exception up front so that
122      __cxa_get_globals is all set up.  Ideally, this would not be
123      necessary, but it is a well-known idiom, and using this technique
124      means that we can still validate the fact that exceptions can be
125      thrown when malloc fails.  */
126   try{fn_throw();}
127   catch(int a){}
129   fail = 1;
131   try{fn_throw();}
132   catch(int a){}
134   try{fn_rethrow();}
135   catch(int a){}
137   try{fn_catchthrow();}
138   catch(int a){}
139   
140   return 0;