tests: catch up with compiler warnings
diff --git a/tests/allocator-test.cc b/tests/allocator-test.cc
index 98de832..8a5887d 100644
--- a/tests/allocator-test.cc
+++ b/tests/allocator-test.cc
@@ -101,8 +101,7 @@
 			  "Checked that all allocations have been deallocated ({} of {})",
 			  static_cast<int>(i),
 			  static_cast<int>(TestIterations));
-			Timeout t{1};
-			thread_sleep(&t);
+			TEST(sleep(1) >= 0, "Failed to sleep");
 		}
 		allocations.clear();
 	}
@@ -122,8 +121,7 @@
 			freeStart.wait(0);
 			// One extra sleep to make sure that we're really in the blocking
 			// sleep.
-			Timeout t{2};
-			thread_sleep(&t);
+			TEST(sleep(2) >= 0, "Failed to sleep");
 			debug_log(
 			  "Deallocation thread resuming, freeing pool of allocations");
 			// Free all of the allocations to make space.
@@ -131,7 +129,9 @@
 			{
 				if (allocation != nullptr)
 				{
-					heap_free(MALLOC_CAPABILITY, allocation);
+					TEST_EQUAL(heap_free(MALLOC_CAPABILITY, allocation),
+					           0,
+					           "Could not free allocation");
 				}
 			}
 			// Notify the parent thread that we're done.
@@ -426,6 +426,7 @@
 
 	void test_hazards()
 	{
+		int sleeps;
 		debug_log("Before allocating, quota left: {}",
 		          heap_quota_remaining(SECOND_HEAP));
 		Timeout longTimeout{1000};
@@ -446,21 +447,22 @@
 			// Exiting this task will cause this closure to be freed, which
 			// will collect dangling hazard pointers.  Wait for long enough for
 			// the heap check to work.
-			t = 1;
-			thread_sleep(&t);
+			TEST(sleep(1) >= 0, "Failed to sleep");
 		});
 		// Allow the async function to run and establish hazards
+		sleeps = 0;
 		while (state.load() != 1)
 		{
-			Timeout t{1};
-			thread_sleep(&t);
+			TEST(sleep(1) >= 0, "Failed to sleep");
+			TEST(sleeps++ < 100,
+			     "Background thread failed to establish hazards");
 		}
 		debug_log("Before freeing, quota left: {}",
 		          heap_quota_remaining(SECOND_HEAP));
-		heap_free(SECOND_HEAP, ptr);
+		TEST_EQUAL(heap_free(SECOND_HEAP, ptr), 0, "First free failed");
 		debug_log("After free 1, quota left: {}",
 		          heap_quota_remaining(SECOND_HEAP));
-		heap_free(SECOND_HEAP, ptr2);
+		TEST_EQUAL(heap_free(SECOND_HEAP, ptr2), 0, "Second free failed");
 		debug_log("After free 2, quota left: {}",
 		          heap_quota_remaining(SECOND_HEAP));
 		TEST(Capability{ptr}.is_valid(),
@@ -471,21 +473,21 @@
 		     ptr2);
 		state = 2;
 		// Yield to allow the hazards to be dropped.
-		Timeout t{1};
-		thread_sleep(&t);
+		TEST(sleep(1) >= 0, "Failed to yield to drop hazards");
 		// Try a double free.  This may logically succeed, but should not affect
 		// our quota.
-		heap_free(SECOND_HEAP, ptr);
+		TEST_EQUAL(heap_free(SECOND_HEAP, ptr),
+		           -EPERM,
+		           "Attempt to free freed but hazarded pointer not EPERM");
 		// Sleep again to make sure that the lambda from our async is gone.
 		// The logs may make it take more than one quantum in debug builds.
 		// The next test requires all memory allocated from the malloc
 		// capability to be freed before it starts.
