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:
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;