| ... | ... | @@ -2180,7 +2180,9 @@ static ConstExprValue *ir_build_const_from(IrAnalyze *ira, IrInstruction *old_in |
| 2180 | 2180 | } else if (old_instruction->id == IrInstructionIdFieldPtr) { |
| 2181 | 2181 | zig_panic("TODO"); |
| 2182 | 2182 | } else if (old_instruction->id == IrInstructionIdElemPtr) { |
| 2183 | | zig_panic("TODO"); |
| 2183 | IrInstructionElemPtr *elem_ptr_instruction = ir_create_instruction<IrInstructionElemPtr>(ira->new_irb.exec, |
| 2184 | old_instruction->source_node); |
| 2185 | new_instruction = &elem_ptr_instruction->base; |
| 2184 | 2186 | } else { |
| 2185 | 2187 | IrInstructionConst *const_instruction = ir_create_instruction<IrInstructionConst>(ira->new_irb.exec, |
| 2186 | 2188 | old_instruction->source_node); |
| ... | ... | @@ -2577,7 +2579,7 @@ static TypeTableEntry *ir_analyze_instruction_return(IrAnalyze *ira, |
| 2577 | 2579 | IrInstructionReturn *return_instruction) |
| 2578 | 2580 | { |
| 2579 | 2581 | IrInstruction *value = return_instruction->value->other; |
| 2580 | | if (value == ira->codegen->invalid_instruction) |
| 2582 | if (value->type_entry->id == TypeTableEntryIdInvalid) |
| 2581 | 2583 | return ir_finish_anal(ira, ira->codegen->builtin_types.entry_unreachable); |
| 2582 | 2584 | ira->implicit_return_type_list.append(value); |
| 2583 | 2585 | |
| ... | ... | @@ -3512,7 +3514,12 @@ static TypeTableEntry *ir_analyze_instruction_var_ptr(IrAnalyze *ira, IrInstruct |
| 3512 | 3514 | |
| 3513 | 3515 | static TypeTableEntry *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstructionElemPtr *elem_ptr_instruction) { |
| 3514 | 3516 | IrInstruction *array_ptr = elem_ptr_instruction->array_ptr->other; |
| 3517 | if (array_ptr->type_entry->id == TypeTableEntryIdInvalid) |
| 3518 | return ira->codegen->builtin_types.entry_invalid; |
| 3519 | |
| 3515 | 3520 | IrInstruction *elem_index = elem_ptr_instruction->elem_index->other; |
| 3521 | if (elem_index->type_entry->id == TypeTableEntryIdInvalid) |
| 3522 | return ira->codegen->builtin_types.entry_invalid; |
| 3516 | 3523 | |
| 3517 | 3524 | TypeTableEntry *array_type = array_ptr->type_entry; |
| 3518 | 3525 | TypeTableEntry *return_type; |
| ... | ... | @@ -3522,7 +3529,7 @@ static TypeTableEntry *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruc |
| 3522 | 3529 | } else if (array_type->id == TypeTableEntryIdArray) { |
| 3523 | 3530 | if (array_type->data.array.len == 0) { |
| 3524 | 3531 | add_node_error(ira->codegen, elem_ptr_instruction->base.source_node, |
| 3525 | | buf_sprintf("out of bounds array access")); |
| 3532 | buf_sprintf("index 0 outside array of size 0")); |
| 3526 | 3533 | } |
| 3527 | 3534 | TypeTableEntry *child_type = array_type->data.array.child_type; |
| 3528 | 3535 | return_type = get_pointer_to_type(ira->codegen, child_type, false); |
| ... | ... | @@ -3541,12 +3548,57 @@ static TypeTableEntry *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruc |
| 3541 | 3548 | if (casted_elem_index == ira->codegen->invalid_instruction) |
| 3542 | 3549 | return ira->codegen->builtin_types.entry_invalid; |
| 3543 | 3550 | |
| 3544 | | if (array_ptr->static_value.ok && casted_elem_index->static_value.ok) { |
| 3545 | | zig_panic("TODO compile time array access"); |
| 3551 | if (casted_elem_index->static_value.ok) { |
| 3552 | uint64_t index = casted_elem_index->static_value.data.x_bignum.data.x_uint; |
| 3553 | if (array_type->id == TypeTableEntryIdArray) { |
| 3554 | uint64_t array_len = array_type->data.array.len; |
| 3555 | if (index >= array_len) { |
| 3556 | add_node_error(ira->codegen, elem_ptr_instruction->base.source_node, |
| 3557 | buf_sprintf("index %" PRIu64 " outside array of size %" PRIu64, |
| 3558 | index, array_len)); |
| 3559 | return ira->codegen->builtin_types.entry_invalid; |
| 3560 | } |
| 3561 | } |
| 3562 | |
| 3563 | if (array_ptr->static_value.ok) { |
| 3564 | bool depends_on_compile_var = array_ptr->static_value.depends_on_compile_var || |
| 3565 | casted_elem_index->static_value.depends_on_compile_var; |
| 3566 | ConstExprValue *out_val = ir_build_const_from(ira, &elem_ptr_instruction->base, depends_on_compile_var); |
| 3567 | out_val->data.x_ptr.len = 1; |
| 3568 | out_val->data.x_ptr.is_c_str = false; |
| 3569 | out_val->data.x_ptr.ptr = allocate<ConstExprValue *>(1); |
| 3570 | if (array_type->id == TypeTableEntryIdPointer) { |
| 3571 | uint64_t pointer_len = array_ptr->static_value.data.x_ptr.len; |
| 3572 | if (index >= pointer_len) { |
| 3573 | add_node_error(ira->codegen, elem_ptr_instruction->base.source_node, |
| 3574 | buf_sprintf("index %" PRIu64 " outside pointer of size %" PRIu64, |
| 3575 | index, pointer_len)); |
| 3576 | return ira->codegen->builtin_types.entry_invalid; |
| 3577 | } |
| 3578 | out_val->data.x_ptr.ptr[0] = array_ptr->static_value.data.x_ptr.ptr[index]; |
| 3579 | } else if (is_slice(array_type)) { |
| 3580 | ConstExprValue *ptr_field = array_ptr->static_value.data.x_struct.fields[0]; |
| 3581 | ConstExprValue *len_field = array_ptr->static_value.data.x_struct.fields[1]; |
| 3582 | uint64_t slice_len = len_field->data.x_bignum.data.x_uint; |
| 3583 | if (index >= slice_len) { |
| 3584 | add_node_error(ira->codegen, elem_ptr_instruction->base.source_node, |
| 3585 | buf_sprintf("index %" PRIu64 " outside slice of size %" PRIu64, |
| 3586 | index, slice_len)); |
| 3587 | return ira->codegen->builtin_types.entry_invalid; |
| 3588 | } |
| 3589 | assert(index < ptr_field->data.x_ptr.len); |
| 3590 | out_val->data.x_ptr.ptr[0] = ptr_field->data.x_ptr.ptr[index]; |
| 3591 | } else if (array_type->id == TypeTableEntryIdArray) { |
| 3592 | out_val->data.x_ptr.ptr[0] = array_ptr->static_value.data.x_array.fields[index]; |
| 3593 | } else { |
| 3594 | zig_unreachable(); |
| 3595 | } |
| 3596 | return return_type; |
| 3597 | } |
| 3598 | |
| 3546 | 3599 | } |
| 3547 | 3600 | |
| 3548 | 3601 | ir_build_elem_ptr_from(&ira->new_irb, &elem_ptr_instruction->base, array_ptr, casted_elem_index); |
| 3549 | | |
| 3550 | 3602 | return return_type; |
| 3551 | 3603 | } |
| 3552 | 3604 | |