1// { dg-do run { xfail powerpc-ibm-aix* } } 2// { dg-options "-flat_namespace" { target *-*-darwin[67]* } } 3// Test __cxa_vec routines 4// Copyright (C) 2000, 2005 Free Software Foundation, Inc. 5// Contributed by Nathan Sidwell 7 Apr 2000 <nathan@nathan@codesourcery.com> 6 7#if defined (__GXX_ABI_VERSION) && __GXX_ABI_VERSION >= 100 8#include <cxxabi.h> 9#include <stdio.h> 10#include <new> 11#include <stdlib.h> 12#include <setjmp.h> 13 14static int ctor_count = 0; 15static int dtor_count = 0; 16static bool dtor_repeat = false; 17 18// Allocate enough padding to hold an array cookie. 19#ifdef __ARM_EABI__ 20#define padding 8 21#else 22#define padding (sizeof (std::size_t)) 23#endif 24 25// our pseudo ctors and dtors 26static abi::__cxa_cdtor_return_type ctor (void *x) 27{ 28 if (!ctor_count) 29 throw 1; 30 ctor_count--; 31#ifdef __ARM_EABI__ 32 return x; 33#endif 34} 35 36static abi::__cxa_cdtor_return_type dtor (void *x) 37{ 38 if (!dtor_count) 39 { 40 if (!dtor_repeat) 41 dtor_count--; 42 throw 1; 43 } 44 dtor_count--; 45#ifdef __ARM_EABI__ 46 return x; 47#endif 48} 49 50// track new and delete 51static int blocks = 0; 52void *operator new[] (std::size_t size) throw (std::bad_alloc) 53{ 54 void *ptr = malloc (size); 55 56 if (!ptr) 57 throw std::bad_alloc (); 58 blocks++; 59 return ptr; 60} 61 62void operator delete[] (void *ptr) throw () 63{ 64 if (ptr) 65 { 66 free (ptr); 67 blocks--; 68 } 69} 70static jmp_buf jump; 71 72// allocate and delete an array with no problems 73void test0 () 74{ 75 static bool started = false; 76 77 if (!started) 78 { 79 started = true; 80 std::set_terminate (test0); 81 82 ctor_count = dtor_count = 5; 83 dtor_repeat = false; 84 blocks = 0; 85 86 try 87 { 88 void *ary = abi::__cxa_vec_new (5, 1, padding, ctor, dtor); 89 abi::__cxa_vec_delete (ary, 1, padding, dtor); 90 if (ctor_count || dtor_count || blocks) 91 longjmp (jump, 1); 92 } 93 catch (...) 94 { 95 longjmp (jump, 2); 96 } 97 } 98 else 99 { 100 longjmp (jump, 3); 101 } 102 return; 103} 104 105// allocate and delete an array with exception on ctor 106void test1 () 107{ 108 static bool started = false; 109 110 if (!started) 111 { 112 started = true; 113 std::set_terminate (test1); 114 115 ctor_count = dtor_count = 5; 116 dtor_repeat = false; 117 blocks = 0; 118 119 ctor_count = 4; 120 try 121 { 122 void *ary = abi::__cxa_vec_new (5, 1, padding, ctor, dtor); 123 longjmp (jump, 1); 124 } 125 catch (...) 126 { 127 // we expect to get here 128 if (ctor_count || dtor_count != 1 || blocks) 129 longjmp (jump, 2); 130 } 131 } 132 else 133 { 134 longjmp (jump, 3); 135 } 136 return; 137} 138 139// allocate and delete an array with exception on dtor 140void test2 () 141{ 142 static bool started = false; 143 144 if (!started) 145 { 146 started = true; 147 std::set_terminate (test2); 148 ctor_count = dtor_count = 5; 149 dtor_repeat = false; 150 blocks = 0; 151 152 dtor_count = 3; 153 try 154 { 155 void *ary = abi::__cxa_vec_new (5, 1, padding, ctor, dtor); 156 abi::__cxa_vec_delete (ary, 1, padding, dtor); 157 longjmp (jump, 1); 158 } 159 catch (...) 160 { 161 // we expect to get here 162 if (ctor_count || dtor_count != -2u || blocks) 163 longjmp (jump, 2); 164 } 165 } 166 else 167 { 168 longjmp (jump, 3); 169 } 170 return; 171} 172 173// allocate an array with double exception on dtor 174void test3 () 175{ 176 static bool started = false; 177 178 if (!started) 179 { 180 started = true; 181 std::set_terminate (test3); 182 183 ctor_count = dtor_count = 5; 184 dtor_repeat = false; 185 blocks = 0; 186 187 dtor_count = 3; 188 dtor_repeat = true; 189 try 190 { 191 void *ary = abi::__cxa_vec_new (5, 1, padding, ctor, dtor); 192 abi::__cxa_vec_delete (ary, 1, padding, dtor); 193 longjmp (jump, 1); 194 } 195 catch (...) 196 { 197 // we do not expect to get here 198 longjmp (jump, 2); 199 } 200 } 201 else 202 { 203 // we expect to get here (via terminate) 204 if (ctor_count || dtor_count || blocks != 1) 205 longjmp (jump, 3); 206 longjmp (jump, -1); 207 } 208 return; 209} 210 211// allocate an array with exception on ctor and exception in cleanup 212void test4 () 213{ 214 static bool started = false; 215 216 if (!started) 217 { 218 started = true; 219 std::set_terminate (test4); 220 221 ctor_count = dtor_count = 5; 222 dtor_repeat = false; 223 blocks = 0; 224 225 ctor_count = 3; 226 dtor_count = 2; 227 try 228 { 229 void *ary = abi::__cxa_vec_new (5, 1, padding, ctor, dtor); 230 longjmp (jump, 1); 231 } 232 catch (...) 233 { 234 // we do not expect to get here 235 longjmp (jump, 2); 236 } 237 } 238 else 239 { 240 // we expect to get here (via terminate) 241 if (ctor_count || dtor_count != -1u || blocks != 1) 242 longjmp (jump, 3); 243 longjmp (jump, -1); 244 } 245 return; 246} 247 248static void (*tests[])() = 249{ 250 test0, 251 test1, 252 test2, 253 test3, 254 test4, 255 NULL 256}; 257 258int main () 259{ 260 int ix; 261 int n; 262 int errors = 0; 263 264 for (ix = 0; tests[ix]; ix++) 265 { 266 if (n = setjmp (jump)) 267 { 268 if (n > 0) 269 { 270 printf ("test %d failed %d\n", ix, n); 271 errors++; 272 } 273 } 274 else 275 tests[ix] (); 276 } 277 return errors; 278} 279 280#else 281int main () 282{ 283 return 0; 284} 285#endif 286