Ensure that you cannot return a suspension
diff --git a/internal/cgen/base/fundamental-private.h b/internal/cgen/base/fundamental-private.h
index a9a786f..081d8c4 100644
--- a/internal/cgen/base/fundamental-private.h
+++ b/internal/cgen/base/fundamental-private.h
@@ -14,10 +14,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-static inline wuffs_base__empty_struct  //
-wuffs_base__ignore_status(wuffs_base__status z) {
-  return wuffs_base__make_empty_struct();
-}
+// ---------------- Fundamentals
 
 // WUFFS_BASE__MAGIC is a magic number to check that initializers are called.
 // It's not foolproof, given C doesn't automatically zero memory before use,
@@ -73,6 +70,21 @@
 #define WUFFS_BASE__UNLIKELY(expr) (expr)
 #endif
 
+// --------
+
+static inline wuffs_base__empty_struct  //
+wuffs_base__ignore_status(wuffs_base__status z) {
+  return wuffs_base__make_empty_struct();
+}
+
+static inline wuffs_base__status  //
+wuffs_base__status__ensure_not_a_suspension(wuffs_base__status z) {
+  if (z.repr && (*z.repr == '$')) {
+    z.repr = wuffs_base__error__cannot_return_a_suspension;
+  }
+  return z;
+}
+
 // ---------------- Numeric Types
 
 extern const uint8_t wuffs_base__low_bits_mask__u8[9];
diff --git a/internal/cgen/data.go b/internal/cgen/data.go
index 4523847..d921b79 100644
--- a/internal/cgen/data.go
+++ b/internal/cgen/data.go
@@ -184,9 +184,11 @@
 	""
 
 const baseFundamentalPrivateH = "" +
