From 1066004b79d014b4c3d10da19c84c679e21b88e5 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Thu, 21 Feb 2019 14:44:14 -0500 Subject: better handling of arrays in packed structs * Separate LoadPtr IR instructions into pass1 and pass2 variants. * Define `type_size_bits` for extern structs to be the same as their `@sizeOf(T) * 8` and allow them in packed structs. * More helpful error messages when trying to use types in packed structs that are not allowed. * Support arrays in packed structs even when they are not byte-aligned. * Add compile error for using arrays in packed structs when the padding bits would be problematic. This is necessary since we do not have packed arrays. closes #677 --- src/ir.cpp | 32 ++++++++++++++++++++++++++------ 1 file changed, 26 insertions(+), 6 deletions(-) (limited to 'src/ir.cpp') diff --git a/src/ir.cpp b/src/ir.cpp index a385592e2d..284f50e3a2 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -416,6 +416,10 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionLoadPtr *) { return IrInstructionIdLoadPtr; } +static constexpr IrInstructionId ir_instruction_id(IrInstructionLoadPtrGen *) { + return IrInstructionIdLoadPtrGen; +} + static constexpr IrInstructionId ir_instruction_id(IrInstructionStorePtr *) { return IrInstructionIdStorePtr; } @@ -2292,6 +2296,19 @@ static IrInstruction *ir_build_ptr_cast_gen(IrAnalyze *ira, IrInstruction *sourc return &instruction->base; } +static IrInstruction *ir_build_load_ptr_gen(IrAnalyze *ira, IrInstruction *source_instruction, + IrInstruction *ptr, ZigType *ty) +{ + IrInstructionLoadPtrGen *instruction = ir_build_instruction( + &ira->new_irb, source_instruction->scope, source_instruction->source_node); + instruction->base.value.type = ty; + instruction->ptr = ptr; + + ir_ref_instruction(ptr, ira->new_irb.current_basic_block); + + return &instruction->base; +} + static IrInstruction *ir_build_bit_cast(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *dest_type, IrInstruction *value) { @@ -11534,10 +11551,11 @@ static IrInstruction *ir_get_deref(IrAnalyze *ira, IrInstruction *source_instruc IrInstructionRef *ref_inst = reinterpret_cast(ptr); return ref_inst->value; } - IrInstruction *load_ptr_instruction = ir_build_load_ptr(&ira->new_irb, source_instruction->scope, - source_instruction->source_node, ptr); - load_ptr_instruction->value.type = child_type; - return load_ptr_instruction; + IrInstruction *result = ir_build_load_ptr_gen(ira, source_instruction, ptr, child_type); + if (type_entry->data.pointer.host_int_bytes != 0 && handle_is_ptr(child_type)) { + ir_add_alloca(ira, result, child_type); + } + return result; } else { ir_add_error_node(ira, source_instruction->source_node, buf_sprintf("attempt to dereference non-pointer type '%s'", @@ -13398,8 +13416,8 @@ static IrInstruction *ir_analyze_instruction_export(IrAnalyze *ira, IrInstructio } // TODO audit the various ways to use @export - if (want_var_export && target->id == IrInstructionIdLoadPtr) { - IrInstructionLoadPtr *load_ptr = reinterpret_cast(target); + if (want_var_export && target->id == IrInstructionIdLoadPtrGen) { + IrInstructionLoadPtrGen *load_ptr = reinterpret_cast(target); if (load_ptr->ptr->id == IrInstructionIdVarPtr) { IrInstructionVarPtr *var_ptr = reinterpret_cast(load_ptr->ptr); ZigVar *var = var_ptr->var; @@ -22316,6 +22334,7 @@ static IrInstruction *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructio case IrInstructionIdVectorToArray: case IrInstructionIdAssertZero: case IrInstructionIdResizeSlice: + case IrInstructionIdLoadPtrGen: zig_unreachable(); case IrInstructionIdReturn: @@ -22722,6 +22741,7 @@ bool ir_has_side_effects(IrInstruction *instruction) { case IrInstructionIdUnOp: case IrInstructionIdBinOp: case IrInstructionIdLoadPtr: + case IrInstructionIdLoadPtrGen: case IrInstructionIdConst: case IrInstructionIdCast: case IrInstructionIdContainerInitList: -- cgit v1.2.3