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