harec

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

commit b271d374207b7d13aa27b9cb079613f37a2954e0
parent b95dcfd0ca8d599c406415236329020fb31c72e4
Author: Armin Weigl <tb46305@gmail.com>
Date:   Sun, 19 Feb 2023 10:45:21 +0100

check: verify define compatibility

Signed-off-by: Armin Weigl <tb46305@gmail.com>

Diffstat:
Msrc/check.c | 36+++++++++++++++++++++++++++++++++++-
Mtests/36-defines.ha | 2+-
2 files changed, 36 insertions(+), 2 deletions(-)

diff --git a/src/check.c b/src/check.c @@ -3315,11 +3315,24 @@ check_expression(struct context *ctx, static struct declaration * check_const(struct context *ctx, const struct scope_object *obj, + const struct location *loc, const struct ast_global_decl *adecl) { struct declaration *decl = xcalloc(1, sizeof(struct declaration)); const struct scope_object *shadow_obj = scope_lookup( ctx->defines, &adecl->ident); + if (obj != shadow_obj) { + // Shadowed by define + if (obj->type != shadow_obj->type) { + char *typename = gen_typename(obj->type); + char *shadow_typename = gen_typename(shadow_obj->type); + error(ctx, *loc, NULL, + "Constant of type %s is shadowed by define of incompatible type %s", + typename, shadow_typename); + free(typename); + free(shadow_typename); + } + } decl->type = DECL_CONST; decl->constant.type = obj->type; decl->constant.value = shadow_obj->value; @@ -3493,7 +3506,7 @@ check_declaration(struct context *ctx, struct declaration *decl = NULL; switch (adecl->decl_type) { case AST_DECL_CONST: - decl = check_const(ctx, &idecl->obj, &adecl->constant); + decl = check_const(ctx, &idecl->obj, &adecl->loc, &adecl->constant); break; case AST_DECL_FUNC: decl = check_function(ctx, &idecl->obj, adecl); @@ -4306,6 +4319,27 @@ check_internal(struct type_store *ts, // XXX: shadowed declarations are not checked for consistency ctx.scope = ctx.defines; + for (const struct scope_object *obj = ctx.scope->objects; + obj; obj = obj->lnext) { + const struct scope_object *shadowed_obj = + scope_lookup(ctx.unit, &obj->name); + if (!shadowed_obj) { + continue; + } + if (shadowed_obj->otype == O_CONST) { + continue; + } + if (shadowed_obj->otype == O_SCAN) { + const struct incomplete_declaration *idecl = + (struct incomplete_declaration *)shadowed_obj; + if (idecl->type == IDECL_DECL && + idecl->decl.decl_type == AST_DECL_CONST) { + continue; + } + } + error(&ctx, defineloc, NULL, "Define shadows a non-define object"); + } + struct declarations **next_decl = &unit->declarations; // Perform actual declaration resolution for (const struct scope_object *obj = ctx.unit->objects; diff --git a/tests/36-defines.ha b/tests/36-defines.ha @@ -47,5 +47,5 @@ export fn main() void = { import(); mandatory(); optional(); - // TODO: compatibility(); + compatibility(); };