xref: /llvm-project/bolt/test/runtime/X86/rethrow.cpp (revision 3ac46f377a06f344705f334640c4e1d5eca4e9c0)
1 #include <iostream>
2 #include <stdexcept>
3 
erringFunc()4 void erringFunc() { throw std::runtime_error("Hello"); }
5 
libCallA()6 void libCallA() { erringFunc(); }
7 
libCallB()8 void libCallB() { throw std::runtime_error("World"); }
9 
handleEventA()10 void handleEventA() {
11   try {
12     libCallA();
13   } catch (std::runtime_error &E) {
14     std::cout << "handleEventA: unhandled error " << E.what() << "\n";
15     throw;
16   }
17 }
18 
handleEventB()19 void handleEventB() {
20   try {
21     libCallB();
22   } catch (std::runtime_error &E) {
23     std::cout << "handleEventB: handle error " << E.what() << "\n";
24   }
25 }
26 
27 class EventGen {
28   unsigned RemainingEvents = 5;
29 
30 public:
generateEvent()31   int generateEvent() {
32     if (RemainingEvents > 0) {
33       --RemainingEvents;
34       return (RemainingEvents % 3) + 1;
35     }
36     return 0;
37   }
38 };
39 
40 class TerminateException : public std::runtime_error {
41 public:
TerminateException()42   TerminateException() : std::runtime_error("Time to stop!") {}
43 };
44 
runEventLoop(EventGen & EG)45 void runEventLoop(EventGen &EG) {
46   while (true) {
47     try {
48       int Ev = EG.generateEvent();
49       switch (Ev) {
50       case 0:
51         throw TerminateException();
52       case 1:
53         handleEventA();
54         break;
55       case 2:
56         handleEventB();
57         break;
58       }
59     } catch (TerminateException &E) {
60       std::cout << "Terminated?\n";
61       throw;
62     } catch (std::runtime_error &E) {
63       std::cout << "Unhandled error: " << E.what() << "\n";
64     }
65   }
66 }
67 
68 struct CleanUp {
~CleanUpCleanUp69   ~CleanUp() { std::cout << "Cleanup\n"; }
70 };
71 
main()72 int main() {
73   EventGen EG;
74   try {
75     CleanUp CU;
76     runEventLoop(EG);
77   } catch (TerminateException &E) {
78     std::cout << "Terminated!\n";
79   }
80   return 0;
81 }
82 
83 /*
84 REQUIRES: system-linux
85 
86 RUN: %clang++ %cflags %s -o %t.exe -Wl,-q
87 RUN: llvm-bolt %t.exe --split-functions --split-strategy=randomN \
88 RUN:         --split-all-cold --split-eh --bolt-seed=7 -o %t.bolt
89 RUN: %t.bolt | FileCheck %s
90 
91 CHECK: handleEventB: handle error World
92 CHECK-NEXT: handleEventA: unhandled error Hello
93 CHECK-NEXT: Unhandled error: Hello
94 CHECK-NEXT: handleEventB: handle error World
95 CHECK-NEXT: handleEventA: unhandled error Hello
96 CHECK-NEXT: Unhandled error: Hello
97 CHECK-NEXT: Terminated?
98 CHECK-NEXT: Cleanup
99 CHECK-NEXT: Terminated!
100 */
101