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 <iostream>
13#include <cstdlib>
14
15void my_terminate () { exit ( 0 ); }
16
17//  Wrapper routines
18void *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
24void my_dealloc2 ( void *p ) {
25//  std::printf ( "Freeing %lx\n", (unsigned long) p );
26    std::free ( p );
27    }
28
29void 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
34void my_construct ( void *p ) {
35//  std::printf ( "Constructing %lx\n", (unsigned long) p );
36    }
37
38void my_destruct  ( void *p ) {
39//  std::printf ( "Destructing  %lx\n", (unsigned long) p );
40    }
41
42int gCounter;
43void count_construct ( void *p ) { ++gCounter; }
44void count_destruct  ( void *p ) { --gCounter; }
45
46
47int gConstructorCounter;
48int gConstructorThrowTarget;
49int gDestructorCounter;
50int gDestructorThrowTarget;
51void throw_construct ( void *p ) { if ( gConstructorCounter   == gConstructorThrowTarget ) throw 1; ++gConstructorCounter; }
52void throw_destruct  ( void *p ) { if ( ++gDestructorCounter  == gDestructorThrowTarget  ) throw 2; }
53
54struct vec_on_stack {
55    void *storage;
56    vec_on_stack () : storage ( __cxxabiv1::__cxa_vec_new    (            10, 40, 8, throw_construct, throw_destruct )) {}
57    ~vec_on_stack () {          __cxxabiv1::__cxa_vec_delete ( storage,       40, 8,                  throw_destruct );  }
58    };
59
60
61//  Make sure the constructors and destructors are matched
62void test_exception_in_destructor ( ) {
63
64//  Try throwing from a destructor while unwinding the stack -- should abort
65    gConstructorCounter = gDestructorCounter = 0;
66    gConstructorThrowTarget = -1;
67    gDestructorThrowTarget  = 5;
68    try {
69        vec_on_stack v;
70        throw 3;
71        }
72    catch ( int i ) {}
73
74    std::cerr << "should never get here" << std::endl;
75    }
76
77
78
79int main ( int argc, char *argv [] ) {
80    std::set_terminate ( my_terminate );
81    test_exception_in_destructor ();
82    return 1;       // we failed if we get here
83    }
84