-	"static inline wuffs_base__empty_struct  //\nwuffs_base__ignore_status(wuffs_base__status z) {\n  return wuffs_base__make_empty_struct();\n}\n\n// WUFFS_BASE__MAGIC is a magic number to check that initializers are called.\n// It's not foolproof, given C doesn't automatically zero memory before use,\n// but it should catch 99.99% of cases.\n//\n// Its (non-zero) value is arbitrary, based on md5sum(\"wuffs\").\n#define WUFFS_BASE__MAGIC ((uint32_t)0x3CCB6C71)\n\n// WUFFS_BASE__DISABLED is a magic number to indicate that a non-recoverable\n// error was previously encountered.\n//\n// Its (non-zero) value is arbitrary, based on md5sum(\"disabled\").\n#define WUFFS_BASE__DISABLED ((uint32_t)0x075AE3D2)\n\n// Denote intentional fallthroughs for -Wimplicit-fallthrough.\n//\n// The order matters here. Clang also defines \"__GNUC__\".\n#if defined(__clang__) && defined(__cplusplus) && (__cplusplus >= 201103L)\n#define WUFFS_BASE__FALLTHROUGH [[clang::fallthrough]]\n#elif !defined(__clang__) && defined(__GNUC__) && (__GNUC__ >= 7)\n#define WUFFS_BAS" +
-	"E__FALLTHROUGH __attribute__((fallthrough))\n#else\n#define WUFFS_BASE__FALLTHROUGH\n#endif\n\n// Use switch cases for coroutine suspension points, similar to the technique\n// in https://www.chiark.greenend.org.uk/~sgtatham/coroutines.html\n//\n// We use trivial macros instead of an explicit assignment and case statement\n// so that clang-format doesn't get confused by the unusual \"case\"s.\n#define WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0 case 0:;\n#define WUFFS_BASE__COROUTINE_SUSPENSION_POINT(n) \\\n  coro_susp_point = n;                            \\\n  WUFFS_BASE__FALLTHROUGH;                        \\\n  case n:;\n\n#define WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(n) \\\n  if (!status.repr) {                                           \\\n    goto ok;                                                    \\\n  } else if (*status.repr != '$') {                             \\\n    goto exit;                                                  \\\n  }                                                             \\\n  coro_susp_point" +
-	" = n;                                          \\\n  goto suspend;                                                 \\\n  case n:;\n\n// Clang also defines \"__GNUC__\".\n#if defined(__GNUC__)\n#define WUFFS_BASE__LIKELY(expr) (__builtin_expect(!!(expr), 1))\n#define WUFFS_BASE__UNLIKELY(expr) (__builtin_expect(!!(expr), 0))\n#else\n#define WUFFS_BASE__LIKELY(expr) (expr)\n#define WUFFS_BASE__UNLIKELY(expr) (expr)\n#endif\n\n" +
+	"// ---------------- Fundamentals\n\n// WUFFS_BASE__MAGIC is a magic number to check that initializers are called.\n// It's not foolproof, given C doesn't automatically zero memory before use,\n// but it should catch 99.99% of cases.\n//\n// Its (non-zero) value is arbitrary, based on md5sum(\"wuffs\").\n#define WUFFS_BASE__MAGIC ((uint32_t)0x3CCB6C71)\n\n// WUFFS_BASE__DISABLED is a magic number to indicate that a non-recoverable\n// error was previously encountered.\n//\n// Its (non-zero) value is arbitrary, based on md5sum(\"disabled\").\n#define WUFFS_BASE__DISABLED ((uint32_t)0x075AE3D2)\n\n// Denote intentional fallthroughs for -Wimplicit-fallthrough.\n//\n// The order matters here. Clang also defines \"__GNUC__\".\n#if defined(__clang__) && defined(__cplusplus) && (__cplusplus >= 201103L)\n#define WUFFS_BASE__FALLTHROUGH [[clang::fallthrough]]\n#elif !defined(__clang__) && defined(__GNUC__) && (__GNUC__ >= 7)\n#define WUFFS_BASE__FALLTHROUGH __attribute__((fallthrough))\n#else\n#define WUFFS_BASE__FALLTHROUGH\n#endif\n\n// Use switch " +
+	"cases for coroutine suspension points, similar to the technique\n// in https://www.chiark.greenend.org.uk/~sgtatham/coroutines.html\n//\n// We use trivial macros instead of an explicit assignment and case statement\n// so that clang-format doesn't get confused by the unusual \"case\"s.\n#define WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0 case 0:;\n#define WUFFS_BASE__COROUTINE_SUSPENSION_POINT(n) \\\n  coro_susp_point = n;                            \\\n  WUFFS_BASE__FALLTHROUGH;                        \\\n  case n:;\n\n#define WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(n) \\\n  if (!status.repr) {                                           \\\n    goto ok;                                                    \\\n  } else if (*status.repr != '$') {                             \\\n    goto exit;                                                  \\\n  }                                                             \\\n  coro_susp_point = n;                                          \\\n  goto suspend;                                        " +
+	"         \\\n  case n:;\n\n// Clang also defines \"__GNUC__\".\n#if defined(__GNUC__)\n#define WUFFS_BASE__LIKELY(expr) (__builtin_expect(!!(expr), 1))\n#define WUFFS_BASE__UNLIKELY(expr) (__builtin_expect(!!(expr), 0))\n#else\n#define WUFFS_BASE__LIKELY(expr) (expr)\n#define WUFFS_BASE__UNLIKELY(expr) (expr)\n#endif\n\n" +
+	"" +
+	"// --------\n\nstatic inline wuffs_base__empty_struct  //\nwuffs_base__ignore_status(wuffs_base__status z) {\n  return wuffs_base__make_empty_struct();\n}\n\nstatic inline wuffs_base__status  //\nwuffs_base__status__ensure_not_a_suspension(wuffs_base__status z) {\n  if (z.repr && (*z.repr == '$')) {\n    z.repr = wuffs_base__error__cannot_return_a_suspension;\n  }\n  return z;\n}\n\n" +
 	"" +
 	"// ---------------- Numeric Types\n\nextern const uint8_t wuffs_base__low_bits_mask__u8[9];\nextern const uint16_t wuffs_base__low_bits_mask__u16[17];\nextern const uint32_t wuffs_base__low_bits_mask__u32[33];\nextern const uint64_t wuffs_base__low_bits_mask__u64[65];\n\n#define WUFFS_BASE__LOW_BITS_MASK__U8(n) (wuffs_base__low_bits_mask__u8[n])\n#define WUFFS_BASE__LOW_BITS_MASK__U16(n) (wuffs_base__low_bits_mask__u16[n])\n#define WUFFS_BASE__LOW_BITS_MASK__U32(n) (wuffs_base__low_bits_mask__u32[n])\n#define WUFFS_BASE__LOW_BITS_MASK__U64(n) (wuffs_base__low_bits_mask__u64[n])\n\n" +
 	"" +
