From 93aeb8c3bc3f13cb1f282e3e749258a23790d947 Mon Sep 17 00:00:00 2001 From: Ingo Weinhold Date: Wed, 16 Nov 2005 21:34:32 +0000 Subject: [PATCH] Added small app testing throwing/catching of exceptions beyond shared object bounds. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@14975 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- src/tests/misc/Jamfile | 2 + src/tests/misc/exception-test/Jamfile | 12 ++ .../misc/exception-test/exception-test.cpp | 204 ++++++++++++++++++ src/tests/misc/exception-test/exceptions.cpp | 28 +++ src/tests/misc/exception-test/exceptions.h | 52 +++++ 5 files changed, 298 insertions(+) create mode 100644 src/tests/misc/exception-test/Jamfile create mode 100644 src/tests/misc/exception-test/exception-test.cpp create mode 100644 src/tests/misc/exception-test/exceptions.cpp create mode 100644 src/tests/misc/exception-test/exceptions.h diff --git a/src/tests/misc/Jamfile b/src/tests/misc/Jamfile index ae02e548b3..d18e2ecb25 100644 --- a/src/tests/misc/Jamfile +++ b/src/tests/misc/Jamfile @@ -3,3 +3,5 @@ SubDir HAIKU_TOP src tests misc ; SetSubDirSupportedPlatformsBeOSCompatible ; SimpleTest rtti-test : rtti-test.cpp : be ; + +SubInclude HAIKU_TOP src tests misc exception-test ; diff --git a/src/tests/misc/exception-test/Jamfile b/src/tests/misc/exception-test/Jamfile new file mode 100644 index 0000000000..1309c8444f --- /dev/null +++ b/src/tests/misc/exception-test/Jamfile @@ -0,0 +1,12 @@ +SubDir HAIKU_TOP src tests misc exception-test ; + +SetSubDirSupportedPlatformsBeOSCompatible ; + +SharedLibrary libexceptiontest.so + : exceptions.cpp +; + +SimpleTest exception-test + : exception-test.cpp + : libexceptiontest.so $(TARGET_LIBSTDC++) +; diff --git a/src/tests/misc/exception-test/exception-test.cpp b/src/tests/misc/exception-test/exception-test.cpp new file mode 100644 index 0000000000..29e655db2c --- /dev/null +++ b/src/tests/misc/exception-test/exception-test.cpp @@ -0,0 +1,204 @@ +#include + +#include + +#include "exceptions.h" + +using std::string; + +static const char *kCaughtNothing = "nothing"; +static const char *kCaughtGeneric = "generic"; +static const char *kCaughtBase = "ExceptionBase"; +static const char *kCaughtA = "ExceptionA"; +static const char *kCaughtB = "ExceptionB"; +static const char *kCaughtVirtualBase = "VirtualExceptionBase"; +static const char *kCaughtVirtualA = "VirtualExceptionA"; +static const char *kCaughtVirtualB = "VirtualExceptionB"; +static const char *kCaughtInt = "VirtualInt"; + + +static string +catchBase(void (*function)()) +{ + try { + (*function)(); + } catch (ExceptionBase exception) { + return kCaughtBase; + } catch (...) { + return kCaughtGeneric; + } + return kCaughtNothing; +} + + +static string +catchA(void (*function)()) +{ + try { + (*function)(); + } catch (ExceptionA exception) { + return kCaughtA; + } catch (...) { + return kCaughtGeneric; + } + return kCaughtNothing; +} + + +static string +catchB(void (*function)()) +{ + try { + (*function)(); + } catch (ExceptionB exception) { + return kCaughtB; + } catch (...) { + return kCaughtGeneric; + } + return kCaughtNothing; +} + + +static string +catchVirtualBase(void (*function)()) +{ + try { + (*function)(); + } catch (VirtualExceptionBase exception) { + return kCaughtVirtualBase; + } catch (...) { + return kCaughtGeneric; + } + return kCaughtNothing; +} + + +static string +catchVirtualA(void (*function)()) +{ + try { + (*function)(); + } catch (VirtualExceptionA exception) { + return kCaughtVirtualA; + } catch (...) { + return kCaughtGeneric; + } + return kCaughtNothing; +} + + +static string +catchVirtualB(void (*function)()) +{ + try { + (*function)(); + } catch (VirtualExceptionB exception) { + return kCaughtVirtualB; + } catch (...) { + return kCaughtGeneric; + } + return kCaughtNothing; +} + + +static string +catchInt(void (*function)()) +{ + try { + (*function)(); + } catch (int exception) { + return kCaughtInt; + } catch (...) { + return kCaughtGeneric; + } + return kCaughtNothing; +} + +static string +catchAny(void (*function)()) +{ + try { + (*function)(); + } catch (int exception) { + return kCaughtInt; + } catch (VirtualExceptionA exception) { + return kCaughtVirtualA; + } catch (VirtualExceptionB exception) { + return kCaughtVirtualB; + } catch (VirtualExceptionBase exception) { + return kCaughtVirtualBase; + } catch (ExceptionA exception) { + return kCaughtA; + } catch (ExceptionB exception) { + return kCaughtB; + } catch (ExceptionBase exception) { + return kCaughtBase; + } catch (...) { + return kCaughtGeneric; + } + return kCaughtNothing; +} + +static void +test(string (*catcher)(void (*)()), void (*thrower)(), const char *expected) +{ + string caught((*catcher)(thrower)); + if (caught != expected) { + printf("ERROR: expected exception: %s, but caught: %s\n", expected, + caught.c_str()); + } +} + +int +main() +{ + test(catchBase, throwBase, kCaughtBase); + test(catchBase, throwA, kCaughtBase); + test(catchBase, throwB, kCaughtBase); + test(catchBase, throwVirtualBase, kCaughtBase); + test(catchBase, throwVirtualA, kCaughtBase); + test(catchBase, throwVirtualB, kCaughtBase); + test(catchBase, throwInt, kCaughtGeneric); + + test(catchA, throwBase, kCaughtGeneric); + test(catchA, throwA, kCaughtA); + test(catchA, throwB, kCaughtGeneric); + test(catchA, throwVirtualBase, kCaughtGeneric); + test(catchA, throwVirtualA, kCaughtGeneric); + test(catchA, throwVirtualB, kCaughtGeneric); + test(catchA, throwInt, kCaughtGeneric); + + test(catchVirtualBase, throwBase, kCaughtGeneric); + test(catchVirtualBase, throwA, kCaughtGeneric); + test(catchVirtualBase, throwB, kCaughtGeneric); + test(catchVirtualBase, throwVirtualBase, kCaughtVirtualBase); + test(catchVirtualBase, throwVirtualA, kCaughtVirtualBase); + test(catchVirtualBase, throwVirtualB, kCaughtVirtualBase); + test(catchVirtualBase, throwInt, kCaughtGeneric); + + test(catchVirtualA, throwBase, kCaughtGeneric); + test(catchVirtualA, throwA, kCaughtGeneric); + test(catchVirtualA, throwB, kCaughtGeneric); + test(catchVirtualA, throwVirtualBase, kCaughtGeneric); + test(catchVirtualA, throwVirtualA, kCaughtVirtualA); + test(catchVirtualA, throwVirtualB, kCaughtGeneric); + test(catchVirtualA, throwInt, kCaughtGeneric); + + test(catchInt, throwBase, kCaughtGeneric); + test(catchInt, throwA, kCaughtGeneric); + test(catchInt, throwB, kCaughtGeneric); + test(catchInt, throwVirtualBase, kCaughtGeneric); + test(catchInt, throwVirtualA, kCaughtGeneric); + test(catchInt, throwVirtualB, kCaughtGeneric); + test(catchInt, throwInt, kCaughtInt); + + test(catchAny, throwBase, kCaughtBase); + test(catchAny, throwA, kCaughtA); + test(catchAny, throwB, kCaughtB); + test(catchAny, throwVirtualBase, kCaughtVirtualBase); + test(catchAny, throwVirtualA, kCaughtVirtualA); + test(catchAny, throwVirtualB, kCaughtVirtualB); + test(catchAny, throwInt, kCaughtInt); + + return 0; +} diff --git a/src/tests/misc/exception-test/exceptions.cpp b/src/tests/misc/exception-test/exceptions.cpp new file mode 100644 index 0000000000..05f870053d --- /dev/null +++ b/src/tests/misc/exception-test/exceptions.cpp @@ -0,0 +1,28 @@ + +#include "exceptions.h" + +ExceptionBase::ExceptionBase() {} +ExceptionBase::~ExceptionBase() {} + +ExceptionA::ExceptionA() {} +ExceptionA::~ExceptionA() {} + +ExceptionB::ExceptionB() {} +ExceptionB::~ExceptionB() {} + +VirtualExceptionBase::VirtualExceptionBase() {} +VirtualExceptionBase::~VirtualExceptionBase() {} + +VirtualExceptionA::VirtualExceptionA() {} +VirtualExceptionA::~VirtualExceptionA() {} + +VirtualExceptionB::VirtualExceptionB() {} +VirtualExceptionB::~VirtualExceptionB() {} + +void throwBase() { throw ExceptionBase(); } +void throwA() { throw ExceptionA(); } +void throwB() { throw ExceptionB(); } +void throwVirtualBase() { throw VirtualExceptionBase(); } +void throwVirtualA() { throw VirtualExceptionA(); } +void throwVirtualB() { throw VirtualExceptionB(); } +void throwInt() { throw int(7); } diff --git a/src/tests/misc/exception-test/exceptions.h b/src/tests/misc/exception-test/exceptions.h new file mode 100644 index 0000000000..0a3beb725b --- /dev/null +++ b/src/tests/misc/exception-test/exceptions.h @@ -0,0 +1,52 @@ + +#ifndef EXCEPTIONS_H +#define EXCEPTIONS_H + +struct ExceptionBase { + ExceptionBase(); + ~ExceptionBase(); +}; + +struct ExceptionA : ExceptionBase { + ExceptionA(); + ~ExceptionA(); + + int a; +}; + +struct ExceptionB : ExceptionBase { + ExceptionB(); + ~ExceptionB(); + + int b; +}; + +struct VirtualExceptionBase : ExceptionBase { + VirtualExceptionBase(); + virtual ~VirtualExceptionBase(); +}; + +struct VirtualExceptionA : VirtualExceptionBase { + VirtualExceptionA(); + virtual ~VirtualExceptionA(); + + int a; +}; + +struct VirtualExceptionB : VirtualExceptionBase { + VirtualExceptionB(); + virtual ~VirtualExceptionB(); + + int b; +}; + +void throwBase(); +void throwA(); +void throwB(); +void throwVirtualBase(); +void throwVirtualA(); +void throwVirtualB(); +void throwInt(); + + +#endif // EXCEPTIONS_H