Index: tests/exceptions/.expect/conditional.txt
===================================================================
--- tests/exceptions/.expect/conditional.txt	(revision 6d43cdde0e3ec27d64977f210123157ee7b67ffa)
+++ tests/exceptions/.expect/conditional.txt	(revision 6d43cdde0e3ec27d64977f210123157ee7b67ffa)
@@ -0,0 +1,2 @@
+Caught num_error: expected=2 actual=2.
+Caught num_error: expected=2 actual=2.
Index: tests/exceptions/.expect/except-0.txt
===================================================================
--- tests/exceptions/.expect/except-0.txt	(revision 309012709e091dfaf06aaeec56491e73a68b71a1)
+++ 	(revision )
@@ -1,51 +1,0 @@
-Exiting: terminate function
-Exiting: bar function
-foo caught exception zen.
-Exiting: foo function
-
-alpha caught exception zen
-resume returned
-Exiting: resume function
-Exiting: beta function
-Exiting: alpha function
-
-walk out of farewell
-See you next time
-leaving farewell
-
-jump out of farewell
-See you next time
-leaving farewell
-
-Exiting: resume function
-fallback caught termination zen
-
-Exiting: terminate function
-Exiting: terminate function
-Exiting: terminate_swap
-terminate_swapped caught exception yang
-Exiting: terminate_swapped
-
-resume_swapped caught exception yang
-resume returned
-Exiting: resume function
-resume returned
-Exiting: resume function
-Exiting: resume_swap
-
-Exiting: terminate function
-reterminate zen caught and will rethrow exception zen
-reterminate 1 caught exception zen
-
-reresume zen caught and rethrows exception zen
-reresume 1 caught exception zen
-resume returned
-Exiting: resume function
-
-Exiting: terminate function
-fy caught exception zen
-fee caught exception zen
-resume returned
-Exiting: resume function
-
-Exiting: main function
Index: tests/exceptions/.expect/except-1.txt
===================================================================
--- tests/exceptions/.expect/except-1.txt	(revision 309012709e091dfaf06aaeec56491e73a68b71a1)
+++ 	(revision )
@@ -1,13 +1,0 @@
-First Caught
-Both Caught
-Part A Complete
-First Catch and rethrow
-Second Catch
-Part B Complete
-Throw before cleanup
-Catch after cleanup
-Part C Complete
-Caught initial throw.
-Caught intermediate throw.
-Caught final throw.
-Part D Complete
Index: tests/exceptions/.expect/except-2.txt
===================================================================
--- tests/exceptions/.expect/except-2.txt	(revision 309012709e091dfaf06aaeec56491e73a68b71a1)
+++ 	(revision )
@@ -1,3 +1,0 @@
-throw yin caught.
-throwResume yang caught <> throwResume returned.
-Should be printed.
Index: tests/exceptions/.expect/except-3.txt
===================================================================
--- tests/exceptions/.expect/except-3.txt	(revision 309012709e091dfaf06aaeec56491e73a68b71a1)
+++ 	(revision )
@@ -1,1 +1,0 @@
-throw [] unwind <> catch
Index: tests/exceptions/.expect/finally.txt
===================================================================
--- tests/exceptions/.expect/finally.txt	(revision 6d43cdde0e3ec27d64977f210123157ee7b67ffa)
+++ tests/exceptions/.expect/finally.txt	(revision 6d43cdde0e3ec27d64977f210123157ee7b67ffa)
@@ -0,0 +1,21 @@
+termination throw
+finally during unwind
+Exiting: termination inner finally
+termination catch
+finally after catch
+Exiting: termination outer finally
+
+resumption throw
+resumption catch
+finally after resume
+Exiting: resumption inner finally
+finally after catch
+Exiting: resumption outer finally
+
+walking out of try
+walking through finally
+Exiting: walking finally
+
+jumping out of try
+jumping through finally
+Exiting: jumping finally
Index: tests/exceptions/.expect/interact.txt
===================================================================
--- tests/exceptions/.expect/interact.txt	(revision 6d43cdde0e3ec27d64977f210123157ee7b67ffa)
+++ tests/exceptions/.expect/interact.txt	(revision 6d43cdde0e3ec27d64977f210123157ee7b67ffa)
@@ -0,0 +1,9 @@
+caught as termination
+Entering: try block with resume throw
+intermediate rethrow
+Exiting: try block with resume throw
+caught as termination
+
+terminate catch on terminate
+
+resume catch on resume
Index: tests/exceptions/.expect/resume.txt
===================================================================
--- tests/exceptions/.expect/resume.txt	(revision 6d43cdde0e3ec27d64977f210123157ee7b67ffa)
+++ tests/exceptions/.expect/resume.txt	(revision 6d43cdde0e3ec27d64977f210123157ee7b67ffa)
@@ -0,0 +1,20 @@
+simple throw
+simple catch
+Exiting: simple catch clause
+end of try clause
+Exiting: simple try clause
+
+throwing child exception
+inner parent match
+
+caught yin as yin
+
+rethrow inner try
+caught throw, will rethrow
+Exiting: rethrowing catch clause
+caught rethrow
+Exiting: rethrow catch clause
+Exiting: rethrow inner try
+
+caught yin, will throw yang
+caught yang
Index: tests/exceptions/.expect/terminate.txt
===================================================================
--- tests/exceptions/.expect/terminate.txt	(revision 6d43cdde0e3ec27d64977f210123157ee7b67ffa)
+++ tests/exceptions/.expect/terminate.txt	(revision 6d43cdde0e3ec27d64977f210123157ee7b67ffa)
@@ -0,0 +1,25 @@
+simple throw
+Exiting: simple try clause
+simple catch
+Exiting: simple catch clause
+
+throwing child exception
+inner parent match
+
+caught yin as yin
+
+rethrow inner try
+Exiting: rethrow inner try
+caught throw, will rethrow
+Exiting: rethrowing catch clause
+caught rethrow
+Exiting: rethrow catch clause
+
+caught yin, will throw yang
+caught yang
+
+throwing first exception
+caught first exception
+throwing second exception
+caught second exception
+recaught first exception
Index: tests/exceptions/conditional.cfa
===================================================================
--- tests/exceptions/conditional.cfa	(revision 6d43cdde0e3ec27d64977f210123157ee7b67ffa)
+++ tests/exceptions/conditional.cfa	(revision 6d43cdde0e3ec27d64977f210123157ee7b67ffa)
@@ -0,0 +1,74 @@
+// Conditional Catch Test
+
+// I may fold this back into terminate.cfa and resume.cfa once setting
+// up the non-trivial exception is reasonable to do.
+
+#include "except-mac.hfa"
+#include <stdio.h>
+
+DECLARE_EXCEPT(num_error, BASE_EXCEPT,
+	int (*code)(num_error *this);
+);
+
+struct num_error {
+	VTABLE_FIELD(num_error);
+    char * msg;
+    int num;
+};
+
+void num_error_msg(num_error * this) {
+    if ( ! this->msg ) {
+        static const char * base = "Num Error with code: X";
+        this->msg = (char *)malloc(22);
+        for (int i = 0 ; (this->msg[i] = base[i]) ; ++i);
+    }
+    this->msg[21] = '0' + this->num;
+    return this->msg;
+}
+void ?{}(num_error & this, int num) {
+	VTABLE_INIT(this, num_error);
+    this.msg = 0;
+    this.num = num;
+}
+void ?{}(num_error & this, num_error & other) {
+    this.virtual_table = other.virtual_table;
+    this.msg = 0;
+    this.num = other.num;
+}
+void copy(num_error * this, num_error * other) {
+	*this = *other;
+}
+void ^?{}(num_error & this) {
+    if( this.msg ) free( this.msg );
+}
+int num_error_code( num_error * this ) {
+    return this->num;
+}
+
+VTABLE_INSTANCE(num_error, BASE_EXCEPT, copy, ^?{},
+	num_error_msg, num_error_code
+);
+
+void caught_num_error(int expect, num_error * actual) {
+	printf("Caught num_error: expected=%d actual=%d.\n", expect, actual->num);
+}
+
+int main(int argc, char * argv[]) {
+	num_error exc = 2;
+
+	try {
+		THROW(&exc);
+	} catch (num_error * error ; 3 == error->virtual_table->code( error )) {
+		caught_num_error(3, error);
+	} catch (num_error * error ; 2 == error->virtual_table->code( error )) {
+		caught_num_error(2, error);
+	}
+
+	try {
+		THROW_RESUME(&exc);
+	} catchResume (num_error * error ; 3 == error->virtual_table->code( error )) {
+		caught_num_error(3, error);
+	} catchResume (num_error * error ; 2 == error->virtual_table->code( error )) {
+		caught_num_error(2, error);
+	}
+}
Index: tests/exceptions/except-0.cfa
===================================================================
--- tests/exceptions/except-0.cfa	(revision 309012709e091dfaf06aaeec56491e73a68b71a1)
+++ 	(revision )
@@ -1,249 +1,0 @@
-// Draft of tests for exception handling.
-// Outdated: The integer constant exceptions need to be replaced with virtual
-// exceptions for the new system.
-
-// ERROR: exceptions do not interact with ^?{} properly.
-
-#include <stdio.h>
-#include <stdbool.h>
-
-#include "except-mac.hfa"
-TRIVIAL_EXCEPTION(yin)
-TRIVIAL_EXCEPTION(yang)
-TRIVIAL_EXCEPTION(zen)
-
-
-// Local type to mark exits from scopes. (see ERROR)
-struct signal_exit {
-	const char * area;
-};
-
-void ?{}(signal_exit & this, const char * area) {
-	this.area = area;
-}
-
-void ^?{}(signal_exit & this) {
-	printf("Exiting: %s\n", this.area);
-//	sout | "Exiting:" | this->area;
-}
-
-
-// Mark throws: make sure to only pass in exception types.
-forall(dtype T)
-void terminate(T * except_value) {
-	signal_exit a = {"terminate function"};
-	THROW(except_value);
-	printf("terminate returned\n");
-}
-
-forall(dtype T)
-void resume(T * except_value) {
-	signal_exit a = {"resume function"};
-	THROW_RESUME(except_value);
-	printf("resume returned\n");
-}
-
-// Termination Test: Two handlers: no catch, catch
-void bar() {
-	signal_exit a = {"bar function"};
-	try {
-		terminate(&(zen){});
-	} catch (yin * error) {
-		printf("bar caught exception yin.\n");
-	}
-}
-
-void foo() {
-	signal_exit a = {"foo function"};
-	try {
-		bar();
-	} catch (yang * error) {
-		printf("foo caught exception yang.\n");
-	} catch (zen * error) {
-		printf("foo caught exception zen.\n");
-	}
-}
-
-// Resumption Two Handler Test: no catch, catch.
-void beta() {
-	signal_exit a = {"beta function"};
-	try {
-		zen x;
-		resume(&x);
-	} catchResume (yin * error) {
-		printf("beta caught exception yin\n");
-	}
-}
-
-void alpha() {
-	signal_exit a = {"alpha function"};
-	try {
-		beta();
-	} catchResume (yang * error) {
-		printf("alpha caught exception yang\n");
-	} catchResume (zen * error) {
-		printf("alpha caught exception zen\n");
-	}
-}
-
-// Finally Test:
-void farewell(bool jump) {
-	try {
-		if (jump) {
-			printf("jump out of farewell\n");
-			goto endoffunction;
-		} else {
-			printf("walk out of farewell\n");
-		}
-	} finally {
-		printf("See you next time\n");
-	}
-	endoffunction:
-	printf("leaving farewell\n");
-}
-
-// Resume-to-Terminate Test:
-void fallback() {
-	try {
-		zen x;
-		resume(&x);
-	} catch (zen * error) {
-		printf("fallback caught termination zen\n");
-	}
-}
-
-// Terminate Throw New Exception:
-void terminate_swap() {
-	signal_exit a = {"terminate_swap"};
-	try {
-		yin x;
-		terminate(&x);
-	} catch (yin * error) {
-		yang y;
-		terminate(&y);
-	}
-}
-
-void terminate_swapped() {
-	signal_exit a = {"terminate_swapped"};
-	try {
-		terminate_swap();
-	} catch (yang * error) {
-		printf("terminate_swapped caught exception yang\n");
-	}
-}
-
-// Resume Throw New Exception:
-void resume_swap() {
-	signal_exit a = {"resume_swap"};
-	try {
-		yin x;
-		resume(&x);
-	} catchResume (yin * error) {
-		yang y;
-		resume(&y);
-	}
-}
-
-void resume_swapped() {
-	try {
-		resume_swap();
-	} catchResume (yang * error) {
-		printf("resume_swapped caught exception yang\n");
-	}
-}
-
-// Terminate Rethrow:
-void reterminate() {
-	try {
-		try {
-			zen x;
-			terminate(&x);
-		} catch (zen * error) {
-			printf("reterminate zen caught and "
-			       "will rethrow exception zen\n");
-			throw;
-		}
-	} catch (zen * error) {
-		printf("reterminate 1 caught exception zen\n");
-	}
-}
-
-// Resume Rethrow:
-void reresume() {
-	try {
-		try {
-			zen x;
-			resume(&x);
-		} catchResume (zen * error) {
-			printf("reresume zen caught and rethrows exception zen\n");
-			throwResume;
-		}
-	} catchResume (zen * error) {
-		printf("reresume 1 caught exception zen\n");
-	}
-}
-
-// Terminate-Resume interaction:
-void fum() {
-	// terminate block, call resume
-	try {
-		zen x;
-		resume(&x);
-	} catch (zen * error) {
-		printf("fum caught exception zen\n");
-	}
-}
-
-void foe() {
-	// resume block, call terminate
-	try {
-		zen y;
-		terminate(&y);
-	} catchResume (zen * error) {
-		printf("foe caught exception zen\n");
-	}
-}
-
-void fy() {
-	// terminate block calls fum, call foe
-	try {
-		foe();
-	} catch (zen * error) {
-		printf("fy caught exception zen\n");
-		fum();
-	}
-}
-
-void fee() {
-	// resume block, call fy
-	try {
-		fy();
-	} catchResume (zen * error) {
-		printf("fee caught exception zen\n");
-	}
-}
-
-
-// main: choose which tests to run
-int main(int argc, char * argv[]) {
-	signal_exit a = {"main function"};
-
-	foo(); printf("\n");
-	alpha(); printf("\n");
-	farewell(false); printf("\n");
-	farewell(true); printf("\n");
-	fallback(); printf("\n");
-	terminate_swapped(); printf("\n");
-	resume_swapped(); printf("\n");
-	reterminate(); printf("\n");
-	reresume(); printf("\n");
-	fee(); printf("\n");
-
-	// Uncaught termination test.
-	/* Removed due to non-deterministic output.
-	printf("Throw uncaught.\n");
-	yang z;
-	terminate(&z);
-	*/
-}
Index: tests/exceptions/except-1.cfa
===================================================================
--- tests/exceptions/except-1.cfa	(revision 309012709e091dfaf06aaeec56491e73a68b71a1)
+++ 	(revision )
@@ -1,81 +1,0 @@
-// Draft memory management test. (remember -fexceptions)
-// Outdated: The integer constant exceptions need to be replaced with virtual
-// exceptions for the new system.
-
-#include <stdio.h>
-
-#include "except-mac.hfa"
-TRIVIAL_EXCEPTION(yin)
-TRIVIAL_EXCEPTION(yang)
-
-int main()
-{
-	try {
-		yin a;
-		THROW(&a);
-	}
-	catch( yin * err ) {
-		printf("First Caught\n");
-		try {
-			yang b;
-			THROW(&b);
-		}
-		catch( yang * err ) {
-			printf("Both Caught\n");
-		}
-	}
-	printf("Part A Complete\n");
-
-	try {
-		try {
-			yang c;
-			THROW(&c);
-		}
-		catch( yang * err ) {
-			printf("First Catch and rethrow\n");
-			throw;
-		}
-	}
-	catch( yang * err ) {
-		printf("Second Catch\n");
-	}
-	printf("Part B Complete\n");
-
-	try {
-		try {
-			yin d;
-			THROW(&d);
-		}
-		catch( yin * err ) {
-			printf("Throw before cleanup\n");
-			yang e;
-			THROW(&e);
-		}
-	}
-	catch( yang * err ) {
-		printf("Catch after cleanup\n");
-	}
-	printf("Part C Complete\n");
-
-	try {
-		try {
-			yin f;
-			THROW(&f);
-		}
-		catch( yin * err ) {
-			printf("Caught initial throw.\n");
-			try {
-				yang g;
-				THROW(&g);
-			}
-			catch( yang * err ) {
-				printf("Caught intermediate throw.\n");
-			}
-			throw;
-		}
-	}
-	catch( yin * err ) {
-		printf("Caught final throw.\n");
-	}
-	printf("Part D Complete\n");
-}
Index: tests/exceptions/except-2.cfa
===================================================================
--- tests/exceptions/except-2.cfa	(revision 309012709e091dfaf06aaeec56491e73a68b71a1)
+++ 	(revision )
@@ -1,92 +1,0 @@
-// New draft of exception tests.
-
-
-#include <stdlib.hfa>
-#include "except-mac.hfa"
-
-TRIVIAL_EXCEPTION(yin)
-TRIVIAL_EXCEPTION(yang)
-
-struct num_error;
-struct num_error_vtable {
-	struct TABLE(BASE_EXCEPT) const * parent;
-	size_t size;
-	void (*copy)(num_error &this, num_error & other);
-	void (*free)(num_error &this);
-	const char * (*msg)(num_error *this);
-	int (*code)(num_error *this);
-};
-extern num_error_vtable INSTANCE(num_error);
-
-struct num_error {
-	struct num_error_vtable const * virtual_table;
-	char * msg;
-	int num;
-};
-
-void num_error_msg(num_error * this) {
-	if ( ! this->msg ) {
-		static const char * base = "Num Error with code: X";
-		this->msg = (char *)malloc(22);
-		for (int i = 0 ; (this->msg[i] = base[i]) ; ++i);
-	}
-	this->msg[21] = '0' + this->num;
-	return this->msg;
-}
-void ?{}(num_error & this, int num) {
-	this.virtual_table = &INSTANCE(num_error);
-	this.msg = 0;
-	this.num = num;
-}
-void ?{}(num_error & this, num_error & other) {
-	this.virtual_table = other.virtual_table;
-	this.msg = 0;
-	this.num = other.num;
-}
-void ^?{}(num_error & this) {
-	if( this.msg ) free( this.msg );
-}
-int num_error_code( num_error * this ) {
-	return this->num;
-}
-num_error_vtable _num_error_vtable_instance @= {
-	&INSTANCE(BASE_EXCEPT),
-	sizeof(num_error), ?{}, ^?{},
-	num_error_msg, num_error_code
-};
-
-
-// Test simple throwing, matching and catching.
-void throw_catch() {
-	try {
-		yin black;
-		THROW(&black);
-	} catch ( yin * error ) {
-		printf("throw yin caught.\n");
-	}
-
-	try {
-		yang white;
-		THROW_RESUME(&white);
-		printf("> throwResume returned.\n");
-	} catchResume ( yang * error ) {
-		printf("throwResume yang caught <");
-	}
-
-	try {
-		num_error x = { 2 };
-		THROW(&x);
-	}
-	catch (num_error * error ; 3 == error->virtual_table->code( error ) ) {
-		printf("exception at %p\n", error );
-		printf("Should not be printed.\n");
-	}
-	catch (num_error * error ; 2 == error->virtual_table->code( error ) ) {
-		printf("Should be printed.\n");
-	}
-}
-
-int main (int argc, char * argv[]) {
-	throw_catch();
-	return 0;
-}
Index: tests/exceptions/except-3.cfa
===================================================================
--- tests/exceptions/except-3.cfa	(revision 309012709e091dfaf06aaeec56491e73a68b71a1)
+++ 	(revision )
@@ -1,18 +1,0 @@
-// Test that __attribute__((cleanup(...))) is working.
-
-#include <stdio.h>
-#include "except-mac.hfa"
-TRIVIAL_EXCEPTION(myth)
-
-int main (int argc, char * argv[]) {
-	try {
-		try {
-			printf("throw [");
-			THROW(&(myth){});
-		} finally {
-			printf("] unwind <");
-		}
-	} catch (myth * error) {
-		printf("> catch\n");
-	}
-}
Index: tests/exceptions/except-io.hfa
===================================================================
--- tests/exceptions/except-io.hfa	(revision 6d43cdde0e3ec27d64977f210123157ee7b67ffa)
+++ tests/exceptions/except-io.hfa	(revision 6d43cdde0e3ec27d64977f210123157ee7b67ffa)
@@ -0,0 +1,29 @@
+// Common tools for the exception tests.
+
+#include <stdio.h>
+
+// Echo when a destructor is run and an area/block is left.
+struct loud_exit {
+    const char * area;
+};
+
+inline void ?{}(loud_exit & this, const char * area) {
+    this.area = area;
+}
+
+inline void ^?{}(loud_exit & this) {
+    printf("Exiting: %s\n", this.area);
+}
+
+struct loud_region {
+	const char * region;
+};
+
+inline void ?{}(loud_region & this, const char * region) {
+	this.region = region;
+	printf("Entering: %s\n", region);
+}
+
+inline void ^?{}(loud_region & this) {
+	printf("Exiting: %s\n", this.region);
+}
Index: tests/exceptions/except-mac.hfa
===================================================================
--- tests/exceptions/except-mac.hfa	(revision 309012709e091dfaf06aaeec56491e73a68b71a1)
+++ tests/exceptions/except-mac.hfa	(revision 6d43cdde0e3ec27d64977f210123157ee7b67ffa)
@@ -6,5 +6,5 @@
 #define GLUE3(left, middle, right) left##middle##right
 