diff --git a/internal/cgen/statement.go b/internal/cgen/statement.go
index b4e17fb..783876b 100644
--- a/internal/cgen/statement.go
+++ b/internal/cgen/statement.go
@@ -483,9 +483,30 @@
 	b.writes("return ")
 	if g.currFunk.astFunc.Out() == nil {
 		b.writes("wuffs_base__make_empty_struct()")
-	} else if err := g.writeExpr(b, retExpr, depth); err != nil {
-		return err
+	} else {
+		couldBeSuspension := false
+		if retExpr.MType().IsStatus() && !n.RetsError() {
+			couldBeSuspension = true
+			if retExpr.Operator() == 0 {
+				if id := retExpr.Ident(); id == t.IDOk {
+					couldBeSuspension = false
+				} else if s := g.tm.ByID(id); (len(s) > 1) && (s[0] == '"') {
+					couldBeSuspension = s[1] == '$'
+				}
+			}
+		}
+
+		if couldBeSuspension {
+			b.writes("wuffs_base__status__ensure_not_a_suspension(")
+		}
+		if err := g.writeExpr(b, retExpr, depth); err != nil {
+			return err
+		}
+		if couldBeSuspension {
+			b.writeb(')')
+		}
 	}
+
 	b.writeb(';')
 	return nil
 }
diff --git a/lang/parse/parse.go b/lang/parse/parse.go
index e9eb4f8..5dc7a43 100644
--- a/lang/parse/parse.go
+++ b/lang/parse/parse.go
@@ -776,6 +776,11 @@
 			return nil, fmt.Errorf(`parse: %s an impure expression at %s:%d`,
 				x.Str(p.tm), p.filename, p.line())
 		}
+		if (x == t.IDReturn) && (value.Operator() == 0) {
+			if s := p.tm.ByID(value.Ident()); (len(s) > 1) && (s[0] == '"') && (s[1] == '$') {
+				return nil, fmt.Errorf(`parse: cannot return a suspension at %s:%d`, p.filename, p.line())
+			}
+		}
 		return a.NewRet(x, value).AsNode(), nil
 
 	case t.IDWhile:
diff --git a/release/c/wuffs-unsupported-snapshot.c b/release/c/wuffs-unsupported-snapshot.c
index ba0b2f7..283c0ab 100644
--- a/release/c/wuffs-unsupported-snapshot.c
+++ b/release/c/wuffs-unsupported-snapshot.c
@@ -7400,10 +7400,7 @@
 extern "C" {
 #endif
 
-static inline wuffs_base__empty_struct  //
-wuffs_base__ignore_status(wuffs_base__status z) {
-  return wuffs_base__make_empty_struct();
-}
+// ---------------- Fundamentals
 
 // WUFFS_BASE__MAGIC is a magic number to check that initializers are called.
 // It's not foolproof, given C doesn't automatically zero memory before use,
@@ -7459,6 +7456,21 @@
 #define WUFFS_BASE__UNLIKELY(expr) (expr)
 #endif
 
+// --------
+
+static inline wuffs_base__empty_struct  //
+wuffs_base__ignore_status(wuffs_base__status z) {
+  return wuffs_base__make_empty_struct();
+}
+
+static inline wuffs_base__status  //
+wuffs_base__status__ensure_not_a_suspension(wuffs_base__status z) {
+  if (z.repr && (*z.repr == '$')) {
+    z.repr = wuffs_base__error__cannot_return_a_suspension;
+  }
+  return z;
+}
+
 // ---------------- Numeric Types
 
 extern const uint8_t wuffs_base__low_bits_mask__u8[9];