For exception handling, LSDA call sites have to be emitted for each fragment individually. With this patch, call sites and respective LSDA symbols are generated and associated with each fragment of their function, such that they can be used by the emitter. Reviewed By: maksfb Differential Revision: https://reviews.llvm.org/D132052
101 lines
2.1 KiB
C++
101 lines
2.1 KiB
C++
#include <iostream>
|
|
#include <stdexcept>
|
|
|
|
void erringFunc() { throw std::runtime_error("Hello"); }
|
|
|
|
void libCallA() { erringFunc(); }
|
|
|
|
void libCallB() { throw std::runtime_error("World"); }
|
|
|
|
void handleEventA() {
|
|
try {
|
|
libCallA();
|
|
} catch (std::runtime_error &E) {
|
|
std::cout << "handleEventA: unhandled error " << E.what() << "\n";
|
|
throw;
|
|
}
|
|
}
|
|
|
|
void handleEventB() {
|
|
try {
|
|
libCallB();
|
|
} catch (std::runtime_error &E) {
|
|
std::cout << "handleEventB: handle error " << E.what() << "\n";
|
|
}
|
|
}
|
|
|
|
class EventGen {
|
|
unsigned RemainingEvents = 5;
|
|
|
|
public:
|
|
int generateEvent() {
|
|
if (RemainingEvents > 0) {
|
|
--RemainingEvents;
|
|
return (RemainingEvents % 3) + 1;
|
|
}
|
|
return 0;
|
|
}
|
|
};
|
|
|
|
class TerminateException : public std::runtime_error {
|
|
public:
|
|
TerminateException() : std::runtime_error("Time to stop!") {}
|
|
};
|
|
|
|
void runEventLoop(EventGen &EG) {
|
|
while (true) {
|
|
try {
|
|
int Ev = EG.generateEvent();
|
|
switch (Ev) {
|
|
case 0:
|
|
throw TerminateException();
|
|
case 1:
|
|
handleEventA();
|
|
break;
|
|
case 2:
|
|
handleEventB();
|
|
break;
|
|
}
|
|
} catch (TerminateException &E) {
|
|
std::cout << "Terminated?\n";
|
|
throw;
|
|
} catch (std::runtime_error &E) {
|
|
std::cout << "Unhandled error: " << E.what() << "\n";
|
|
}
|
|
}
|
|
}
|
|
|
|
struct CleanUp {
|
|
~CleanUp() { std::cout << "Cleanup\n"; }
|
|
};
|
|
|
|
int main() {
|
|
EventGen EG;
|
|
try {
|
|
CleanUp CU;
|
|
runEventLoop(EG);
|
|
} catch (TerminateException &E) {
|
|
std::cout << "Terminated!\n";
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
/*
|
|
REQUIRES: system-linux
|
|
|
|
RUN: %clang++ %cflags %s -o %t.exe -Wl,-q
|
|
RUN: llvm-bolt %t.exe --split-functions --split-strategy=randomN \
|
|
RUN: --split-all-cold --split-eh --bolt-seed=7 -o %t.bolt
|
|
RUN: %t.bolt | FileCheck %s
|
|
|
|
CHECK: handleEventB: handle error World
|
|
CHECK-NEXT: handleEventA: unhandled error Hello
|
|
CHECK-NEXT: Unhandled error: Hello
|
|
CHECK-NEXT: handleEventB: handle error World
|
|
CHECK-NEXT: handleEventA: unhandled error Hello
|
|
CHECK-NEXT: Unhandled error: Hello
|
|
CHECK-NEXT: Terminated?
|
|
CHECK-NEXT: Cleanup
|
|
CHECK-NEXT: Terminated!
|
|
*/
|