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 {...@@ -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 }
2356023565
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;
2356423568
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;
2371123715
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;
2371423723
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");
2const std = @import("std");2const std = @import("std");
33
4pub fn addCases(cases: *tests.CompileErrorContext) void {4pub 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 {
612612
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);
617617
618 const term = child.wait() catch |err| {618 const term = child.wait() catch |err| {