-// The fully (perhaps overly) qualified name of the base exception type:
+// The fully qualified name of the base exception type:
 #define BASE_EXCEPT __cfaehm_base_exception_t
 
@@ -34,5 +34,5 @@
 	__VA_ARGS__ \
 }; \
-extern TABLE(except_name) INSTANCE(except_name);
+extern TABLE(except_name) INSTANCE(except_name)
 
 // The first field of the exception structure should be created with this.
@@ -50,5 +50,5 @@
 	&INSTANCE(parent_name), sizeof(except_name), \
 	copy, free, msg, ## __VA_ARGS__ \
-};
+}
 
 // Same, but used declarators for arguments.
@@ -57,11 +57,11 @@
 	.parent : &INSTANCE(parent_name), .size : sizeof(except_name), \
 	.copy : copy, .free : free, .msg : msg, ## __VA_ARGS__ \
-};
+}
 
 
 
 // Declare a trivial exception, one that adds no features:
-#define TRIVIAL_EXCEPTION(name) \
-DECLARE_EXCEPT(name,BASE_EXCEPT,) \
+#define _TRIVIAL_EXCEPTION(name, parent_name, ...) \
+DECLARE_EXCEPT(name,parent_name,); \
 struct name { \
 	VTABLE_FIELD(name); \
@@ -76,3 +76,6 @@
 	VTABLE_INIT(this,name); \
 } \
