From 38b5812c4895eb0157f99348f51c40bbd17c3b94 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Thu, 1 Aug 2019 02:37:22 -0400 Subject: allow 128 bit cmpxchg on x86_64 --- src/ir.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'src/ir.cpp') diff --git a/src/ir.cpp b/src/ir.cpp index be7a8e2e51..f34c840496 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -24735,10 +24735,11 @@ static ZigType *ir_resolve_atomic_operand_type(IrAnalyze *ira, IrInstruction *op operand_type->data.integral.bit_count)); return ira->codegen->builtin_types.entry_invalid; } - if (operand_type->data.integral.bit_count > ira->codegen->pointer_size_bytes * 8) { + uint32_t max_atomic_bits = target_arch_largest_atomic_bits(ira->codegen->zig_target->arch); + if (operand_type->data.integral.bit_count > max_atomic_bits) { ir_add_error(ira, op, - buf_sprintf("expected integer type pointer size or smaller, found %" PRIu32 "-bit integer type", - operand_type->data.integral.bit_count)); + buf_sprintf("expected %" PRIu32 "-bit integer type or smaller, found %" PRIu32 "-bit integer type", + max_atomic_bits, operand_type->data.integral.bit_count)); return ira->codegen->builtin_types.entry_invalid; } if (!is_power_of_2(operand_type->data.integral.bit_count)) { -- cgit v1.2.3 From a5cb0f77d11bdcc504fe3e6afa928c88de821518 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Fri, 2 Aug 2019 13:54:58 -0400 Subject: assignment participates in result location fix one regression with optionals but there are more --- src/ir.cpp | 21 +++++++++++++++------ test/stage1/behavior/eval.zig | 10 ++++++++++ 2 files changed, 25 insertions(+), 6 deletions(-) (limited to 'src/ir.cpp') diff --git a/src/ir.cpp b/src/ir.cpp index f34c840496..8a46fec7c9 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -4001,12 +4001,20 @@ static IrInstruction *ir_gen_bin_op_id(IrBuilder *irb, Scope *scope, AstNode *no static IrInstruction *ir_gen_assign(IrBuilder *irb, Scope *scope, AstNode *node) { IrInstruction *lvalue = ir_gen_node_extra(irb, node->data.bin_op_expr.op1, scope, LValPtr, nullptr); - IrInstruction *rvalue = ir_gen_node(irb, node->data.bin_op_expr.op2, scope); + if (lvalue == irb->codegen->invalid_instruction) + return irb->codegen->invalid_instruction; - if (lvalue == irb->codegen->invalid_instruction || rvalue == irb->codegen->invalid_instruction) + ResultLocInstruction *result_loc_inst = allocate(1); + result_loc_inst->base.id = ResultLocIdInstruction; + result_loc_inst->base.source_instruction = lvalue; + ir_ref_instruction(lvalue, irb->current_basic_block); + ir_build_reset_result(irb, scope, node, &result_loc_inst->base); + + IrInstruction *rvalue = ir_gen_node_extra(irb, node->data.bin_op_expr.op2, scope, LValNone, + &result_loc_inst->base); + if (rvalue == irb->codegen->invalid_instruction) return irb->codegen->invalid_instruction; - ir_build_store_ptr(irb, scope, node, lvalue, rvalue); return ir_build_const_void(irb, scope, node); } @@ -17477,6 +17485,7 @@ static IrInstruction *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruct return result; } else if (is_slice(array_type)) { ConstExprValue *ptr_field = &array_ptr_val->data.x_struct.fields[slice_ptr_index]; + ir_assert(ptr_field != nullptr, &elem_ptr_instruction->base); if (ptr_field->data.x_ptr.special == ConstPtrSpecialHardCodedAddr) { IrInstruction *result = ir_build_elem_ptr(&ira->new_irb, elem_ptr_instruction->base.scope, elem_ptr_instruction->base.source_node, array_ptr, casted_elem_index, false, @@ -17663,7 +17672,7 @@ static IrInstruction *ir_analyze_struct_field_ptr(IrAnalyze *ira, IrInstruction return ira->codegen->invalid_instruction; if (type_is_invalid(struct_val->type)) return ira->codegen->invalid_instruction; - if (struct_val->special == ConstValSpecialUndef && initializing) { + if (initializing && struct_val->special == ConstValSpecialUndef) { struct_val->data.x_struct.fields = create_const_vals(struct_type->data.structure.src_field_count); struct_val->special = ConstValSpecialStatic; for (size_t i = 0; i < struct_type->data.structure.src_field_count; i += 1) { @@ -18764,7 +18773,7 @@ static IrInstruction *ir_analyze_unwrap_optional_payload(IrAnalyze *ira, IrInstr if (optional_val == nullptr) return ira->codegen->invalid_instruction; - if (initializing && optional_val->special == ConstValSpecialUndef) { + if (initializing) { switch (type_has_one_possible_value(ira->codegen, child_type)) { case OnePossibleValueInvalid: return ira->codegen->invalid_instruction; @@ -23260,7 +23269,7 @@ static IrInstruction *ir_analyze_unwrap_error_payload(IrAnalyze *ira, IrInstruct ConstExprValue *err_union_val = const_ptr_pointee(ira, ira->codegen, ptr_val, source_instr->source_node); if (err_union_val == nullptr) return ira->codegen->invalid_instruction; - if (err_union_val->special == ConstValSpecialUndef && initializing) { + if (initializing && err_union_val->special == ConstValSpecialUndef) { ConstExprValue *vals = create_const_vals(2); ConstExprValue *err_set_val = &vals[0]; ConstExprValue *payload_val = &vals[1]; diff --git a/test/stage1/behavior/eval.zig b/test/stage1/behavior/eval.zig index 97d3a269cc..58d662d768 100644 --- a/test/stage1/behavior/eval.zig +++ b/test/stage1/behavior/eval.zig @@ -1,5 +1,6 @@ const std = @import("std"); const expect = std.testing.expect; +const expectEqual = std.testing.expectEqual; const builtin = @import("builtin"); test "compile time recursion" { @@ -794,3 +795,12 @@ test "no undeclared identifier error in unanalyzed branches" { lol_this_doesnt_exist = nonsense; } } + +test "comptime assign int to optional int" { + comptime { + var x: ?i32 = null; + x = 2; + x.? *= 10; + expectEqual(20, x.?); + } +} -- cgit v1.2.3 From 9069ee957cb8c9069028b325af5b862bbf8f66af Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Fri, 2 Aug 2019 15:17:02 -0400 Subject: fix discarding function call results --- src/ir.cpp | 65 +++++++++++++++++++++++++++------------------ test/stage1/behavior/fn.zig | 19 +++++++++++++ 2 files changed, 58 insertions(+), 26 deletions(-) (limited to 'src/ir.cpp') diff --git a/src/ir.cpp b/src/ir.cpp index 8a46fec7c9..de2e4e1654 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -189,7 +189,8 @@ static IrInstruction *ir_analyze_bit_cast(IrAnalyze *ira, IrInstruction *source_ static IrInstruction *ir_resolve_result_raw(IrAnalyze *ira, IrInstruction *suspend_source_instr, ResultLoc *result_loc, ZigType *value_type, IrInstruction *value, bool force_runtime, bool non_null_comptime); static IrInstruction *ir_resolve_result(IrAnalyze *ira, IrInstruction *suspend_source_instr, - ResultLoc *result_loc, ZigType *value_type, IrInstruction *value, bool force_runtime, bool non_null_comptime); + ResultLoc *result_loc, ZigType *value_type, IrInstruction *value, bool force_runtime, + bool non_null_comptime, bool allow_discard); static IrInstruction *ir_analyze_unwrap_optional_payload(IrAnalyze *ira, IrInstruction *source_instr, IrInstruction *base_ptr, bool safety_check_on, bool initializing); static IrInstruction *ir_analyze_unwrap_error_payload(IrAnalyze *ira, IrInstruction *source_instr, @@ -11163,7 +11164,8 @@ static IrInstruction *ir_resolve_ptr_of_array_to_slice(IrAnalyze *ira, IrInstruc } if (result_loc == nullptr) result_loc = no_result_loc(); - IrInstruction *result_loc_inst = ir_resolve_result(ira, source_instr, result_loc, wanted_type, nullptr, true, false); + IrInstruction *result_loc_inst = ir_resolve_result(ira, source_instr, result_loc, wanted_type, nullptr, true, + false, true); if (type_is_invalid(result_loc_inst->value.type) || instr_is_unreachable(result_loc_inst)) { return result_loc_inst; } @@ -11623,7 +11625,7 @@ static IrInstruction *ir_analyze_optional_wrap(IrAnalyze *ira, IrInstruction *so } IrInstruction *result_loc_inst = nullptr; if (result_loc != nullptr) { - result_loc_inst = ir_resolve_result(ira, source_instr, result_loc, wanted_type, nullptr, true, false); + result_loc_inst = ir_resolve_result(ira, source_instr, result_loc, wanted_type, nullptr, true, false, true); if (type_is_invalid(result_loc_inst->value.type) || instr_is_unreachable(result_loc_inst)) { return result_loc_inst; } @@ -11666,7 +11668,7 @@ static IrInstruction *ir_analyze_err_wrap_payload(IrAnalyze *ira, IrInstruction IrInstruction *result_loc_inst; if (handle_is_ptr(wanted_type)) { if (result_loc == nullptr) result_loc = no_result_loc(); - result_loc_inst = ir_resolve_result(ira, source_instr, result_loc, wanted_type, nullptr, true, false); + result_loc_inst = ir_resolve_result(ira, source_instr, result_loc, wanted_type, nullptr, true, false, true); if (type_is_invalid(result_loc_inst->value.type) || instr_is_unreachable(result_loc_inst)) { return result_loc_inst; } @@ -11751,7 +11753,7 @@ static IrInstruction *ir_analyze_err_wrap_code(IrAnalyze *ira, IrInstruction *so IrInstruction *result_loc_inst; if (handle_is_ptr(wanted_type)) { if (result_loc == nullptr) result_loc = no_result_loc(); - result_loc_inst = ir_resolve_result(ira, source_instr, result_loc, wanted_type, nullptr, true, false); + result_loc_inst = ir_resolve_result(ira, source_instr, result_loc, wanted_type, nullptr, true, false, true); if (type_is_invalid(result_loc_inst->value.type) || instr_is_unreachable(result_loc_inst)) { return result_loc_inst; } @@ -11824,7 +11826,8 @@ static IrInstruction *ir_get_ref(IrAnalyze *ira, IrInstruction *source_instructi IrInstruction *result_loc; if (type_has_bits(ptr_type) && !handle_is_ptr(value->value.type)) { - result_loc = ir_resolve_result(ira, source_instruction, no_result_loc(), value->value.type, nullptr, true, false); + result_loc = ir_resolve_result(ira, source_instruction, no_result_loc(), value->value.type, nullptr, true, + false, true); } else { result_loc = nullptr; } @@ -11868,7 +11871,8 @@ static IrInstruction *ir_analyze_array_to_slice(IrAnalyze *ira, IrInstruction *s if (!array_ptr) array_ptr = ir_get_ref(ira, source_instr, array, true, false); if (result_loc == nullptr) result_loc = no_result_loc(); - IrInstruction *result_loc_inst = ir_resolve_result(ira, source_instr, result_loc, wanted_type, nullptr, true, false); + IrInstruction *result_loc_inst = ir_resolve_result(ira, source_instr, result_loc, wanted_type, nullptr, + true, false, true); if (type_is_invalid(result_loc_inst->value.type) || instr_is_unreachable(result_loc_inst)) { return result_loc_inst; } @@ -12524,7 +12528,8 @@ static IrInstruction *ir_analyze_vector_to_array(IrAnalyze *ira, IrInstruction * if (result_loc == nullptr) { result_loc = no_result_loc(); } - IrInstruction *result_loc_inst = ir_resolve_result(ira, source_instr, result_loc, array_type, nullptr, true, false); + IrInstruction *result_loc_inst = ir_resolve_result(ira, source_instr, result_loc, array_type, nullptr, + true, false, true); if (type_is_invalid(result_loc_inst->value.type) || instr_is_unreachable(result_loc_inst)) { return result_loc_inst; } @@ -13105,7 +13110,8 @@ static IrInstruction *ir_get_deref(IrAnalyze *ira, IrInstruction *source_instruc IrInstruction *result_loc_inst; if (type_entry->data.pointer.host_int_bytes != 0 && handle_is_ptr(child_type)) { if (result_loc == nullptr) result_loc = no_result_loc(); - result_loc_inst = ir_resolve_result(ira, source_instruction, result_loc, child_type, nullptr, true, false); + result_loc_inst = ir_resolve_result(ira, source_instruction, result_loc, child_type, nullptr, + true, false, true); if (type_is_invalid(result_loc_inst->value.type) || instr_is_unreachable(result_loc_inst)) { return result_loc_inst; } @@ -15360,7 +15366,7 @@ static IrInstruction *ir_resolve_result_raw(IrAnalyze *ira, IrInstruction *suspe if (peer_parent->peers.length == 1) { IrInstruction *parent_result_loc = ir_resolve_result(ira, suspend_source_instr, peer_parent->parent, - value_type, value, force_runtime, non_null_comptime); + value_type, value, force_runtime, non_null_comptime, true); result_peer->suspend_pos.basic_block_index = SIZE_MAX; result_peer->suspend_pos.instruction_index = SIZE_MAX; if (parent_result_loc == nullptr || type_is_invalid(parent_result_loc->value.type) || @@ -15380,7 +15386,7 @@ static IrInstruction *ir_resolve_result_raw(IrAnalyze *ira, IrInstruction *suspe if (peer_parent->skipped) { if (non_null_comptime) { return ir_resolve_result(ira, suspend_source_instr, peer_parent->parent, - value_type, value, force_runtime, non_null_comptime); + value_type, value, force_runtime, non_null_comptime, true); } return nullptr; } @@ -15398,7 +15404,7 @@ static IrInstruction *ir_resolve_result_raw(IrAnalyze *ira, IrInstruction *suspe } IrInstruction *parent_result_loc = ir_resolve_result(ira, suspend_source_instr, peer_parent->parent, - peer_parent->resolved_type, nullptr, force_runtime, non_null_comptime); + peer_parent->resolved_type, nullptr, force_runtime, non_null_comptime, true); if (parent_result_loc == nullptr || type_is_invalid(parent_result_loc->value.type) || parent_result_loc->value.type->id == ZigTypeIdUnreachable) { @@ -15448,7 +15454,7 @@ static IrInstruction *ir_resolve_result_raw(IrAnalyze *ira, IrInstruction *suspe } IrInstruction *parent_result_loc = ir_resolve_result(ira, suspend_source_instr, result_bit_cast->parent, - dest_type, bitcasted_value, force_runtime, non_null_comptime); + dest_type, bitcasted_value, force_runtime, non_null_comptime, true); if (parent_result_loc == nullptr || type_is_invalid(parent_result_loc->value.type) || parent_result_loc->value.type->id == ZigTypeIdUnreachable) { @@ -15477,8 +15483,15 @@ static IrInstruction *ir_resolve_result_raw(IrAnalyze *ira, IrInstruction *suspe static IrInstruction *ir_resolve_result(IrAnalyze *ira, IrInstruction *suspend_source_instr, ResultLoc *result_loc_pass1, ZigType *value_type, IrInstruction *value, bool force_runtime, - bool non_null_comptime) + bool non_null_comptime, bool allow_discard) { + if (!allow_discard && result_loc_pass1->id == ResultLocIdInstruction && + instr_is_comptime(result_loc_pass1->source_instruction) && + result_loc_pass1->source_instruction->value.type->id == ZigTypeIdPointer && + result_loc_pass1->source_instruction->value.data.x_ptr.special == ConstPtrSpecialDiscard) + { + result_loc_pass1 = no_result_loc(); + } IrInstruction *result_loc = ir_resolve_result_raw(ira, suspend_source_instr, result_loc_pass1, value_type, value, force_runtime, non_null_comptime); if (result_loc == nullptr || (instr_is_unreachable(result_loc) || type_is_invalid(result_loc->value.type))) @@ -15533,7 +15546,7 @@ static IrInstruction *ir_analyze_instruction_resolve_result(IrAnalyze *ira, IrIn if (type_is_invalid(implicit_elem_type)) return ira->codegen->invalid_instruction; IrInstruction *result_loc = ir_resolve_result(ira, &instruction->base, instruction->result_loc, - implicit_elem_type, nullptr, false, true); + implicit_elem_type, nullptr, false, true, true); if (result_loc != nullptr) return result_loc; @@ -15542,7 +15555,7 @@ static IrInstruction *ir_analyze_instruction_resolve_result(IrAnalyze *ira, IrIn instruction->result_loc->id == ResultLocIdReturn) { result_loc = ir_resolve_result(ira, &instruction->base, no_result_loc(), - implicit_elem_type, nullptr, false, true); + implicit_elem_type, nullptr, false, true, true); if (result_loc != nullptr && (type_is_invalid(result_loc->value.type) || instr_is_unreachable(result_loc))) { @@ -15631,7 +15644,7 @@ static IrInstruction *ir_analyze_async_call(IrAnalyze *ira, IrInstructionCallSrc ZigType *async_return_type = get_error_union_type(ira->codegen, alloc_fn_error_set_type, promise_type); IrInstruction *result_loc = ir_resolve_result(ira, &call_instruction->base, no_result_loc(), - async_return_type, nullptr, true, true); + async_return_type, nullptr, true, true, false); if (type_is_invalid(result_loc->value.type) || instr_is_unreachable(result_loc)) { return result_loc; } @@ -16390,7 +16403,7 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCallSrc *c IrInstruction *result_loc; if (handle_is_ptr(impl_fn_type_id->return_type)) { result_loc = ir_resolve_result(ira, &call_instruction->base, call_instruction->result_loc, - impl_fn_type_id->return_type, nullptr, true, true); + impl_fn_type_id->return_type, nullptr, true, true, false); if (result_loc != nullptr && (type_is_invalid(result_loc->value.type) || instr_is_unreachable(result_loc))) { @@ -16512,7 +16525,7 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCallSrc *c IrInstruction *result_loc; if (handle_is_ptr(return_type)) { result_loc = ir_resolve_result(ira, &call_instruction->base, call_instruction->result_loc, - return_type, nullptr, true, true); + return_type, nullptr, true, true, false); if (result_loc != nullptr && (type_is_invalid(result_loc->value.type) || instr_is_unreachable(result_loc))) { return result_loc; } @@ -17028,7 +17041,7 @@ static IrInstruction *ir_analyze_instruction_phi(IrAnalyze *ira, IrInstructionPh // In case resolving the parent activates a suspend, do it now IrInstruction *parent_result_loc = ir_resolve_result(ira, &phi_instruction->base, peer_parent->parent, - peer_parent->resolved_type, nullptr, false, false); + peer_parent->resolved_type, nullptr, false, false, true); if (parent_result_loc != nullptr && (type_is_invalid(parent_result_loc->value.type) || instr_is_unreachable(parent_result_loc))) { @@ -21541,7 +21554,7 @@ static IrInstruction *ir_analyze_instruction_cmpxchg(IrAnalyze *ira, IrInstructi IrInstruction *result_loc; if (handle_is_ptr(result_type)) { result_loc = ir_resolve_result(ira, &instruction->base, instruction->result_loc, - result_type, nullptr, true, false); + result_type, nullptr, true, false, true); if (type_is_invalid(result_loc->value.type) || instr_is_unreachable(result_loc)) { return result_loc; } @@ -21798,7 +21811,7 @@ static IrInstruction *ir_analyze_instruction_from_bytes(IrAnalyze *ira, IrInstru } IrInstruction *result_loc = ir_resolve_result(ira, &instruction->base, instruction->result_loc, - dest_slice_type, nullptr, true, false); + dest_slice_type, nullptr, true, false, true); if (result_loc != nullptr && (type_is_invalid(result_loc->value.type) || instr_is_unreachable(result_loc))) { return result_loc; } @@ -21875,7 +21888,7 @@ static IrInstruction *ir_analyze_instruction_to_bytes(IrAnalyze *ira, IrInstruct } IrInstruction *result_loc = ir_resolve_result(ira, &instruction->base, instruction->result_loc, - dest_slice_type, nullptr, true, false); + dest_slice_type, nullptr, true, false, true); if (type_is_invalid(result_loc->value.type) || instr_is_unreachable(result_loc)) { return result_loc; } @@ -22617,7 +22630,7 @@ static IrInstruction *ir_analyze_instruction_slice(IrAnalyze *ira, IrInstruction } IrInstruction *result_loc = ir_resolve_result(ira, &instruction->base, instruction->result_loc, - return_type, nullptr, true, false); + return_type, nullptr, true, false, true); if (type_is_invalid(result_loc->value.type) || instr_is_unreachable(result_loc)) { return result_loc; } @@ -25397,7 +25410,7 @@ static IrInstruction *ir_analyze_instruction_end_expr(IrAnalyze *ira, IrInstruct bool was_written = instruction->result_loc->written; IrInstruction *result_loc = ir_resolve_result(ira, &instruction->base, instruction->result_loc, - value->value.type, value, false, false); + value->value.type, value, false, false, true); if (result_loc != nullptr) { if (type_is_invalid(result_loc->value.type)) return ira->codegen->invalid_instruction; @@ -25429,7 +25442,7 @@ static IrInstruction *ir_analyze_instruction_bit_cast_src(IrAnalyze *ira, IrInst return operand; IrInstruction *result_loc = ir_resolve_result(ira, &instruction->base, - &instruction->result_loc_bit_cast->base, operand->value.type, operand, false, false); + &instruction->result_loc_bit_cast->base, operand->value.type, operand, false, false, true); if (result_loc != nullptr && (type_is_invalid(result_loc->value.type) || instr_is_unreachable(result_loc))) return result_loc; diff --git a/test/stage1/behavior/fn.zig b/test/stage1/behavior/fn.zig index d6d670b09b..6b9c8b8fe7 100644 --- a/test/stage1/behavior/fn.zig +++ b/test/stage1/behavior/fn.zig @@ -228,3 +228,22 @@ test "implicit cast fn call result to optional in field result" { S.entry(); comptime S.entry(); } + +test "discard the result of a function that returns a struct" { + const S = struct { + fn entry() void { + _ = func(); + } + + fn func() Foo { + return undefined; + } + + const Foo = struct { + a: u64, + b: u64, + }; + }; + S.entry(); + comptime S.entry(); +} -- cgit v1.2.3 From d105769926fd5360a5309be3e202cc65d32ce604 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Fri, 2 Aug 2019 16:09:40 -0400 Subject: fix regressions regarding writing through const pointers --- src/all_types.hpp | 2 ++ src/ir.cpp | 34 ++++++++++++++++++---------------- test/compile_errors.zig | 16 ++++++++-------- 3 files changed, 28 insertions(+), 24 deletions(-) (limited to 'src/ir.cpp') diff --git a/src/all_types.hpp b/src/all_types.hpp index a6b2bc51c3..4c3aeade9e 100644 --- a/src/all_types.hpp +++ b/src/all_types.hpp @@ -2543,6 +2543,7 @@ struct IrInstructionLoadPtrGen { struct IrInstructionStorePtr { IrInstruction base; + bool allow_write_through_const; IrInstruction *ptr; IrInstruction *value; }; @@ -3707,6 +3708,7 @@ enum ResultLocId { struct ResultLoc { ResultLocId id; bool written; + bool allow_write_through_const; IrInstruction *resolved_loc; // result ptr IrInstruction *source_instruction; IrInstruction *gen_instruction; // value to store to the result loc diff --git a/src/ir.cpp b/src/ir.cpp index de2e4e1654..65a21a418d 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -198,7 +198,7 @@ static IrInstruction *ir_analyze_unwrap_error_payload(IrAnalyze *ira, IrInstruct static IrInstruction *ir_analyze_unwrap_err_code(IrAnalyze *ira, IrInstruction *source_instr, IrInstruction *base_ptr, bool initializing); static IrInstruction *ir_analyze_store_ptr(IrAnalyze *ira, IrInstruction *source_instr, - IrInstruction *ptr, IrInstruction *uncasted_value); + IrInstruction *ptr, IrInstruction *uncasted_value, bool allow_write_through_const); static IrInstruction *ir_gen_union_init_expr(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *union_type, IrInstruction *field_name, AstNode *expr_node, LVal lval, ResultLoc *parent_result_loc); @@ -1613,7 +1613,7 @@ static IrInstruction *ir_build_unreachable(IrBuilder *irb, Scope *scope, AstNode return &unreachable_instruction->base; } -static IrInstruction *ir_build_store_ptr(IrBuilder *irb, Scope *scope, AstNode *source_node, +static IrInstructionStorePtr *ir_build_store_ptr(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *ptr, IrInstruction *value) { IrInstructionStorePtr *instruction = ir_build_instruction(irb, scope, source_node); @@ -1625,7 +1625,7 @@ static IrInstruction *ir_build_store_ptr(IrBuilder *irb, Scope *scope, AstNode * ir_ref_instruction(ptr, irb->current_basic_block); ir_ref_instruction(value, irb->current_basic_block); - return &instruction->base; + return instruction; } static IrInstruction *ir_build_var_decl_src(IrBuilder *irb, Scope *scope, AstNode *source_node, @@ -6051,6 +6051,7 @@ static IrInstruction *ir_gen_container_init_expr(IrBuilder *irb, Scope *scope, A ResultLocInstruction *result_loc_inst = allocate(1); result_loc_inst->base.id = ResultLocIdInstruction; result_loc_inst->base.source_instruction = field_ptr; + result_loc_inst->base.allow_write_through_const = true; ir_ref_instruction(field_ptr, irb->current_basic_block); ir_build_reset_result(irb, scope, expr_node, &result_loc_inst->base); @@ -6089,6 +6090,7 @@ static IrInstruction *ir_gen_container_init_expr(IrBuilder *irb, Scope *scope, A ResultLocInstruction *result_loc_inst = allocate(1); result_loc_inst->base.id = ResultLocIdInstruction; result_loc_inst->base.source_instruction = elem_ptr; + result_loc_inst->base.allow_write_through_const = true; ir_ref_instruction(elem_ptr, irb->current_basic_block); ir_build_reset_result(irb, scope, expr_node, &result_loc_inst->base); @@ -6646,7 +6648,7 @@ static IrInstruction *ir_gen_for_expr(IrBuilder *irb, Scope *parent_scope, AstNo ir_set_cursor_at_end_and_append_block(irb, continue_block); IrInstruction *new_index_val = ir_build_bin_op(irb, child_scope, node, IrBinOpAdd, index_val, one, false); - ir_mark_gen(ir_build_store_ptr(irb, child_scope, node, index_ptr, new_index_val)); + ir_build_store_ptr(irb, child_scope, node, index_ptr, new_index_val)->allow_write_through_const = true; ir_build_br(irb, child_scope, node, cond_block, is_comptime); IrInstruction *else_result = nullptr; @@ -14848,7 +14850,7 @@ static IrInstruction *ir_analyze_instruction_decl_var(IrAnalyze *ira, // instruction. assert(deref->value.special != ConstValSpecialRuntime); var_ptr->value.special = ConstValSpecialRuntime; - ir_analyze_store_ptr(ira, var_ptr, var_ptr, deref); + ir_analyze_store_ptr(ira, var_ptr, var_ptr, deref, false); } if (var_ptr->value.special == ConstValSpecialStatic && var->mem_slot_index != SIZE_MAX) { @@ -15862,7 +15864,7 @@ no_mem_slot: } static IrInstruction *ir_analyze_store_ptr(IrAnalyze *ira, IrInstruction *source_instr, - IrInstruction *ptr, IrInstruction *uncasted_value) + IrInstruction *ptr, IrInstruction *uncasted_value, bool allow_write_through_const) { assert(ptr->value.type->id == ZigTypeIdPointer); @@ -15878,7 +15880,7 @@ static IrInstruction *ir_analyze_store_ptr(IrAnalyze *ira, IrInstruction *source ZigType *child_type = ptr->value.type->data.pointer.child_type; - if (ptr->value.type->data.pointer.is_const && !source_instr->is_gen) { + if (ptr->value.type->data.pointer.is_const && !allow_write_through_const) { ir_add_error(ira, source_instr, buf_sprintf("cannot assign to constant")); return ira->codegen->invalid_instruction; } @@ -15957,10 +15959,9 @@ static IrInstruction *ir_analyze_store_ptr(IrAnalyze *ira, IrInstruction *source break; } - IrInstruction *result = ir_build_store_ptr(&ira->new_irb, source_instr->scope, source_instr->source_node, - ptr, value); - result->value.type = ira->codegen->builtin_types.entry_void; - return result; + IrInstructionStorePtr *store_ptr = ir_build_store_ptr(&ira->new_irb, source_instr->scope, + source_instr->source_node, ptr, value); + return &store_ptr->base; } static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCallSrc *call_instruction, @@ -18283,7 +18284,7 @@ static IrInstruction *ir_analyze_instruction_store_ptr(IrAnalyze *ira, IrInstruc if (type_is_invalid(value->value.type)) return ira->codegen->invalid_instruction; - return ir_analyze_store_ptr(ira, &instruction->base, ptr, value); + return ir_analyze_store_ptr(ira, &instruction->base, ptr, value, instruction->allow_write_through_const); } static IrInstruction *ir_analyze_instruction_load_ptr(IrAnalyze *ira, IrInstructionLoadPtr *instruction) { @@ -19691,7 +19692,7 @@ static IrInstruction *ir_analyze_container_init_fields(IrAnalyze *ira, IrInstruc IrInstruction *field_ptr = ir_analyze_struct_field_ptr(ira, instruction, field, result_loc, container_type, true); - ir_analyze_store_ptr(ira, instruction, field_ptr, runtime_inst); + ir_analyze_store_ptr(ira, instruction, field_ptr, runtime_inst, false); if (instr_is_comptime(field_ptr) && field_ptr->value.data.x_ptr.mut != ConstPtrMutRuntimeVar) { const_ptrs.append(field_ptr); } else { @@ -19708,7 +19709,7 @@ static IrInstruction *ir_analyze_container_init_fields(IrAnalyze *ira, IrInstruc IrInstruction *field_result_loc = const_ptrs.at(i); IrInstruction *deref = ir_get_deref(ira, field_result_loc, field_result_loc, nullptr); field_result_loc->value.special = ConstValSpecialRuntime; - ir_analyze_store_ptr(ira, field_result_loc, field_result_loc, deref); + ir_analyze_store_ptr(ira, field_result_loc, field_result_loc, deref, false); } } } @@ -19835,7 +19836,7 @@ static IrInstruction *ir_analyze_instruction_container_init_list(IrAnalyze *ira, assert(elem_result_loc->value.special == ConstValSpecialStatic); IrInstruction *deref = ir_get_deref(ira, elem_result_loc, elem_result_loc, nullptr); elem_result_loc->value.special = ConstValSpecialRuntime; - ir_analyze_store_ptr(ira, elem_result_loc, elem_result_loc, deref); + ir_analyze_store_ptr(ira, elem_result_loc, elem_result_loc, deref, false); } } } @@ -25418,7 +25419,8 @@ static IrInstruction *ir_analyze_instruction_end_expr(IrAnalyze *ira, IrInstruct return result_loc; if (!was_written) { - IrInstruction *store_ptr = ir_analyze_store_ptr(ira, &instruction->base, result_loc, value); + IrInstruction *store_ptr = ir_analyze_store_ptr(ira, &instruction->base, result_loc, value, + instruction->result_loc->allow_write_through_const); if (type_is_invalid(store_ptr->value.type)) { return ira->codegen->invalid_instruction; } diff --git a/test/compile_errors.zig b/test/compile_errors.zig index 40ce8d304b..a4bc2a66f0 100644 --- a/test/compile_errors.zig +++ b/test/compile_errors.zig @@ -201,7 +201,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { \\ return error.OutOfMemory; \\} , - "tmp.zig:2:7: error: error is discarded", + "tmp.zig:2:12: error: error is discarded", ); cases.add( @@ -2740,7 +2740,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { \\ 3 = 3; \\} , - "tmp.zig:2:7: error: cannot assign to constant", + "tmp.zig:2:9: error: cannot assign to constant", ); cases.add( @@ -2750,7 +2750,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { \\ a = 4; \\} , - "tmp.zig:3:7: error: cannot assign to constant", + "tmp.zig:3:9: error: cannot assign to constant", ); cases.add( @@ -2820,7 +2820,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { \\} \\export fn entry() void { f(); } , - "tmp.zig:3:7: error: cannot assign to constant", + "tmp.zig:3:9: error: cannot assign to constant", ); cases.add( @@ -3883,7 +3883,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { \\ \\export fn entry() usize { return @sizeOf(@typeOf(a)); } , - "tmp.zig:6:24: error: unable to evaluate constant expression", + "tmp.zig:6:26: error: unable to evaluate constant expression", "tmp.zig:4:17: note: called from here", ); @@ -4133,7 +4133,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { \\ cstr[0] = 'W'; \\} , - "tmp.zig:3:11: error: cannot assign to constant", + "tmp.zig:3:13: error: cannot assign to constant", ); cases.add( @@ -4143,7 +4143,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { \\ cstr[0] = 'W'; \\} , - "tmp.zig:3:11: error: cannot assign to constant", + "tmp.zig:3:13: error: cannot assign to constant", ); cases.add( @@ -4291,7 +4291,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { \\ f.field = 0; \\} , - "tmp.zig:6:13: error: cannot assign to constant", + "tmp.zig:6:15: error: cannot assign to constant", ); cases.add( -- cgit v1.2.3