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