| author | |
| committer | |
| log | beae932e0f8ab39f97a142282c67c83c979f8be1 |
| tree | 81390dd27b0f0290d113cc4221ddb8416be55bd1 |
| parent | c3afaa1f580510cf2ef304ce65d78a86314b38a5 |
| parent | b1e44adcba55e3839a3676db83ff61c344f3bbad |
| signature |
Fix missing compile error on assign to slice and array parameters4 files changed, 57 insertions(+), 4 deletions(-)
build.zig+3-2| ... | @@ -225,10 +225,11 @@ fn findLLVM(b: *Builder, llvm_config_exe: []const u8) !LibraryDep { | ... | @@ -225,10 +225,11 @@ fn findLLVM(b: *Builder, llvm_config_exe: []const u8) !LibraryDep { |
| 225 | if (fs.path.isAbsolute(lib_arg)) { | 225 | if (fs.path.isAbsolute(lib_arg)) { |
| 226 | try result.libs.append(lib_arg); | 226 | try result.libs.append(lib_arg); |
| 227 | } else { | 227 | } else { |
| 228 | var lib_arg_copy = lib_arg; | ||
| 228 | if (mem.endsWith(u8, lib_arg, ".lib")) { | 229 | if (mem.endsWith(u8, lib_arg, ".lib")) { |
| 229 | lib_arg = lib_arg[0 .. lib_arg.len - 4]; | 230 | lib_arg_copy = lib_arg[0 .. lib_arg.len - 4]; |
| 230 | } | 231 | } |
| 231 | try result.system_libs.append(lib_arg); | 232 | try result.system_libs.append(lib_arg_copy); |
| 232 | } | 233 | } |
| 233 | } | 234 | } |
| 234 | } | 235 | } |
src/ir.cpp+17-1| ... | @@ -23556,10 +23556,14 @@ static IrInstGen *ir_analyze_instruction_container_init_list(IrAnalyze *ira, | ... | @@ -23556,10 +23556,14 @@ static IrInstGen *ir_analyze_instruction_container_init_list(IrAnalyze *ira, |
| 23556 | IrInstGen *result_loc = instruction->result_loc->child; | 23556 | IrInstGen *result_loc = instruction->result_loc->child; |
| 23557 | if (type_is_invalid(result_loc->value->type)) | 23557 | if (type_is_invalid(result_loc->value->type)) |
| 23558 | return result_loc; | 23558 | return result_loc; |
| 23559 | |||
| 23559 | ir_assert(result_loc->value->type->id == ZigTypeIdPointer, &instruction->base.base); | 23560 | ir_assert(result_loc->value->type->id == ZigTypeIdPointer, &instruction->base.base); |
| 23561 | if (result_loc->value->type->data.pointer.is_const) { | ||
| 23562 | ir_add_error(ira, &instruction->base.base, buf_sprintf("cannot assign to constant")); | ||
| 23563 | return ira->codegen->invalid_inst_gen; | ||
| 23564 | } | ||
| 23560 | 23565 | ||
| 23561 | ZigType *container_type = result_loc->value->type->data.pointer.child_type; | 23566 | ZigType *container_type = result_loc->value->type->data.pointer.child_type; |
| 23562 | |||
| 23563 | size_t elem_count = instruction->item_count; | 23567 | size_t elem_count = instruction->item_count; |
| 23564 | 23568 | ||
| 23565 | if (is_slice(container_type)) { | 23569 | if (is_slice(container_type)) { |
| ... | @@ -23710,6 +23714,11 @@ static IrInstGen *ir_analyze_instruction_container_init_fields(IrAnalyze *ira, | ... | @@ -23710,6 +23714,11 @@ static IrInstGen *ir_analyze_instruction_container_init_fields(IrAnalyze *ira, |
| 23710 | return result_loc; | 23714 | return result_loc; |
| 23711 | 23715 | ||
| 23712 | ir_assert(result_loc->value->type->id == ZigTypeIdPointer, &instruction->base.base); | 23716 | ir_assert(result_loc->value->type->id == ZigTypeIdPointer, &instruction->base.base); |
| 23717 | if (result_loc->value->type->data.pointer.is_const) { | ||
| 23718 | ir_add_error(ira, &instruction->base.base, buf_sprintf("cannot assign to constant")); | ||
| 23719 | return ira->codegen->invalid_inst_gen; | ||
| 23720 | } | ||
| 23721 | |||
| 23713 | ZigType *container_type = result_loc->value->type->data.pointer.child_type; | 23722 | ZigType *container_type = result_loc->value->type->data.pointer.child_type; |
| 23714 | 23723 | ||
| 23715 | return ir_analyze_container_init_fields(ira, &instruction->base.base, container_type, | 23724 | return ir_analyze_container_init_fields(ira, &instruction->base.base, container_type, |
| ... | @@ -27179,6 +27188,13 @@ done_with_return_type: | ... | @@ -27179,6 +27188,13 @@ done_with_return_type: |
| 27179 | if (type_is_invalid(result_loc->value->type) || result_loc->value->type->id == ZigTypeIdUnreachable) { | 27188 | if (type_is_invalid(result_loc->value->type) || result_loc->value->type->id == ZigTypeIdUnreachable) { |
| 27180 | return result_loc; | 27189 | return result_loc; |
| 27181 | } | 27190 | } |
| 27191 | |||
| 27192 | ir_assert(result_loc->value->type->id == ZigTypeIdPointer, &instruction->base.base); | ||
| 27193 | if (result_loc->value->type->data.pointer.is_const) { | ||
| 27194 | ir_add_error(ira, &instruction->base.base, buf_sprintf("cannot assign to constant")); | ||
| 27195 | return ira->codegen->invalid_inst_gen; | ||
| 27196 | } | ||
| 27197 | |||
| 27182 | IrInstGen *dummy_value = ir_const(ira, &instruction->base.base, return_type); | 27198 | IrInstGen *dummy_value = ir_const(ira, &instruction->base.base, return_type); |
| 27183 | dummy_value->value->special = ConstValSpecialRuntime; | 27199 | dummy_value->value->special = ConstValSpecialRuntime; |
| 27184 | IrInstGen *dummy_result = ir_implicit_cast2(ira, &instruction->base.base, | 27200 | IrInstGen *dummy_result = ir_implicit_cast2(ira, &instruction->base.base, |
test/compile_errors.zig+36| ... | @@ -2,6 +2,42 @@ const tests = @import("tests.zig"); | ... | @@ -2,6 +2,42 @@ const tests = @import("tests.zig"); |
| 2 | const std = @import("std"); | 2 | const std = @import("std"); |
| 3 | 3 | ||
| 4 | pub fn addCases(cases: *tests.CompileErrorContext) void { | 4 | pub fn addCases(cases: *tests.CompileErrorContext) void { |
| 5 | cases.addTest("reassign to array parameter", | ||
| 6 | \\fn reassign(a: [3]f32) void { | ||
| 7 | \\ a = [3]f32{4, 5, 6}; | ||
| 8 | \\} | ||
| 9 | \\export fn entry() void { | ||
| 10 | \\ reassign(.{1, 2, 3}); | ||
| 11 | \\} | ||
| 12 | , &[_][]const u8{ | ||
| 13 | "tmp.zig:2:15: error: cannot assign to constant" | ||
| 14 | }); | ||
| 15 | |||
| 16 | cases.addTest("reassign to slice parameter", | ||
| 17 | \\pub fn reassign(s: []const u8) void { | ||
| 18 | \\ s = s[0..]; | ||
| 19 | \\} | ||
| 20 | \\export fn entry() void { | ||
| 21 | \\ reassign("foo"); | ||
| 22 | \\} | ||
| 23 | , &[_][]const u8{ | ||
| 24 | "tmp.zig:2:10: error: cannot assign to constant" | ||
| 25 | }); | ||
| 26 | |||
| 27 | cases.addTest("reassign to struct parameter", | ||
| 28 | \\const S = struct { | ||
| 29 | \\ x: u32, | ||
| 30 | \\}; | ||
| 31 | \\fn reassign(s: S) void { | ||
| 32 | \\ s = S{.x = 2}; | ||
| 33 | \\} | ||
| 34 | \\export fn entry() void { | ||
| 35 | \\ reassign(S{.x = 3}); | ||
| 36 | \\} | ||
| 37 | , &[_][]const u8{ | ||
| 38 | "tmp.zig:5:10: error: cannot assign to constant" | ||
| 39 | }); | ||
| 40 | |||
| 5 | cases.addTest("reference to const data", | 41 | cases.addTest("reference to const data", |
| 6 | \\export fn foo() void { | 42 | \\export fn foo() void { |
| 7 | \\ var ptr = &[_]u8{0,0,0,0}; | 43 | \\ var ptr = &[_]u8{0,0,0,0}; |
test/tests.zig+1-1| ... | @@ -612,7 +612,7 @@ pub const StackTracesContext = struct { | ... | @@ -612,7 +612,7 @@ pub const StackTracesContext = struct { |
| 612 | 612 | ||
| 613 | const stdout = child.stdout.?.inStream().readAllAlloc(b.allocator, max_stdout_size) catch unreachable; | 613 | const stdout = child.stdout.?.inStream().readAllAlloc(b.allocator, max_stdout_size) catch unreachable; |
| 614 | defer b.allocator.free(stdout); | 614 | defer b.allocator.free(stdout); |
| 615 | const stderr = child.stderr.?.inStream().readAllAlloc(b.allocator, max_stdout_size) catch unreachable; | 615 | var stderr = child.stderr.?.inStream().readAllAlloc(b.allocator, max_stdout_size) catch unreachable; |
| 616 | defer b.allocator.free(stderr); | 616 | defer b.allocator.free(stderr); |
| 617 | 617 | ||
| 618 | const term = child.wait() catch |err| { | 618 | const term = child.wait() catch |err| { |