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 #include "cxxabi.h" 11 12 #include <stdio.h> 13 #include <cstdlib> 14 15 void my_terminate () { exit ( 0 ); } 16 17 // Wrapper routines 18 void *my_alloc2 ( size_t sz ) { 19 void *p = std::malloc ( sz ); 20 // std::printf ( "Allocated %ld bytes at %lx\n", sz, (unsigned long) p ); 21 return p; 22 } 23 24 void my_dealloc2 ( void *p ) { 25 // std::printf ( "Freeing %lx\n", (unsigned long) p ); 26 std::free ( p ); 27 } 28 29 void my_dealloc3 ( void *p, size_t sz ) { 30 // std::printf ( "Freeing %lx (size %ld)\n", (unsigned long) p, sz ); 31 std::free ( p ); 32 } 33 34 #ifdef __arm__ 35 #define CTOR_RETURN_TYPE void* 36 #define CTOR_RETURN(x) return x 37 #else 38 #define CTOR_RETURN_TYPE void 39 #define CTOR_RETURN(x) return 40 #endif 41 42 CTOR_RETURN_TYPE my_construct ( void *p ) { 43 // printf ( "Constructing %p\n", p ); 44 CTOR_RETURN(p); 45 } 46 47 CTOR_RETURN_TYPE my_destruct ( void *p ) { 48 // printf ( "Destructing %p\n", p ); 49 CTOR_RETURN(p); 50 } 51 52 int gCounter; 53 CTOR_RETURN_TYPE count_construct ( void *p ) { ++gCounter; CTOR_RETURN(p); } 54 CTOR_RETURN_TYPE count_destruct ( void *p ) { --gCounter; CTOR_RETURN(p); } 55 56 57 int gConstructorCounter; 58 int gConstructorThrowTarget; 59 int gDestructorCounter; 60 int gDestructorThrowTarget; 61 CTOR_RETURN_TYPE throw_construct ( void *p ) { 62 if ( gConstructorCounter == gConstructorThrowTarget ) 63 throw 1; 64 ++gConstructorCounter; 65 CTOR_RETURN(p); 66 } 67 68 CTOR_RETURN_TYPE throw_destruct ( void *p ) { 69 if ( ++gDestructorCounter == gDestructorThrowTarget ) 70 throw 2; 71 CTOR_RETURN(p); 72 } 73 74 struct vec_on_stack { 75 void *storage; 76 vec_on_stack () : storage ( __cxxabiv1::__cxa_vec_new ( 10, 40, 8, throw_construct, throw_destruct )) {} 77 ~vec_on_stack () { __cxxabiv1::__cxa_vec_delete ( storage, 40, 8, throw_destruct ); } 78 }; 79 80 81 // Make sure the constructors and destructors are matched 82 void test_exception_in_destructor ( ) { 83 84 // Try throwing from a destructor while unwinding the stack -- should abort 85 gConstructorCounter = gDestructorCounter = 0; 86 gConstructorThrowTarget = -1; 87 gDestructorThrowTarget = 5; 88 try { 89 vec_on_stack v; 90 throw 3; 91 } 92 catch ( int i ) {} 93 94 fprintf(stderr, "should never get here\n"); 95 } 96 97 98 99 int main ( int argc, char *argv [] ) { 100 std::set_terminate ( my_terminate ); 101 test_exception_in_destructor (); 102 return 1; // we failed if we get here 103 } 104