authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-04-08 21:02:50-04:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2020-04-08 21:02:50-04:00
logbeae932e0f8ab39f97a142282c67c83c979f8be1
tree81390dd27b0f0290d113cc4221ddb8416be55bd1
parentc3afaa1f580510cf2ef304ce65d78a86314b38a5
parentb1e44adcba55e3839a3676db83ff61c344f3bbad
signaturebadge-question-mark Signed by PGP key 4AEE18F83AFDEB23

Merge pull request #4975 from Vexu/param-reassign

Fix missing compile error on assign to slice and array parameters

4 files changed, 57 insertions(+), 4 deletions(-)

build.zig+3-2
......@@ -225,10 +225,11 @@ fn findLLVM(b: *Builder, llvm_config_exe: []const u8) !LibraryDep {
225225 if (fs.path.isAbsolute(lib_arg)) {
226226 try result.libs.append(lib_arg);
227227 } else {
228 var lib_arg_copy = lib_arg;
228229 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];
230231 }
231 try result.system_libs.append(lib_arg);
232 try result.system_libs.append(lib_arg_copy);
232233 }
233234 }
234235 }
src/ir.cpp+17-1
......@@ -23556,10 +23556,14 @@ static IrInstGen *ir_analyze_instruction_container_init_list(IrAnalyze *ira,
2355623556 IrInstGen *result_loc = instruction->result_loc->child;
2355723557 if (type_is_invalid(result_loc->value->type))
2355823558 return result_loc;
23559
2355923560 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 }
2356023565
2356123566 ZigType *container_type = result_loc->value->type->data.pointer.child_type;
23562
2356323567 size_t elem_count = instruction->item_count;
2356423568
2356523569 if (is_slice(container_type)) {
......@@ -23710,6 +23714,11 @@ static IrInstGen *ir_analyze_instruction_container_init_fields(IrAnalyze *ira,
2371023714 return result_loc;
2371123715
2371223716 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
2371323722 ZigType *container_type = result_loc->value->type->data.pointer.child_type;
2371423723
2371523724 return ir_analyze_container_init_fields(ira, &instruction->base.base, container_type,
......@@ -27179,6 +27188,13 @@ done_with_return_type:
2717927188 if (type_is_invalid(result_loc->value->type) || result_loc->value->type->id == ZigTypeIdUnreachable) {
2718027189 return result_loc;
2718127190 }
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
2718227198 IrInstGen *dummy_value = ir_const(ira, &instruction->base.base, return_type);
2718327199 dummy_value->value->special = ConstValSpecialRuntime;
2718427200 IrInstGen *dummy_result = ir_implicit_cast2(ira, &instruction->base.base,
test/compile_errors.zig+36
......@@ -2,6 +2,42 @@ const tests = @import("tests.zig");
22const std = @import("std");
33
44pub 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
541 cases.addTest("reference to const data",
642 \\export fn foo() void {
743 \\ var ptr = &[_]u8{0,0,0,0};
test/tests.zig+1-1
......@@ -612,7 +612,7 @@ pub const StackTracesContext = struct {
612612
613613 const stdout = child.stdout.?.inStream().readAllAlloc(b.allocator, max_stdout_size) catch unreachable;
614614 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;
616616 defer b.allocator.free(stderr);
617617
618618 const term = child.wait() catch |err| {