blob: 88bd73957dda10f72f62a2c43321f2b699721393 [file] [log] [blame]
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");
}