| import core.stdc.stdio : fprintf, stderr; | |
| class MyException : Exception | |
| { | |
| this() { super(typeof(this).stringof); } | |
| } | |
| void throw_catch() | |
| { | |
| try | |
| { | |
| throw new MyException; | |
| } | |
| catch (MyException) | |
| { | |
| } | |
| catch (Exception) | |
| { | |
| assert(false); | |
| } | |
| } | |
| // Test that exceptions that are entirely thrown and caught in finally blocks don't affect exception handling. | |
| void test1() | |
| { | |
| try | |
| { | |
| try | |
| { | |
| throw new Exception("p"); | |
| } | |
| finally | |
| { | |
| throw_catch(); | |
| } | |
| } | |
| catch (Exception e) | |
| { | |
| assert(e.msg == "p"); | |
| } | |
| } | |
| // Test that exceptions that are entirely thrown and caught in finally blocks don't interfere with chaining. | |
| void test2() | |
| { | |
| try | |
| { | |
| try | |
| { | |
| try | |
| { | |
| throw new Exception("p"); | |
| } | |
| finally | |
| { | |
| throw new Exception("q"); | |
| } | |
| } | |
| finally | |
| { | |
| throw_catch(); | |
| } | |
| } | |
| catch(Exception e) | |
| { | |
| assert(e.msg == "p"); | |
| assert(e.next.msg == "q"); | |
| assert(!e.next.next); | |
| } | |
| } | |
| void test3() | |
| { | |
| try | |
| { | |
| try | |
| { | |
| try | |
| { | |
| throw new Exception("p"); | |
| } | |
| finally | |
| { | |
| throw_catch(); | |
| } | |
| } | |
| finally | |
| { | |
| throw new Exception("q"); | |
| } | |
| } | |
| catch(Exception e) | |
| { | |
| assert(e.msg == "p"); | |
| assert(e.next.msg == "q"); | |
| assert(!e.next.next); | |
| } | |
| } | |
| // Test order of exception handler operations. | |
| void test4() | |
| { | |
| string result; | |
| void throw_catch() | |
| { | |
| pragma(inline, false); | |
| try | |
| { | |
| result ~= "b"; | |
| throw new MyException; | |
| } | |
| catch (MyException) | |
| { | |
| result ~= "c"; | |
| } | |
| catch (Exception) | |
| { | |
| assert(false); | |
| } | |
| } | |
| try | |
| { | |
| try | |
| { | |
| result ~= "a"; | |
| throw new Exception(""); | |
| } | |
| finally | |
| { | |
| throw_catch(); | |
| } | |
| } | |
| catch(Exception e) | |
| { | |
| result ~= "d"; | |
| } | |
| assert(result == "abcd"); | |
| } | |
| void test5() | |
| { | |
| string result; | |
| void fail() | |
| { | |
| result ~= "b"; | |
| throw new Exception("a"); | |
| } | |
| void throw_catch() | |
| { | |
| pragma(inline, false); | |
| try | |
| { | |
| fail(); | |
| } | |
| catch(Exception e) | |
| { | |
| assert(e.msg == "a"); | |
| assert(!e.next); | |
| result ~= "c"; | |
| } | |
| } | |
| try | |
| { | |
| try | |
| { | |
| result ~= "a"; | |
| throw new Exception("x"); | |
| } | |
| finally | |
| { | |
| throw_catch(); | |
| } | |
| } | |
| catch (Exception e) | |
| { | |
| assert(e.msg == "x"); | |
| assert(!e.next); | |
| result ~= "d"; | |
| } | |
| assert(result == "abcd"); | |
| } | |
| void main() { | |
| test1(); | |
| test2(); | |
| test3(); | |
| test4(); | |
| test5(); | |
| fprintf(stderr, "success.\n"); | |
| } |