mirror of
https://github.com/c3lang/c3c.git
synced 2026-02-27 12:01:16 +00:00
- Using @noreturn in a trailing body macro would not work properly #2326.
- Bug when reporting error in a macro return would crash the compiler #2326. - Short body return expression would not have the correct span.
This commit is contained in:
@@ -74,6 +74,9 @@
|
||||
- Regression: Chaining an optional together with contracts could in some cases lose the optional.
|
||||
- `char[*] b = *(char[*]*)&a;` would crash the compiler if `a` was a slice. #2320
|
||||
- Implicitly cast const int expressions would sometimes not be detected as compile time const.
|
||||
- Using @noreturn in a short body macro would not work properly #2326.
|
||||
- Bug when reporting error in a macro return would crash the compiler #2326.
|
||||
- Short body return expression would not have the correct span.
|
||||
|
||||
### Stdlib changes
|
||||
- Improve contract for readline. #2280
|
||||
|
||||
@@ -1077,6 +1077,7 @@ static inline Ast *parse_return_stmt(ParseContext *c)
|
||||
if (!tok_is(c, TOKEN_EOS))
|
||||
{
|
||||
ASSIGN_EXPR_OR_RET(ast->return_stmt.expr, parse_expr(c), poisoned_ast);
|
||||
RANGE_EXTEND_PREV(ast);
|
||||
}
|
||||
CONSUME_EOS_OR_RET(poisoned_ast);
|
||||
return ast;
|
||||
@@ -1532,6 +1533,7 @@ Ast *parse_short_body(ParseContext *c, TypeInfoId return_type, bool is_regular_f
|
||||
TypeInfo *rtype = return_type ? type_infoptr(return_type) : NULL;
|
||||
bool is_void_return = rtype && rtype->resolve_status == RESOLVE_DONE && rtype->type->type_kind == TYPE_VOID;
|
||||
ASSIGN_EXPR_OR_RET(Expr *expr, parse_expr(c), poisoned_ast);
|
||||
ret->span = expr->span;
|
||||
if (expr->expr_kind == EXPR_CALL && expr->call_expr.macro_body)
|
||||
{
|
||||
ret->ast_kind = AST_EXPR_STMT;
|
||||
@@ -1548,7 +1550,7 @@ Ast *parse_short_body(ParseContext *c, TypeInfoId return_type, bool is_regular_f
|
||||
}
|
||||
ret->return_stmt.expr = expr;
|
||||
END:;
|
||||
RANGE_EXTEND_PREV(ast);
|
||||
|
||||
if (is_regular_fn)
|
||||
{
|
||||
CONSUME_EOS_OR_RET(poisoned_ast);
|
||||
|
||||
@@ -2809,7 +2809,7 @@ bool sema_expr_analyse_macro_call(SemaContext *context, Expr *call_expr, Expr *s
|
||||
}
|
||||
else if (is_no_return)
|
||||
{
|
||||
SEMA_ERROR(context->block_returns[0], "Return used despite macro being marked '@noreturn'.");
|
||||
SEMA_ERROR(macro_context.block_returns[0], "Return used despite macro being marked '@noreturn'.");
|
||||
goto EXIT_FAIL;
|
||||
}
|
||||
|
||||
|
||||
@@ -575,6 +575,13 @@ static inline bool sema_analyse_block_exit_stmt(SemaContext *context, Ast *state
|
||||
if (!sema_analyse_expr(context, ret_expr)) return false;
|
||||
}
|
||||
if (!sema_check_return_matches_opt_returns(context, ret_expr)) return false;
|
||||
if (ret_expr->expr_kind == EXPR_CALL && ret_expr->call_expr.no_return)
|
||||
{
|
||||
statement->ast_kind = AST_EXPR_STMT;
|
||||
statement->expr_stmt = ret_expr;
|
||||
sema_inline_return_defers(context, statement, context->block_return_defer);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
9
test/test_suite/macros/macro_noreturn1.c3
Normal file
9
test/test_suite/macros/macro_noreturn1.c3
Normal file
@@ -0,0 +1,9 @@
|
||||
import std;
|
||||
macro @gogo_abort() @noreturn => os::exit(1);
|
||||
|
||||
fn void main()
|
||||
{
|
||||
File? f = file::open("/tmp/ooo", "w");
|
||||
if (catch err = f) @gogo_abort();
|
||||
File g = f;
|
||||
}
|
||||
Reference in New Issue
Block a user