-		int sleeps = 0;
+		sleeps = 0;
 		while (heap_quota_remaining(MALLOC_CAPABILITY) < MALLOC_QUOTA &&
 		       heap_quota_remaining(MALLOC_CAPABILITY) > 0)
 		{
-			Timeout t{1};
-			thread_sleep(&t);
+			TEST(sleep(1) >= 0, "Failed to sleep");
 			TEST(sleeps++ < 100,
 			     "Sleeping for too long waiting for async lambda to be freed");
 		}
@@ -712,7 +714,7 @@
 	TEST(ret == 0, "Freeing array failed: {}", ret);
 
 	test_blocking_allocator();
-	heap_quarantine_empty();
+	TEST_EQUAL(heap_quarantine_empty(), 0, "Could not flush quarantine");
 	test_revoke();
 	test_fuzz();
 	allocations.clear();
diff --git a/tests/compartment_calls-test.cc b/tests/compartment_calls-test.cc
index a8ed1ee..d8c8368 100644
--- a/tests/compartment_calls-test.cc
+++ b/tests/compartment_calls-test.cc
@@ -68,7 +68,10 @@
 
 	test_number_of_arguments();
 
-	test_incorrect_export_table(nullptr, &outTestFailed);
+	TEST_EQUAL(
+	  test_incorrect_export_table(nullptr, &outTestFailed),
+	  0,
+	  "Test incorrect entry point without error handler bad return value");
 	TEST(outTestFailed == false,
 	     "Test incorrect entry point without error handler failed");
 	return 0;
diff --git a/tests/compartment_calls.h b/tests/compartment_calls.h
index b740f31..6e4103d 100644
--- a/tests/compartment_calls.h
+++ b/tests/compartment_calls.h
@@ -38,11 +38,10 @@
   const int *x4,
   int        x5,
   int        x6);
-__cheri_compartment("compartment_calls_inner") void test_incorrect_export_table(
+__cheri_compartment("compartment_calls_inner") int test_incorrect_export_table(
   __cheri_callback void (*fn)(),
   bool *outTestFailed);
 __cheri_compartment(
   "compartment_calls_inner_with_"
   "handler") int test_incorrect_export_table_with_handler(__cheri_callback int (*fn)());
-__cheri_compartment("compartment_calls_outer") void compartment_call_outer();
 constexpr int ConstantValue = 0x41414141;
diff --git a/tests/compartment_calls_inner.cc b/tests/compartment_calls_inner.cc
index 43fd9d0..efd6138 100644
--- a/tests/compartment_calls_inner.cc
+++ b/tests/compartment_calls_inner.cc
@@ -97,8 +97,8 @@
 	return 0;
 }
 
