#include #include #include #define D() printf("exceptions.m:%d\n", __LINE__) @interface A @end @implementation A @end void f0() { @throw(@"hi"); } int f1(int return_in_finally) { @try { D(); f0(); D(); return 0; } @finally { D(); if (return_in_finally) return 1; } return 2; } int f2(int return_in_catch) { @try { D(); f0(); D(); return 0; } @catch(A *x) { } @catch(...) { D(); if (return_in_catch) return 1; } return 2; } int f3() { @try { D(); f0(); D(); return 0; } @catch(...) { D(); @throw(@"hello"); D(); } return 2; } void t1() { @try { D(); printf("f1() = %d\n", f1(1)); D(); printf("f1() = %d\n", f1(0)); D(); } @catch(id e) { D(); } @finally { D(); } D(); } void t2() { @try { D(); printf("f2() = %d\n", f2(1)); D(); printf("f2() = %d\n", f2(0)); D(); } @catch(id e) { D(); } @finally { D(); } D(); } void t3() { @try { D(); printf("f3() = %d\n", f3()); D(); } @catch(id e) { D(); } @finally { D(); } D(); } void t4() { int i; @try { for (i=0; i<10; ++i) { @try { printf("i=%d\n", i); // These all end up being a continue due to the finally block. if (i==2) return; D(); if (i==3) @throw(@"x"); D(); if (i==4) break; D(); if (i==5) @throw([[NSObject alloc] init]); D(); if (i==6) continue; D(); } @catch (NSString *e) { D(); @throw; } @catch (id e) { D(); @throw; } @finally { D(); if (i==8) return; D(); continue; } } } @finally { D(); } } void t5() { @try { return; } @finally { D(); } } int main() { id Pool = [[NSAutoreleasePool alloc] init]; t1(); t2(); t3(); // Disabled for now until we move to USE_REFERENCE_OUTPUT, gcc/llvm-gcc get // the semantics wrong on x86_64. #if 0 t4(); #endif t5(); [Pool release]; return 0; }