| ... | @@ -2180,7 +2180,9 @@ static ConstExprValue *ir_build_const_from(IrAnalyze *ira, IrInstruction *old_in | ... | @@ -2180,7 +2180,9 @@ static ConstExprValue *ir_build_const_from(IrAnalyze *ira, IrInstruction *old_in |
| 2180 | } else if (old_instruction->id == IrInstructionIdFieldPtr) { | 2180 | } else if (old_instruction->id == IrInstructionIdFieldPtr) { |
| 2181 | zig_panic("TODO"); | 2181 | zig_panic("TODO"); |
| 2182 | } else if (old_instruction->id == IrInstructionIdElemPtr) { | 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 | } else { | 2186 | } else { |
| 2185 | IrInstructionConst *const_instruction = ir_create_instruction<IrInstructionConst>(ira->new_irb.exec, | 2187 | IrInstructionConst *const_instruction = ir_create_instruction<IrInstructionConst>(ira->new_irb.exec, |
| 2186 | old_instruction->source_node); | 2188 | old_instruction->source_node); |
| ... | @@ -2577,7 +2579,7 @@ static TypeTableEntry *ir_analyze_instruction_return(IrAnalyze *ira, | ... | @@ -2577,7 +2579,7 @@ static TypeTableEntry *ir_analyze_instruction_return(IrAnalyze *ira, |
| 2577 | IrInstructionReturn *return_instruction) | 2579 | IrInstructionReturn *return_instruction) |
| 2578 | { | 2580 | { |
| 2579 | IrInstruction *value = return_instruction->value->other; | 2581 | IrInstruction *value = return_instruction->value->other; |
| 2580 | if (value == ira->codegen->invalid_instruction) | 2582 | if (value->type_entry->id == TypeTableEntryIdInvalid) |
| 2581 | return ir_finish_anal(ira, ira->codegen->builtin_types.entry_unreachable); | 2583 | return ir_finish_anal(ira, ira->codegen->builtin_types.entry_unreachable); |
| 2582 | ira->implicit_return_type_list.append(value); | 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,7 +3514,12 @@ static TypeTableEntry *ir_analyze_instruction_var_ptr(IrAnalyze *ira, IrInstruct |
| 3512 | | 3514 | |
| 3513 | static TypeTableEntry *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstructionElemPtr *elem_ptr_instruction) { | 3515 | static TypeTableEntry *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstructionElemPtr *elem_ptr_instruction) { |
| 3514 | IrInstruction *array_ptr = elem_ptr_instruction->array_ptr->other; | 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 | IrInstruction *elem_index = elem_ptr_instruction->elem_index->other; | 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 | TypeTableEntry *array_type = array_ptr->type_entry; | 3524 | TypeTableEntry *array_type = array_ptr->type_entry; |
| 3518 | TypeTableEntry *return_type; | 3525 | TypeTableEntry *return_type; |
| ... | @@ -3522,7 +3529,7 @@ static TypeTableEntry *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruc | ... | @@ -3522,7 +3529,7 @@ static TypeTableEntry *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruc |
| 3522 | } else if (array_type->id == TypeTableEntryIdArray) { | 3529 | } else if (array_type->id == TypeTableEntryIdArray) { |
| 3523 | if (array_type->data.array.len == 0) { | 3530 | if (array_type->data.array.len == 0) { |
| 3524 | add_node_error(ira->codegen, elem_ptr_instruction->base.source_node, | 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 | TypeTableEntry *child_type = array_type->data.array.child_type; | 3534 | TypeTableEntry *child_type = array_type->data.array.child_type; |
| 3528 | return_type = get_pointer_to_type(ira->codegen, child_type, false); | 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,12 +3548,57 @@ static TypeTableEntry *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruc |
| 3541 | if (casted_elem_index == ira->codegen->invalid_instruction) | 3548 | if (casted_elem_index == ira->codegen->invalid_instruction) |
| 3542 | return ira->codegen->builtin_types.entry_invalid; | 3549 | return ira->codegen->builtin_types.entry_invalid; |
| 3543 | | 3550 | |
| 3544 | if (array_ptr->static_value.ok && casted_elem_index->static_value.ok) { | 3551 | if (casted_elem_index->static_value.ok) { |
| 3545 | zig_panic("TODO compile time array access"); | 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 | ir_build_elem_ptr_from(&ira->new_irb, &elem_ptr_instruction->base, array_ptr, casted_elem_index); | 3601 | ir_build_elem_ptr_from(&ira->new_irb, &elem_ptr_instruction->base, array_ptr, casted_elem_index); |
| 3549 | | | |
| 3550 | return return_type; | 3602 | return return_type; |
| 3551 | } | 3603 | } |
| 3552 | | 3604 | |