From bca02f81cd5affa288bac0cc0ed08fe730072aec Mon Sep 17 00:00:00 2001 From: Harold Brenes Date: Tue, 22 Apr 2025 19:16:29 -0400 Subject: Include the ivar in the Objective-C class unconditionally of it being used or not. Allow pseudo-fields for ivar access. --- src/llvm_backend_expr.cpp | 32 ++++++++++++++++++++++++-------- 1 file changed, 24 insertions(+), 8 deletions(-) (limited to 'src/llvm_backend_expr.cpp') diff --git a/src/llvm_backend_expr.cpp b/src/llvm_backend_expr.cpp index c5ea0ddac..b9c01ad03 100644 --- a/src/llvm_backend_expr.cpp +++ b/src/llvm_backend_expr.cpp @@ -5138,8 +5138,6 @@ gb_internal lbAddr lb_build_addr_internal(lbProcedure *p, Ast *expr) { return lb_build_addr(p, unparen_expr(se->selector)); } - - Type *type = base_type(tav.type); if (tav.mode == Addressing_Type) { // Addressing_Type Selection sel = lookup_field(tav.type, selector, true); if (sel.pseudo_field) { @@ -5174,18 +5172,37 @@ gb_internal lbAddr lb_build_addr_internal(lbProcedure *p, Ast *expr) { return lb_addr_swizzle(a, type, swizzle_count, swizzle_indices); } - Selection sel = lookup_field(type, selector, false); + Selection sel = lookup_field(tav.type, selector, false); GB_ASSERT(sel.entity != nullptr); - if (sel.pseudo_field) { - GB_ASSERT(sel.entity->kind == Entity_Procedure || sel.entity->kind == Entity_ProcGroup); + if (sel.pseudo_field && (sel.entity->kind == Entity_Procedure || sel.entity->kind == Entity_ProcGroup)) { + // GB_ASSERT(sel.entity->kind == Entity_Procedure || sel.entity->kind == Entity_ProcGroup); Entity *e = entity_of_node(sel_node); GB_ASSERT(e->kind == Entity_Procedure); return lb_addr(lb_find_value_from_entity(p->module, e)); } - if (sel.is_bit_field) { - lbAddr addr = lb_build_addr(p, se->expr); + lbAddr addr = lb_build_addr(p, se->expr); + + // TODO(harold): Ensure objc_ivar is always null when objc_implement is not set! + Type *d_type = type_deref(tav.type); //base_type(tav.type); + if (d_type->kind == Type_Named && d_type->Named.type_name->TypeName.objc_ivar) { + // NOTE(harold): We need to load the ivar from the current address and + // replace addr with the loaded ivar addr to apply the selector load properly. + + // If it's a deep pointer, dereference it first + // TODO(harold): Ensure this is save to do here. lb_emit_deep_field_gep() has several derefs, once per index. + // Not sure what multiple indices represent... + Type* type = tav.type; + if (is_type_pointer(type)) { + type = type_deref(type); + addr = lb_addr(lb_emit_load(p, addr.addr)); + } + lbValue ivar_ptr = lb_handle_objc_ivar_for_objc_object_pointer(p, addr.addr); + addr = lb_addr(ivar_ptr); + } + + if (sel.is_bit_field) { Selection sub_sel = sel; sub_sel.index.count -= 1; @@ -5211,7 +5228,6 @@ gb_internal lbAddr lb_build_addr_internal(lbProcedure *p, Ast *expr) { } { - lbAddr addr = lb_build_addr(p, se->expr); if (addr.kind == lbAddr_Map) { lbValue v = lb_addr_load(p, addr); lbValue a = lb_address_from_load_or_generate_local(p, v); -- cgit v1.2.3 From 53adff38f08f676bf2e9c40de9040a59c9a8fda6 Mon Sep 17 00:00:00 2001 From: Harold Brenes Date: Tue, 22 Apr 2025 21:44:32 -0400 Subject: Fixes to Ivar pseudo fields. --- src/llvm_backend_expr.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'src/llvm_backend_expr.cpp') diff --git a/src/llvm_backend_expr.cpp b/src/llvm_backend_expr.cpp index b9c01ad03..cc49a7be8 100644 --- a/src/llvm_backend_expr.cpp +++ b/src/llvm_backend_expr.cpp @@ -5192,7 +5192,13 @@ gb_internal lbAddr lb_build_addr_internal(lbProcedure *p, Ast *expr) { // If it's a deep pointer, dereference it first // TODO(harold): Ensure this is save to do here. lb_emit_deep_field_gep() has several derefs, once per index. // Not sure what multiple indices represent... - Type* type = tav.type; + Type* type = type_deref(addr.addr.type); + + // TODO(harold): Checker: Must NOT allow ivar dereferencing on non-pointer types. + // this would access memory outside the size of the value. + // In fact, locals/globals of Objective-C types ought not be allowed at all. + GB_ASSERT(is_type_pointer(type)); + if (is_type_pointer(type)) { type = type_deref(type); addr = lb_addr(lb_emit_load(p, addr.addr)); -- cgit v1.2.3 From c2dfc4b74929354bbbc1395d7dd4568718e3b30c Mon Sep 17 00:00:00 2001 From: Harold Brenes Date: Wed, 30 Apr 2025 20:25:21 -0400 Subject: Cleanup ivar generation for selector expressions. Cleanup ObjC superclass resolution. --- src/check_decl.cpp | 2 +- src/llvm_backend_expr.cpp | 24 +++++------------------- 2 files changed, 6 insertions(+), 20 deletions(-) (limited to 'src/llvm_backend_expr.cpp') diff --git a/src/check_decl.cpp b/src/check_decl.cpp index c6746f3eb..a37d20f56 100644 --- a/src/check_decl.cpp +++ b/src/check_decl.cpp @@ -575,7 +575,7 @@ gb_internal void check_type_decl(CheckerContext *ctx, Entity *e, Ast *init_expr, break; } - super = super->Named.type_name->TypeName.objc_superclass; + super = named_type->Named.type_name->TypeName.objc_superclass; } } else { if (ac.objc_superclass != nullptr) { diff --git a/src/llvm_backend_expr.cpp b/src/llvm_backend_expr.cpp index cc49a7be8..334ce62d5 100644 --- a/src/llvm_backend_expr.cpp +++ b/src/llvm_backend_expr.cpp @@ -5175,7 +5175,6 @@ gb_internal lbAddr lb_build_addr_internal(lbProcedure *p, Ast *expr) { Selection sel = lookup_field(tav.type, selector, false); GB_ASSERT(sel.entity != nullptr); if (sel.pseudo_field && (sel.entity->kind == Entity_Procedure || sel.entity->kind == Entity_ProcGroup)) { - // GB_ASSERT(sel.entity->kind == Entity_Procedure || sel.entity->kind == Entity_ProcGroup); Entity *e = entity_of_node(sel_node); GB_ASSERT(e->kind == Entity_Procedure); return lb_addr(lb_find_value_from_entity(p->module, e)); @@ -5183,26 +5182,13 @@ gb_internal lbAddr lb_build_addr_internal(lbProcedure *p, Ast *expr) { lbAddr addr = lb_build_addr(p, se->expr); - // TODO(harold): Ensure objc_ivar is always null when objc_implement is not set! - Type *d_type = type_deref(tav.type); //base_type(tav.type); - if (d_type->kind == Type_Named && d_type->Named.type_name->TypeName.objc_ivar) { + // NOTE(harold): Only allow ivar pseudo field access on indirect selectors. + // It is incoherent otherwise as Objective-C objects are zero-sized. + Type *deref_type = type_deref(tav.type); + if (tav.type->kind == Type_Pointer && deref_type->kind == Type_Named && deref_type->Named.type_name->TypeName.objc_ivar) { // NOTE(harold): We need to load the ivar from the current address and // replace addr with the loaded ivar addr to apply the selector load properly. - - // If it's a deep pointer, dereference it first - // TODO(harold): Ensure this is save to do here. lb_emit_deep_field_gep() has several derefs, once per index. - // Not sure what multiple indices represent... - Type* type = type_deref(addr.addr.type); - - // TODO(harold): Checker: Must NOT allow ivar dereferencing on non-pointer types. - // this would access memory outside the size of the value. - // In fact, locals/globals of Objective-C types ought not be allowed at all. - GB_ASSERT(is_type_pointer(type)); - - if (is_type_pointer(type)) { - type = type_deref(type); - addr = lb_addr(lb_emit_load(p, addr.addr)); - } + addr = lb_addr(lb_emit_load(p, addr.addr)); lbValue ivar_ptr = lb_handle_objc_ivar_for_objc_object_pointer(p, addr.addr); addr = lb_addr(ivar_ptr); -- cgit v1.2.3