Index: tests/exceptions/cancel/.expect/thread.txt
===================================================================
--- tests/exceptions/cancel/.expect/thread.txt	(revision 6a77224bf06bbc28a67a04ce5efe7106814a9045)
+++ tests/exceptions/cancel/.expect/thread.txt	(revision 6a77224bf06bbc28a67a04ce5efe7106814a9045)
@@ -0,0 +1,2 @@
+0112345
+0112345
Index: tests/exceptions/cancel/thread.cfa
===================================================================
--- tests/exceptions/cancel/thread.cfa	(revision 6a77224bf06bbc28a67a04ce5efe7106814a9045)
+++ tests/exceptions/cancel/thread.cfa	(revision 6a77224bf06bbc28a67a04ce5efe7106814a9045)
@@ -0,0 +1,56 @@
+// Try cancelling a thread.
+
+#include <thread.hfa>
+#include <exception.hfa>
+
+TRIVIAL_EXCEPTION(internal_error);
+
+thread WillCancel {};
+
+const char * msg(ThreadCancelled(WillCancel) * this) {
+	return "ThreadCancelled(WillCancel)";
+}
+
+void main(WillCancel &) {
+	printf("1");
+	cancel_stack((internal_error){});
+	printf("!");
+}
+
+void explicit() {
+	try {
+		printf("0");
+		WillCancel cancel;
+		printf("1");
+		join(cancel);
+		printf("4");
+	} catchResume (ThreadCancelled(WillCancel) * error) {
+		printf("2");
+		if ((virtual internal_error *)error->the_exception) {
+			printf("3");
+		}
+	}
+	printf("5\n");
+}
+
+void implicit() {
+	try {
+		{
+			printf("0");
+			WillCancel cancel;
+			printf("1");
+		}
+		printf("4");
+	} catchResume (ThreadCancelled(WillCancel) * error) {
+		printf("2");
+		if ((virtual internal_error *)error->the_exception) {
+			printf("3");
+		}
+	}
+	printf("5\n");
+}
+
+int main(int argc, char * argv[]) {
+	explicit();
+	implicit();
+}
