harec

[hare] Hare compiler, written in C11 for POSIX OSs
Log | Files | Refs | README | LICENSE

commit a1aa5039bc199cfe56731dcdd4e1cb616a9ab7a5
parent 1f8d030130795ba8458c8f5234cbc153463d3b13
Author: Drew DeVault <sir@cmpwn.com>
Date:   Sat, 26 Nov 2022 12:52:54 +0100

Revert "Allow abort/assert to accept non-constant strings."

This reverts commit 1f8d030130795ba8458c8f5234cbc153463d3b13.

Diffstat:
Mdocs/runtime.txt | 4++--
Minclude/expr.h | 2+-
Mrt/abort.ha | 14+++++++++-----
Msrc/check.c | 26++++++++++++++++++++++++--
Msrc/gen.c | 18+-----------------
Msrc/parse.c | 4++--
6 files changed, 39 insertions(+), 29 deletions(-)

diff --git a/docs/runtime.txt b/docs/runtime.txt @@ -1,9 +1,9 @@ harec expects the runtime to provide some features under the "rt" namespace. -@noreturn @symbol("rt.abort") fn _abort(loc: str, msg: str) void; +@noreturn @symbol("rt.abort") fn _abort(msg: str) void; Print a diagnostic message and terminate the program. -@noreturn fn abort_fixed(loc: str, reason: int) void; +@noreturn fn abort_fixed(reason: int) void; Print a diagnostic message from a list of pre-determined abort reasons, and terminate the program. The list of reasons are: diff --git a/include/expr.h b/include/expr.h @@ -347,7 +347,7 @@ struct expression { const struct type *result; enum expr_type type; bool terminates; - struct location loc; // For aborts + struct location loc; // For fixed aborts union { struct expression_access access; struct expression_alloc alloc; diff --git a/rt/abort.ha b/rt/abort.ha @@ -1,9 +1,6 @@ -export @noreturn @symbol("rt.abort") fn _abort(loc: str, msg: str) void = { +export @noreturn @symbol("rt.abort") fn _abort(msg: str) void = { const prefix = "Abort: "; - const sep = ": "; write(2, constchar(prefix), len(prefix)); - write(2, constchar(loc), len(loc)); - write(2, constchar(sep), len(sep)); write(2, constchar(msg), len(msg)); write(2, constchar("\n"), 1); kill(getpid(), SIGABRT); @@ -19,5 +16,12 @@ const reasons: [_]str = [ ]; export @noreturn fn abort_fixed(loc: str, i: int) void = { - _abort(loc, reasons[i]); + const prefix = "Abort: "; + const sep = ": "; + write(2, constchar(prefix), len(prefix)); + write(2, constchar(loc), len(loc)); + write(2, constchar(sep), len(sep)); + write(2, constchar(reasons[i]), len(reasons[i])); + write(2, constchar("\n"), 1); + kill(getpid(), SIGABRT); }; diff --git a/src/check.c b/src/check.c @@ -601,11 +601,33 @@ check_expr_assert(struct context *ctx, "Assertion message must be string"); return; } + + assert(expr->assert.message->type == EXPR_CONSTANT); + size_t n = snprintf(NULL, 0, "%s:%d:%d: ", + sources[aexpr->loc.file], + aexpr->loc.lineno, aexpr->loc.colno); + size_t s_len = expr->assert.message->constant.string.len; + char *s = xcalloc(1, n + s_len + 1); + snprintf(s, n + 1, "%s:%d:%d: ", sources[aexpr->loc.file], + aexpr->loc.lineno, aexpr->loc.colno); + memcpy(s+n, expr->assert.message->constant.string.value, s_len); + s[n + s_len] = '\0'; + + expr->assert.message->constant.string.value = s; + expr->assert.message->constant.string.len = n + s_len; } else { + int n = snprintf(NULL, 0, "Assertion failed: %s:%d:%d", + sources[aexpr->loc.file], + aexpr->loc.lineno, aexpr->loc.colno); + char *s = xcalloc(1, n + 1); + snprintf(s, n, "Assertion failed: %s:%d:%d", + sources[aexpr->loc.file], + aexpr->loc.lineno, aexpr->loc.colno); + expr->assert.message->type = EXPR_CONSTANT; expr->assert.message->result = &builtin_type_const_str; - expr->assert.message->constant.string.value = "Assertion failed"; - expr->assert.message->constant.string.len = 16; + expr->assert.message->constant.string.value = s; + expr->assert.message->constant.string.len = n - 1; } if (expr->assert.is_static) { diff --git a/src/gen.c b/src/gen.c @@ -808,23 +808,7 @@ gen_expr_assert(struct gen_context *ctx, const struct expression *expr) } struct qbe_value qmsg = mkqval(ctx, &msg); - - int n = snprintf(NULL, 0, "%s:%d:%d", - sources[expr->loc.file], expr->loc.lineno, - expr->loc.colno); - char *s = xcalloc(1, n + 1); - snprintf(s, n, "%s:%d:%d", - sources[expr->loc.file], expr->loc.lineno, - expr->loc.colno); - struct expression eloc = {0}; - eloc.type = EXPR_CONSTANT; - eloc.result = &builtin_type_const_str; - eloc.constant.string.value = s; - eloc.constant.string.len = n - 1; - struct gen_value loc_msg = gen_expr(ctx, &eloc); - struct qbe_value loc_qmsg = mkqval(ctx, &loc_msg); - - pushi(ctx->current, NULL, Q_CALL, &rtfunc, &loc_qmsg, &qmsg, NULL); + pushi(ctx->current, NULL, Q_CALL, &rtfunc, &qmsg, NULL); if (expr->assert.cond) { push(&ctx->current->body, &passedl); diff --git a/src/parse.c b/src/parse.c @@ -1112,7 +1112,7 @@ parse_assertion_expression(struct lexer *lexer, bool is_static) want(lexer, T_LPAREN, &tok); exp->assert.cond = parse_expression(lexer); if (lex(lexer, &tok) == T_COMMA) { - exp->assert.message = parse_expression(lexer); + exp->assert.message = parse_constant(lexer); } else { unlex(lexer, &tok); } @@ -1122,7 +1122,7 @@ parse_assertion_expression(struct lexer *lexer, bool is_static) want(lexer, T_LPAREN, &tok); if (lex(lexer, &tok) != T_RPAREN) { unlex(lexer, &tok); - exp->assert.message = parse_expression(lexer); + exp->assert.message = parse_constant(lexer); want(lexer, T_RPAREN, &tok); } break;