1 // UNSUPPORTED: libunwind-no-exceptions
2 // Tell lit to add -lc++abi/-lcxxrt/-lsupc++, etc. to the linker flags:
3 // ADDITIONAL_LINK_FLAGS: %{link_libcxxabi}
4
5 #include <stdio.h>
6 #include <stdlib.h>
7
8 static int dtors_called = 0;
9
10 struct WithCleanup {
WithCleanupWithCleanup11 WithCleanup(const char *func) : func(func) {
12 fprintf(stderr, "Created object with destructor in %s!\n", func);
13 }
WithCleanupWithCleanup14 WithCleanup(const WithCleanup &other) : func(other.func) {
15 fprintf(stderr, "struct WithCleanup(%s) copied!\n", func);
16 }
~WithCleanupWithCleanup17 ~WithCleanup() {
18 fprintf(stderr, "Calling destructor in %s!\n", func);
19 dtors_called++;
20 }
21
22 private:
23 const char *func;
24 };
25
26 struct SomeException {
SomeExceptionSomeException27 SomeException(const char *message) : message(message) {}
28 const char *message;
29 };
30
raise_exception(bool raise)31 __attribute__((noinline)) int raise_exception(bool raise) {
32 if (raise) {
33 fprintf(stderr, "About to throw an exception...\n");
34 throw SomeException("Exception occurred.");
35 } else {
36 fprintf(stderr, "Not throwing yet...\n");
37 }
38 return 0;
39 };
40
test_function()41 __attribute__((noinline)) void test_function() {
42 fprintf(stderr, "%s: enter\n", __func__);
43 raise_exception(false);
44 WithCleanup object(__func__);
45 raise_exception(true);
46 fprintf(stderr, "ERROR: returned from raise_exception!\n");
47 abort();
48 }
49
main()50 int main() {
51 try {
52 WithCleanup object(__func__);
53 fprintf(stderr, "About to call test_function!\n");
54 test_function();
55 fprintf(stderr, "ERROR: returned from test_function!\n");
56 abort();
57 } catch (const SomeException &s) {
58 fprintf(stderr, "%s: caught exception with message: %s\n", __func__,
59 s.message);
60 }
61 if (dtors_called != 2) {
62 fprintf(stderr, "Expected 2 destructors to be called but got %d\n",
63 dtors_called);
64 abort();
65 }
66 fprintf(stderr, "Success!\n");
67 return (0);
68 }
69