-VTABLE_INSTANCE(name,BASE_EXCEPT,GLUE2(name,_copy),^?{},GLUE2(name,_msg),)
+VTABLE_INSTANCE(name,parent_name,GLUE2(name,_copy),^?{},GLUE2(name,_msg),)
+
+// TRIVIAL_EXCEPTION(name_of_exception, [parent_exception])
+#define TRIVIAL_EXCEPTION(...) _TRIVIAL_EXCEPTION(__VA_ARGS__,BASE_EXCEPT,)
Index: tests/exceptions/finally.cfa
===================================================================
--- tests/exceptions/finally.cfa	(revision 6d43cdde0e3ec27d64977f210123157ee7b67ffa)
+++ tests/exceptions/finally.cfa	(revision 6d43cdde0e3ec27d64977f210123157ee7b67ffa)
@@ -0,0 +1,60 @@
+// Finally Clause Tests
+
+#include "except-mac.hfa"
+#include "except-io.hfa"
+
+TRIVIAL_EXCEPTION(myth);
+
+int main(int argc, char * argv[]) {
+	myth exc;
+
+	try {
+		try {
+			printf("termination throw\n");
+			THROW(&exc);
+		} finally {
+			loud_exit a = "termination inner finally";
+			printf("finally during unwind\n");
+		}
+	} catch (myth * error) {
+		printf("termination catch\n");
+	} finally {
+		loud_exit a = "termination outer finally";
+		printf("finally after catch\n");
+	}
+	printf("\n");
+
+	try {
+		try {
+			printf("resumption throw\n");
+			THROW_RESUME(&exc);
+		} finally {
+			loud_exit a = "resumption inner finally";
+			printf("finally after resume\n");
+		}
+	} catchResume (myth * error) {
+		printf("resumption catch\n");
+	} finally {
+		loud_exit a = "resumption outer finally";
+		printf("finally after catch\n");
+	}
+	printf("\n");
+
+	try {
+		printf("walking out of try\n");
+	} finally {
+		loud_exit a = "walking finally";
+		printf("walking through finally\n");
+	}
+	printf("\n");
+
+	try {
+		printf("jumping out of try\n");
+		goto endoffunction;
+	} finally {
+		loud_exit a = "jumping finally";
+		printf("jumping through finally\n");
+	}
+	endoffunction:
+	;
+}
Index: tests/exceptions/interact.cfa
===================================================================
--- tests/exceptions/interact.cfa	(revision 6d43cdde0e3ec27d64977f210123157ee7b67ffa)
+++ tests/exceptions/interact.cfa	(revision 6d43cdde0e3ec27d64977f210123157ee7b67ffa)
@@ -0,0 +1,53 @@
+// Testing Interactions Between Termination and Resumption
+
+#include "except-mac.hfa"
+#include "except-io.hfa"
+
+TRIVIAL_EXCEPTION(star);
+
+int main(int argc, char * argv[]) {
+	// Resume falls back to terminate.
+	try {
+		THROW_RESUME(&(star){});
+	} catch (star *) {
+		printf("caught as termination\n");
+	}
+	// Variant of the above to check timing.
+	try {
+		loud_region a = "try block with resume throw";
+		THROW_RESUME(&(star){});
+	} catch (star *) {
+		printf("caught as termination\n");
+	} catchResume (star *) {
+		printf("intermediate rethrow\n");
+		throwResume;
+	}
+	printf("\n");
+
+	// Resume does not catch terminate.
+	try {
+		try {
+			THROW(&(star){});
+		} catchResume (star *) {
+			printf("resume catch on terminate\n");
+		}
+	} catchResume (star *) {
+		printf("resume catch on terminate\n");
+	} catch (star *) {
+		printf("terminate catch on terminate\n");
+	}
+	printf("\n");
+
+	// Terminate does not catch resume.
+	try {
+		try {
+			THROW_RESUME(&(star){});
+		} catch (star *) {
+			printf("terminate catch on resume\n");
+		}
+	} catch (star *) {
+		printf("terminate catch on resume\n");
+	} catchResume (star *) {
+		printf("resume catch on resume\n");
+	}
+}
Index: tests/exceptions/resume.cfa
===================================================================
--- tests/exceptions/resume.cfa	(revision 6d43cdde0e3ec27d64977f210123157ee7b67ffa)
+++ tests/exceptions/resume.cfa	(revision 6d43cdde0e3ec27d64977f210123157ee7b67ffa)
@@ -0,0 +1,103 @@
+// Resumption Exception Tests
+
+#include "except-mac.hfa"
+#include "except-io.hfa"
+
+TRIVIAL_EXCEPTION(yin);
+TRIVIAL_EXCEPTION(yang);
+TRIVIAL_EXCEPTION(zen);
+TRIVIAL_EXCEPTION(moment_of, zen);
+
+int main(int argc, char * argv[]) {
+	// The simple throw catchResume test.
+	try {
+		loud_exit a = "simple try clause";
+		printf("simple throw\n");
+		THROW_RESUME(&(zen){});
+		printf("end of try clause\n");
+	} catchResume (zen * error) {
+		loud_exit a = "simple catch clause";
+		printf("simple catch\n");
+	}
+	printf("\n");
+
+	// Catch a parent of the given exception.
+	try {
+		printf("throwing child exception\n");
+		THROW_RESUME(&(moment_of){});
+	} catchResume (zen *) {
+		printf("inner parent match\n");
+	} catchResume (moment_of *) {
+		printf("outer exact match\n");
+	}
+	printf("\n");
+
+	// Don't catch if handler does not match exception.
+	try {
+		try {
+			THROW_RESUME(&(yin){});
+		} catchResume (zen *) {
+			printf("caught yin as zen\n");
+		}
+	} catchResume (yang *) {
+		printf("caught yin as yang\n");
+	} catchResume (yin *) {
+		printf("caught yin as yin\n");
+	}
+	printf("\n");
+
+	// Test rethrowing an exception.
+	try {
+		try {
+			loud_exit a = "rethrow inner try";
+			printf("rethrow inner try\n");
+			THROW_RESUME(&(zen){});
+		} catchResume (zen *) {
+			loud_exit a = "rethrowing catch clause";
+			printf("caught throw, will rethrow\n");
+			throwResume;
+		}
+	} catchResume (zen *) {
+		loud_exit a = "rethrow catch clause";
+		printf("caught rethrow\n");
+	}
+	printf("\n");
+
+	// Throw a different exception in a catch.
+	try {
+		try {
+			THROW_RESUME(&(yin){});
+		} catchResume (yin *) {
+			printf("caught yin, will throw yang\n");
+			THROW_RESUME(&(yang){});
+		} catchResume (yang *) {
+			printf("caught exception from same try\n");
+		}
+	} catchResume (yang *) {
+		printf("caught yang\n");
+	}
+#ifdef FAILING
+	printf("\n");
+
+	// Another throw in the catch does not interfere.
+	try {
+		try {
+			printf("throwing first exception\n");
+			THROW_RESUME(&(yin){});
+		} catchResume (yin *) {
+			printf("caught first exception\n");
+			try {
+				printf("throwing second exception\n");
+				THROW_RESUME(&(yang){});
+			} catchResume (yang *) {
+				printf("caught second exception\n");
+			}
+			throwResume;
+		}
+	} catchResume (yin *) {
+		printf("recaught first exception\n");
+	} catchResume (yang *) {
+		printf("caught second exception (bad location)\n");
+	}
+#endif
+}
Index: tests/exceptions/terminate.cfa
===================================================================
--- tests/exceptions/terminate.cfa	(revision 6d43cdde0e3ec27d64977f210123157ee7b67ffa)
+++ tests/exceptions/terminate.cfa	(revision 6d43cdde0e3ec27d64977f210123157ee7b67ffa)
@@ -0,0 +1,101 @@
+// Termination Exception Tests
+
+#include "except-mac.hfa"
+#include "except-io.hfa"
+
+TRIVIAL_EXCEPTION(yin);
+TRIVIAL_EXCEPTION(yang);
+TRIVIAL_EXCEPTION(zen);
+TRIVIAL_EXCEPTION(moment_of, zen);
+
+int main(int argc, char * argv[]) {
+	// The simple throw catch test.
+	try {
+		loud_exit a = "simple try clause";
+		printf("simple throw\n");
+		THROW(&(zen){});
+		printf("end of try clause\n");
+	} catch (zen * error) {
+        loud_exit a = "simple catch clause";
+		printf("simple catch\n");
+	}
+	printf("\n");
+
+	// Catch a parent of the given exception.
+	try {
+		printf("throwing child exception\n");
+		THROW(&(moment_of){});
+	} catch (zen *) {
+		printf("inner parent match\n");
+	} catch (moment_of *) {
+		printf("outer exact match\n");
+	}
+	printf("\n");
+
+	// Don't catch if handler does not match exception.
+	try {
+		try {
+			THROW(&(yin){});
+		} catch (zen *) {
+			printf("caught yin as zen\n");
+		}
+	} catch (yang *) {
+		printf("caught yin as yang\n");
+	} catch (yin *) {
+		printf("caught yin as yin\n");
+	}
+	printf("\n");
+
+	// Test rethrowing an exception.
+	try {
+		try {
+			loud_exit a = "rethrow inner try";
+			printf("rethrow inner try\n");
+			THROW(&(zen){});
+		} catch (zen *) {
+			loud_exit a = "rethrowing catch clause";
+			printf("caught throw, will rethrow\n");
+			throw;
+		}
+	} catch (zen *) {
+		loud_exit a = "rethrow catch clause";
+		printf("caught rethrow\n");
+	}
+	printf("\n");
+
+	// Throw a different exception in a catch.
+	try {
+		try {
+			THROW(&(yin){});
+		} catch (yin *) {
+			printf("caught yin, will throw yang\n");
+			THROW(&(yang){});
+		} catch (yang *) {
+			printf("caught exception from same try\n");
+		}
+	} catch (yang *) {
+		printf("caught yang\n");
+	}
+	printf("\n");
+
+	// Another throw in the catch does not interfere.
+	try {
+		try {
+			printf("throwing first exception\n");
+			THROW(&(yin){});
+		} catch (yin *) {
+			printf("caught first exception\n");
+			try {
+				printf("throwing second exception\n");
+				THROW(&(yang){});
+			} catch (yang *) {
+				printf("caught second exception\n");
+			}
+			throw;
+		}
+	} catch (yin *) {
+		printf("recaught first exception\n");
+	} catch (yang *) {
+		printf("caught second exception (bad location)\n");
+	}
+}
