aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorRoland Kovacs <zen3ger@tutanota.com>2024-08-11 01:09:22 +0200
committerRoland Kovacs <zen3ger@tutanota.com>2024-08-12 19:52:42 +0200
commit9eb7186cda2081c7fadbc0d196346b4e57f5e4c1 (patch)
tree45b674bc5052b9670e18f7755696348f5d35f0a0 /src
parentbe7a1f671c85040121fb8a96aca9c2c2b2c0fc7e (diff)
Fix alias handling of procedures
An incorrect memmove when overriding entities caused multiple ones to point to the same procedure with incomplete variant data, resulting in later hiting a compiler assertion. Introduced delayed type checking for procedure aliases, as it was masked by the previous error in the override logic.
Diffstat (limited to 'src')
-rw-r--r--src/check_decl.cpp4
-rw-r--r--src/checker.cpp12
2 files changed, 15 insertions, 1 deletions
diff --git a/src/check_decl.cpp b/src/check_decl.cpp
index a1436fe03..1425aafa8 100644
--- a/src/check_decl.cpp
+++ b/src/check_decl.cpp
@@ -180,6 +180,8 @@ gb_internal void override_entity_in_scope(Entity *original_entity, Entity *new_e
original_entity->flags |= EntityFlag_Overridden;
original_entity->type = new_entity->type;
+ original_entity->kind = new_entity->kind;
+ original_entity->decl_info = new_entity->decl_info;
original_entity->aliased_of = new_entity;
original_entity->identifier.store(new_entity->identifier);
@@ -193,7 +195,7 @@ gb_internal void override_entity_in_scope(Entity *original_entity, Entity *new_e
// This is most likely NEVER required, but it does not at all hurt to keep
isize offset = cast(u8 *)&original_entity->Dummy.start - cast(u8 *)original_entity;
isize size = gb_size_of(*original_entity) - offset;
- gb_memmove(cast(u8 *)original_entity, cast(u8 *)new_entity, size);
+ gb_memmove(cast(u8 *)original_entity + offset, cast(u8 *)new_entity + offset, size);
}
gb_internal bool check_override_as_type_due_to_aliasing(CheckerContext *ctx, Entity *e, Entity *entity, Ast *init, Type *named_type) {
diff --git a/src/checker.cpp b/src/checker.cpp
index 60000ec29..91e7a08fe 100644
--- a/src/checker.cpp
+++ b/src/checker.cpp
@@ -5676,6 +5676,18 @@ gb_internal void check_procedure_later_from_entity(Checker *c, Entity *e, char c
if ((e->flags & EntityFlag_ProcBodyChecked) != 0) {
return;
}
+ if ((e->flags & EntityFlag_Overridden) != 0) {
+ // NOTE (zen3ger) Delay checking of a proc alias until the underlying proc is checked.
+ GB_ASSERT(e->aliased_of != nullptr);
+ GB_ASSERT(e->aliased_of->kind == Entity_Procedure);
+ if ((e->aliased_of->flags & EntityFlag_ProcBodyChecked) != 0) {
+ e->flags |= EntityFlag_ProcBodyChecked;
+ return;
+ }
+ // NOTE (zen3ger) A proc alias *does not* have a body and tags!
+ check_procedure_later(c, e->file, e->token, e->decl_info, e->type, nullptr, 0);
+ return;
+ }
Type *type = base_type(e->type);
if (type == t_invalid) {
return;