-void test_incorrect_export_table(__cheri_callback void (*fn)(),
-                                 bool *outTestFailed)
+int test_incorrect_export_table(__cheri_callback void (*fn)(),
+                                bool *outTestFailed)
 {
 	/*
 	 * Trigger a cross-compartment call with an invalid export entry.
@@ -111,4 +111,6 @@
 	fn();
 
 	*outTestFailed = false;
+
+	return 0;
 }
diff --git a/tests/crash_recovery-test.cc b/tests/crash_recovery-test.cc
index cc67b24..1de2977 100644
--- a/tests/crash_recovery-test.cc
+++ b/tests/crash_recovery-test.cc
@@ -49,7 +49,7 @@
 int test_crash_recovery()
 {
 	debug_log("Calling crashy compartment indirectly");
-	test_crash_recovery_outer(0);
+	TEST_EQUAL(test_crash_recovery_outer(0), 0, "Indirect crash failed");
 	check_stack();
 	TEST(crashes == 0, "Ran crash handler for outer compartment");
 	debug_log("Compartment with no error handler returned normally after "
diff --git a/tests/crash_recovery.h b/tests/crash_recovery.h
index 9c2c7bd..ebbdb56 100644
--- a/tests/crash_recovery.h
+++ b/tests/crash_recovery.h
@@ -6,7 +6,7 @@
 
 __cheri_compartment("crash_recovery_inner") void *test_crash_recovery_inner(
   int);
-__cheri_compartment("crash_recovery_outer") void test_crash_recovery_outer(int);
+__cheri_compartment("crash_recovery_outer") int test_crash_recovery_outer(int);
 
 /**
  * Checks that the stack is entirely full of zeroes below the current stack
diff --git a/tests/crash_recovery_outer.cc b/tests/crash_recovery_outer.cc
index 9d3513d..6b59b7e 100644
--- a/tests/crash_recovery_outer.cc
+++ b/tests/crash_recovery_outer.cc
@@ -6,7 +6,7 @@
 #include <cheri.hh>
 #include <errno.h>
 
-void test_crash_recovery_outer(int)
+int test_crash_recovery_outer(int)
 {
 	debug_log(
 	  "Calling crashy compartment from compartment with no error handler");
@@ -19,4 +19,5 @@
 	debug_log("Calling crashy compartment returned to compartment with no "
 	          "error handler.  Return value: {}",
 	          ret);
+	return 0;
 }
diff --git a/tests/futex-test.cc b/tests/futex-test.cc
index 4abfe6c..433f110 100644
--- a/tests/futex-test.cc
+++ b/tests/futex-test.cc
@@ -25,6 +25,7 @@
 {
 	static uint32_t futex;
 	int             ret;
+	int             sleeps;
 	// Make sure that waking a futex with no sleepers doesn't crash!
 	ret = futex_wake(&futex, 1);
 	TEST(ret == 0, "Waking a futex with no sleepers should return 0");
@@ -32,7 +33,7 @@
 	// has been set to 1.
 	async([]() {
 		futex = 1;
-		futex_wake(&futex, 1);
+		(void)futex_wake(&futex, 1);
 	});
 	debug_log("Calling blocking futex_wait");
 	ret = futex_wait(&futex, 0);
@@ -123,7 +124,7 @@
             while (state != 1)
             {
                 Timeout t{3};
-                thread_sleep(&t);
+                (void)thread_sleep(&t);
             }
             debug_log("Consuming all CPU on medium-priority thread");
             state = 2;
@@ -144,27 +145,31 @@
             debug_log("Low-priority thread finished, unlocking");
             state = 4;
             futex = 0;
-            futex_wake(&futex, 1);
+            (void)futex_wake(&futex, 1);
         }
 	};
 	async(priorityBug);
 	async(priorityBug);
 	debug_log("Waiting for background threads to enter the right state");
-	while (state != 2)
+	for (sleeps = 0; (sleeps < 100) && (state != 2); sleeps++)
 	{
-		Timeout t{3};
-		thread_sleep(&t);
+		TEST(sleep(3) >= 0, "Failed to sleep");
 	}
+	TEST(sleeps < 100, "Waited too long for background threads");
 	debug_log("High-priority thread attempting to acquire futex owned by "
 	          "low-priority thread without priority propagation");
 	state       = 3;
 	t.remaining = 1;
-	futex_timed_wait(&t, &futex, futex, FutexNone);
+	TEST_EQUAL(futex_timed_wait(&t, &futex, futex, FutexNone),
+	           -ETIMEDOUT,
+	           "futex_timed_wait failed");
 	TEST(futex != 0, "Made progress surprisingly!");
 	debug_log("High-priority thread attempting to acquire futex owned by "
 	          "low-priority thread with priority propagation");
 	t.remaining = 4;
-	futex_timed_wait(&t, &futex, futex, FutexPriorityInheritance);
+	TEST_EQUAL(futex_timed_wait(&t, &futex, futex, FutexPriorityInheritance),
+	           0,
+	           "futex_timed_wait failed");
 	TEST(futex == 0, "Failed to make progress!");
 
 	futex       = 1234;
diff --git a/tests/list-test.cc b/tests/list-test.cc
index 5ea7700..bf6f66a 100644
--- a/tests/list-test.cc
+++ b/tests/list-test.cc
@@ -174,7 +174,10 @@
 	// we do not use here), not to the removed element.
 	LinkedObject::ObjectRing *removedCell = objects.first();
 	ds::linked_list::remove(objects.first());
-	heap_free(MALLOC_CAPABILITY, LinkedObject::from_ring(removedCell));
+	TEST_EQUAL(
+	  heap_free(MALLOC_CAPABILITY, LinkedObject::from_ring(removedCell)),
+	  0,
+	  "Failed to free removed cell");
 	TEST(LinkedObject::from_ring(objects.first())->data == 1,
 	     "First element of the list is incorrect after removing the first "
 	     "element, expected {}, got {}",
@@ -191,7 +194,8 @@
 	{
 		struct LinkedObject *o = LinkedObject::from_ring(cell);
 		cell                   = cell->cell_next();
-		heap_free(MALLOC_CAPABILITY, o);
+		TEST_EQUAL(
+		  heap_free(MALLOC_CAPABILITY, o), 0, "Failed to free list object");
 		counter++;
 	}
 
@@ -213,7 +217,10 @@
 		  // removed cell. This is great here because we will free the
 		  // object anyways. We could also use `remove` here.
 		  auto l = ds::linked_list::unsafe_remove(cell);
-		  heap_free(MALLOC_CAPABILITY, LinkedObject::from_ring(cell));
+		  TEST_EQUAL(
+		    heap_free(MALLOC_CAPABILITY, LinkedObject::from_ring(cell)),
+		    0,
+		    "Failed to free searched object");
 		  // `l` is the predecessor of `cell` in the residual ring, so
 		  // this does exactly what we want when `::search` iterates.
 		  cell = l;
@@ -221,7 +228,9 @@
 		  return false;
 	  });
 	// `::search` does not visit the element passed (`middle`)
-	heap_free(MALLOC_CAPABILITY, LinkedObject::from_ring(middle));
+	TEST_EQUAL(heap_free(MALLOC_CAPABILITY, LinkedObject::from_ring(middle)),
+	           0,
+	           "Failed to free middle object");
 	counter++;
 
 	TEST(counter == NumberOfListElements - 1,
diff --git a/tests/multiwaiter-test.cc b/tests/multiwaiter-test.cc
index b6b77dd..16cbc04 100644
--- a/tests/multiwaiter-test.cc
+++ b/tests/multiwaiter-test.cc
@@ -47,7 +47,7 @@
 			sleep(1);
 			debug_log("Waking futex from background thread");
 			*futexWord = value;
-			futex_wake(futexWord, 1);
+			TEST(futex_wake(futexWord, 1) >= 0, "futex_wait failed");
 		});
 	};
 
diff --git a/tests/stack-test.cc b/tests/stack-test.cc
index b3b894f..205a398 100644
--- a/tests/stack-test.cc
+++ b/tests/stack-test.cc
@@ -27,16 +27,17 @@
 	return ErrorRecoveryBehaviour::ForceUnwind;
 }
 
-__cheri_callback void test_trusted_stack_exhaustion()
+__cheri_callback int test_trusted_stack_exhaustion()
 {
-	exhaust_trusted_stack(&test_trusted_stack_exhaustion,
-	                      &threadStackTestFailed);
+	return exhaust_trusted_stack(&test_trusted_stack_exhaustion,
+	                             &threadStackTestFailed);
 }
 
-__cheri_callback void cross_compartment_call()
+__cheri_callback int cross_compartment_call()
 {
 	TEST(false,
 	     "Cross compartment call with invalid CSP shouldn't be reachable");
+	return -EINVAL;
 }
 
 namespace
@@ -70,7 +71,10 @@
 	void expect_handler(bool handlerExpected)
 	{
 		debug_log("Expected to invoke the handler? {}", handlerExpected);
-		set_expected_behaviour(&threadStackTestFailed, handlerExpected);
+		TEST_EQUAL(
+		  set_expected_behaviour(&threadStackTestFailed, handlerExpected),
+		  0,
+		  "Failed to set expectations");
 	}
 
 	__attribute__((used)) extern "C" int test_small_stack()
@@ -114,7 +118,7 @@
 // Defeat the compiler optimisation that may turn our first call to this into a
 // call. If the compiler does this then we will fail on an even number of
 // cross-compartment calls not an odd number.
-__cheri_callback void (*volatile crossCompartmentCall)();
+__cheri_callback int (*volatile crossCompartmentCall)();
 
 /*
  * The stack tests should cover the edge-cases scenarios for both
@@ -139,7 +143,7 @@
 	TEST(ret == -ENOTENOUGHSTACK,
 	     "test_with_small_stack failed, returned {} with 128-byte stack",
 	     ret);
-	__cheri_callback void (*callback)() = cross_compartment_call;
+	__cheri_callback int (*callback)() = cross_compartment_call;
 
 	crossCompartmentCall = test_trusted_stack_exhaustion;
 	debug_log("exhaust trusted stack, do self recursion with a cheri_callback");
@@ -148,12 +152,15 @@
 
 	debug_log("exhausting the compartment stack");
 	expect_handler(false);
-	exhaust_thread_stack();
+	TEST_EQUAL(
+	  exhaust_thread_stack(), -ECOMPARTMENTFAIL, "exhaust_thread_stack failed");
 
 	debug_log("exhausting the compartment stack during a switcher call");
 	expect_handler(false);
 	threadStackTestFailed = true;
-	exhaust_thread_stack_spill(callback);
+	TEST_EQUAL(exhaust_thread_stack_spill(callback),
+	           0,
+	           "exhaust_thread_stack_spill failed");
 	TEST(threadStackTestFailed == false, "switcher did not return error");
 
 	debug_log("modifying stack permissions on fault");
@@ -164,7 +171,9 @@
 		  compartmentStackPermissions.without(permissionToRemove);
 		debug_log("Permissions: {}", permissions);
 		expect_handler(stack_is_mostly_valid(permissions));
-		set_csp_permissions_on_fault(permissions);
+		TEST_EQUAL(set_csp_permissions_on_fault(permissions),
+		           -ECOMPARTMENTFAIL,
+		           "Unexpected success with restricted permissions");
 	}
 
 	debug_log("modifying stack permissions on cross compartment call");
@@ -173,16 +182,22 @@
 		auto permissions =
 		  compartmentStackPermissions.without(permissionToRemove);
 		debug_log("Permissions: {}", permissions);
-		set_csp_permissions_on_call(permissions, callback);
+		TEST_EQUAL(set_csp_permissions_on_call(permissions, callback),
+		           -ECOMPARTMENTFAIL,
+		           "Unexpected success with restricted permissions");
 	}
 
 	debug_log("invalid stack on fault");
 	expect_handler(false);
-	test_stack_invalid_on_fault();
+	TEST_EQUAL(test_stack_invalid_on_fault(),
+	           -ECOMPARTMENTFAIL,
+	           "stack_invalid_on_fault failed");
 
 	debug_log("invalid stack on cross compartment call");
 	expect_handler(false);
+	TEST_EQUAL(test_stack_invalid_on_call(callback),
+	           -ECOMPARTMENTFAIL,
+	           "stack_invalid_on_call failed");
 
-	test_stack_invalid_on_call(callback);
 	return 0;
 }
diff --git a/tests/stack_integrity_thread.cc b/tests/stack_integrity_thread.cc
index c897432..ee9f427 100644
--- a/tests/stack_integrity_thread.cc
+++ b/tests/stack_integrity_thread.cc
@@ -64,14 +64,16 @@
  * Set up the handler expectations.  Takes the caller's error flag and
  * whether the handler is expected as arguments.
  */
-void set_expected_behaviour(bool *outTestFailed, bool handlerExpected)
+int set_expected_behaviour(bool *outTestFailed, bool handlerExpected)
 {
 	expectedHandler       = handlerExpected;
 	threadStackTestFailed = outTestFailed;
 	*outTestFailed        = handlerExpected;
+
+	return 0;
 }
 
-void exhaust_thread_stack()
+int exhaust_thread_stack()
 {
 	/* Move the compartment's stack near its end, in order to
 	 * trigger stack exhaustion while the switcher handles
@@ -92,6 +94,8 @@
 
 	*threadStackTestFailed = true;
 	TEST(false, "Should be unreachable");
+
+	return 0;
 }
 
 /**
@@ -99,7 +103,7 @@
  * callee-saved state.  The result should simply be an error return, rather than
  * a forced-unwind.
  */
-void exhaust_thread_stack_spill(__cheri_callback void (*fn)())
+int exhaust_thread_stack_spill(__cheri_callback int (*fn)())
 {
 	register auto      rfn asm("ct1") = fn;
 	register uintptr_t res asm("ca0") = 0;
@@ -126,52 +130,59 @@
 
 	*threadStackTestFailed = false;
 	TEST(res == -ENOTENOUGHSTACK, "Bad return {}", res);
+
+	return 0;
 }
 
-void set_csp_permissions_on_fault(PermissionSet newPermissions)
+int set_csp_permissions_on_fault(PermissionSet newPermissions)
 {
 	__asm__ volatile(
 	  "candperm csp, csp, %0\n"
 	  "csh      zero, 0(cnull)\n" ::"r"(newPermissions.as_raw()));
 
 	TEST(false, "Should be unreachable");
+	return -EINVAL;
 }
 
-void set_csp_permissions_on_call(PermissionSet newPermissions,
-                                 __cheri_callback void (*fn)())
+int set_csp_permissions_on_call(PermissionSet newPermissions,
+                                __cheri_callback int (*fn)())
 {
 	CALL_CHERI_CALLBACK(fn, "candperm csp, csp, %1\n", newPermissions.as_raw());
 
 	TEST(false, "Should be unreachable");
+	return -EINVAL;
 }
 
-void test_stack_invalid_on_fault()
+int test_stack_invalid_on_fault()
 {
 	__asm__ volatile("ccleartag     csp, csp\n"
 	                 "csh           zero, 0(cnull)\n");
 
 	*threadStackTestFailed = true;
 	TEST(false, "Should be unreachable");
+	return -EINVAL;
 }
 
-void test_stack_invalid_on_call(__cheri_callback void (*fn)())
+int test_stack_invalid_on_call(__cheri_callback int (*fn)())
 {
 	// the `move zero, %1` is a no-op, just to have an operand
 	CALL_CHERI_CALLBACK(fn, "move zero, %1\nccleartag csp, csp\n", 0);
 
 	*threadStackTestFailed = true;
 	TEST(false, "Should be unreachable");
+	return -EINVAL;
 }
 
-void self_recursion(__cheri_callback void (*fn)())
+int self_recursion(__cheri_callback int (*fn)())
 {
 	(*fn)();
+	return 0;
 }
 
-void exhaust_trusted_stack(__cheri_callback void (*fn)(),
-                           bool *outLeakedSwitcherCapability)
+int exhaust_trusted_stack(__cheri_callback int (*fn)(),
+                          bool *outLeakedSwitcherCapability)
 {
-	self_recursion(fn);
+	return self_recursion(fn);
 }
 
 int test_stack_requirement()
diff --git a/tests/stack_tests.h b/tests/stack_tests.h
index 93ad94b..90b49df 100644
--- a/tests/stack_tests.h
+++ b/tests/stack_tests.h
@@ -4,28 +4,27 @@
 
 using namespace CHERI;
 
-__cheri_compartment("stack_integrity_thread") void exhaust_trusted_stack(
-  __cheri_callback void (*fn)(),
+__cheri_compartment("stack_integrity_thread") int exhaust_trusted_stack(
+  __cheri_callback int (*fn)(),
   bool *outLeakedSwitcherCapability);
-__cheri_compartment("stack_integrity_thread") void exhaust_thread_stack();
-__cheri_compartment("stack_integrity_thread") void exhaust_thread_stack_spill(
-  __cheri_callback void (*fn)());
-__cheri_compartment("stack_integrity_thread") void set_csp_permissions_on_fault(
+__cheri_compartment("stack_integrity_thread") int exhaust_thread_stack();
+__cheri_compartment("stack_integrity_thread") int exhaust_thread_stack_spill(
+  __cheri_callback int (*fn)());
+__cheri_compartment("stack_integrity_thread") int set_csp_permissions_on_fault(
   PermissionSet newPermissions);
-__cheri_compartment("stack_integrity_thread") void set_csp_permissions_on_call(
+__cheri_compartment("stack_integrity_thread") int set_csp_permissions_on_call(
   PermissionSet newPermissions,
-  __cheri_callback void (*fn)());
-__cheri_compartment(
-  "stack_integrity_thread") void test_stack_invalid_on_fault();
-__cheri_compartment("stack_integrity_thread") void test_stack_invalid_on_call(
-  __cheri_callback void (*fn)());
+  __cheri_callback int (*fn)());
+__cheri_compartment("stack_integrity_thread") int test_stack_invalid_on_fault();
+__cheri_compartment("stack_integrity_thread") int test_stack_invalid_on_call(
+  __cheri_callback int (*fn)());
 
 /**
  * Sets what we expect to happen for this test.  Is a fault expected to invoke
  * the handler?  The fault handler will set or clear `*outTestFailed` when a
  * fault is received, depending on whether it was expected.
  */
-__cheri_compartment("stack_integrity_thread") void set_expected_behaviour(
+__cheri_compartment("stack_integrity_thread") int set_expected_behaviour(
   bool *outTestFailed,
   bool  handlerExpected);
 
diff --git a/tests/test-runner.cc b/tests/test-runner.cc
index 37d2958..6d89591 100644
--- a/tests/test-runner.cc
+++ b/tests/test-runner.cc
@@ -79,7 +79,7 @@
 /**
  * Test suite entry point.  Runs all of the tests that we have defined.
  */
-void __cheri_compartment("test_runner") run_tests()
+int __cheri_compartment("test_runner") run_tests()
 {
 	// magic_enum is a pretty powerful stress-test of various bits of linkage.
 	// In generating `enum_values`, it generates constant strings and pointers
diff --git a/tests/tests.hh b/tests/tests.hh
index 14780ed..79779b7 100644
--- a/tests/tests.hh
+++ b/tests/tests.hh
@@ -56,6 +56,6 @@
 inline Ticks sleep(Ticks ticks)
 {
 	Timeout t{ticks};
-	thread_sleep(&t);
+	TEST(thread_sleep(&t) >= 0, "Failed to sleep");
 	return t.elapsed;
 };
diff --git a/tests/thread_pool-test.cc b/tests/thread_pool-test.cc
index 52a08e0..00377b3 100644
--- a/tests/thread_pool-test.cc
+++ b/tests/thread_pool-test.cc
@@ -75,8 +75,7 @@
 	int sleeps = 0;
 	while (counter < 2)
 	{
-		Timeout t{1};
-		thread_sleep(&t);
+		TEST(sleep(1) >= 0, "Failed to sleep");
 		TEST(sleeps < 100, "Gave up after too many sleeps");
 	}
 	debug_log("Yielded {} times for the thread pool to run our jobs", sleeps);
@@ -125,8 +124,7 @@
 	{
 		if (!asyncThread)
 		{
-			Timeout t{1};
-			thread_sleep(&t);
+			TEST(sleep(1) >= 0, "Failed to sleep");
 		}
 	}
 	TEST(asyncThread, "Worker thread did not provide thread pointer");
@@ -134,8 +132,7 @@
 	bool ret         = switcher_interrupt_thread(asyncThread);
 	interruptStarted = true;
 	TEST(ret, "Interrupting worker thread failed: {}", ret);
-	Timeout t{3};
-	thread_sleep(&t);
+	TEST(sleep(3) >= 0, "Failed to sleep");
 	TEST(interrupted, "Worker thread was not interrupted");
 	return 0;
 	static cheriot::atomic<uint32_t> barrier{3};