| ... | @@ -10624,13 +10624,16 @@ static ZigType *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_node, ZigT | ... | @@ -10624,13 +10624,16 @@ static ZigType *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_node, ZigT |
| 10624 | | 10624 | |
| 10625 | static void copy_const_val(ConstExprValue *dest, ConstExprValue *src, bool same_global_refs) { | 10625 | static void copy_const_val(ConstExprValue *dest, ConstExprValue *src, bool same_global_refs) { |
| 10626 | ConstGlobalRefs *global_refs = dest->global_refs; | 10626 | ConstGlobalRefs *global_refs = dest->global_refs; |
| 10627 | assert(!same_global_refs || src->global_refs != nullptr); | 10627 | memcpy(dest, src, sizeof(ConstExprValue)); |
| 10628 | *dest = *src; | | |
| 10629 | if (!same_global_refs) { | 10628 | if (!same_global_refs) { |
| 10630 | dest->global_refs = global_refs; | 10629 | dest->global_refs = global_refs; |
| | 10630 | if (src->special == ConstValSpecialUndef) |
| | 10631 | return; |
| 10631 | if (dest->type->id == ZigTypeIdStruct) { | 10632 | if (dest->type->id == ZigTypeIdStruct) { |
| 10632 | dest->data.x_struct.fields = allocate_nonzero<ConstExprValue>(dest->type->data.structure.src_field_count); | 10633 | dest->data.x_struct.fields = create_const_vals(dest->type->data.structure.src_field_count); |
| 10633 | memcpy(dest->data.x_struct.fields, src->data.x_struct.fields, sizeof(ConstExprValue) * dest->type->data.structure.src_field_count); | 10634 | for (size_t i = 0; i < dest->type->data.structure.src_field_count; i += 1) { |
| | 10635 | copy_const_val(&dest->data.x_struct.fields[i], &src->data.x_struct.fields[i], false); |
| | 10636 | } |
| 10634 | } | 10637 | } |
| 10635 | } | 10638 | } |
| 10636 | } | 10639 | } |
| ... | @@ -13579,7 +13582,7 @@ static ErrorMsg *ir_eval_math_op_scalar(IrAnalyze *ira, IrInstruction *source_in | ... | @@ -13579,7 +13582,7 @@ static ErrorMsg *ir_eval_math_op_scalar(IrAnalyze *ira, IrInstruction *source_in |
| 13579 | } | 13582 | } |
| 13580 | } else { | 13583 | } else { |
| 13581 | float_div_trunc(out_val, op1_val, op2_val); | 13584 | float_div_trunc(out_val, op1_val, op2_val); |
| 13582 | ConstExprValue remainder; | 13585 | ConstExprValue remainder = {}; |
| 13583 | float_rem(&remainder, op1_val, op2_val); | 13586 | float_rem(&remainder, op1_val, op2_val); |
| 13584 | if (float_cmp_zero(&remainder) != CmpEQ) { | 13587 | if (float_cmp_zero(&remainder) != CmpEQ) { |
| 13585 | return ir_add_error(ira, source_instr, buf_sprintf("exact division had a remainder")); | 13588 | return ir_add_error(ira, source_instr, buf_sprintf("exact division had a remainder")); |
| ... | @@ -13954,8 +13957,8 @@ static IrInstruction *ir_analyze_bin_op_math(IrAnalyze *ira, IrInstructionBinOp | ... | @@ -13954,8 +13957,8 @@ static IrInstruction *ir_analyze_bin_op_math(IrAnalyze *ira, IrInstructionBinOp |
| 13954 | // have a remainder function ambiguity problem | 13957 | // have a remainder function ambiguity problem |
| 13955 | ok = true; | 13958 | ok = true; |
| 13956 | } else { | 13959 | } else { |
| 13957 | ConstExprValue rem_result; | 13960 | ConstExprValue rem_result = {}; |
| 13958 | ConstExprValue mod_result; | 13961 | ConstExprValue mod_result = {}; |
| 13959 | float_rem(&rem_result, op1_val, op2_val); | 13962 | float_rem(&rem_result, op1_val, op2_val); |
| 13960 | float_mod(&mod_result, op1_val, op2_val); | 13963 | float_mod(&mod_result, op1_val, op2_val); |
| 13961 | ok = float_cmp(&rem_result, &mod_result) == CmpEQ; | 13964 | ok = float_cmp(&rem_result, &mod_result) == CmpEQ; |
| ... | @@ -14178,10 +14181,12 @@ static IrInstruction *ir_analyze_array_cat(IrAnalyze *ira, IrInstructionBinOp *i | ... | @@ -14178,10 +14181,12 @@ static IrInstruction *ir_analyze_array_cat(IrAnalyze *ira, IrInstructionBinOp *i |
| 14178 | | 14181 | |
| 14179 | size_t next_index = 0; | 14182 | size_t next_index = 0; |
| 14180 | for (size_t i = op1_array_index; i < op1_array_end; i += 1, next_index += 1) { | 14183 | for (size_t i = op1_array_index; i < op1_array_end; i += 1, next_index += 1) { |
| 14181 | out_array_val->data.x_array.data.s_none.elements[next_index] = op1_array_val->data.x_array.data.s_none.elements[i]; | 14184 | copy_const_val(&out_array_val->data.x_array.data.s_none.elements[next_index], |
| | 14185 | &op1_array_val->data.x_array.data.s_none.elements[i], true); |
| 14182 | } | 14186 | } |
| 14183 | for (size_t i = op2_array_index; i < op2_array_end; i += 1, next_index += 1) { | 14187 | for (size_t i = op2_array_index; i < op2_array_end; i += 1, next_index += 1) { |
| 14184 | out_array_val->data.x_array.data.s_none.elements[next_index] = op2_array_val->data.x_array.data.s_none.elements[i]; | 14188 | copy_const_val(&out_array_val->data.x_array.data.s_none.elements[next_index], |
| | 14189 | &op2_array_val->data.x_array.data.s_none.elements[i], true); |
| 14185 | } | 14190 | } |
| 14186 | if (next_index < new_len) { | 14191 | if (next_index < new_len) { |
| 14187 | ConstExprValue *null_byte = &out_array_val->data.x_array.data.s_none.elements[next_index]; | 14192 | ConstExprValue *null_byte = &out_array_val->data.x_array.data.s_none.elements[next_index]; |
| ... | @@ -14242,7 +14247,8 @@ static IrInstruction *ir_analyze_array_mult(IrAnalyze *ira, IrInstructionBinOp * | ... | @@ -14242,7 +14247,8 @@ static IrInstruction *ir_analyze_array_mult(IrAnalyze *ira, IrInstructionBinOp * |
| 14242 | uint64_t i = 0; | 14247 | uint64_t i = 0; |
| 14243 | for (uint64_t x = 0; x < mult_amt; x += 1) { | 14248 | for (uint64_t x = 0; x < mult_amt; x += 1) { |
| 14244 | for (uint64_t y = 0; y < old_array_len; y += 1) { | 14249 | for (uint64_t y = 0; y < old_array_len; y += 1) { |
| 14245 | out_val->data.x_array.data.s_none.elements[i] = array_val->data.x_array.data.s_none.elements[y]; | 14250 | copy_const_val(&out_val->data.x_array.data.s_none.elements[i], |
| | 14251 | &array_val->data.x_array.data.s_none.elements[y], true); |
| 14246 | i += 1; | 14252 | i += 1; |
| 14247 | } | 14253 | } |
| 14248 | } | 14254 | } |
| ... | @@ -14382,7 +14388,12 @@ static IrInstruction *ir_analyze_instruction_decl_var(IrAnalyze *ira, | ... | @@ -14382,7 +14388,12 @@ static IrInstruction *ir_analyze_instruction_decl_var(IrAnalyze *ira, |
| 14382 | if (instr_is_comptime(var_ptr) && var_ptr->value.data.x_ptr.mut != ConstPtrMutRuntimeVar) { | 14388 | if (instr_is_comptime(var_ptr) && var_ptr->value.data.x_ptr.mut != ConstPtrMutRuntimeVar) { |
| 14383 | init_val = const_ptr_pointee(ira, ira->codegen, &var_ptr->value, decl_var_instruction->base.source_node); | 14389 | init_val = const_ptr_pointee(ira, ira->codegen, &var_ptr->value, decl_var_instruction->base.source_node); |
| 14384 | if (is_comptime_var) { | 14390 | if (is_comptime_var) { |
| 14385 | var->const_value = init_val; | 14391 | if (var->gen_is_const) { |
| | 14392 | var->const_value = init_val; |
| | 14393 | } else { |
| | 14394 | var->const_value = create_const_vals(1); |
| | 14395 | copy_const_val(var->const_value, init_val, false); |
| | 14396 | } |
| 14386 | } | 14397 | } |
| 14387 | } | 14398 | } |
| 14388 | | 14399 | |
| ... | @@ -15291,7 +15302,7 @@ static bool ir_analyze_fn_call_generic_arg(IrAnalyze *ira, AstNode *fn_proto_nod | ... | @@ -15291,7 +15302,7 @@ static bool ir_analyze_fn_call_generic_arg(IrAnalyze *ira, AstNode *fn_proto_nod |
| 15291 | arg_val = create_const_runtime(casted_arg->value.type); | 15302 | arg_val = create_const_runtime(casted_arg->value.type); |
| 15292 | } | 15303 | } |
| 15293 | if (arg_part_of_generic_id) { | 15304 | if (arg_part_of_generic_id) { |
| 15294 | generic_id->params[generic_id->param_count] = *arg_val; | 15305 | copy_const_val(&generic_id->params[generic_id->param_count], arg_val, true); |
| 15295 | generic_id->param_count += 1; | 15306 | generic_id->param_count += 1; |
| 15296 | } | 15307 | } |
| 15297 | | 15308 | |
| ... | @@ -15476,7 +15487,7 @@ static IrInstruction *ir_analyze_store_ptr(IrAnalyze *ira, IrInstruction *source | ... | @@ -15476,7 +15487,7 @@ static IrInstruction *ir_analyze_store_ptr(IrAnalyze *ira, IrInstruction *source |
| 15476 | // * "string literal used as comptime slice is memoized" | 15487 | // * "string literal used as comptime slice is memoized" |
| 15477 | // * "comptime modification of const struct field" - except modified to avoid | 15488 | // * "comptime modification of const struct field" - except modified to avoid |
| 15478 | // ConstPtrMutComptimeVar, thus defeating the logic below. | 15489 | // ConstPtrMutComptimeVar, thus defeating the logic below. |
| 15479 | bool same_global_refs = ptr->value.data.x_ptr.mut != ConstPtrMutComptimeVar; | 15490 | bool same_global_refs = ptr->value.data.x_ptr.mut == ConstPtrMutComptimeConst; |
| 15480 | copy_const_val(dest_val, &value->value, same_global_refs); | 15491 | copy_const_val(dest_val, &value->value, same_global_refs); |
| 15481 | if (!ira->new_irb.current_basic_block->must_be_comptime_source_instr) { | 15492 | if (!ira->new_irb.current_basic_block->must_be_comptime_source_instr) { |
| 15482 | ira->new_irb.current_basic_block->must_be_comptime_source_instr = source_instr; | 15493 | ira->new_irb.current_basic_block->must_be_comptime_source_instr = source_instr; |
| ... | @@ -15877,7 +15888,7 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCallSrc *c | ... | @@ -15877,7 +15888,7 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCallSrc *c |
| 15877 | nullptr, nullptr, fn_proto_node->data.fn_proto.align_expr, nullptr, ira->new_irb.exec, nullptr); | 15888 | nullptr, nullptr, fn_proto_node->data.fn_proto.align_expr, nullptr, ira->new_irb.exec, nullptr); |
| 15878 | IrInstructionConst *const_instruction = ir_create_instruction<IrInstructionConst>(&ira->new_irb, | 15889 | IrInstructionConst *const_instruction = ir_create_instruction<IrInstructionConst>(&ira->new_irb, |
| 15879 | impl_fn->child_scope, fn_proto_node->data.fn_proto.align_expr); | 15890 | impl_fn->child_scope, fn_proto_node->data.fn_proto.align_expr); |
| 15880 | const_instruction->base.value = *align_result; | 15891 | copy_const_val(&const_instruction->base.value, align_result, true); |
| 15881 | | 15892 | |
| 15882 | uint32_t align_bytes = 0; | 15893 | uint32_t align_bytes = 0; |
| 15883 | ir_resolve_align(ira, &const_instruction->base, &align_bytes); | 15894 | ir_resolve_align(ira, &const_instruction->base, &align_bytes); |
| ... | @@ -21667,7 +21678,7 @@ static IrInstruction *ir_analyze_instruction_memset(IrAnalyze *ira, IrInstructio | ... | @@ -21667,7 +21678,7 @@ static IrInstruction *ir_analyze_instruction_memset(IrAnalyze *ira, IrInstructio |
| 21667 | | 21678 | |
| 21668 | ConstExprValue *byte_val = &casted_byte->value; | 21679 | ConstExprValue *byte_val = &casted_byte->value; |
| 21669 | for (size_t i = start; i < end; i += 1) { | 21680 | for (size_t i = start; i < end; i += 1) { |
| 21670 | dest_elements[i] = *byte_val; | 21681 | copy_const_val(&dest_elements[i], byte_val, true); |
| 21671 | } | 21682 | } |
| 21672 | | 21683 | |
| 21673 | return ir_const_void(ira, &instruction->base); | 21684 | return ir_const_void(ira, &instruction->base); |
| ... | @@ -21835,7 +21846,7 @@ static IrInstruction *ir_analyze_instruction_memcpy(IrAnalyze *ira, IrInstructio | ... | @@ -21835,7 +21846,7 @@ static IrInstruction *ir_analyze_instruction_memcpy(IrAnalyze *ira, IrInstructio |
| 21835 | // TODO check for noalias violations - this should be generalized to work for any function | 21846 | // TODO check for noalias violations - this should be generalized to work for any function |
| 21836 | | 21847 | |
| 21837 | for (size_t i = 0; i < count; i += 1) { | 21848 | for (size_t i = 0; i < count; i += 1) { |
| 21838 | dest_elements[dest_start + i] = src_elements[src_start + i]; | 21849 | copy_const_val(&dest_elements[dest_start + i], &src_elements[src_start + i], true); |
| 21839 | } | 21850 | } |
| 21840 | | 21851 | |
| 21841 | return ir_const_void(ira, &instruction->base); | 21852 | return ir_const_void(ira, &instruction->base); |