From 59e867a2992f28ec07d1df3ce81e8a0dade43cec Mon Sep 17 00:00:00 2001 From: fennecdjay Date: Thu, 14 Mar 2024 08:21:09 +0100 Subject: [PATCH] :art: update --- include/sema_private.h | 1 + src/sema/sema.c | 17 ++++++++++++++--- tests/try-handle/duplicate_handler.gw | 6 ++++++ tests/try-handle/retry_outside_handle.gw | 3 +++ 4 files changed, 24 insertions(+), 3 deletions(-) create mode 100644 tests/try-handle/duplicate_handler.gw create mode 100644 tests/try-handle/retry_outside_handle.gw diff --git a/include/sema_private.h b/include/sema_private.h index d6eee9f5..a98a6ea4 100644 --- a/include/sema_private.h +++ b/include/sema_private.h @@ -10,6 +10,7 @@ typedef struct { bool scope; bool handling; bool in_variadic; + bool in_defer; } Sema; #ifdef __SEMA_IMPLEMENTATION__ diff --git a/src/sema/sema.c b/src/sema/sema.c index 811e8844..bef5c35e 100644 --- a/src/sema/sema.c +++ b/src/sema/sema.c @@ -331,6 +331,11 @@ ANN static bool sema_stmt_return(Sema *a, Stmt_Exp b) { POISON(a, stmt_self(b)); ok = false; } + if(a->in_defer) { + gwerr_basic("'return' statement in defered action", NULL, NULL, a->filename, stmt_self(b)->loc, 0); + POISON(a, stmt_self(b)); + ok = false; + } if(b->val && !unique_expression(a, b->val, "in `return` statement")) ok = false; return ok; @@ -377,7 +382,7 @@ ANN static bool sema_stmt_pp(Sema *a, Stmt_PP b) { ANN static bool sema_stmt_retry(Sema *a NUSED, Stmt_Exp b NUSED) { if(a->handling) return true; - gwerr_basic("`retry outside of `handle` block", NULL, NULL, a->filename, stmt_self(b)->loc, 0); + gwerr_basic("`retry` outside of `handle` block", NULL, NULL, a->filename, stmt_self(b)->loc, 0); return false; } @@ -422,7 +427,10 @@ ANN static bool sema_stmt_try(Sema *a, Stmt_Try b) { } ANN static bool sema_stmt_defer(Sema *a, Stmt_Defer b) { + const bool in_defer = a ->in_defer; + a->in_defer = true; return sema_stmt(a, b->stmt, false); + a ->in_defer = in_defer; } ANN2(1, 2) static bool sema_spread(Sema *a, const Spread_Def spread, MP_Vector **acc) { @@ -662,20 +670,23 @@ ANN static bool sema_func_def(Sema *a, Func_Def b) { const Tmpl *tmpl = b->base->tmpl; const bool is_base = tmpl && tmpl_base(tmpl); const bool is_spread = tmpl && is_spread_tmpl(tmpl); - const bool in_variadic = a->in_variadic; const bool is_fill = !is_base && is_spread; + const bool in_variadic = a->in_variadic; + const bool in_defer = a->in_defer; a->in_variadic = in_variadic || is_spread; + a->in_defer = in_defer; if(is_fill && !fill(a, tmpl)) return false; bool ok = sema_func_base(a, b->base, !GET_FLAG(b->base, abstract)); if(b->d.code) { const bool func = a->func; - a->func = true; + a->func = true; // we can move this out (void)sema_stmt_list(a, &b->d.code); // ignore code in return value a->func = func; } if(is_fill) unfill(a, tmpl); a->in_variadic = in_variadic; + a->in_defer = in_defer; return ok; } diff --git a/tests/try-handle/duplicate_handler.gw b/tests/try-handle/duplicate_handler.gw new file mode 100644 index 00000000..ee3ab2ea --- /dev/null +++ b/tests/try-handle/duplicate_handler.gw @@ -0,0 +1,6 @@ +#! [contains] duplicate handler tag +try { + +} handle Foo { +} handle Foo {} + diff --git a/tests/try-handle/retry_outside_handle.gw b/tests/try-handle/retry_outside_handle.gw new file mode 100644 index 00000000..d23fc073 --- /dev/null +++ b/tests/try-handle/retry_outside_handle.gw @@ -0,0 +1,3 @@ + +#! [contains] `retry` outside of `handle` block +retry; -- 2.43.0