From 7f460e46d61904d75319c1cd1ce1d58265254641 Mon Sep 17 00:00:00 2001 From: Frederik Seiffert Date: Mon, 2 Dec 2019 10:16:13 +0100 Subject: [PATCH] Added additional exception tests. Adds ARC and ObjC++ variants of ExceptionTest. --- Test/CMakeLists.txt | 8 +++ Test/ExceptionTestObjCXX.mm | 97 +++++++++++++++++++++++++++++++ Test/ExceptionTestObjCXX_arc.mm | 96 ++++++++++++++++++++++++++++++ Test/ExceptionTest_arc.m | 100 ++++++++++++++++++++++++++++++++ 4 files changed, 301 insertions(+) create mode 100644 Test/ExceptionTestObjCXX.mm create mode 100644 Test/ExceptionTestObjCXX_arc.mm create mode 100644 Test/ExceptionTest_arc.m diff --git a/Test/CMakeLists.txt b/Test/CMakeLists.txt index 10993b80..40350315 100644 --- a/Test/CMakeLists.txt +++ b/Test/CMakeLists.txt @@ -26,6 +26,7 @@ set(TESTS ConstantString.m Category.m ExceptionTest.m + ExceptionTest_arc.m FastARC.m Forward.m ManyManySelectors.m @@ -57,6 +58,13 @@ set(TESTS setSuperclass.m ) +if (ENABLE_OBJCXX) + list(APPEND TESTS + ExceptionTestObjCXX.mm + ExceptionTestObjCXX_arc.mm + ) +endif() + if (WIN32) else () # Don't run the tests that are specific to Itanium-style exceptions on diff --git a/Test/ExceptionTestObjCXX.mm b/Test/ExceptionTestObjCXX.mm new file mode 100644 index 00000000..0caabdbc --- /dev/null +++ b/Test/ExceptionTestObjCXX.mm @@ -0,0 +1,97 @@ +#include "Test.h" + +BOOL finallyEntered = NO; +BOOL cleanupRun = NO; +BOOL idRethrown = NO; +BOOL catchallRethrown = NO; +BOOL testCaught = NO; +BOOL wrongMatch = NO; + +@interface NSString : Test @end +void runCleanup(void *x) +{ + assert(cleanupRun == NO); + cleanupRun = YES; +} + +int throwException(void) +{ + @throw [Test new]; +} + +int finally(void) +{ + __attribute__((cleanup(runCleanup))) + int x; + (void)x; + @try { throwException(); } + @finally { finallyEntered = YES; } + return 0; +} +int rethrow_id(void) +{ + @try { finally(); } + @catch(id x) + { + assert(object_getClass(x) == [Test class]); + idRethrown = YES; + @throw; + } + return 0; +} +int rethrow_test(void) +{ + @try { rethrow_id(); } + @catch (Test *t) + { + testCaught = YES; + @throw; + } + @catch (id x) + { + assert(0 && "should not be reached!"); + } + @catch (...) + { + assert(0 && "should not be reached!"); + } +} +int rethrow_catchall(void) +{ + @try { rethrow_test(); } + @catch(...) + { + assert(testCaught); + catchallRethrown = YES; + @throw; + } + return 0; +} +int not_matched_catch(void) +{ + @try { rethrow_catchall(); } + @catch(NSString *s) + { + wrongMatch = YES; + } + return 0; +} + +int main(void) +{ + @try + { + rethrow_catchall(); + } + @catch (id x) + { + assert(finallyEntered == YES); + assert(cleanupRun == YES); + assert(idRethrown == YES); + assert(catchallRethrown == YES); + assert(wrongMatch == NO); + assert(object_getClass(x) == [Test class]); + [x dealloc]; + } + return 0; +} diff --git a/Test/ExceptionTestObjCXX_arc.mm b/Test/ExceptionTestObjCXX_arc.mm new file mode 100644 index 00000000..30e490d7 --- /dev/null +++ b/Test/ExceptionTestObjCXX_arc.mm @@ -0,0 +1,96 @@ +#include "Test.h" + +BOOL finallyEntered = NO; +BOOL cleanupRun = NO; +BOOL idRethrown = NO; +BOOL catchallRethrown = NO; +BOOL testCaught = NO; +BOOL wrongMatch = NO; + +@interface NSString : Test @end +void runCleanup(void *x) +{ + assert(cleanupRun == NO); + cleanupRun = YES; +} + +int throwException(void) +{ + @throw [Test new]; +} + +int finally(void) +{ + __attribute__((cleanup(runCleanup))) + int x; + (void)x; + @try { throwException(); } + @finally { finallyEntered = YES; } + return 0; +} +int rethrow_id(void) +{ + @try { finally(); } + @catch(id x) + { + assert(object_getClass(x) == [Test class]); + idRethrown = YES; + @throw; + } + return 0; +} +int rethrow_test(void) +{ + @try { rethrow_id(); } + @catch (Test *t) + { + testCaught = YES; + @throw; + } + @catch (id x) + { + assert(0 && "should not be reached!"); + } + @catch (...) + { + assert(0 && "should not be reached!"); + } +} +int rethrow_catchall(void) +{ + @try { rethrow_test(); } + @catch(...) + { + assert(testCaught); + catchallRethrown = YES; + @throw; + } + return 0; +} +int not_matched_catch(void) +{ + @try { rethrow_catchall(); } + @catch(NSString *s) + { + wrongMatch = YES; + } + return 0; +} + +int main(void) +{ + @try + { + rethrow_catchall(); + } + @catch (id x) + { + assert(finallyEntered == YES); + assert(cleanupRun == YES); + assert(idRethrown == YES); + assert(catchallRethrown == YES); + assert(wrongMatch == NO); + assert(object_getClass(x) == [Test class]); + } + return 0; +} diff --git a/Test/ExceptionTest_arc.m b/Test/ExceptionTest_arc.m new file mode 100644 index 00000000..e4ccba8c --- /dev/null +++ b/Test/ExceptionTest_arc.m @@ -0,0 +1,100 @@ +#include "Test.h" + +#if __cplusplus +#error This is not an ObjC++ test! +#endif + +BOOL finallyEntered = NO; +BOOL cleanupRun = NO; +BOOL idRethrown = NO; +BOOL catchallRethrown = NO; +BOOL testCaught = NO; +BOOL wrongMatch = NO; + +@interface NSString : Test @end +void runCleanup(void *x) +{ + assert(cleanupRun == NO); + cleanupRun = YES; +} + +int throw(void) +{ + @throw [Test new]; +} + +int finally(void) +{ + __attribute__((cleanup(runCleanup))) + int x; + (void)x; + @try { throw(); } + @finally { finallyEntered = YES; } + return 0; +} +int rethrow_id(void) +{ + @try { finally(); } + @catch(id x) + { + assert(object_getClass(x) == [Test class]); + idRethrown = YES; + @throw; + } + return 0; +} +int rethrow_test(void) +{ + @try { rethrow_id(); } + @catch (Test *t) + { + testCaught = YES; + @throw; + } + @catch (id x) + { + assert(0 && "should not be reached!"); + } + @catch (...) + { + assert(0 && "should not be reached!"); + } +} +int rethrow_catchall(void) +{ + @try { rethrow_test(); } + @catch(...) + { + assert(testCaught); + catchallRethrown = YES; + @throw; + } + return 0; +} +int not_matched_catch(void) +{ + @try { rethrow_catchall(); } + @catch(NSString *s) + { + wrongMatch = YES; + } + return 0; +} + +int main(void) +{ + @try + { + rethrow_catchall(); + } + @catch (id x) + { + assert(finallyEntered == YES); + assert(cleanupRun == YES); + assert(idRethrown == YES); + assert(catchallRethrown == YES); + assert(wrongMatch == NO); + assert(object_getClass(x) == [Test class]); + } + return 0; +}