1 //===--------------------------- test_vector2.cpp -------------------------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is dual licensed under the MIT and the University of Illinois Open 6 // Source Licenses. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 // UNSUPPORTED: libcxxabi-no-exceptions 11 12 #include "cxxabi.h" 13 14 #include <iostream> 15 #include <cstdlib> 16 17 void my_terminate () { exit ( 0 ); } 18 19 // Wrapper routines 20 void *my_alloc2 ( size_t sz ) { 21 void *p = std::malloc ( sz ); 22 // std::printf ( "Allocated %ld bytes at %lx\n", sz, (unsigned long) p ); 23 return p; 24 } 25 26 void my_dealloc2 ( void *p ) { 27 // std::printf ( "Freeing %lx\n", (unsigned long) p ); 28 std::free ( p ); 29 } 30 31 void my_dealloc3 ( void *p, size_t ) { 32 // std::printf ( "Freeing %lx (size %ld)\n", (unsigned long) p, sz ); 33 std::free ( p ); 34 } 35 36 void my_construct ( void *) { 37 // std::printf ( "Constructing %lx\n", (unsigned long) p ); 38 } 39 40 void my_destruct ( void *) { 41 // std::printf ( "Destructing %lx\n", (unsigned long) p ); 42 } 43 44 int gCounter; 45 void count_construct ( void * ) { ++gCounter; } 46 void count_destruct ( void * ) { --gCounter; } 47 48 49 int gConstructorCounter; 50 int gConstructorThrowTarget; 51 int gDestructorCounter; 52 int gDestructorThrowTarget; 53 void throw_construct ( void * ) { if ( gConstructorCounter == gConstructorThrowTarget ) throw 1; ++gConstructorCounter; } 54 void throw_destruct ( void * ) { if ( ++gDestructorCounter == gDestructorThrowTarget ) throw 2; } 55 56 struct vec_on_stack { 57 void *storage; 58 vec_on_stack () : storage ( __cxxabiv1::__cxa_vec_new ( 10, 40, 8, throw_construct, throw_destruct )) {} 59 ~vec_on_stack () { __cxxabiv1::__cxa_vec_delete ( storage, 40, 8, throw_destruct ); } 60 }; 61 62 63 // Make sure the constructors and destructors are matched 64 void test_exception_in_destructor ( ) { 65 66 // Try throwing from a destructor while unwinding the stack -- should abort 67 gConstructorCounter = gDestructorCounter = 0; 68 gConstructorThrowTarget = -1; 69 gDestructorThrowTarget = 5; 70 try { 71 vec_on_stack v; 72 throw 3; 73 } 74 catch ( int i ) {} 75 76 std::cerr << "should never get here" << std::endl; 77 } 78 79 80 81 int main () { 82 std::set_terminate ( my_terminate ); 83 test_exception_in_destructor (); 84 return 1; // we failed if we get here 85 } 86