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