harec

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

commit a5ae7ef30f047c3cb4ad6946084ed0c8fb64208f
parent 99df56f9d2228fa896f6e7f6e4fa8f8a2da208e2
Author: Eyal Sawady <ecs@d2evs.net>
Date:   Wed, 10 Mar 2021 00:22:19 -0500

Add location to fixed aborts

Diffstat:
Minclude/expr.h | 2++
Mrt/abort.ha | 15++++++++++++---
Msrc/check.c | 1+
Msrc/gen.c | 54++++++++++++++++++++++++++++++------------------------
4 files changed, 45 insertions(+), 27 deletions(-)

diff --git a/include/expr.h b/include/expr.h @@ -2,6 +2,7 @@ #define HAREC_EXPR_H #include <stdint.h> #include "identifier.h" +#include "lex.h" #include "types.h" struct scope; @@ -316,6 +317,7 @@ struct expression { const struct type *result; enum expr_type type; bool terminates; + 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 @@ -6,11 +6,20 @@ export @noreturn @symbol("rt.abort") fn _abort(msg: str) void = { kill(getpid(), SIGABRT); }; -// See include/gen.h +// See harec:include/gen.h const reasons: [_]str = [ "slice or array access out of bounds", // 0 "type assertion failed", // 1 - "allocation failed", // 2 + "out of memory", // 2 ]; -export @noreturn fn abort_fixed(i: int) void = _abort(reasons[i]); +export @noreturn fn abort_fixed(loc: str, i: int) void = { + const prefix = "Abort: "; + const sep = ": "; + write(2, prefix: *const char, len(prefix)); + write(2, loc: *const char, len(loc)); + write(2, sep: *const char, len(sep)); + write(2, reasons[i]: *const char, len(reasons[i])); + write(2, "\n": *const char, 1); + kill(getpid(), SIGABRT); +}; diff --git a/src/check.c b/src/check.c @@ -2161,6 +2161,7 @@ check_expression(struct context *ctx, const struct type *hint) { trenter(TR_CHECK, "expression"); + expr->loc = aexpr->loc; switch (aexpr->type) { case EXPR_ACCESS: diff --git a/src/gen.c b/src/gen.c @@ -297,6 +297,32 @@ gen_loadtemp(struct gen_context *ctx, } static void +gen_fixed_abort(struct gen_context *ctx, struct location loc, + enum fixed_aborts reason) +{ + int n = snprintf(NULL, 0, "%s:%d:%d", loc.path, loc.lineno, loc.colno); + char *s = xcalloc(1, n + 1); + snprintf(s, n, "%s:%d:%d", loc.path, loc.lineno, loc.colno); + + struct qbe_value location = {0}; + struct expression eloc = {0}; + eloc.type = EXPR_CONSTANT; + eloc.result = &builtin_type_const_str; + eloc.constant.string.value = s; + eloc.constant.string.len = n; + alloc_temp(ctx, &location, &builtin_type_const_str, "str.%d"); + qval_deref(&location); + gen_expression(ctx, &eloc, &location); + + struct qbe_value rtabort = {0}, tmp = {0}; + rtabort.kind = QV_GLOBAL; + rtabort.name = strdup("rt.abort_fixed"); + rtabort.type = &qbe_long; + constl(&tmp, reason); + pushi(ctx->current, NULL, Q_CALL, &rtabort, &location, &tmp, NULL); +} + +static void address_ident(struct gen_context *ctx, const struct expression *expr, struct qbe_value *out) @@ -355,12 +381,7 @@ address_index(struct gen_context *ctx, pushi(ctx->current, NULL, Q_JNZ, &valid, &bvalid, &binvalid, NULL); push(&ctx->current->body, &invalidl); - struct qbe_value rtfunc = {0}; - rtfunc.kind = QV_GLOBAL; - rtfunc.name = strdup("rt.abort_fixed"); - rtfunc.type = &qbe_long; - constl(&valid, ABORT_OOB); - pushi(ctx->current, NULL, Q_CALL, &rtfunc, &valid, NULL); + gen_fixed_abort(ctx, expr->loc, ABORT_OOB); push(&ctx->current->body, &validl); } @@ -589,12 +610,7 @@ gen_expr_alloc(struct gen_context *ctx, if (type_dealias(expr->result)->pointer.flags & PTR_NULLABLE) { pushi(ctx->current, NULL, Q_JMP, &bend, NULL); } else { - struct qbe_value reason = {0}, rtabort = {0}; - constl(&reason, ABORT_ALLOC_FAILURE); - rtabort.kind = QV_GLOBAL; - rtabort.name = strdup("rt.abort_fixed"); - rtabort.type = &qbe_long; - pushi(ctx->current, NULL, Q_CALL, &rtabort, &reason, NULL); + gen_fixed_abort(ctx, expr->loc, ABORT_ALLOC_FAILURE); } push(&ctx->current->body, &validl); if (!type_is_aggregate(type_dealias(expr->result)->pointer.referent)) { @@ -786,12 +802,7 @@ gen_expr_assign_slice(struct gen_context *ctx, pushi(ctx->current, NULL, Q_JNZ, &temp, &bequal, &bdiff, NULL); push(&ctx->current->body, &diffl); - struct qbe_value rtabort = {0}; - rtabort.kind = QV_GLOBAL; - rtabort.name = strdup("rt.abort_fixed"); - rtabort.type = &qbe_long; - constl(&temp, ABORT_OOB); - pushi(ctx->current, NULL, Q_CALL, &rtabort, &temp, NULL); + gen_fixed_abort(ctx, expr->loc, ABORT_OOB); push(&ctx->current->body, &equall); struct qbe_value rtmemcpy = {0}, optr = {0}, vptr = {0}; @@ -1131,12 +1142,7 @@ gen_type_assertion(struct gen_context *ctx, push(&ctx->current->body, &invalidl); - struct qbe_value rtfunc = {0}; - rtfunc.kind = QV_GLOBAL; - rtfunc.name = strdup("rt.abort_fixed"); - rtfunc.type = &qbe_long; - constl(&result, ABORT_TYPE_ASSERTION); - pushi(ctx->current, NULL, Q_CALL, &rtfunc, &result, NULL); + gen_fixed_abort(ctx, expr->loc, ABORT_TYPE_ASSERTION); push(&ctx->current->body, &validl); }