diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/analyze.cpp | 19 | ||||
| -rw-r--r-- | src/ir.cpp | 409 |
2 files changed, 254 insertions, 174 deletions
diff --git a/src/analyze.cpp b/src/analyze.cpp index a4ee17d56c..414ce09b2c 100644 --- a/src/analyze.cpp +++ b/src/analyze.cpp @@ -1018,10 +1018,14 @@ static ReqCompTime type_val_resolve_requires_comptime(CodeGen *g, ConstExprValue zig_unreachable(); case LazyValueIdSliceType: { LazyValueSliceType *lazy_slice_type = reinterpret_cast<LazyValueSliceType *>(type_val->data.x_lazy); + if (type_is_invalid(lazy_slice_type->elem_type)) + return ReqCompTimeInvalid; return type_requires_comptime(g, lazy_slice_type->elem_type, parent_type); } case LazyValueIdPtrType: { LazyValuePtrType *lazy_ptr_type = reinterpret_cast<LazyValuePtrType *>(type_val->data.x_lazy); + if (type_is_invalid(lazy_ptr_type->elem_type)) + return ReqCompTimeInvalid; return type_requires_comptime(g, lazy_ptr_type->elem_type, parent_type); } } @@ -2239,7 +2243,7 @@ static Error resolve_struct_zero_bits(CodeGen *g, ZigType *struct_type) { if (struct_type->data.structure.resolve_status != ResolveStatusInvalid) { struct_type->data.structure.resolve_status = ResolveStatusInvalid; g->trace_err = add_node_error(g, decl_node, - buf_sprintf("dependency loop: whether struct '%s' has non-zero size", + buf_sprintf("struct '%s' depends on itself", buf_ptr(&struct_type->name))); } return ErrorSemanticAnalyzeFail; @@ -2308,6 +2312,10 @@ static Error resolve_struct_zero_bits(CodeGen *g, ZigType *struct_type) { struct_type->data.structure.requires_comptime = true; break; case ReqCompTimeInvalid: + if (g->trace_err != nullptr) { + g->trace_err = add_error_note(g, g->trace_err, field_node, + buf_create_from_str("while checking this field")); + } struct_type->data.structure.resolve_status = ResolveStatusInvalid; return ErrorSemanticAnalyzeFail; case ReqCompTimeNo: @@ -2770,6 +2778,8 @@ ZigFn *create_fn(CodeGen *g, AstNode *proto_node) { fn_entry->body_node = (proto_node->data.fn_proto.fn_def_node == nullptr) ? nullptr : proto_node->data.fn_proto.fn_def_node->data.fn_def.body; + fn_entry->analyzed_executable.source_node = fn_entry->body_node; + return fn_entry; } @@ -4863,7 +4873,10 @@ OnePossibleValue type_has_one_possible_value(CodeGen *g, ZigType *type_entry) { case ZigTypeIdStruct: for (size_t i = 0; i < type_entry->data.structure.src_field_count; i += 1) { TypeStructField *field = &type_entry->data.structure.fields[i]; - switch (type_val_resolve_has_one_possible_value(g, field->type_val)) { + OnePossibleValue opv = (field->type_entry != nullptr) ? + type_has_one_possible_value(g, field->type_entry) : + type_val_resolve_has_one_possible_value(g, field->type_val); + switch (opv) { case OnePossibleValueInvalid: return OnePossibleValueInvalid; case OnePossibleValueNo: @@ -4901,7 +4914,6 @@ ReqCompTime type_requires_comptime(CodeGen *g, ZigType *ty, ZigType *parent_type } switch (ty->id) { case ZigTypeIdInvalid: - case ZigTypeIdOpaque: zig_unreachable(); case ZigTypeIdComptimeFloat: case ZigTypeIdComptimeInt: @@ -4934,6 +4946,7 @@ ReqCompTime type_requires_comptime(CodeGen *g, ZigType *ty, ZigType *parent_type } case ZigTypeIdFn: return ty->data.fn.is_generic ? ReqCompTimeYes : ReqCompTimeNo; + case ZigTypeIdOpaque: case ZigTypeIdEnum: case ZigTypeIdErrorSet: case ZigTypeIdBool: diff --git a/src/ir.cpp b/src/ir.cpp index 92b8598442..c545109d24 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -11058,14 +11058,21 @@ static IrInstruction *ir_analyze_err_set_cast(IrAnalyze *ira, IrInstruction *sou } static IrInstruction *ir_analyze_frame_ptr_to_anyframe(IrAnalyze *ira, IrInstruction *source_instr, - IrInstruction *value, ZigType *wanted_type) + IrInstruction *frame_ptr, ZigType *wanted_type) { - if (instr_is_comptime(value)) { - zig_panic("TODO comptime frame pointer"); + if (instr_is_comptime(frame_ptr)) { + ConstExprValue *ptr_val = ir_resolve_const(ira, frame_ptr, UndefBad); + if (ptr_val == nullptr) + return ira->codegen->invalid_instruction; + + ir_assert(ptr_val->type->id == ZigTypeIdPointer, source_instr); + if (ptr_val->data.x_ptr.mut != ConstPtrMutRuntimeVar) { + zig_panic("TODO comptime frame pointer"); + } } IrInstruction *result = ir_build_cast(&ira->new_irb, source_instr->scope, source_instr->source_node, - wanted_type, value, CastOpBitCast); + wanted_type, frame_ptr, CastOpBitCast); result->value.type = wanted_type; return result; } @@ -13618,21 +13625,34 @@ static IrInstruction *ir_analyze_bin_op_math(IrAnalyze *ira, IrInstructionBinOp if (type_is_invalid(casted_op2->value.type)) return ira->codegen->invalid_instruction; - if (op1->value.special == ConstValSpecialUndef || casted_op2->value.special == ConstValSpecialUndef) { - IrInstruction *result = ir_const(ira, &instruction->base, op1->value.type); - result->value.special = ConstValSpecialUndef; - return result; + // If either operand is undef, result is undef. + ConstExprValue *op1_val = nullptr; + ConstExprValue *op2_val = nullptr; + if (instr_is_comptime(op1)) { + op1_val = ir_resolve_const(ira, op1, UndefOk); + if (op1_val == nullptr) + return ira->codegen->invalid_instruction; + if (op1_val->special == ConstValSpecialUndef) + return ir_const_undef(ira, &instruction->base, op1->value.type); } - if (casted_op2->value.special == ConstValSpecialStatic && op1->value.special == ConstValSpecialStatic && + if (instr_is_comptime(casted_op2)) { + op2_val = ir_resolve_const(ira, casted_op2, UndefOk); + if (op2_val == nullptr) + return ira->codegen->invalid_instruction; + if (op2_val->special == ConstValSpecialUndef) + return ir_const_undef(ira, &instruction->base, op1->value.type); + } + + if (op2_val != nullptr && op1_val != nullptr && (op1->value.data.x_ptr.special == ConstPtrSpecialHardCodedAddr || op1->value.data.x_ptr.special == ConstPtrSpecialNull)) { - uint64_t start_addr = (op1->value.data.x_ptr.special == ConstPtrSpecialNull) ? - 0 : op1->value.data.x_ptr.data.hard_coded_addr.addr; + uint64_t start_addr = (op1_val->data.x_ptr.special == ConstPtrSpecialNull) ? + 0 : op1_val->data.x_ptr.data.hard_coded_addr.addr; uint64_t elem_offset; if (!ir_resolve_usize(ira, casted_op2, &elem_offset)) return ira->codegen->invalid_instruction; - ZigType *elem_type = op1->value.type->data.pointer.child_type; + ZigType *elem_type = op1_val->type->data.pointer.child_type; if ((err = type_resolve(ira->codegen, elem_type, ResolveStatusSizeKnown))) return ira->codegen->invalid_instruction; uint64_t byte_offset = type_size(ira->codegen, elem_type) * elem_offset; @@ -13644,7 +13664,7 @@ static IrInstruction *ir_analyze_bin_op_math(IrAnalyze *ira, IrInstructionBinOp } else { zig_unreachable(); } - IrInstruction *result = ir_const(ira, &instruction->base, op1->value.type); + IrInstruction *result = ir_const(ira, &instruction->base, op1_val->type); result->value.data.x_ptr.special = ConstPtrSpecialHardCodedAddr; result->value.data.x_ptr.mut = ConstPtrMutRuntimeVar; result->value.data.x_ptr.data.hard_coded_addr.addr = new_addr; @@ -14213,9 +14233,13 @@ static IrInstruction *ir_analyze_instruction_decl_var(IrAnalyze *ira, } break; case ReqCompTimeNo: - if (init_val != nullptr) { - if (init_val->special == ConstValSpecialStatic && - init_val->type->id == ZigTypeIdFn && + if (init_val != nullptr && value_is_comptime(init_val)) { + if ((err = ir_resolve_const_val(ira->codegen, ira->new_irb.exec, + decl_var_instruction->base.source_node, init_val, UndefOk))) + { + result_type = ira->codegen->builtin_types.entry_invalid; + } else if (init_val->type->id == ZigTypeIdFn && + init_val->special != ConstValSpecialUndef && init_val->data.x_ptr.special != ConstPtrSpecialHardCodedAddr && init_val->data.x_ptr.data.fn.fn_entry->fn_inline == FnInlineAlways) { @@ -14273,7 +14297,7 @@ static IrInstruction *ir_analyze_instruction_decl_var(IrAnalyze *ira, } } - if (init_val != nullptr && init_val->special != ConstValSpecialRuntime) { + if (init_val != nullptr && value_is_comptime(init_val)) { // Resolve ConstPtrMutInfer if (var->gen_is_const) { var_ptr->value.data.x_ptr.mut = ConstPtrMutComptimeConst; @@ -14292,7 +14316,7 @@ static IrInstruction *ir_analyze_instruction_decl_var(IrAnalyze *ira, ir_analyze_store_ptr(ira, var_ptr, var_ptr, deref, false); } - if (var_ptr->value.special == ConstValSpecialStatic && var->mem_slot_index != SIZE_MAX) { + if (instr_is_comptime(var_ptr) && var->mem_slot_index != SIZE_MAX) { assert(var->mem_slot_index < ira->exec_context.mem_slot_list.length); ConstExprValue *mem_slot = ira->exec_context.mem_slot_list.at(var->mem_slot_index); copy_const_val(mem_slot, init_val, !is_comptime_var || var->gen_is_const); @@ -15222,7 +15246,7 @@ static IrInstruction *ir_get_var_ptr(IrAnalyze *ira, IrInstruction *instruction, if (linkage_makes_it_runtime) goto no_mem_slot; - if (var->const_value->special == ConstValSpecialStatic) { + if (value_is_comptime(var->const_value)) { mem_slot = var->const_value; } else { if (var->mem_slot_index != SIZE_MAX && (comptime_var_mem || var->gen_is_const)) { @@ -19361,7 +19385,10 @@ static IrInstruction *ir_analyze_instruction_err_name(IrAnalyze *ira, IrInstruct ZigType *u8_ptr_type = get_pointer_to_type_extra(ira->codegen, ira->codegen->builtin_types.entry_u8, true, false, PtrLenUnknown, 0, 0, 0, false); ZigType *str_type = get_slice_type(ira->codegen, u8_ptr_type); - if (casted_value->value.special == ConstValSpecialStatic) { + if (instr_is_comptime(casted_value)) { + ConstExprValue *val = ir_resolve_const(ira, casted_value, UndefBad); + if (val == nullptr) + return ira->codegen->invalid_instruction; ErrorTableEntry *err = casted_value->value.data.x_err_set; if (!err->cached_error_name_val) { ConstExprValue *array_val = create_const_str_lit(ira->codegen, &err->name); @@ -21524,64 +21551,75 @@ static IrInstruction *ir_analyze_instruction_memset(IrAnalyze *ira, IrInstructio return ira->codegen->invalid_instruction; // TODO test this at comptime with u8 and non-u8 types - if (casted_dest_ptr->value.special == ConstValSpecialStatic && - casted_byte->value.special == ConstValSpecialStatic && - casted_count->value.special == ConstValSpecialStatic && - casted_dest_ptr->value.data.x_ptr.special != ConstPtrSpecialHardCodedAddr && - casted_dest_ptr->value.data.x_ptr.mut != ConstPtrMutRuntimeVar) + if (instr_is_comptime(casted_dest_ptr) && + instr_is_comptime(casted_byte) && + instr_is_comptime(casted_count)) { - ConstExprValue *dest_ptr_val = &casted_dest_ptr->value; + ConstExprValue *dest_ptr_val = ir_resolve_const(ira, casted_dest_ptr, UndefBad); + if (dest_ptr_val == nullptr) + return ira->codegen->invalid_instruction; - ConstExprValue *dest_elements; - size_t start; - size_t bound_end; - switch (dest_ptr_val->data.x_ptr.special) { - case ConstPtrSpecialInvalid: - case ConstPtrSpecialDiscard: - zig_unreachable(); - case ConstPtrSpecialRef: - dest_elements = dest_ptr_val->data.x_ptr.data.ref.pointee; - start = 0; - bound_end = 1; - break; - case ConstPtrSpecialBaseArray: - { - ConstExprValue *array_val = dest_ptr_val->data.x_ptr.data.base_array.array_val; - expand_undef_array(ira->codegen, array_val); - dest_elements = array_val->data.x_array.data.s_none.elements; - start = dest_ptr_val->data.x_ptr.data.base_array.elem_index; - bound_end = array_val->type->data.array.len; - break; - } - case ConstPtrSpecialBaseStruct: - zig_panic("TODO memset on const inner struct"); - case ConstPtrSpecialBaseErrorUnionCode: - zig_panic("TODO memset on const inner error union code"); - case ConstPtrSpecialBaseErrorUnionPayload: - zig_panic("TODO memset on const inner error union payload"); - case ConstPtrSpecialBaseOptionalPayload: - zig_panic("TODO memset on const inner optional payload"); - case ConstPtrSpecialHardCodedAddr: - zig_unreachable(); - case ConstPtrSpecialFunction: - zig_panic("TODO memset on ptr cast from function"); - case ConstPtrSpecialNull: - zig_panic("TODO memset on null ptr"); - } + ConstExprValue *byte_val = ir_resolve_const(ira, casted_byte, UndefOk); + if (byte_val == nullptr) + return ira->codegen->invalid_instruction; - size_t count = bigint_as_unsigned(&casted_count->value.data.x_bigint); - size_t end = start + count; - if (end > bound_end) { - ir_add_error(ira, count_value, buf_sprintf("out of bounds pointer access")); + ConstExprValue *count_val = ir_resolve_const(ira, casted_count, UndefBad); + if (count_val == nullptr) return ira->codegen->invalid_instruction; - } - ConstExprValue *byte_val = &casted_byte->value; - for (size_t i = start; i < end; i += 1) { - copy_const_val(&dest_elements[i], byte_val, true); - } + if (casted_dest_ptr->value.data.x_ptr.special != ConstPtrSpecialHardCodedAddr && + casted_dest_ptr->value.data.x_ptr.mut != ConstPtrMutRuntimeVar) + { + ConstExprValue *dest_elements; + size_t start; + size_t bound_end; + switch (dest_ptr_val->data.x_ptr.special) { + case ConstPtrSpecialInvalid: + case ConstPtrSpecialDiscard: + zig_unreachable(); + case ConstPtrSpecialRef: + dest_elements = dest_ptr_val->data.x_ptr.data.ref.pointee; + start = 0; + bound_end = 1; + break; + case ConstPtrSpecialBaseArray: + { + ConstExprValue *array_val = dest_ptr_val->data.x_ptr.data.base_array.array_val; + expand_undef_array(ira->codegen, array_val); + dest_elements = array_val->data.x_array.data.s_none.elements; + start = dest_ptr_val->data.x_ptr.data.base_array.elem_index; + bound_end = array_val->type->data.array.len; + break; + } + case ConstPtrSpecialBaseStruct: + zig_panic("TODO memset on const inner struct"); + case ConstPtrSpecialBaseErrorUnionCode: + zig_panic("TODO memset on const inner error union code"); + case ConstPtrSpecialBaseErrorUnionPayload: + zig_panic("TODO memset on const inner error union payload"); + case ConstPtrSpecialBaseOptionalPayload: + zig_panic("TODO memset on const inner optional payload"); + case ConstPtrSpecialHardCodedAddr: + zig_unreachable(); + case ConstPtrSpecialFunction: + zig_panic("TODO memset on ptr cast from function"); + case ConstPtrSpecialNull: + zig_panic("TODO memset on null ptr"); + } - return ir_const_void(ira, &instruction->base); + size_t count = bigint_as_unsigned(&count_val->data.x_bigint); + size_t end = start + count; + if (end > bound_end) { + ir_add_error(ira, count_value, buf_sprintf("out of bounds pointer access")); + return ira->codegen->invalid_instruction; + } + + for (size_t i = start; i < end; i += 1) { + copy_const_val(&dest_elements[i], byte_val, true); + } + + return ir_const_void(ira, &instruction->base); + } } IrInstruction *result = ir_build_memset(&ira->new_irb, instruction->base.scope, instruction->base.source_node, @@ -21649,107 +21687,118 @@ static IrInstruction *ir_analyze_instruction_memcpy(IrAnalyze *ira, IrInstructio // TODO test this at comptime with u8 and non-u8 types // TODO test with dest ptr being a global runtime variable - if (casted_dest_ptr->value.special == ConstValSpecialStatic && - casted_src_ptr->value.special == ConstValSpecialStatic && - casted_count->value.special == ConstValSpecialStatic && - casted_dest_ptr->value.data.x_ptr.special != ConstPtrSpecialHardCodedAddr) + if (instr_is_comptime(casted_dest_ptr) && + instr_is_comptime(casted_src_ptr) && + instr_is_comptime(casted_count)) { - size_t count = bigint_as_unsigned(&casted_count->value.data.x_bigint); + ConstExprValue *dest_ptr_val = ir_resolve_const(ira, casted_dest_ptr, UndefBad); + if (dest_ptr_val == nullptr) + return ira->codegen->invalid_instruction; - ConstExprValue *dest_ptr_val = &casted_dest_ptr->value; - ConstExprValue *dest_elements; - size_t dest_start; - size_t dest_end; - switch (dest_ptr_val->data.x_ptr.special) { - case ConstPtrSpecialInvalid: - case ConstPtrSpecialDiscard: - zig_unreachable(); - case ConstPtrSpecialRef: - dest_elements = dest_ptr_val->data.x_ptr.data.ref.pointee; - dest_start = 0; - dest_end = 1; - break; - case ConstPtrSpecialBaseArray: - { - ConstExprValue *array_val = dest_ptr_val->data.x_ptr.data.base_array.array_val; - expand_undef_array(ira->codegen, array_val); - dest_elements = array_val->data.x_array.data.s_none.elements; - dest_start = dest_ptr_val->data.x_ptr.data.base_array.elem_index; - dest_end = array_val->type->data.array.len; - break; - } - case ConstPtrSpecialBaseStruct: - zig_panic("TODO memcpy on const inner struct"); - case ConstPtrSpecialBaseErrorUnionCode: - zig_panic("TODO memcpy on const inner error union code"); - case ConstPtrSpecialBaseErrorUnionPayload: - zig_panic("TODO memcpy on const inner error union payload"); - case ConstPtrSpecialBaseOptionalPayload: - zig_panic("TODO memcpy on const inner optional payload"); - case ConstPtrSpecialHardCodedAddr: - zig_unreachable(); - case ConstPtrSpecialFunction: - zig_panic("TODO memcpy on ptr cast from function"); - case ConstPtrSpecialNull: - zig_panic("TODO memcpy on null ptr"); - } + ConstExprValue *src_ptr_val = ir_resolve_const(ira, casted_src_ptr, UndefBad); + if (src_ptr_val == nullptr) + return ira->codegen->invalid_instruction; - if (dest_start + count > dest_end) { - ir_add_error(ira, &instruction->base, buf_sprintf("out of bounds pointer access")); + ConstExprValue *count_val = ir_resolve_const(ira, casted_count, UndefBad); + if (count_val == nullptr) return ira->codegen->invalid_instruction; - } - ConstExprValue *src_ptr_val = &casted_src_ptr->value; - ConstExprValue *src_elements; - size_t src_start; - size_t src_end; + if (dest_ptr_val->data.x_ptr.special != ConstPtrSpecialHardCodedAddr) { + size_t count = bigint_as_unsigned(&count_val->data.x_bigint); - switch (src_ptr_val->data.x_ptr.special) { - case ConstPtrSpecialInvalid: - case ConstPtrSpecialDiscard: - zig_unreachable(); - case ConstPtrSpecialRef: - src_elements = src_ptr_val->data.x_ptr.data.ref.pointee; - src_start = 0; - src_end = 1; - break; - case ConstPtrSpecialBaseArray: - { - ConstExprValue *array_val = src_ptr_val->data.x_ptr.data.base_array.array_val; - expand_undef_array(ira->codegen, array_val); - src_elements = array_val->data.x_array.data.s_none.elements; - src_start = src_ptr_val->data.x_ptr.data.base_array.elem_index; - src_end = array_val->type->data.array.len; + ConstExprValue *dest_elements; + size_t dest_start; + size_t dest_end; + switch (dest_ptr_val->data.x_ptr.special) { + case ConstPtrSpecialInvalid: + case ConstPtrSpecialDiscard: + zig_unreachable(); + case ConstPtrSpecialRef: + dest_elements = dest_ptr_val->data.x_ptr.data.ref.pointee; + dest_start = 0; + dest_end = 1; break; - } - case ConstPtrSpecialBaseStruct: - zig_panic("TODO memcpy on const inner struct"); - case ConstPtrSpecialBaseErrorUnionCode: - zig_panic("TODO memcpy on const inner error union code"); - case ConstPtrSpecialBaseErrorUnionPayload: - zig_panic("TODO memcpy on const inner error union payload"); - case ConstPtrSpecialBaseOptionalPayload: - zig_panic("TODO memcpy on const inner optional payload"); - case ConstPtrSpecialHardCodedAddr: - zig_unreachable(); - case ConstPtrSpecialFunction: - zig_panic("TODO memcpy on ptr cast from function"); - case ConstPtrSpecialNull: - zig_panic("TODO memcpy on null ptr"); - } + case ConstPtrSpecialBaseArray: + { + ConstExprValue *array_val = dest_ptr_val->data.x_ptr.data.base_array.array_val; + expand_undef_array(ira->codegen, array_val); + dest_elements = array_val->data.x_array.data.s_none.elements; + dest_start = dest_ptr_val->data.x_ptr.data.base_array.elem_index; + dest_end = array_val->type->data.array.len; + break; + } + case ConstPtrSpecialBaseStruct: + zig_panic("TODO memcpy on const inner struct"); + case ConstPtrSpecialBaseErrorUnionCode: + zig_panic("TODO memcpy on const inner error union code"); + case ConstPtrSpecialBaseErrorUnionPayload: + zig_panic("TODO memcpy on const inner error union payload"); + case ConstPtrSpecialBaseOptionalPayload: + zig_panic("TODO memcpy on const inner optional payload"); + case ConstPtrSpecialHardCodedAddr: + zig_unreachable(); + case ConstPtrSpecialFunction: + zig_panic("TODO memcpy on ptr cast from function"); + case ConstPtrSpecialNull: + zig_panic("TODO memcpy on null ptr"); + } - if (src_start + count > src_end) { - ir_add_error(ira, &instruction->base, buf_sprintf("out of bounds pointer access")); - return ira->codegen->invalid_instruction; - } + if (dest_start + count > dest_end) { + ir_add_error(ira, &instruction->base, buf_sprintf("out of bounds pointer access")); + return ira->codegen->invalid_instruction; + } - // TODO check for noalias violations - this should be generalized to work for any function + ConstExprValue *src_elements; + size_t src_start; + size_t src_end; - for (size_t i = 0; i < count; i += 1) { - copy_const_val(&dest_elements[dest_start + i], &src_elements[src_start + i], true); - } + switch (src_ptr_val->data.x_ptr.special) { + case ConstPtrSpecialInvalid: + case ConstPtrSpecialDiscard: + zig_unreachable(); + case ConstPtrSpecialRef: + src_elements = src_ptr_val->data.x_ptr.data.ref.pointee; + src_start = 0; + src_end = 1; + break; + case ConstPtrSpecialBaseArray: + { + ConstExprValue *array_val = src_ptr_val->data.x_ptr.data.base_array.array_val; + expand_undef_array(ira->codegen, array_val); + src_elements = array_val->data.x_array.data.s_none.elements; + src_start = src_ptr_val->data.x_ptr.data.base_array.elem_index; + src_end = array_val->type->data.array.len; + break; + } + case ConstPtrSpecialBaseStruct: + zig_panic("TODO memcpy on const inner struct"); + case ConstPtrSpecialBaseErrorUnionCode: + zig_panic("TODO memcpy on const inner error union code"); + case ConstPtrSpecialBaseErrorUnionPayload: + zig_panic("TODO memcpy on const inner error union payload"); + case ConstPtrSpecialBaseOptionalPayload: + zig_panic("TODO memcpy on const inner optional payload"); + case ConstPtrSpecialHardCodedAddr: + zig_unreachable(); + case ConstPtrSpecialFunction: + zig_panic("TODO memcpy on ptr cast from function"); + case ConstPtrSpecialNull: + zig_panic("TODO memcpy on null ptr"); + } - return ir_const_void(ira, &instruction->base); + if (src_start + count > src_end) { + ir_add_error(ira, &instruction->base, buf_sprintf("out of bounds pointer access")); + return ira->codegen->invalid_instruction; + } + + // TODO check for noalias violations - this should be generalized to work for any function + + for (size_t i = 0; i < count; i += 1) { + copy_const_val(&dest_elements[dest_start + i], &src_elements[src_start + i], true); + } + + return ir_const_void(ira, &instruction->base); + } } IrInstruction *result = ir_build_memcpy(&ira->new_irb, instruction->base.scope, instruction->base.source_node, @@ -22412,13 +22461,26 @@ static IrInstruction *ir_analyze_instruction_overflow_op(IrAnalyze *ira, IrInstr if (type_is_invalid(casted_result_ptr->value.type)) return ira->codegen->invalid_instruction; - if (casted_op1->value.special == ConstValSpecialStatic && - casted_op2->value.special == ConstValSpecialStatic && - casted_result_ptr->value.special == ConstValSpecialStatic) + if (instr_is_comptime(casted_op1) && + instr_is_comptime(casted_op2) && + instr_is_comptime(casted_result_ptr)) { - BigInt *op1_bigint = &casted_op1->value.data.x_bigint; - BigInt *op2_bigint = &casted_op2->value.data.x_bigint; - ConstExprValue *pointee_val = const_ptr_pointee(ira, ira->codegen, &casted_result_ptr->value, casted_result_ptr->source_node); + ConstExprValue *op1_val = ir_resolve_const(ira, casted_op1, UndefBad); + if (op1_val == nullptr) + return ira->codegen->invalid_instruction; + + ConstExprValue *op2_val = ir_resolve_const(ira, casted_op2, UndefBad); + if (op2_val == nullptr) + return ira->codegen->invalid_instruction; + + ConstExprValue *result_val = ir_resolve_const(ira, casted_result_ptr, UndefBad); + if (result_val == nullptr) + return ira->codegen->invalid_instruction; + + BigInt *op1_bigint = &op1_val->data.x_bigint; + BigInt *op2_bigint = &op2_val->data.x_bigint; + ConstExprValue *pointee_val = const_ptr_pointee(ira, ira->codegen, result_val, + casted_result_ptr->source_node); if (pointee_val == nullptr) return ira->codegen->invalid_instruction; BigInt *dest_bigint = &pointee_val->data.x_bigint; @@ -22839,9 +22901,9 @@ static IrInstruction *ir_analyze_instruction_fn_proto(IrAnalyze *ira, IrInstruct return ir_const_type(ira, &instruction->base, get_generic_fn_type(ira->codegen, &fn_type_id)); } else { IrInstruction *param_type_value = instruction->param_types[fn_type_id.next_param_index]->child; - if (type_is_invalid(param_type_value->value.type)) - return ira->codegen->invalid_instruction; ZigType *param_type = ir_resolve_type(ira, param_type_value); + if (type_is_invalid(param_type)) + return ira->codegen->invalid_instruction; switch (type_requires_comptime(ira->codegen, param_type, nullptr)) { case ReqCompTimeYes: if (!calling_convention_allows_zig_types(fn_type_id.cc)) { @@ -23271,7 +23333,12 @@ static IrInstruction *ir_analyze_ptr_cast(IrAnalyze *ira, IrInstruction *source_ if (!val) return ira->codegen->invalid_instruction; - if (val->special == ConstValSpecialStatic) { + if (value_is_comptime(val)) { + if ((err = ir_resolve_const_val(ira->codegen, ira->new_irb.exec, + source_instr->source_node, val, UndefBad))) + { + return ira->codegen->invalid_instruction; + } bool is_addr_zero = val->data.x_ptr.special == ConstPtrSpecialNull || (val->data.x_ptr.special == ConstPtrSpecialHardCodedAddr && val->data.x_ptr.data.hard_coded_addr.addr == 0); |
